From 697e99c8210bcf76855d7c114bbd1a99d935318b Mon Sep 17 00:00:00 2001 From: Dmitry Kichinsky Date: Sat, 1 Feb 2025 13:38:08 +0100 Subject: [PATCH] [maven] IDEA-255308 fix "Package not found" error for multi-release modules GitOrigin-RevId: c0450edd873e2a8a7f3d8fdea5000acb313d3b21 --- .../impl/analysis/ModuleHighlightUtil.java | 7 ++- .../daemon/impl/analysis/MultiReleaseUtil.kt | 48 +++++++++++++------ .../psi/impl/JavaPlatformModuleSystem.kt | 2 +- 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/ModuleHighlightUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/ModuleHighlightUtil.java index 5745477bf658..67b227394795 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/ModuleHighlightUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/ModuleHighlightUtil.java @@ -27,6 +27,7 @@ import com.intellij.psi.PsiPackageAccessibilityStatement.Role; import com.intellij.psi.impl.IncompleteModelUtil; import com.intellij.psi.search.FilenameIndex; import com.intellij.psi.util.*; +import com.intellij.util.ArrayUtil; import com.intellij.util.ObjectUtils; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.JBIterable; @@ -328,6 +329,10 @@ final class ModuleHighlightUtil { if (target instanceof PsiPackage psiPackage) { boolean inTests = ModuleRootManager.getInstance(module).getFileIndex().isInTestSourceContent(file.getVirtualFile()); directories = psiPackage.getDirectories(module.getModuleScope(inTests)); + Module mainMultiReleaseModule = MultiReleaseUtil.getMainMultiReleaseModule(module); + if (mainMultiReleaseModule != null) { + directories = ArrayUtil.mergeArrays(directories, psiPackage.getDirectories(mainMultiReleaseModule.getModuleScope(inTests))); + } } String packageName = statement.getPackageName(); boolean opens = statement.getRole() == Role.OPENS; @@ -427,7 +432,7 @@ final class ModuleHighlightUtil { if (implTarget instanceof PsiClass implClass) { Module fileModule = ModuleUtilCore.findModuleForFile(file); Module implModule = ModuleUtilCore.findModuleForFile(implClass.getContainingFile()); - if (fileModule != implModule && !MultiReleaseUtil.inSameMultiReleaseModule(implModule, fileModule)) { + if (fileModule != implModule && !MultiReleaseUtil.areMainAndAdditionalMultiReleaseModules(implModule, fileModule)) { String message = JavaErrorBundle.message("module.service.alien"); HighlightInfo.Builder info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range(implRef)).descriptionAndTooltip(message); diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/MultiReleaseUtil.kt b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/MultiReleaseUtil.kt index e0c4afd785ac..2167b457b40d 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/MultiReleaseUtil.kt +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/MultiReleaseUtil.kt @@ -3,6 +3,7 @@ package com.intellij.codeInsight.daemon.impl.analysis import com.intellij.openapi.module.Module +import com.intellij.openapi.module.ModuleManager import com.intellij.platform.backend.workspace.workspaceModel import com.intellij.platform.workspace.jps.entities.ModuleId import com.intellij.platform.workspace.jps.entities.exModuleOptions @@ -14,29 +15,48 @@ private const val MAIN = "main" private val javaVersionPattern: Pattern by lazy { Pattern.compile("java\\d+") } @Internal -fun inSameMultiReleaseModule(mainModule: Module, additionalModule: Module): Boolean { +fun areMainAndAdditionalMultiReleaseModules(mainModule: Module, additionalModule: Module): Boolean { // Maven val project = additionalModule.project val storage = project.workspaceModel.currentSnapshot - val placeModuleName = additionalModule.name - val targetModuleName = mainModule.name - val placeModuleExOptions = storage.resolve(ModuleId(placeModuleName))?.exModuleOptions - val targetModuleExOptions = storage.resolve(ModuleId(targetModuleName))?.exModuleOptions - if (placeModuleExOptions?.externalSystem == MAVEN_EXTERNAL_SOURCE_ID - && targetModuleExOptions?.externalSystem == MAVEN_EXTERNAL_SOURCE_ID) { - val baseModuleName = targetModuleName.substringBeforeLast('.') - if (placeModuleName.startsWith(baseModuleName) - && placeModuleExOptions.externalSystemModuleType == "MAIN_ONLY_ADDITIONAL" // StandardMavenModuleType.MAIN_ONLY_ADDITIONAL - && targetModuleExOptions.externalSystemModuleType == "MAIN_ONLY" // StandardMavenModuleType.MAIN_ONLY + val additionalModuleName = additionalModule.name + val mainModuleName = mainModule.name + val additionalModuleExOptions = storage.resolve(ModuleId(additionalModuleName))?.exModuleOptions + val mainModuleExOptions = storage.resolve(ModuleId(mainModuleName))?.exModuleOptions + if (additionalModuleExOptions?.externalSystem == MAVEN_EXTERNAL_SOURCE_ID + && mainModuleExOptions?.externalSystem == MAVEN_EXTERNAL_SOURCE_ID) { + val baseModuleName = mainModuleName.substringBeforeLast('.') + if (additionalModuleName.startsWith(baseModuleName) + && additionalModuleExOptions.externalSystemModuleType == "MAIN_ONLY_ADDITIONAL" // StandardMavenModuleType.MAIN_ONLY_ADDITIONAL + && mainModuleExOptions.externalSystemModuleType == "MAIN_ONLY" // StandardMavenModuleType.MAIN_ONLY ) { return true } } // Gradle - if (targetModuleName.endsWith(".$MAIN")) { - val baseModuleName = targetModuleName.substringBeforeLast(MAIN) - return javaVersionPattern.matcher(placeModuleName.substringAfter(baseModuleName)).matches() + if (mainModuleName.endsWith(".$MAIN")) { + val baseModuleName = mainModuleName.substringBeforeLast(MAIN) + return javaVersionPattern.matcher(additionalModuleName.substringAfter(baseModuleName)).matches() } return false +} + +@Internal +fun getMainMultiReleaseModule(additionalModule: Module): Module? { + // Maven + val project = additionalModule.project + val storage = project.workspaceModel.currentSnapshot + val additionalModuleName = additionalModule.name + val additionalModuleExOptions = storage.resolve(ModuleId(additionalModuleName))?.exModuleOptions + if (additionalModuleExOptions?.externalSystem == MAVEN_EXTERNAL_SOURCE_ID) { + val baseModuleName = additionalModuleName.substringBeforeLast('.') + val mainModuleName = "$baseModuleName.$MAIN" + val mainModuleExOptions = storage.resolve(ModuleId(mainModuleName))?.exModuleOptions + if (mainModuleExOptions?.externalSystemModuleType == "MAIN_ONLY" // StandardMavenModuleType.MAIN_ONLY + ) { + return ModuleManager.getInstance(project).findModuleByName(mainModuleName) + } + } + return null } \ No newline at end of file diff --git a/java/java-impl/src/com/intellij/psi/impl/JavaPlatformModuleSystem.kt b/java/java-impl/src/com/intellij/psi/impl/JavaPlatformModuleSystem.kt index b48e2f66c874..09d786578d62 100644 --- a/java/java-impl/src/com/intellij/psi/impl/JavaPlatformModuleSystem.kt +++ b/java/java-impl/src/com/intellij/psi/impl/JavaPlatformModuleSystem.kt @@ -301,7 +301,7 @@ internal class JavaPlatformModuleSystem : JavaModuleSystemEx { private fun inSameMultiReleaseModule(current: ModuleInfo, target: ModuleInfo): Boolean { val placeModule = current.jpsModule ?: return false val targetModule = target.jpsModule ?: return false - return com.intellij.codeInsight.daemon.impl.analysis.inSameMultiReleaseModule(targetModule, placeModule) + return com.intellij.codeInsight.daemon.impl.analysis.areMainAndAdditionalMultiReleaseModules(targetModule, placeModule) } private fun detectAutomaticModule(current: ModuleInfo): PsiJavaModule? {