[java-highlighting] checkModuleReference migrated to ModuleChecker and JavaModuleDefinitionInspection

Part of IDEA-365344 Create a new Java error highlighter with minimal dependencies (PSI only)

GitOrigin-RevId: b801fdbe22df163a4f0db153016ae50671ccc866
This commit is contained in:
Tagir Valeev
2025-02-19 20:42:37 +00:00
committed by intellij-monorepo-bot
parent e51112fe28
commit 42ce63523e
6 changed files with 20 additions and 46 deletions
@@ -702,6 +702,7 @@ final class JavaErrorVisitor extends JavaElementVisitor {
super.visitImportModuleStatement(statement);
if (!hasErrorResults()) checkFeature(statement, JavaFeature.MODULE_IMPORT_DECLARATIONS);
if (!hasErrorResults()) myImportChecker.checkImportModuleInModuleInfo(statement);
if (!hasErrorResults()) myModuleChecker.checkModuleReference(statement);
}
@Override
@@ -217,6 +217,15 @@ final class ModuleChecker {
}
}
void checkModuleReference(@NotNull PsiImportModuleStatement statement) {
PsiJavaModuleReferenceElement refElement = statement.getModuleReference();
if (refElement == null) return;
PsiJavaModuleReference ref = refElement.getReference();
if (ref != null && ref.resolve() == null) {
reportUnresolvedJavaModule(refElement);
}
}
private void reportUnresolvedJavaModule(@NotNull PsiJavaModuleReferenceElement refElement) {
PsiJavaModuleReference ref = refElement.getReference();
assert ref != null : refElement.getParent();
@@ -249,7 +249,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
@Override
public void visitImportModuleStatement(@NotNull PsiImportModuleStatement statement) {
super.visitImportModuleStatement(statement);
if (!hasErrorResults()) add(ModuleHighlightUtil.checkModuleReference(statement));
if (!hasErrorResults()) add(ModuleHighlightUtil.checkModuleReferenceAccess(statement));
}
static @Nullable JavaResolveResult resolveOptimised(@NotNull PsiJavaCodeReferenceElement ref, @NotNull PsiFile containingFile) {
@@ -2,29 +2,21 @@
package com.intellij.codeInsight.daemon.impl.analysis;
import com.intellij.codeInsight.JavaModuleSystemEx;
import com.intellij.codeInsight.daemon.JavaErrorBundle;
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInsight.intention.QuickFixFactory;
import com.intellij.psi.*;
import com.intellij.psi.impl.IncompleteModelUtil;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
// generates HighlightInfoType.ERROR-like HighlightInfos for modularity-related (Jigsaw) problems
final class ModuleHighlightUtil {
static HighlightInfo.Builder checkModuleReference(@NotNull PsiImportModuleStatement statement) {
static HighlightInfo.Builder checkModuleReferenceAccess(@NotNull PsiImportModuleStatement statement) {
PsiJavaModuleReferenceElement refElement = statement.getModuleReference();
if (refElement == null) return null;
PsiJavaModuleReference ref = refElement.getReference();
assert ref != null : refElement.getParent();
PsiJavaModule target = ref.resolve();
if (target == null) return getUnresolvedJavaModuleReason(statement, refElement);
if (target == null) return null;
for (JavaModuleSystem moduleSystem : JavaModuleSystem.EP_NAME.getExtensionList()) {
if (!(moduleSystem instanceof JavaModuleSystemEx javaModuleSystemEx)) continue;
JavaModuleSystemEx.ErrorWithFixes fixes = javaModuleSystemEx.checkAccess(target, statement);
@@ -37,34 +29,4 @@ final class ModuleHighlightUtil {
}
return null;
}
private static @NotNull HighlightInfo.Builder getUnresolvedJavaModuleReason(@NotNull PsiElement parent, @NotNull PsiJavaModuleReferenceElement refElement) {
PsiJavaModuleReference ref = refElement.getReference();
assert ref != null : refElement.getParent();
ResolveResult[] results = ref.multiResolve(true);
switch (results.length) {
case 0:
if (IncompleteModelUtil.isIncompleteModel(parent)) {
return HighlightUtil.getPendingReferenceHighlightInfo(refElement);
} else {
return HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF)
.range(refElement)
.descriptionAndTooltip(JavaErrorBundle.message("module.not.found", refElement.getReferenceText()));
}
case 1:
String message = JavaErrorBundle.message("module.not.on.path", refElement.getReferenceText());
HighlightInfo.Builder info = HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF)
.range(refElement)
.descriptionAndTooltip(message);
List<IntentionAction> registrar = new ArrayList<>();
QuickFixFactory.getInstance().registerOrderEntryFixes(ref, registrar);
QuickFixAction.registerQuickFixActions(info, null, registrar);
return info;
default:
return HighlightInfo.newHighlightInfo(HighlightInfoType.WARNING)
.range(refElement)
.descriptionAndTooltip(JavaErrorBundle.message("module.ambiguous", refElement.getReferenceText()));
}
}
}
@@ -36,7 +36,7 @@ public final class JavaModuleDefinitionInspection extends AbstractBaseJavaLocalI
@Override
public void visitRequiresStatement(@NotNull PsiRequiresStatement statement) {
checkModuleReference(statement);
checkModuleReference(statement.getReferenceElement());
}
@Override
@@ -50,6 +50,11 @@ public final class JavaModuleDefinitionInspection extends AbstractBaseJavaLocalI
}
}
@Override
public void visitImportModuleStatement(@NotNull PsiImportModuleStatement statement) {
checkModuleReference(statement.getModuleReference());
}
@Override
public void visitPackageAccessibilityStatement(@NotNull PsiPackageAccessibilityStatement statement) {
if (statement.getRole() != PsiPackageAccessibilityStatement.Role.OPENS) return;
@@ -71,8 +76,7 @@ public final class JavaModuleDefinitionInspection extends AbstractBaseJavaLocalI
.register();
}
void checkModuleReference(@NotNull PsiRequiresStatement statement) {
PsiJavaModuleReferenceElement refElement = statement.getReferenceElement();
private void checkModuleReference(PsiJavaModuleReferenceElement refElement) {
if (refElement != null) {
PsiJavaModuleReference ref = refElement.getReference();
if (ref != null) {
@@ -184,8 +184,6 @@ yield.unqualified.method.warn=Unqualified call to 'yield' method is not supporte
redundant.semicolon.warn=Redundant semicolons between import statements are prohibited starting from Java 21
module.open.duplicate.text=Go to duplicate
module.not.found=Module not found: {0}
module.ambiguous=Ambiguous module reference: {0}
module.not.on.path=Module is not in dependencies: {0}
package.not.found=Package not found: {0}
package.is.empty=Package is empty: {0}