diff --git a/java/codeserver/core/resources/META-INF/JavaCodeServerCore.xml b/java/codeserver/core/resources/META-INF/JavaCodeServerCore.xml index ec47d70f0457..9f17ccea8f48 100644 --- a/java/codeserver/core/resources/META-INF/JavaCodeServerCore.xml +++ b/java/codeserver/core/resources/META-INF/JavaCodeServerCore.xml @@ -1,6 +1,8 @@ + + serviceImplementation="com.intellij.java.codeserver.core.JavaPsiModuleUtil$Helper" + overrides="true"/> \ No newline at end of file diff --git a/java/codeserver/core/src/com/intellij/java/codeserver/core/JavaPlatformModuleSystem.java b/java/codeserver/core/src/com/intellij/java/codeserver/core/JavaPlatformModuleSystem.java new file mode 100644 index 000000000000..d2233c0e4ba4 --- /dev/null +++ b/java/codeserver/core/src/com/intellij/java/codeserver/core/JavaPlatformModuleSystem.java @@ -0,0 +1,30 @@ +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.java.codeserver.core; + +import com.intellij.psi.*; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; + +/** + * Checks package accessibility according to JLS 7 "Packages and Modules". + * + * @see JLS 7 "Packages and Modules" + * @see JEP 261: Module System + */ +@ApiStatus.Internal +final class JavaPlatformModuleSystem implements JavaModuleSystem { + @Override + public boolean isAccessible(@NotNull String targetPackageName, PsiFile targetFile, @NotNull PsiElement place) { + return JavaModuleGraphHelper.getInstance().isAccessible(targetPackageName, targetFile, place); + } + + @Override + public boolean isAccessible(@NotNull PsiJavaModule targetModule, @NotNull PsiElement place) { + return JavaModuleGraphHelper.getInstance().isAccessible(targetModule, place); + } + + @Override + public boolean isAccessible(@NotNull PsiClass target, @NotNull PsiElement place) { + return JavaModuleGraphHelper.getInstance().isAccessible(target, place); + } +} \ No newline at end of file diff --git a/java/codeserver/core/src/com/intellij/java/codeserver/core/JavaPsiModuleUtil.java b/java/codeserver/core/src/com/intellij/java/codeserver/core/JavaPsiModuleUtil.java index bd4246441fe2..8a8d45b102f0 100644 --- a/java/codeserver/core/src/com/intellij/java/codeserver/core/JavaPsiModuleUtil.java +++ b/java/codeserver/core/src/com/intellij/java/codeserver/core/JavaPsiModuleUtil.java @@ -619,5 +619,22 @@ public final class JavaPsiModuleUtil { public @NotNull Set getAllTransitiveDependencies(@NotNull PsiJavaModule psiJavaModule) { return JavaPsiModuleUtil.getAllTransitiveDependencies(psiJavaModule); } + + @Override + public boolean isAccessible(@NotNull String targetPackageName, PsiFile targetFile, @NotNull PsiElement place) { + PsiFile useFile = place.getContainingFile() != null ? place.getContainingFile().getOriginalFile() : null; + if (useFile == null) return true; + List infos = JpmsModuleInfo.findTargetModuleInfos(targetPackageName, targetFile, useFile); + if (infos == null) return true; + return !infos.isEmpty() && ContainerUtil.exists( + infos, info -> info.accessAt(useFile).checkAccess(useFile, JpmsModuleAccessInfo.JpmsModuleAccessMode.EXPORT) == null); + } + + @Override + public boolean isAccessible(@NotNull PsiJavaModule targetModule, @NotNull PsiElement place) { + PsiFile useFile = place.getContainingFile() != null ? place.getContainingFile().getOriginalFile() : null; + if (useFile == null) return true; + return new JpmsModuleInfo.TargetModuleInfo(targetModule, "").accessAt(useFile).checkModuleAccess(place) == null; + } } } diff --git a/java/codeserver/core/src/com/intellij/java/codeserver/core/JpmsModuleAccessInfo.kt b/java/codeserver/core/src/com/intellij/java/codeserver/core/JpmsModuleAccessInfo.kt index 5487e4dc968b..cc855fcda54a 100644 --- a/java/codeserver/core/src/com/intellij/java/codeserver/core/JpmsModuleAccessInfo.kt +++ b/java/codeserver/core/src/com/intellij/java/codeserver/core/JpmsModuleAccessInfo.kt @@ -262,7 +262,7 @@ data class JpmsModuleAccessInfo(val current: JpmsModuleInfo.CurrentModuleInfo, v val options = JavaCompilerConfigurationProxy.getAdditionalOptions(module.project, module) if (options.isEmpty()) return false val prefix = "${targetName}/${packageName}=" - return JavaCompilerConfigurationProxy.optionValues(options, JavaModuleSystem.ADD_EXPORTS_OPTION) + return JavaCompilerConfigurationProxy.optionValues(options, ADD_EXPORTS_OPTION) .filter { it.startsWith(prefix) } .map { it.substring(prefix.length) } .flatMap { it.splitToSequence(",") } @@ -271,22 +271,31 @@ data class JpmsModuleAccessInfo(val current: JpmsModuleInfo.CurrentModuleInfo, v private fun inAddedModules(module: Module, moduleName: String): Boolean { val options = JavaCompilerConfigurationProxy.getAdditionalOptions(module.project, module) - return JavaCompilerConfigurationProxy.optionValues(options, JavaModuleSystem.ADD_MODULES_OPTION) + return JavaCompilerConfigurationProxy.optionValues(options, ADD_MODULES_OPTION) .flatMap { it.splitToSequence(",") } - .any { it == moduleName || it == JavaModuleSystem.ALL_SYSTEM || it == JavaModuleSystem.ALL_MODULE_PATH } + .any { it == moduleName || it == ALL_SYSTEM || it == ALL_MODULE_PATH } } private fun inAddedReads(fromJavaModule: PsiJavaModule, toJavaModule: PsiJavaModule?): Boolean { val fromModule = ModuleUtilCore.findModuleForPsiElement(fromJavaModule) ?: return false val options = JavaCompilerConfigurationProxy.getAdditionalOptions(fromModule.project, fromModule) - return JavaCompilerConfigurationProxy.optionValues(options, JavaModuleSystem.ADD_READS_OPTION) + return JavaCompilerConfigurationProxy.optionValues(options, ADD_READS_OPTION) .flatMap { it.splitToSequence(",") } .any { val (optFromModuleName, optToModuleName) = it.split("=").apply { it.first() to it.last() } fromJavaModule.name == optFromModuleName && - (toJavaModule?.name == optToModuleName || (optToModuleName == JavaModuleSystem.ALL_UNNAMED && isUnnamedModule(toJavaModule))) + (toJavaModule?.name == optToModuleName || (optToModuleName == ALL_UNNAMED && isUnnamedModule(toJavaModule))) } } private fun isUnnamedModule(module: PsiJavaModule?) = module == null || module is LightJavaModule + + companion object { + const val ALL_UNNAMED: String = "ALL-UNNAMED" + const val ALL_SYSTEM: String = "ALL-SYSTEM" + const val ALL_MODULE_PATH: String = "ALL-MODULE-PATH" + const val ADD_EXPORTS_OPTION: String = "--add-exports" + const val ADD_MODULES_OPTION: String = "--add-modules" + const val ADD_READS_OPTION: String = "--add-reads" + } } \ No newline at end of file diff --git a/java/codeserver/core/src/com/intellij/java/codeserver/core/JpmsModuleInfo.kt b/java/codeserver/core/src/com/intellij/java/codeserver/core/JpmsModuleInfo.kt index 4b223f3f091c..0ca9902903c3 100644 --- a/java/codeserver/core/src/com/intellij/java/codeserver/core/JpmsModuleInfo.kt +++ b/java/codeserver/core/src/com/intellij/java/codeserver/core/JpmsModuleInfo.kt @@ -27,7 +27,7 @@ sealed interface JpmsModuleInfo { * @property jpsModule JPS module initialization. */ class CurrentModuleInfo(override val module: PsiJavaModule?, val name: String, jps: () -> Module? = { null }) : JpmsModuleInfo { - constructor(use: PsiJavaModule?, element: PsiElement) : this(use, use?.name ?: JavaModuleSystem.ALL_UNNAMED, { + constructor(use: PsiJavaModule?, element: PsiElement) : this(use, use?.name ?: JpmsModuleAccessInfo.ALL_UNNAMED, { ModuleUtilCore.findModuleForPsiElement(element) }) diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaModuleGraphUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaModuleGraphUtil.java index 51be42e221fa..a1ff99f46813 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaModuleGraphUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaModuleGraphUtil.java @@ -90,7 +90,7 @@ public final class JavaModuleGraphUtil { */ public static boolean isModuleReadable(@NotNull PsiElement place, @NotNull PsiJavaModule targetModule) { - return ContainerUtil.and(JavaModuleSystem.EP_NAME.getExtensionList(), sys -> sys.isAccessible(targetModule, place)); + return JavaModuleGraphHelper.getInstance().isAccessible(targetModule, place); } public static boolean addDependency(@NotNull PsiJavaModule from, @@ -118,7 +118,7 @@ public final class JavaModuleGraphUtil { if (fromDescriptor == null) return false; PsiJavaModule toDescriptor = findDescriptorByElement(to); if (toDescriptor == null) return false; - if(!ContainerUtil.and(JavaModuleSystem.EP_NAME.getExtensionList(), sys -> sys.isAccessible(to, from))) return false; + if (!JavaModuleGraphHelper.getInstance().isAccessible(to, from)) return false; return addDependency(fromDescriptor, toDescriptor, scope); } diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddExportsOptionFix.kt b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddExportsOptionFix.kt index 7250128293a5..f697f3f86f88 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddExportsOptionFix.kt +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddExportsOptionFix.kt @@ -2,8 +2,8 @@ package com.intellij.codeInsight.daemon.impl.quickfix import com.intellij.codeInsight.daemon.QuickFixBundle +import com.intellij.java.codeserver.core.JpmsModuleAccessInfo import com.intellij.openapi.module.Module -import com.intellij.psi.JavaModuleSystem import org.jetbrains.annotations.Nls class AddExportsOptionFix(module: Module, @@ -12,19 +12,19 @@ class AddExportsOptionFix(module: Module, private val useName: String) : CompilerOptionFix(module) { private val qualifier = "${targetName}/${packageName}" - override fun getText(): @Nls String = QuickFixBundle.message("add.compiler.option.fix.name", "${JavaModuleSystem.ADD_EXPORTS_OPTION} ${qualifier}=${useName}") + override fun getText(): @Nls String = QuickFixBundle.message("add.compiler.option.fix.name", "${JpmsModuleAccessInfo.ADD_EXPORTS_OPTION} ${qualifier}=${useName}") override fun update(options: MutableList) { var idx = -1 var candidate = -1 var offset = 0 for ((i, option) in options.withIndex()) { - if (option.startsWith(JavaModuleSystem.ADD_EXPORTS_OPTION)) { - if (option.length == JavaModuleSystem.ADD_EXPORTS_OPTION.length) { + if (option.startsWith(JpmsModuleAccessInfo.ADD_EXPORTS_OPTION)) { + if (option.length == JpmsModuleAccessInfo.ADD_EXPORTS_OPTION.length) { candidate = i + 1; offset = 0 } - else if (option[JavaModuleSystem.ADD_EXPORTS_OPTION.length] == '=') { - candidate = i; offset = JavaModuleSystem.ADD_EXPORTS_OPTION.length + 1 + else if (option[JpmsModuleAccessInfo.ADD_EXPORTS_OPTION.length] == '=') { + candidate = i; offset = JpmsModuleAccessInfo.ADD_EXPORTS_OPTION.length + 1 } } if (i == candidate && option.startsWith(qualifier, offset)) { @@ -35,7 +35,7 @@ class AddExportsOptionFix(module: Module, } } when (idx) { - -1 -> options += listOf(JavaModuleSystem.ADD_EXPORTS_OPTION, "${qualifier}=${useName}") + -1 -> options += listOf(JpmsModuleAccessInfo.ADD_EXPORTS_OPTION, "${qualifier}=${useName}") else -> options[idx] = "${options[idx].trimEnd(',')},${useName}" } } diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddModulesOptionFix.kt b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddModulesOptionFix.kt index bbe21a48fec7..f329a20ed352 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddModulesOptionFix.kt +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddModulesOptionFix.kt @@ -2,23 +2,23 @@ package com.intellij.codeInsight.daemon.impl.quickfix import com.intellij.codeInsight.daemon.QuickFixBundle +import com.intellij.java.codeserver.core.JpmsModuleAccessInfo import com.intellij.openapi.module.Module -import com.intellij.psi.JavaModuleSystem import org.jetbrains.annotations.Nls class AddModulesOptionFix(module: Module, private val moduleName: String) : CompilerOptionFix(module) { - override fun getText(): @Nls String = QuickFixBundle.message("add.compiler.option.fix.name", "${JavaModuleSystem.ADD_MODULES_OPTION} ${moduleName}") + override fun getText(): @Nls String = QuickFixBundle.message("add.compiler.option.fix.name", "${JpmsModuleAccessInfo.ADD_MODULES_OPTION} ${moduleName}") override fun update(options: MutableList) { var idx = -1 for ((i, option) in options.withIndex()) { - if (option.startsWith(JavaModuleSystem.ADD_MODULES_OPTION)) { - if (option.length == JavaModuleSystem.ADD_MODULES_OPTION.length) idx = i + 1 - else if (option[JavaModuleSystem.ADD_MODULES_OPTION.length] == '=') idx = i + if (option.startsWith(JpmsModuleAccessInfo.ADD_MODULES_OPTION)) { + if (option.length == JpmsModuleAccessInfo.ADD_MODULES_OPTION.length) idx = i + 1 + else if (option[JpmsModuleAccessInfo.ADD_MODULES_OPTION.length] == '=') idx = i } } when (idx) { - -1 -> options += listOf(JavaModuleSystem.ADD_MODULES_OPTION, moduleName) + -1 -> options += listOf(JpmsModuleAccessInfo.ADD_MODULES_OPTION, moduleName) options.size -> options += moduleName else -> { val value = options[idx] diff --git a/java/java-impl/resources/META-INF/JavaPlugin.xml b/java/java-impl/resources/META-INF/JavaPlugin.xml index fb92d7c4c251..29a2ec9f90d3 100644 --- a/java/java-impl/resources/META-INF/JavaPlugin.xml +++ b/java/java-impl/resources/META-INF/JavaPlugin.xml @@ -927,7 +927,6 @@ - diff --git a/java/java-impl/src/com/intellij/psi/impl/JavaPlatformModuleSystem.kt b/java/java-impl/src/com/intellij/psi/impl/JavaPlatformModuleSystem.kt deleted file mode 100644 index 7401f60724df..000000000000 --- a/java/java-impl/src/com/intellij/psi/impl/JavaPlatformModuleSystem.kt +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.psi.impl - -import com.intellij.java.JavaBundle -import com.intellij.java.codeserver.core.JpmsModuleAccessInfo.JpmsModuleAccessMode -import com.intellij.java.codeserver.core.JpmsModuleInfo -import com.intellij.java.codeserver.core.JpmsModuleInfo.TargetModuleInfo -import com.intellij.psi.JavaModuleSystem -import com.intellij.psi.PsiElement -import com.intellij.psi.PsiFile -import com.intellij.psi.PsiJavaModule - -/** - * Checks package accessibility according to JLS 7 "Packages and Modules". - * - * @see JLS 7 "Packages and Modules" - * @see JEP 261: Module System - */ -internal class JavaPlatformModuleSystem : JavaModuleSystem { - override fun getName(): String = JavaBundle.message("java.platform.module.system.name") - - override fun isAccessible(targetPackageName: String, targetFile: PsiFile?, place: PsiElement): Boolean { - val useFile = place.containingFile?.originalFile ?: return true - val infos = JpmsModuleInfo.findTargetModuleInfos(targetPackageName, targetFile, useFile) ?: return true - return infos.isNotEmpty() && infos.any { info -> info.accessAt(useFile).checkAccess(useFile, JpmsModuleAccessMode.EXPORT) == null } - } - - override fun isAccessible(targetModule: PsiJavaModule, place: PsiElement): Boolean { - val useFile = place.containingFile?.originalFile ?: return true - return TargetModuleInfo(targetModule, "").accessAt(useFile).checkModuleAccess(place) == null - } -} \ No newline at end of file diff --git a/java/java-psi-api/src/com/intellij/psi/JavaCompilerConfigurationProxy.java b/java/java-psi-api/src/com/intellij/psi/JavaCompilerConfigurationProxy.java index fc7a083f42e2..0a41c212fd95 100644 --- a/java/java-psi-api/src/com/intellij/psi/JavaCompilerConfigurationProxy.java +++ b/java/java-psi-api/src/com/intellij/psi/JavaCompilerConfigurationProxy.java @@ -14,8 +14,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import static com.intellij.psi.JavaModuleSystem.PATCH_MODULE_OPTION; - /** * Provides additional compiler options for a given module. *

@@ -23,6 +21,7 @@ import static com.intellij.psi.JavaModuleSystem.PATCH_MODULE_OPTION; */ public abstract class JavaCompilerConfigurationProxy { private static final ExtensionPointName EP_NAME = new ExtensionPointName<>("com.intellij.javaCompilerConfigurationProxy"); + private static final String PATCH_MODULE_OPTION = "--patch-module"; /** * Returns additional compiler options applicable to the given module, if any. diff --git a/java/java-psi-api/src/com/intellij/psi/JavaModuleSystem.java b/java/java-psi-api/src/com/intellij/psi/JavaModuleSystem.java index 47823cfca9f6..badc4571ae27 100644 --- a/java/java-psi-api/src/com/intellij/psi/JavaModuleSystem.java +++ b/java/java-psi-api/src/com/intellij/psi/JavaModuleSystem.java @@ -2,9 +2,6 @@ package com.intellij.psi; import com.intellij.openapi.extensions.ExtensionPointName; -import com.intellij.psi.util.PsiUtil; -import com.intellij.psi.util.PsiUtilCore; -import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -12,44 +9,21 @@ import org.jetbrains.annotations.Nullable; * Allows checking accessibility of a given class. *

* A given class is only accessible if all registered extensions consider it accessible - * - * @see com.intellij.codeInsight.JavaModuleSystemEx + * + * @deprecated there's exactly one module system available, and it's accessible via the {@code JavaModuleGraphHelper} service. Use + * {@code isAccessible} methods from that service */ +@Deprecated public interface JavaModuleSystem { - String ADD_EXPORTS_OPTION = "--add-exports"; - String ADD_OPENS_OPTION = "--add-opens"; - String ADD_MODULES_OPTION = "--add-modules"; - String ADD_READS_OPTION = "--add-reads"; - String PATCH_MODULE_OPTION = "--patch-module"; - String LIST_MODULES_OPTION = "--list-modules"; - - String ALL_UNNAMED = "ALL-UNNAMED"; - String ALL_SYSTEM = "ALL-SYSTEM"; - String ALL_MODULE_PATH = "ALL-MODULE-PATH"; - ExtensionPointName EP_NAME = new ExtensionPointName<>("com.intellij.javaModuleSystem"); - /** - * @return name of the module system which will be reported to user in case of inaccessibility - */ - @Nls - @NotNull String getName(); - /** * Checks accessibility of the class * * @param target class which accessibility should be determined * @param place place where accessibility of target is required */ - default boolean isAccessible(@NotNull PsiClass target, @NotNull PsiElement place) { - PsiFile targetFile = target.getContainingFile(); - if (targetFile == null) return true; - - PsiUtilCore.ensureValid(targetFile); - - String packageName = PsiUtil.getPackageName(target); - return packageName == null || isAccessible(packageName, targetFile, place); - } + boolean isAccessible(@NotNull PsiClass target, @NotNull PsiElement place); /** * Checks accessibility of element in the package diff --git a/java/java-psi-impl/resources/META-INF/JavaPsiPlugin.xml b/java/java-psi-impl/resources/META-INF/JavaPsiPlugin.xml index 92ed65a004e9..e3cedecfb80f 100644 --- a/java/java-psi-impl/resources/META-INF/JavaPsiPlugin.xml +++ b/java/java-psi-impl/resources/META-INF/JavaPsiPlugin.xml @@ -80,6 +80,8 @@ serviceImplementation="com.intellij.psi.impl.PsiSubstitutorFactoryImpl"/> + diff --git a/java/java-psi-impl/src/com/intellij/core/JavaCoreApplicationEnvironment.java b/java/java-psi-impl/src/com/intellij/core/JavaCoreApplicationEnvironment.java index 9666f7a02bff..6ae352be8187 100644 --- a/java/java-psi-impl/src/com/intellij/core/JavaCoreApplicationEnvironment.java +++ b/java/java-psi-impl/src/com/intellij/core/JavaCoreApplicationEnvironment.java @@ -67,6 +67,7 @@ public class JavaCoreApplicationEnvironment extends CoreApplicationEnvironment { application.registerService(PsiPackageImplementationHelper.class, new CorePsiPackageImplementationHelper()); application.registerService(PsiSubstitutorFactory.class, new PsiSubstitutorFactoryImpl()); + application.registerService(JavaModuleGraphHelper.class, new DumbJavaModuleGraphHelper()); application.registerService(JavaDirectoryService.class, createJavaDirectoryService()); application.registerService(JavaVersionService.class, new JavaVersionService()); @@ -74,8 +75,8 @@ public class JavaCoreApplicationEnvironment extends CoreApplicationEnvironment { addExplicitExtension(ItemPresentationProviders.INSTANCE, PsiClass.class, new ClassPresentationProvider()); addExplicitExtension(ItemPresentationProviders.INSTANCE, PsiMethod.class, new MethodPresentationProvider()); addExplicitExtension(ItemPresentationProviders.INSTANCE, PsiField.class, new FieldPresentationProvider()); - addExplicitExtension(ItemPresentationProviders.INSTANCE, PsiLocalVariable.class, new VariablePresentationProvider()); - addExplicitExtension(ItemPresentationProviders.INSTANCE, PsiParameter.class, new VariablePresentationProvider()); + addExplicitExtension(ItemPresentationProviders.INSTANCE, PsiLocalVariable.class, new VariablePresentationProvider<>()); + addExplicitExtension(ItemPresentationProviders.INSTANCE, PsiParameter.class, new VariablePresentationProvider<>()); registerApplicationService(JavaCodeFoldingSettings.class, new JavaCodeFoldingSettingsBase()); addExplicitExtension(LanguageFolding.INSTANCE, JavaLanguage.INSTANCE, new JavaFoldingBuilderBase() { diff --git a/java/java-psi-impl/src/com/intellij/psi/DumbJavaModuleGraphHelper.java b/java/java-psi-impl/src/com/intellij/psi/DumbJavaModuleGraphHelper.java new file mode 100644 index 000000000000..bbf18dfabf20 --- /dev/null +++ b/java/java-psi-impl/src/com/intellij/psi/DumbJavaModuleGraphHelper.java @@ -0,0 +1,36 @@ +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.psi; + +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collections; +import java.util.Set; + +/** + * An implementation of {@link JavaModuleGraphHelper} which does not support the Java platform module system: + * no modules are defined, and everything is accessible. + */ +@ApiStatus.Internal +public final class DumbJavaModuleGraphHelper extends JavaModuleGraphHelper { + @Override + public @Nullable PsiJavaModule findDescriptorByElement(@Nullable PsiElement element) { + return null; + } + + @Override + public @NotNull Set getAllTransitiveDependencies(@NotNull PsiJavaModule psiJavaModule) { + return Collections.emptySet(); + } + + @Override + public boolean isAccessible(@NotNull String targetPackageName, @Nullable PsiFile targetFile, @NotNull PsiElement place) { + return true; + } + + @Override + public boolean isAccessible(@NotNull PsiJavaModule targetModule, @NotNull PsiElement place) { + return true; + } +} diff --git a/java/java-psi-impl/src/com/intellij/psi/JavaModuleGraphHelper.java b/java/java-psi-impl/src/com/intellij/psi/JavaModuleGraphHelper.java index 6e3992b548f8..35e9df8d16f4 100644 --- a/java/java-psi-impl/src/com/intellij/psi/JavaModuleGraphHelper.java +++ b/java/java-psi-impl/src/com/intellij/psi/JavaModuleGraphHelper.java @@ -2,6 +2,8 @@ package com.intellij.psi; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.psi.util.PsiUtil; +import com.intellij.psi.util.PsiUtilCore; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -12,6 +14,10 @@ import java.util.Set; * Provides utilities for operations related to Java modules within the PSI tree. */ public abstract class JavaModuleGraphHelper { + public static JavaModuleGraphHelper getInstance() { + return ApplicationManager.getApplication().getService(JavaModuleGraphHelper.class); + } + /** * Retrieves the {@link PsiJavaModule} associated with the specified {@link PsiElement}. * @@ -30,7 +36,37 @@ public abstract class JavaModuleGraphHelper { */ public abstract @NotNull Set getAllTransitiveDependencies(@NotNull PsiJavaModule psiJavaModule); - public static JavaModuleGraphHelper getInstance() { - return ApplicationManager.getApplication().getService(JavaModuleGraphHelper.class); + /** + * Checks accessibility of the class + * + * @param target class which accessibility should be determined + * @param place place where accessibility of target is required + */ + public boolean isAccessible(@NotNull PsiClass target, @NotNull PsiElement place) { + PsiFile targetFile = target.getContainingFile(); + if (targetFile == null) return true; + + PsiUtilCore.ensureValid(targetFile); + + String packageName = PsiUtil.getPackageName(target); + return packageName == null || isAccessible(packageName, targetFile, place); } + + /** + * Checks accessibility of element in the package + * + * @param targetPackageName name of the package which element's accessibility should be determined + * @param targetFile file in which this element is contained + * @param place place where accessibility of target is required + */ + public abstract boolean isAccessible(@NotNull String targetPackageName, @Nullable PsiFile targetFile, @NotNull PsiElement place); + + /** + * Checks accessibility of module in the place + * + * @param targetModule the target java module whose accessibility is being checked + * @param place place where accessibility of target is required + * @return true if the target module is accessible from the specified location, false otherwise + */ + public abstract boolean isAccessible(@NotNull PsiJavaModule targetModule, @NotNull PsiElement place); } \ No newline at end of file diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java index 027151a355cb..67a755f1c0f7 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java @@ -24,8 +24,6 @@ import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.function.Predicate; - public class PsiResolveHelperImpl implements PsiResolveHelper { private static final Logger LOG = Logger.getInstance(PsiResolveHelperImpl.class); private final PsiManager myManager; @@ -127,7 +125,7 @@ public class PsiResolveHelperImpl implements PsiResolveHelper { PsiClass containingClass = member.getContainingClass(); boolean accessible = JavaResolveUtil.isAccessible(member, containingClass, modifierList, place, accessObjectClass, currentFileResolveScope); if (accessible && member instanceof PsiClass && !(member instanceof PsiTypeParameter)) { - accessible = isAccessible(moduleSystem -> moduleSystem.isAccessible(((PsiClass)member), place)); + accessible = JavaModuleGraphHelper.getInstance().isAccessible(((PsiClass)member), place); } if (fromImplicitClassOutsideThisClass(member, place)) { return false; @@ -158,16 +156,7 @@ public class PsiResolveHelperImpl implements PsiResolveHelper { @Override public boolean isAccessible(@NotNull PsiPackage pkg, @NotNull PsiElement place) { - return isAccessible(moduleSystem -> moduleSystem.isAccessible(pkg.getQualifiedName(), null, place)); - } - - private static boolean isAccessible(Predicate predicate) { - for (JavaModuleSystem t : JavaModuleSystem.EP_NAME.getExtensionList()) { - if (!predicate.test(t)) { - return false; - } - } - return true; + return JavaModuleGraphHelper.getInstance().isAccessible(pkg.getQualifiedName(), null, place); } @Override