[maven] IDEA-255308 fix "Package not found" error for multi-release modules

GitOrigin-RevId: c0450edd873e2a8a7f3d8fdea5000acb313d3b21
This commit is contained in:
Dmitry Kichinsky
2025-02-01 14:40:48 +00:00
committed by intellij-monorepo-bot
parent 79f47ce77b
commit 697e99c821
3 changed files with 41 additions and 16 deletions
@@ -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);
@@ -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
}
@@ -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? {