mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[java-highlighting] checkAmbiguousMethodCallIdentifier -> ExpressionChecker
Part of IDEA-365344 Create a new Java error highlighter with minimal dependencies (PSI only) GitOrigin-RevId: 0edb80ae452250e0d12ff987aa5701b048dc91cb
This commit is contained in:
committed by
intellij-monorepo-bot
parent
c16bd2b684
commit
01bc97b6cc
@@ -242,6 +242,7 @@ reference.qualifier.primitive=Cannot access fields on ''{0}'' type
|
||||
reference.unresolved=Cannot resolve symbol ''{0}''
|
||||
reference.ambiguous=Reference to ''{0}'' is ambiguous, both ''{1}'' and ''{2}'' match
|
||||
reference.implicit.class=Implicitly declared class ''{0}'' cannot be referenced
|
||||
reference.non.static.from.static.context=Non-static {0} ''{1}'' cannot be referenced from a static context
|
||||
|
||||
statement.case.outside.switch=Case statement outside switch
|
||||
statement.invalid=Invalid statement
|
||||
@@ -296,6 +297,9 @@ call.constructor.duplicate=Only one explicit constructor call allowed in constru
|
||||
call.constructor.record.in.canonical=Canonical constructor cannot delegate to another constructor
|
||||
call.constructor.recursive=Recursive constructor call
|
||||
call.unresolved=Cannot resolve method ''{0}''
|
||||
call.unresolved.name=Cannot resolve method ''{0}''
|
||||
call.qualifier.primitive=Cannot call methods on ''{0}'' type
|
||||
call.ambiguous.no.match=Cannot resolve method ''{0}'' in ''{1}''
|
||||
call.ambiguous=Ambiguous method call: both ''{0}'' and ''{1}'' match
|
||||
# {0} - colspan, {1} - method1, {2} - class1, {3} - method2, {4} - class2
|
||||
call.ambiguous.tooltip=\
|
||||
|
||||
+63
@@ -16,6 +16,7 @@ import com.intellij.psi.infos.MethodCandidateInfo;
|
||||
import com.intellij.psi.search.searches.ImplicitClassSearch;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.refactoring.util.RefactoringChangeUtil;
|
||||
import com.intellij.util.JavaPsiConstructorUtil;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.ThreeState;
|
||||
@@ -26,6 +27,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.*;
|
||||
|
||||
import static com.intellij.util.ObjectUtils.tryCast;
|
||||
import static java.util.Objects.*;
|
||||
|
||||
final class ExpressionChecker {
|
||||
private final @NotNull JavaErrorVisitor myVisitor;
|
||||
@@ -1150,6 +1152,67 @@ final class ExpressionChecker {
|
||||
}
|
||||
}
|
||||
|
||||
void checkAmbiguousMethodCallIdentifier(JavaResolveResult @NotNull [] resolveResults,
|
||||
@NotNull JavaResolveResult resolveResult,
|
||||
@NotNull PsiMethodCallExpression methodCall) {
|
||||
PsiReferenceExpression referenceToMethod = methodCall.getMethodExpression();
|
||||
PsiElement element = resolveResult.getElement();
|
||||
MethodCandidateInfo methodCandidate2 = findCandidates(resolveResults).second;
|
||||
if (methodCandidate2 != null) return;
|
||||
|
||||
PsiElement anchor = requireNonNullElse(referenceToMethod.getReferenceNameElement(), referenceToMethod);
|
||||
if (element instanceof PsiModifierListOwner owner && !resolveResult.isAccessible()) {
|
||||
myVisitor.myModifierChecker.reportAccessProblem(referenceToMethod, owner, resolveResult);
|
||||
}
|
||||
else if (element != null && !resolveResult.isStaticsScopeCorrect()) {
|
||||
if (element instanceof PsiMethod psiMethod && psiMethod.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
PsiClass containingClass = psiMethod.getContainingClass();
|
||||
if (containingClass != null && containingClass.isInterface()) {
|
||||
myVisitor.checkFeature(anchor, JavaFeature.STATIC_INTERFACE_CALLS);
|
||||
if (myVisitor.hasErrorResults()) return;
|
||||
checkStaticInterfaceCallQualifier(referenceToMethod, resolveResult, containingClass);
|
||||
if (myVisitor.hasErrorResults()) return;
|
||||
}
|
||||
}
|
||||
myVisitor.report(JavaErrorKinds.REFERENCE_NON_STATIC_FROM_STATIC_CONTEXT.create(referenceToMethod, element));
|
||||
}
|
||||
else if (!ContainerUtil.exists(resolveResults, result -> result instanceof MethodCandidateInfo && result.isAccessible())) {
|
||||
PsiClass qualifierClass = RefactoringChangeUtil.getQualifierClass(referenceToMethod);
|
||||
String className = qualifierClass != null ? qualifierClass.getName() : null;
|
||||
PsiExpression qualifierExpression = referenceToMethod.getQualifierExpression();
|
||||
|
||||
if (className != null) {
|
||||
if (IncompleteModelUtil.isIncompleteModel(myVisitor.file()) &&
|
||||
IncompleteModelUtil.canBePendingReference(referenceToMethod)) {
|
||||
myVisitor.report(JavaErrorKinds.REFERENCE_PENDING.create(anchor));
|
||||
return;
|
||||
}
|
||||
myVisitor.report(JavaErrorKinds.CALL_AMBIGUOUS_NO_MATCH.create(methodCall, resolveResults));
|
||||
}
|
||||
else if (qualifierExpression != null &&
|
||||
qualifierExpression.getType() instanceof PsiPrimitiveType primitiveType &&
|
||||
!primitiveType.equals(PsiTypes.nullType())) {
|
||||
if (PsiTypes.voidType().equals(primitiveType) &&
|
||||
PsiUtil.deparenthesizeExpression(qualifierExpression) instanceof PsiReferenceExpression) {
|
||||
return;
|
||||
}
|
||||
myVisitor.report(JavaErrorKinds.CALL_QUALIFIER_PRIMITIVE.create(methodCall, primitiveType));
|
||||
}
|
||||
else {
|
||||
if (qualifierExpression != null) {
|
||||
PsiType type = qualifierExpression.getType();
|
||||
if (type instanceof PsiClassType t && t.resolve() == null || PsiTypes.nullType().equals(type)) return;
|
||||
}
|
||||
if (IncompleteModelUtil.isIncompleteModel(myVisitor.file()) && IncompleteModelUtil.canBePendingReference(referenceToMethod)) {
|
||||
myVisitor.report(JavaErrorKinds.REFERENCE_PENDING.create(anchor));
|
||||
return;
|
||||
}
|
||||
myVisitor.report(JavaErrorKinds.CALL_UNRESOLVED_NAME.create(methodCall, resolveResults));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void checkRestrictedIdentifierReference(@NotNull PsiJavaCodeReferenceElement ref, @NotNull PsiClass resolved) {
|
||||
String name = resolved.getName();
|
||||
if (PsiTypesUtil.isRestrictedIdentifier(name, myVisitor.languageLevel())) {
|
||||
|
||||
+1
@@ -619,6 +619,7 @@ final class JavaErrorVisitor extends JavaElementVisitor {
|
||||
(!result.isAccessible() || !result.isStaticsScopeCorrect())) {
|
||||
PsiExpressionList list = methodCallExpression.getArgumentList();
|
||||
if (!myExpressionChecker.isDummyConstructorCall(methodCallExpression, list, expression)) {
|
||||
myExpressionChecker.checkAmbiguousMethodCallIdentifier(results, result, methodCallExpression);
|
||||
if (!PsiTreeUtil.findChildrenOfType(methodCallExpression.getArgumentList(), PsiLambdaExpression.class).isEmpty()) {
|
||||
PsiElement nameElement = expression.getReferenceNameElement();
|
||||
if (nameElement != null) {
|
||||
|
||||
+27
-1
@@ -2,6 +2,7 @@
|
||||
package com.intellij.java.codeserver.highlighting.errors;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationTargetUtil;
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.HighlightMessageUtil;
|
||||
import com.intellij.core.JavaPsiBundle;
|
||||
import com.intellij.java.codeserver.highlighting.JavaCompilationErrorBundle;
|
||||
import com.intellij.java.codeserver.highlighting.errors.JavaErrorKind.Parameterized;
|
||||
@@ -13,6 +14,7 @@ import com.intellij.pom.java.JavaFeature;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.refactoring.util.RefactoringChangeUtil;
|
||||
import com.intellij.util.VisibilityUtil;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -811,6 +813,15 @@ public final class JavaErrorKinds {
|
||||
.withRawDescription((ref, results) -> message("reference.ambiguous", ref.getReferenceName(),
|
||||
format(requireNonNull(results.get(0).getElement())),
|
||||
format(requireNonNull(results.get(1).getElement()))));
|
||||
public static final Parameterized<PsiJavaCodeReferenceElement, PsiElement> REFERENCE_NON_STATIC_FROM_STATIC_CONTEXT =
|
||||
parameterized(PsiJavaCodeReferenceElement.class, PsiElement.class, "reference.non.static.from.static.context")
|
||||
.withHighlightType((ref, refElement) -> JavaErrorHighlightType.WRONG_REF)
|
||||
.withAnchor((ref, refElement) -> requireNonNullElse(ref.getReferenceNameElement(), ref))
|
||||
.withRawDescription((ref, refElement) -> {
|
||||
String type = JavaElementKind.fromElement(refElement).lessDescriptive().subject();
|
||||
String name = HighlightMessageUtil.getSymbolName(refElement, PsiSubstitutor.EMPTY);
|
||||
return message("reference.non.static.from.static.context", type, name);
|
||||
});
|
||||
|
||||
public static final Simple<PsiSwitchLabelStatementBase> STATEMENT_CASE_OUTSIDE_SWITCH = error("statement.case.outside.switch");
|
||||
public static final Simple<PsiStatement> STATEMENT_INVALID = error("statement.invalid");
|
||||
@@ -886,12 +897,27 @@ public final class JavaErrorKinds {
|
||||
.withAnchor((call, results) -> call.getArgumentList())
|
||||
.withRawDescription((call, results) -> message(
|
||||
"call.unresolved", call.getMethodExpression().getReferenceName() + formatArgumentTypes(call.getArgumentList(), true)));
|
||||
public static final Parameterized<PsiMethodCallExpression, JavaResolveResult[]> CALL_UNRESOLVED_NAME =
|
||||
parameterized(PsiMethodCallExpression.class, JavaResolveResult[].class, "call.unresolved.name")
|
||||
.withRange((call, cls) -> getRange(call))
|
||||
.withRawDescription((call, results) -> message(
|
||||
"call.unresolved.name", call.getMethodExpression().getReferenceName() + formatArgumentTypes(call.getArgumentList(), true)));
|
||||
public static final Parameterized<PsiMethodCallExpression, JavaAmbiguousCallContext> CALL_AMBIGUOUS =
|
||||
parameterized(PsiMethodCallExpression.class, JavaAmbiguousCallContext.class, "call.ambiguous")
|
||||
.withAnchor((call, ctx) -> call.getArgumentList())
|
||||
.withRawDescription((call, ctx) -> ctx.description())
|
||||
.withTooltip((call, ctx) -> ctx.tooltip());
|
||||
|
||||
public static final Parameterized<PsiMethodCallExpression, JavaResolveResult[]> CALL_AMBIGUOUS_NO_MATCH =
|
||||
parameterized(PsiMethodCallExpression.class, JavaResolveResult[].class, "call.ambiguous.no.match")
|
||||
.withRange((call, cls) -> getRange(call))
|
||||
.withRawDescription(
|
||||
(call, cls) -> message("call.ambiguous.no.match", call.getMethodExpression().getReferenceName(),
|
||||
requireNonNull(RefactoringChangeUtil.getQualifierClass(call.getMethodExpression())).getName()));
|
||||
public static final Parameterized<PsiMethodCallExpression, PsiPrimitiveType> CALL_QUALIFIER_PRIMITIVE =
|
||||
parameterized(PsiMethodCallExpression.class, PsiPrimitiveType.class, "call.qualifier.primitive")
|
||||
.withHighlightType((ref, type) -> JavaErrorHighlightType.WRONG_REF)
|
||||
.withRange((call, type) -> getRange(call))
|
||||
.withRawDescription((call, type) -> message("call.qualifier.primitive", type.getPresentableText()));
|
||||
|
||||
public static final Parameterized<PsiMethodCallExpression, PsiMethod> CALL_DIRECT_ABSTRACT_METHOD_ACCESS =
|
||||
parameterized(PsiMethodCallExpression.class, PsiMethod.class, "call.direct.abstract.method.access")
|
||||
|
||||
+2
@@ -510,6 +510,7 @@ public final class HighlightFixUtil {
|
||||
registerUsageFixes(methodCall, info);
|
||||
|
||||
RemoveRedundantArgumentsFix.registerIntentions(methodCandidates, list, info);
|
||||
info.accept(RemoveRepeatingCallFix.createFix(methodCall));
|
||||
registerChangeParameterClassFix(methodCall, list, info);
|
||||
}
|
||||
|
||||
@@ -797,6 +798,7 @@ public final class HighlightFixUtil {
|
||||
WrapExpressionFix.registerWrapAction(candidates, list.getExpressions(), sink);
|
||||
PermuteArgumentsFix.registerFix(sink, methodCall, candidates);
|
||||
registerChangeParameterClassFix(methodCall, list, sink);
|
||||
registerMethodCallIntentions(sink, methodCall, list);
|
||||
}
|
||||
|
||||
private static final class ReturnModel {
|
||||
|
||||
-154
@@ -5,27 +5,19 @@ import com.intellij.codeInsight.ExceptionUtil;
|
||||
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.*;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInsight.intention.QuickFixFactory;
|
||||
import com.intellij.codeInsight.quickfix.LazyQuickFixUpdater;
|
||||
import com.intellij.codeInsight.quickfix.UnresolvedReferenceQuickFixProvider;
|
||||
import com.intellij.codeInspection.LocalQuickFixOnPsiElementAsIntentionAdapter;
|
||||
import com.intellij.core.JavaPsiBundle;
|
||||
import com.intellij.openapi.util.NlsContexts;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.pom.java.JavaFeature;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.IncompleteModelUtil;
|
||||
import com.intellij.psi.impl.light.LightRecordMethod;
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
|
||||
import com.intellij.psi.infos.CandidateInfo;
|
||||
import com.intellij.psi.infos.MethodCandidateInfo;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.refactoring.util.RefactoringChangeUtil;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.xml.util.XmlStringUtil;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -281,139 +273,6 @@ public final class HighlightMethodUtil {
|
||||
return JavaErrorBundle.message("static.interface.method.call.qualifier");
|
||||
}
|
||||
|
||||
static boolean isDummyConstructorCall(@NotNull PsiMethodCallExpression methodCall,
|
||||
@NotNull PsiResolveHelper resolveHelper,
|
||||
@NotNull PsiExpressionList list,
|
||||
@NotNull PsiReferenceExpression referenceToMethod) {
|
||||
boolean isDummy = false;
|
||||
boolean isThisOrSuper = referenceToMethod.getReferenceNameElement() instanceof PsiKeyword;
|
||||
if (isThisOrSuper) {
|
||||
// super(..) or this(..)
|
||||
if (list.isEmpty()) { // implicit ctr call
|
||||
CandidateInfo[] candidates = resolveHelper.getReferencedMethodCandidates(methodCall, true);
|
||||
if (candidates.length == 1 && !candidates[0].getElement().isPhysical()) {
|
||||
isDummy = true;// dummy constructor
|
||||
}
|
||||
}
|
||||
}
|
||||
return isDummy;
|
||||
}
|
||||
|
||||
static HighlightInfo.Builder checkAmbiguousMethodCallIdentifier(@NotNull PsiReferenceExpression referenceToMethod,
|
||||
JavaResolveResult @NotNull [] resolveResults,
|
||||
@NotNull PsiExpressionList list,
|
||||
@Nullable PsiElement element,
|
||||
@NotNull JavaResolveResult resolveResult,
|
||||
@NotNull PsiMethodCallExpression methodCall,
|
||||
@NotNull LanguageLevel languageLevel,
|
||||
@NotNull PsiFile file) {
|
||||
MethodCandidateInfo methodCandidate2 = findCandidates(resolveResults).second;
|
||||
if (methodCandidate2 != null) return null;
|
||||
MethodCandidateInfo[] candidates = HighlightFixUtil.toMethodCandidates(resolveResults);
|
||||
|
||||
HighlightInfoType highlightInfoType = HighlightInfoType.ERROR;
|
||||
String description;
|
||||
PsiElement elementToHighlight = ObjectUtils.notNull(referenceToMethod.getReferenceNameElement(), referenceToMethod);
|
||||
if (element != null && !resolveResult.isAccessible()) {
|
||||
description = HighlightUtil.accessProblemDescription(referenceToMethod, element, resolveResult);
|
||||
}
|
||||
else if (element != null && !resolveResult.isStaticsScopeCorrect()) {
|
||||
if (element instanceof PsiMethod psiMethod && psiMethod.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
PsiClass containingClass = psiMethod.getContainingClass();
|
||||
if (containingClass != null && containingClass.isInterface()) {
|
||||
HighlightInfo.Builder info = HighlightUtil.checkFeature(elementToHighlight, JavaFeature.STATIC_INTERFACE_CALLS, languageLevel, file);
|
||||
if (info != null) return info;
|
||||
info = checkStaticInterfaceCallQualifier(referenceToMethod, resolveResult, elementToHighlight, containingClass);
|
||||
if (info != null) return info;
|
||||
}
|
||||
}
|
||||
|
||||
description = HighlightUtil.staticContextProblemDescription(element);
|
||||
}
|
||||
else if (candidates.length == 0) {
|
||||
PsiClass qualifierClass = RefactoringChangeUtil.getQualifierClass(referenceToMethod);
|
||||
String className = qualifierClass != null ? qualifierClass.getName() : null;
|
||||
PsiExpression qualifierExpression = referenceToMethod.getQualifierExpression();
|
||||
|
||||
if (className != null) {
|
||||
if (IncompleteModelUtil.isIncompleteModel(file) &&
|
||||
IncompleteModelUtil.canBePendingReference(referenceToMethod)) {
|
||||
return HighlightUtil.getPendingReferenceHighlightInfo(elementToHighlight);
|
||||
}
|
||||
description = JavaErrorBundle.message("ambiguous.method.call.no.match", referenceToMethod.getReferenceName(), className);
|
||||
}
|
||||
else if (qualifierExpression != null &&
|
||||
qualifierExpression.getType() instanceof PsiPrimitiveType primitiveType &&
|
||||
!primitiveType.equals(PsiTypes.nullType())) {
|
||||
if (PsiTypes.voidType().equals(primitiveType) &&
|
||||
PsiUtil.deparenthesizeExpression(qualifierExpression) instanceof PsiReferenceExpression) {
|
||||
return null;
|
||||
}
|
||||
description = JavaErrorBundle.message("cannot.call.method.on.type", primitiveType.getPresentableText(false));
|
||||
}
|
||||
else {
|
||||
if (qualifierExpression != null) {
|
||||
PsiType type = qualifierExpression.getType();
|
||||
if (type instanceof PsiClassType t && t.resolve() == null || PsiTypes.nullType().equals(type)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (IncompleteModelUtil.isIncompleteModel(file) && IncompleteModelUtil.canBePendingReference(referenceToMethod)) {
|
||||
return HighlightUtil.getPendingReferenceHighlightInfo(elementToHighlight);
|
||||
}
|
||||
description =
|
||||
JavaErrorBundle.message("cannot.resolve.method", referenceToMethod.getReferenceName() + buildArgTypesList(list, true));
|
||||
}
|
||||
highlightInfoType = HighlightInfoType.WRONG_REF;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
|
||||
String toolTip = XmlStringUtil.escapeString(description);
|
||||
HighlightInfo.Builder builder =
|
||||
HighlightInfo.newHighlightInfo(highlightInfoType).range(elementToHighlight).description(description).escapedToolTip(toolTip);
|
||||
if (element != null && !resolveResult.isStaticsScopeCorrect()) {
|
||||
HighlightFixUtil.registerStaticProblemQuickFixAction(asConsumer(builder), element, referenceToMethod);
|
||||
}
|
||||
HighlightFixUtil.registerMethodCallIntentions(asConsumer(builder), methodCall, list);
|
||||
|
||||
TextRange fixRange = getFixRange(elementToHighlight);
|
||||
CastMethodArgumentFix.REGISTRAR.registerCastActions(candidates, methodCall, asConsumer(builder));
|
||||
WrapWithAdapterMethodCallFix.registerCastActions(candidates, methodCall, asConsumer(builder));
|
||||
WrapObjectWithOptionalOfNullableFix.REGISTAR.registerCastActions(candidates, methodCall, asConsumer(builder));
|
||||
WrapExpressionFix.registerWrapAction(candidates, list.getExpressions(), asConsumer(builder));
|
||||
PermuteArgumentsFix.registerFix(asConsumer(builder), methodCall, candidates);
|
||||
var action = RemoveRepeatingCallFix.createFix(methodCall);
|
||||
if (action != null) {
|
||||
builder.registerFix(action, null, null, fixRange, null);
|
||||
}
|
||||
HighlightFixUtil.registerChangeParameterClassFix(methodCall, list, asConsumer(builder));
|
||||
if (candidates.length == 0) {
|
||||
PsiReference ref = methodCall.getMethodExpression();
|
||||
UnresolvedReferenceQuickFixProvider.registerUnresolvedReferenceLazyQuickFixes(ref, builder);
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
private static @NotNull Pair<MethodCandidateInfo, MethodCandidateInfo> findCandidates(JavaResolveResult @NotNull [] resolveResults) {
|
||||
MethodCandidateInfo methodCandidate1 = null;
|
||||
MethodCandidateInfo methodCandidate2 = null;
|
||||
for (JavaResolveResult result : resolveResults) {
|
||||
if (!(result instanceof MethodCandidateInfo candidate)) continue;
|
||||
if (candidate.isApplicable() && !candidate.getElement().isConstructor()) {
|
||||
if (methodCandidate1 == null) {
|
||||
methodCandidate1 = candidate;
|
||||
}
|
||||
else {
|
||||
methodCandidate2 = candidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Pair.pair(methodCandidate1, methodCandidate2);
|
||||
}
|
||||
|
||||
static HighlightInfo.Builder checkAbstractMethodInConcreteClass(@NotNull PsiMethod method, @NotNull PsiElement elementToHighlight) {
|
||||
HighlightInfo.Builder errorResult = null;
|
||||
PsiClass aClass = method.getContainingClass();
|
||||
@@ -473,19 +332,6 @@ public final class HighlightMethodUtil {
|
||||
return range;
|
||||
}
|
||||
|
||||
private static @NotNull String buildArgTypesList(@NotNull PsiExpressionList list, boolean shortNames) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("(");
|
||||
PsiExpression[] args = list.getExpressions();
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if (i > 0) builder.append(", ");
|
||||
PsiType argType = args[i].getType();
|
||||
builder.append(argType != null ? (shortNames ? argType.getPresentableText() : JavaHighlightUtil.formatType(argType)) : "?");
|
||||
}
|
||||
builder.append(")");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
static boolean hasSurroundingInferenceError(@NotNull PsiElement context) {
|
||||
PsiCall topCall = LambdaUtil.treeWalkUp(context);
|
||||
if (topCall == null) return false;
|
||||
|
||||
+6
-37
@@ -16,7 +16,6 @@ import com.intellij.core.JavaPsiBundle;
|
||||
import com.intellij.java.codeserver.highlighting.JavaErrorCollector;
|
||||
import com.intellij.java.codeserver.highlighting.errors.JavaCompilationError;
|
||||
import com.intellij.java.codeserver.highlighting.errors.JavaErrorHighlightType;
|
||||
import com.intellij.java.codeserver.highlighting.errors.JavaErrorKinds;
|
||||
import com.intellij.lang.annotation.HighlightSeverity;
|
||||
import com.intellij.lang.injection.InjectedLanguageManager;
|
||||
import com.intellij.lang.jvm.JvmModifier;
|
||||
@@ -62,6 +61,7 @@ import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static com.intellij.java.codeserver.highlighting.errors.JavaErrorKinds.*;
|
||||
import static com.intellij.psi.PsiModifier.SEALED;
|
||||
import static com.intellij.util.ObjectUtils.tryCast;
|
||||
import static java.util.Objects.*;
|
||||
@@ -99,11 +99,6 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
private final Map<PsiElement, PsiMethod> myInsideConstructorOfClassCache = new HashMap<>(); // null value means "cached but no corresponding ctr found"
|
||||
private boolean myHasError; // true if myHolder.add() was called with HighlightInfo of >=ERROR severity. On each .visit(PsiElement) call this flag is reset. Useful to determine whether the error was already reported while visiting this PsiElement.
|
||||
|
||||
@Contract(pure = true)
|
||||
private @NotNull PsiResolveHelper getResolveHelper() {
|
||||
return PsiResolveHelper.getInstance(getProject());
|
||||
}
|
||||
|
||||
protected HighlightVisitorImpl() {
|
||||
}
|
||||
|
||||
@@ -138,7 +133,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #HighlightVisitorImpl()} and {@link #getResolveHelper()}
|
||||
* @deprecated use {@link #HighlightVisitorImpl()}
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
protected HighlightVisitorImpl(@NotNull PsiResolveHelper psiResolveHelper) {
|
||||
@@ -251,8 +246,9 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
info.range(anchor);
|
||||
}
|
||||
errorFixProvider.processFixes(error, fix -> info.registerFix(fix.asIntention(), null, null, null, null));
|
||||
error.psiForKind(JavaErrorKinds.EXPRESSION_EXPECTED, JavaErrorKinds.REFERENCE_UNRESOLVED, JavaErrorKinds.REFERENCE_AMBIGUOUS)
|
||||
.or(() -> error.psiForKind(JavaErrorKinds.TYPE_UNKNOWN_CLASS).map(PsiTypeElement::getInnermostComponentReferenceElement))
|
||||
error.psiForKind(EXPRESSION_EXPECTED, REFERENCE_UNRESOLVED, REFERENCE_AMBIGUOUS)
|
||||
.or(() -> error.psiForKind(TYPE_UNKNOWN_CLASS).map(PsiTypeElement::getInnermostComponentReferenceElement))
|
||||
.or(() -> error.psiForKind(CALL_AMBIGUOUS_NO_MATCH, CALL_UNRESOLVED).map(PsiMethodCallExpression::getMethodExpression))
|
||||
.ifPresent(ref -> UnresolvedReferenceQuickFixProvider.registerUnresolvedReferenceLazyQuickFixes(ref, info));
|
||||
add(info);
|
||||
}
|
||||
@@ -752,7 +748,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
|
||||
@Override
|
||||
public void visitReferenceExpression(@NotNull PsiReferenceExpression expression) {
|
||||
JavaResolveResult resultForIncompleteCode = doVisitReferenceElement(expression);
|
||||
doVisitReferenceElement(expression);
|
||||
|
||||
if (!hasErrorResults()) {
|
||||
visitExpression(expression);
|
||||
@@ -780,22 +776,6 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
}
|
||||
}
|
||||
|
||||
PsiElement parent = expression.getParent();
|
||||
if (parent instanceof PsiMethodCallExpression methodCallExpression &&
|
||||
methodCallExpression.getMethodExpression() == expression &&
|
||||
(!result.isAccessible() || !result.isStaticsScopeCorrect())) {
|
||||
PsiExpressionList list = methodCallExpression.getArgumentList();
|
||||
PsiResolveHelper resolveHelper = getResolveHelper();
|
||||
if (!HighlightMethodUtil.isDummyConstructorCall(methodCallExpression, resolveHelper, list, expression)) {
|
||||
try {
|
||||
add(HighlightMethodUtil.checkAmbiguousMethodCallIdentifier(
|
||||
expression, results, list, resolved, result, methodCallExpression, myLanguageLevel, myFile));
|
||||
}
|
||||
catch (IndexNotReadyException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasErrorResults()) add(GenericsHighlightUtil.checkAccessStaticFieldFromEnumConstructor(expression, result));
|
||||
if (!hasErrorResults()) add(HighlightUtil.checkClassReferenceAfterQualifier(expression, resolved));
|
||||
PsiExpression qualifierExpression = expression.getQualifierExpression();
|
||||
@@ -1177,17 +1157,6 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitDefaultCaseLabelElement(@NotNull PsiDefaultCaseLabelElement element) {
|
||||
super.visitDefaultCaseLabelElement(element);
|
||||
// "case default:" will be highlighted as "The label for the default case must only use the 'default' keyword, without 'case'".
|
||||
// see SwitchBlockHighlightingModel#checkSwitchLabelValues
|
||||
// The "case default:" syntax was only allowed in outdated preview versions of Java (from Java 17 Preview to Java 19 Preview).
|
||||
// And even if the "case default" syntax was allowed not only in outdated preview versions of Java, using "case default:"
|
||||
// instead of "default:" looks weird. Therefore, for this case, we do not check the feature availability and do not
|
||||
// suggest increasing the language level.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPatternVariable(@NotNull PsiPatternVariable variable) {
|
||||
super.visitPatternVariable(variable);
|
||||
|
||||
+12
-5
@@ -405,14 +405,21 @@ final class JavaErrorFixProvider {
|
||||
}
|
||||
}
|
||||
});
|
||||
fixes(CALL_AMBIGUOUS, (error, sink) -> {
|
||||
PsiMethodCallExpression methodCall = error.psi();
|
||||
JavaResolveResult[] resolveResults = error.context().results();
|
||||
HighlightFixUtil.registerAmbiguousCallFixes(sink, methodCall, resolveResults);
|
||||
fixes(CALL_UNRESOLVED_NAME,
|
||||
(error, sink) -> HighlightFixUtil.registerMethodCallIntentions(sink, error.psi(), error.psi().getArgumentList()));
|
||||
fix(CALL_QUALIFIER_PRIMITIVE, error -> myFactory.createRenameWrongRefFix(error.psi().getMethodExpression()));
|
||||
fixes(CALL_QUALIFIER_PRIMITIVE,
|
||||
(error, sink) -> HighlightFixUtil.registerMethodCallIntentions(sink, error.psi(), error.psi().getArgumentList()));
|
||||
fixes(CALL_AMBIGUOUS, (error, sink) -> HighlightFixUtil.registerAmbiguousCallFixes(sink, error.psi(), error.context().results()));
|
||||
fixes(CALL_AMBIGUOUS_NO_MATCH, (error, sink) -> HighlightFixUtil.registerAmbiguousCallFixes(sink, error.psi(), error.context()));
|
||||
fixes(REFERENCE_NON_STATIC_FROM_STATIC_CONTEXT, (error, sink) -> {
|
||||
HighlightFixUtil.registerStaticProblemQuickFixAction(sink, error.context(), error.psi());
|
||||
if (error.psi().getParent() instanceof PsiMethodCallExpression methodCall) {
|
||||
HighlightFixUtil.registerMethodCallIntentions(sink, methodCall, methodCall.getArgumentList());
|
||||
}
|
||||
});
|
||||
fixes(CALL_UNRESOLVED, (error, sink) -> {
|
||||
PsiMethodCallExpression methodCall = error.psi();
|
||||
HighlightFixUtil.registerMethodCallIntentions(sink, methodCall, methodCall.getArgumentList());
|
||||
JavaResolveResult[] resolveResults = error.context();
|
||||
if (resolveResults.length == 1) {
|
||||
PsiElement element = resolveResults[0].getElement();
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ class C {
|
||||
interface II extends I {
|
||||
default void m() {
|
||||
I.super.m();
|
||||
<error descr="Unqualified super reference is not allowed in extension method">super.m</error>();
|
||||
<error descr="Unqualified super reference is not allowed in extension method">super.<error descr="Cannot resolve method 'm' in 'Object'">m</error></error>();
|
||||
|
||||
System.out.println(<error descr="'C.I' is not an enclosing class">I.super</error>.i);
|
||||
System.out.println(<error descr="Unqualified super reference is not allowed in extension method">super.<error descr="Cannot resolve symbol 'i'">i</error></error>);
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ import static p.<error descr="Cannot access p.BaseClass">ChildClass</error>.*;
|
||||
|
||||
class Sample {
|
||||
public static void main(String[] args) {
|
||||
<error descr="Cannot access p.BaseClass">ChildClass.foo</error>();
|
||||
ChildClass.<error descr="Cannot resolve method 'foo' in 'ChildClass'">foo</error>();
|
||||
foo();
|
||||
ChildClass cc = ChildClass2.childClass();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user