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 ee13a39ca1d3..b2c3a3f35d88 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 @@ -6,7 +6,7 @@ import com.intellij.openapi.module.ModuleUtilCore import com.intellij.openapi.roots.JdkOrderEntry import com.intellij.openapi.roots.ModuleRootManager import com.intellij.openapi.roots.ProjectRootManager -import com.intellij.pom.java.LanguageLevel +import com.intellij.pom.java.JavaFeature import com.intellij.psi.* import com.intellij.psi.impl.light.LightJavaModule import com.intellij.psi.search.GlobalSearchScope @@ -164,9 +164,8 @@ data class JpmsModuleAccessInfo(val current: JpmsModuleInfo.CurrentModuleInfo, v if (targetModule.name == PsiJavaModule.JAVA_BASE) return true if (!isJdkModule(jpsModule, targetModule)) return false - val languageLevel = PsiUtil.getLanguageLevel(place) // https://bugs.openjdk.org/browse/JDK-8197532 - val jdkModulePred: (PsiJavaModule) -> Boolean = if (languageLevel >= LanguageLevel.JDK_11) { + val jdkModulePred: (PsiJavaModule) -> Boolean = if (PsiUtil.isAvailable(JavaFeature.AUTO_ROOT_MODULES, place)) { { module -> module.exports.any { e -> e.moduleNames.isEmpty() } } } else { diff --git a/java/java-frontback-psi-api/resources/messages/JavaPsiBundle.properties b/java/java-frontback-psi-api/resources/messages/JavaPsiBundle.properties index 6d69410a7165..9fea66e3366e 100644 --- a/java/java-frontback-psi-api/resources/messages/JavaPsiBundle.properties +++ b/java/java-frontback-psi-api/resources/messages/JavaPsiBundle.properties @@ -85,6 +85,7 @@ feature.static.interface.calls=Static interface method calls feature.effectively.final=Effectively final variables feature.try.with.resources.refs=Resource references feature.modules=Modules +feature.auto.root.modules=All API-exporting modules are implicitly root modules feature.private.interface.methods=Private interface methods feature.utf8.property.files=Property files in UTF-8 encoding feature.collection.factories=Collection factory methods diff --git a/java/java-frontback-psi-api/src/com/intellij/pom/java/JavaFeature.java b/java/java-frontback-psi-api/src/com/intellij/pom/java/JavaFeature.java index 9e802e76d9e8..5f212b425835 100644 --- a/java/java-frontback-psi-api/src/com/intellij/pom/java/JavaFeature.java +++ b/java/java-frontback-psi-api/src/com/intellij/pom/java/JavaFeature.java @@ -1,4 +1,4 @@ -// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// 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.pom.java; import com.intellij.core.JavaPsiBundle; @@ -56,6 +56,7 @@ public enum JavaFeature { LVTI(LanguageLevel.JDK_10, "feature.lvti"), VAR_LAMBDA_PARAMETER(LanguageLevel.JDK_11, "feature.var.lambda.parameter"), NESTMATES(LanguageLevel.JDK_11, "feature.nestmates"), + AUTO_ROOT_MODULES(LanguageLevel.JDK_11, "feature.auto.root.modules"), ENHANCED_SWITCH(LanguageLevel.JDK_14, "feature.enhanced.switch"), SWITCH_EXPRESSION(LanguageLevel.JDK_14, "feature.switch.expressions"), SERIAL_ANNOTATION(LanguageLevel.JDK_14, "feature.serial.annotation"), diff --git a/java/java-psi-api/src/com/intellij/psi/PsiJavaModule.java b/java/java-psi-api/src/com/intellij/psi/PsiJavaModule.java index aefcc4349db4..8a4b37d5b4c7 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiJavaModule.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiJavaModule.java @@ -44,9 +44,45 @@ public interface PsiJavaModule extends NavigatablePsiElement, PsiNameIdentifierO @Override @NotNull PsiJavaModuleReferenceElement getNameIdentifier(); @Override @NotNull String getName(); + /** + * Checks whether the module should be excluded from automatic resolution when loaded from the classpath. + * This method reads the module resolution attributes from {@code module-info.class}, as specified in JEP 11. + * + * @return {@code true} if the module is marked with {@code DO_NOT_RESOLVE_BY_DEFAULT}, preventing automatic resolution; + * {@code false} otherwise. + * @see JEP 11: Incubator Modules + */ boolean doNotResolveByDefault(); + /** + * Checks whether the module is marked as deprecated. + * This method reads the module resolution attributes from {@code module-info.class}, as specified in JEP 11. + * + * @return {@code true} if the module is marked with {@code WARN_DEPRECATED}, indicating that it is deprecated; + * {@code false} otherwise. + * @see JEP 11: Incubator Modules + */ boolean warnDeprecated(); + + /** + * Checks whether the module is deprecated and scheduled for removal in a future release. + * This method reads the module resolution attributes from {@code module-info.class}, as specified in JEP 11. + * + * @return {@code true} if the module is marked with {@code WARN_DEPRECATED_FOR_REMOVAL}, indicating that + * it is deprecated and will be removed in a future release; + * {@code false} otherwise. + * @see JEP 11: Incubator Modules + */ boolean warnDeprecatedForRemoval(); + + /** + * Checks whether the module is in incubating mode, meaning it is not yet standardized. + * This method reads the module resolution attributes from {@code module-info.class}, as specified in JEP 11. + * + * @return {@code true} if the module is marked with {@code WARN_INCUBATING}, indicating that it is an + * incubator module and subject to change in future releases; + * {@code false} otherwise. + * @see JEP 11: Incubator Modules + */ boolean warnIncubating(); @NotNull Iterable getRequires();