From 545603587aee81aa029f1cad56bfb36e9ce578f5 Mon Sep 17 00:00:00 2001 From: UNV Date: Mon, 1 Dec 2025 07:35:06 +0300 Subject: [PATCH] Localizing and refactoring compilation error analysis. --- .../analysis/AnnotationsHighlightUtil.java | 186 ++- .../impl/analysis/GenericsHighlightUtil.java | 141 +- .../impl/analysis/HighlightClassUtil.java | 56 +- .../analysis/HighlightControlFlowUtil.java | 68 +- .../impl/analysis/HighlightMethodUtil.java | 266 ++-- .../daemon/impl/analysis/HighlightUtil.java | 290 ++-- .../impl/analysis/HighlightVisitorImpl.java | 106 +- .../impl/analysis/LambdaHighlightingUtil.java | 239 +-- .../impl/analysis/ModuleHighlightUtil.java | 71 +- .../analysis/PostHighlightingVisitor.java | 64 +- .../AddTypeArgumentsConditionalFix.java | 13 +- .../quickfix/ArgumentFixerActionFactory.java | 7 +- .../quickfix/ConvertDoubleToFloatFix.java | 12 +- .../impl/quickfix/PermuteArgumentsFix.java | 2 +- .../quickfix/QualifySuperArgumentFix.java | 25 +- .../impl/quickfix/QualifyThisArgumentFix.java | 20 +- .../quickfix/RemoveRedundantArgumentsFix.java | 4 +- .../impl/quickfix/WrapExpressionFix.java | 2 +- .../language/psi/PsiMethodReferenceUtil.java | 615 ++++---- .../psi/infos/MethodCandidateInfo.java | 1294 ++++++++--------- ...language.JavaCompilationErrorLocalize.yaml | 996 +++++++++++++ ...lo.java.language.JavaLanguageLocalize.yaml | 2 - ....java.language.impl.JavaErrorLocalize.yaml | 622 +------- .../MethodReferenceCompletionProvider.java | 172 ++- .../lambda/FunctionalInterfaceTest.java | 7 +- 25 files changed, 2832 insertions(+), 2448 deletions(-) create mode 100644 java-language-api/src/main/resources/LOCALIZE-LIB/en_US/consulo.java.language.JavaCompilationErrorLocalize.yaml diff --git a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/AnnotationsHighlightUtil.java b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/AnnotationsHighlightUtil.java index bfe37df288..0c97bbd42b 100644 --- a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/AnnotationsHighlightUtil.java +++ b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/AnnotationsHighlightUtil.java @@ -19,7 +19,6 @@ import com.intellij.java.language.JavaFeature; import com.intellij.java.language.LanguageLevel; import com.intellij.java.language.codeInsight.AnnotationTargetUtil; -import com.intellij.java.language.impl.codeInsight.daemon.JavaErrorBundle; import com.intellij.java.language.impl.psi.impl.PsiImplUtil; import com.intellij.java.language.impl.psi.impl.source.PsiClassReferenceType; import com.intellij.java.language.impl.psi.impl.source.PsiImmediateClassType; @@ -28,10 +27,11 @@ import com.intellij.java.language.psi.util.PsiUtil; import com.intellij.java.language.psi.util.TypeConversionUtil; import consulo.annotation.access.RequiredReadAction; +import consulo.annotation.access.RequiredWriteAction; import consulo.codeEditor.Editor; import consulo.java.language.impl.localize.JavaErrorLocalize; +import consulo.java.language.localize.JavaCompilationErrorLocalize; import consulo.language.editor.intention.IntentionAction; -import consulo.language.editor.intention.QuickFixAction; import consulo.language.editor.intention.SyntheticIntentionAction; import consulo.language.editor.rawHighlight.HighlightInfo; import consulo.language.editor.rawHighlight.HighlightInfoType; @@ -68,7 +68,7 @@ public static HighlightInfo checkNameValuePair(PsiNameValuePair pair) { if (ref == null) { return null; } - PsiMethod method = (PsiMethod)ref.resolve(); + PsiMethod method = (PsiMethod) ref.resolve(); if (method == null) { if (pair.getName() != null) { return HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF) @@ -78,14 +78,13 @@ public static HighlightInfo checkNameValuePair(PsiNameValuePair pair) { .create(); } else { - HighlightInfo highlightInfo = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) + HighlightInfo.Builder hlBuilder = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(ref.getElement()) - .descriptionAndTooltip(JavaErrorLocalize.annotationMissingMethod(ref.getCanonicalText())) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.annotationMissingMethod(ref.getCanonicalText())); for (IntentionAction action : QuickFixFactory.getInstance().createAddAnnotationAttributeNameFixes(pair)) { - QuickFixAction.registerQuickFixAction(highlightInfo, action); + hlBuilder.registerFix(action); } - return highlightInfo; + return hlBuilder.create(); } } else { @@ -104,7 +103,7 @@ public static HighlightInfo checkNameValuePair(PsiNameValuePair pair) { @Nullable @RequiredReadAction private static HighlightInfo checkDuplicateAttribute(PsiNameValuePair pair) { - PsiAnnotationParameterList annotation = (PsiAnnotationParameterList)pair.getParent(); + PsiAnnotationParameterList annotation = (PsiAnnotationParameterList) pair.getParent(); PsiNameValuePair[] attributes = annotation.getAttributes(); for (PsiNameValuePair attribute : attributes) { if (attribute == pair) { @@ -114,7 +113,7 @@ private static HighlightInfo checkDuplicateAttribute(PsiNameValuePair pair) { if (Comparing.equal(attribute.getName(), name)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(pair) - .descriptionAndTooltip(JavaErrorLocalize.annotationDuplicateAttribute( + .descriptionAndTooltip(JavaCompilationErrorLocalize.annotationAttributeDuplicate( name == null ? PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME : name )) .create(); @@ -140,7 +139,7 @@ public static HighlightInfo checkMemberValueType(@Nullable PsiAnnotationMemberVa if (!(value instanceof PsiClassObjectAccessExpression)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(value) - .descriptionAndTooltip(JavaErrorLocalize.annotationNonClassLiteralAttributeValue()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.annotationAttributeNonClassLiteral()) .create(); } } @@ -167,8 +166,8 @@ public static HighlightInfo checkMemberValueType(@Nullable PsiAnnotationMemberVa } return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) - .range(value) - .descriptionAndTooltip(JavaErrorLocalize.incompatibleTypes( + .range(annotation) + .descriptionAndTooltip(JavaCompilationErrorLocalize.annotationAttributeIncompatibleType( JavaHighlightUtil.formatType(expectedType), formatReference(nameRef) )) @@ -181,7 +180,7 @@ public static HighlightInfo checkMemberValueType(@Nullable PsiAnnotationMemberVa } return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(value) - .descriptionAndTooltip(JavaErrorLocalize.annotationIllegalArrayInitializer(JavaHighlightUtil.formatType(expectedType))) + .descriptionAndTooltip(JavaCompilationErrorLocalize.annotationAttributeIllegalArrayInitializer(JavaHighlightUtil.formatType(expectedType))) .create(); } @@ -192,8 +191,8 @@ public static HighlightInfo checkMemberValueType(@Nullable PsiAnnotationMemberVa if (psiClass != null && psiClass.isEnum() && !(expr instanceof PsiReferenceExpression refExpr && refExpr.resolve() instanceof PsiEnumConstant)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) - .range(value) - .descriptionAndTooltip(JavaErrorBundle.message("annotation.non.enum.constant.attribute.value")) + .range(expr) + .descriptionAndTooltip(JavaCompilationErrorLocalize.annotationAttributeNonEnumConstant()) .create(); } @@ -205,7 +204,7 @@ public static HighlightInfo checkMemberValueType(@Nullable PsiAnnotationMemberVa return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(value) - .descriptionAndTooltip(JavaErrorLocalize.incompatibleTypes( + .descriptionAndTooltip(JavaCompilationErrorLocalize.annotationAttributeIncompatibleType( JavaHighlightUtil.formatType(expectedType), JavaHighlightUtil.formatType(type) )) @@ -238,30 +237,30 @@ public static HighlightInfo.Builder checkDuplicateAnnotations( if (containedElementFQN != null) { String containerName = annotationType.getQualifiedName(); if (isAnnotationRepeatedTwice(owner, containedElementFQN)) { - return annotationError(annotationToCheck, JavaErrorLocalize.annotationContainerWrongPlace(containerName)); + return annotationError(annotationToCheck, JavaCompilationErrorLocalize.annotationContainerWrongPlace(containerName)); } } else if (isAnnotationRepeatedTwice(owner, annotationType.getQualifiedName())) { if (!languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(element) - .descriptionAndTooltip(JavaErrorLocalize.annotationDuplicateAnnotation()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.annotationDuplicate()); } PsiAnnotation metaAnno = PsiImplUtil.findAnnotation(annotationType.getModifierList(), CommonClassNames.JAVA_LANG_ANNOTATION_REPEATABLE); if (metaAnno == null) { - LocalizeValue explanation = JavaErrorLocalize.annotationNonRepeatable(annotationType.getQualifiedName()); + LocalizeValue explanation = JavaCompilationErrorLocalize.annotationDuplicateNonRepeatable(annotationType.getQualifiedName()); return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(element) - .descriptionAndTooltip(JavaErrorLocalize.annotationDuplicateExplained(explanation)); + .descriptionAndTooltip(JavaCompilationErrorLocalize.annotationDuplicateExplained(explanation)); } - String explanation = doCheckRepeatableAnnotation(metaAnno); - if (explanation != null) { + LocalizeValue explanation = doCheckRepeatableAnnotation(metaAnno); + if (explanation != LocalizeValue.empty()) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(element) - .descriptionAndTooltip(JavaErrorLocalize.annotationDuplicateExplained(explanation)); + .descriptionAndTooltip(JavaCompilationErrorLocalize.annotationDuplicateExplained(explanation)); } PsiClass container = getRepeatableContainer(metaAnno); @@ -271,7 +270,7 @@ else if (isAnnotationRepeatedTwice(owner, annotationType.getQualifiedName())) { if (applicable == null) { return annotationError( annotationToCheck, - JavaErrorLocalize.annotationContainerNotApplicable(container.getName(), targets[0].getPresentableText()) + JavaCompilationErrorLocalize.annotationContainerNotApplicable(container.getName(), targets[0].getPresentableText()) ); } } @@ -289,9 +288,7 @@ private static PsiClass contained(PsiClass annotationType) { if (values.length != 1) { return null; } - PsiMethod value = values[0]; - PsiType returnType = value.getReturnType(); - if (!(returnType instanceof PsiArrayType arrayType)) { + if (!(values[0].getReturnType() instanceof PsiArrayType arrayType)) { return null; } if (!(arrayType.getComponentType() instanceof PsiClassType componentClassType)) { @@ -332,7 +329,7 @@ public static HighlightInfo.Builder checkMissingAttributes(PsiAnnotation annotat if (nameRef == null) { return null; } - PsiClass aClass = (PsiClass)nameRef.resolve(); + PsiClass aClass = (PsiClass) nameRef.resolve(); if (aClass != null && aClass.isAnnotationType()) { Set names = new HashSet<>(); PsiNameValuePair[] attributes = annotation.getParameterList().getAttributes(); @@ -350,7 +347,7 @@ public static HighlightInfo.Builder checkMissingAttributes(PsiAnnotation annotat List missed = new ArrayList<>(); for (PsiMethod method : annotationMethods) { if (PsiUtil.isAnnotationMethod(method)) { - PsiAnnotationMethod annotationMethod = (PsiAnnotationMethod)method; + PsiAnnotationMethod annotationMethod = (PsiAnnotationMethod) method; if (annotationMethod.getDefaultValue() == null && !names.contains(annotationMethod.getName())) { missed.add(annotationMethod.getName()); } @@ -366,7 +363,7 @@ public static HighlightInfo.Builder checkMissingAttributes(PsiAnnotation annotat return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(nameRef) - .descriptionAndTooltip(JavaErrorLocalize.annotationMissingAttribute(buff)) + .descriptionAndTooltip(JavaCompilationErrorLocalize.annotationMissingAttribute(buff)) .registerFix( QuickFixFactory.getInstance().createAddMissingRequiredAnnotationParametersFix(annotation, annotationMethods, missed) ); @@ -384,7 +381,7 @@ public static HighlightInfo.Builder checkConstantExpression(PsiExpression expres if (!PsiUtil.isConstantExpression(expression)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.annotationNonConstantAttributeValue()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.annotationAttributeNonConstant()); } } @@ -399,7 +396,7 @@ public static HighlightInfo.Builder checkValidAnnotationType(PsiType type, PsiTy } return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(typeElement) - .descriptionAndTooltip(JavaErrorLocalize.annotationInvalidAnnotationMemberType(type != null ? type.getPresentableText() : "?")); + .descriptionAndTooltip(JavaCompilationErrorLocalize.annotationMemberInvalidType(type != null ? type.getPresentableText() : "?")); } private static final ElementPattern ANY_ANNOTATION_ALLOWED = psiElement().andOr( @@ -428,7 +425,7 @@ public static HighlightInfo.Builder checkApplicability( PsiAnnotationOwner owner = annotation.getOwner(); PsiAnnotation.TargetType[] targets = AnnotationTargetUtil.getTargetsForLocation(owner); if (owner == null || targets.length == 0) { - return annotationError(annotation, JavaErrorLocalize.annotationNotAllowedHere()); + return annotationError(annotation, JavaCompilationErrorLocalize.annotationNotAllowedHere()); } if (!(owner instanceof PsiModifierList)) { @@ -446,7 +443,7 @@ public static HighlightInfo.Builder checkApplicability( if (applicable == null) { return annotationError( annotation, - JavaErrorLocalize.annotationNotApplicable(nameRef.getText(), targets[0].getPresentableText()) + JavaCompilationErrorLocalize.annotationNotApplicable(nameRef.getText(), targets[0].getPresentableText()) ); } @@ -464,7 +461,7 @@ else if (owner instanceof PsiModifierList modifierList) { if (nextElement instanceof PsiTypeElement typeElement) { PsiType type = typeElement.getType(); if (PsiType.VOID.equals(type)) { - return annotationError(annotation, JavaErrorLocalize.annotationNotAllowedVoid()); + return annotationError(annotation, JavaCompilationErrorLocalize.annotationNotAllowedVoid()); } if (!(type instanceof PsiPrimitiveType)) { PsiJavaCodeReferenceElement ref = getOutermostReferenceElement(typeElement.getInnermostComponentReferenceElement()); @@ -475,10 +472,10 @@ else if (owner instanceof PsiModifierList modifierList) { } } } - else if (owner instanceof PsiTypeElement) { - PsiElement context = PsiTreeUtil.skipParentsOfType((PsiTypeElement)owner, PsiTypeElement.class); + else if (owner instanceof PsiTypeElement typeElem) { + PsiElement context = PsiTreeUtil.skipParentsOfType(typeElem, PsiTypeElement.class); if (context instanceof PsiClassObjectAccessExpression) { - return annotationError(annotation, JavaErrorLocalize.annotationNotAllowedClass()); + return annotationError(annotation, JavaCompilationErrorLocalize.annotationNotAllowedClass()); } } } @@ -506,11 +503,11 @@ private static HighlightInfo.Builder checkReferenceTarget(PsiAnnotation annotati } if (!(refTarget instanceof PsiClass)) { - return annotationError(annotation, JavaErrorLocalize.annotationNotAllowedRef()); + return annotationError(annotation, JavaCompilationErrorLocalize.annotationNotAllowedRef()); } else if (ref.getParent() instanceof PsiJavaCodeReferenceElement javaCodeRef && javaCodeRef.resolve() instanceof PsiMember member && member.isStatic()) { - return annotationError(annotation, JavaErrorLocalize.annotationNotAllowedStatic()); + return annotationError(annotation, JavaCompilationErrorLocalize.annotationNotAllowedStatic()); } return null; } @@ -534,7 +531,7 @@ public static HighlightInfo.Builder checkAnnotationType(PsiAnnotation annotation if (nameRefElem != null && (!(nameRefElem.resolve() instanceof PsiClass annotationClass) || !annotationClass.isAnnotationType())) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(nameRefElem) - .descriptionAndTooltip(JavaErrorLocalize.annotationAnnotationTypeExpected()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.annotationTypeExpected()); } return null; } @@ -548,7 +545,7 @@ public static HighlightInfo.Builder checkCyclicMemberType(PsiTypeElement typeEle if (cyclicDependencies(aClass, type, checked, aClass.getManager())) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(typeElement) - .descriptionAndTooltip(JavaErrorLocalize.annotationCyclicElementType()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.annotationCyclicElementType()); } return null; } @@ -586,10 +583,10 @@ public static HighlightInfo.Builder checkClashesWithSuperMethods(@Nonnull PsiAnn || CommonClassNames.JAVA_LANG_ANNOTATION_ANNOTATION.equals(qualifiedName)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(nameIdentifier) - .descriptionAndTooltip( - "@interface member clashes with '" + JavaHighlightUtil.formatMethod(method) + - "' in " + HighlightUtil.formatClass(containingClass) - ); + .descriptionAndTooltip(JavaCompilationErrorLocalize.annotationMemberClash( + JavaHighlightUtil.formatMethod(method), + HighlightUtil.formatClass(containingClass) + )); } } } @@ -601,11 +598,11 @@ public static HighlightInfo.Builder checkClashesWithSuperMethods(@Nonnull PsiAnn @RequiredReadAction public static HighlightInfo checkAnnotationDeclaration(PsiElement parent, PsiReferenceList list) { if (PsiUtil.isAnnotationMethod(parent)) { - PsiAnnotationMethod method = (PsiAnnotationMethod)parent; + PsiAnnotationMethod method = (PsiAnnotationMethod) parent; if (list == method.getThrowsList()) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(list) - .descriptionAndTooltip(JavaErrorLocalize.annotationMembersMayNotHaveThrowsList()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.annotationMemberMayNotHaveThrowsList()) .create(); } } @@ -613,7 +610,7 @@ else if (parent instanceof PsiClass annotationClass && annotationClass.isAnnotat if (PsiKeyword.EXTENDS.equals(list.getFirstChild().getText())) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(list) - .descriptionAndTooltip(JavaErrorLocalize.annotationMayNotHaveExtendsList()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.annotationMayNotHaveExtendsList()) .create(); } } @@ -650,23 +647,19 @@ public static HighlightInfo.Builder checkTargetAnnotationDuplicates(PsiAnnotatio if (attributes.length < 1) { return null; } - PsiAnnotationMemberValue value = attributes[0].getValue(); - if (!(value instanceof PsiArrayInitializerMemberValue arrayInitializerMemberValue)) { + if (!(attributes[0].getValue() instanceof PsiArrayInitializerMemberValue arrayInitializerMemberValue)) { return null; } PsiAnnotationMemberValue[] arrayInitializers = arrayInitializerMemberValue.getInitializers(); Set targets = new HashSet<>(); for (PsiAnnotationMemberValue initializer : arrayInitializers) { - if (initializer instanceof PsiReferenceExpression refExpr) { - PsiElement target = refExpr.resolve(); - if (target != null) { - if (targets.contains(target)) { - return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) - .range(initializer) - .descriptionAndTooltip(JavaErrorLocalize.repeatedAnnotationTarget()); - } - targets.add(target); + if (initializer instanceof PsiReferenceExpression refExpr && refExpr.resolve() instanceof PsiElement target) { + if (targets.contains(target)) { + return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) + .range(initializer) + .descriptionAndTooltip(JavaCompilationErrorLocalize.annotationRepeatedTarget()); } + targets.add(target); } } return null; @@ -676,19 +669,17 @@ public static HighlightInfo.Builder checkTargetAnnotationDuplicates(PsiAnnotatio @RequiredReadAction public static HighlightInfo.Builder checkFunctionalInterface(@Nonnull PsiAnnotation annotation, @Nonnull LanguageLevel languageLevel) { if (languageLevel.isAtLeast(LanguageLevel.JDK_1_8) - && Comparing.strEqual(annotation.getQualifiedName(), CommonClassNames.JAVA_LANG_FUNCTIONAL_INTERFACE)) { - PsiAnnotationOwner owner = annotation.getOwner(); - if (owner instanceof PsiModifierList modifierList - && modifierList.getParent() instanceof PsiClass psiClass) { - String errorMessage = LambdaHighlightingUtil.checkInterfaceFunctional( - psiClass, - psiClass.getName() + " is not a functional interface" - ); - if (errorMessage != null) { - return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) - .range(annotation) - .descriptionAndTooltip(errorMessage); - } + && CommonClassNames.JAVA_LANG_FUNCTIONAL_INTERFACE.equals(annotation.getQualifiedName()) + && annotation.getOwner() instanceof PsiModifierList modifierList + && modifierList.getParent() instanceof PsiClass psiClass) { + LocalizeValue errorMessage = LambdaHighlightingUtil.checkInterfaceFunctional( + psiClass, + JavaCompilationErrorLocalize.lambdaNotAFunctionalInterface(psiClass.getName()) + ); + if (errorMessage != LocalizeValue.empty()) { + return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) + .range(annotation) + .descriptionAndTooltip(errorMessage); } } return null; @@ -702,8 +693,8 @@ public static HighlightInfo.Builder checkRepeatableAnnotation(PsiAnnotation anno return null; } - String description = doCheckRepeatableAnnotation(annotation); - if (description != null) { + LocalizeValue description = doCheckRepeatableAnnotation(annotation); + if (description != LocalizeValue.empty()) { PsiAnnotationMemberValue containerRef = PsiImplUtil.findAttributeValue(annotation, null); if (containerRef != null) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) @@ -715,31 +706,29 @@ public static HighlightInfo.Builder checkRepeatableAnnotation(PsiAnnotation anno return null; } - @Nullable + @Nonnull @RequiredReadAction - private static String doCheckRepeatableAnnotation(@Nonnull PsiAnnotation annotation) { - PsiAnnotationOwner owner = annotation.getOwner(); - if (!(owner instanceof PsiModifierList modifierList)) { - return null; + private static LocalizeValue doCheckRepeatableAnnotation(@Nonnull PsiAnnotation annotation) { + if (!(annotation.getOwner() instanceof PsiModifierList modifierList)) { + return LocalizeValue.empty(); } if (!(modifierList.getParent() instanceof PsiClass targetClass) || !targetClass.isAnnotationType()) { - return null; + return LocalizeValue.empty(); } PsiClass container = getRepeatableContainer(annotation); if (container == null) { - return null; + return LocalizeValue.empty(); } PsiMethod[] methods = container.findMethodsByName("value", false); if (methods.length == 0) { - return JavaErrorLocalize.annotationContainerNoValue(container.getQualifiedName()).get(); + return JavaCompilationErrorLocalize.annotationContainerNoValue(container.getQualifiedName()); } if (methods.length == 1) { PsiType expected = new PsiImmediateClassType(targetClass, PsiSubstitutor.EMPTY).createArrayType(); if (!expected.equals(methods[0].getReturnType())) { - return JavaErrorLocalize.annotationContainerBadType(container.getQualifiedName(), JavaHighlightUtil.formatType(expected)) - .get(); + return JavaCompilationErrorLocalize.annotationContainerBadType(container.getQualifiedName(), JavaHighlightUtil.formatType(expected)); } } @@ -747,7 +736,7 @@ private static String doCheckRepeatableAnnotation(@Nonnull PsiAnnotation annotat if (targetPolicy != null) { RetentionPolicy containerPolicy = getRetentionPolicy(container); if (containerPolicy != null && targetPolicy.compareTo(containerPolicy) > 0) { - return JavaErrorLocalize.annotationContainerLowRetention(container.getQualifiedName(), containerPolicy).get(); + return JavaCompilationErrorLocalize.annotationContainerLowRetention(container.getQualifiedName(), containerPolicy); } } @@ -755,11 +744,11 @@ private static String doCheckRepeatableAnnotation(@Nonnull PsiAnnotation annotat if (repeatableTargets != null) { Set containerTargets = AnnotationTargetUtil.getAnnotationTargets(container); if (containerTargets != null && !repeatableTargets.containsAll(containerTargets)) { - return JavaErrorLocalize.annotationContainerWideTarget(container.getQualifiedName()).get(); + return JavaCompilationErrorLocalize.annotationContainerWideTarget(container.getQualifiedName()); } } - return null; + return LocalizeValue.empty(); } @Nullable @@ -786,14 +775,14 @@ public static HighlightInfo checkReceiverPlacement(PsiReceiverParameter paramete if (!(owner instanceof PsiMethod method)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(parameter.getIdentifier()) - .descriptionAndTooltip(JavaErrorLocalize.receiverWrongContext()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.receiverWrongContext()) .create(); } if (isStatic(method) || method.isConstructor() && isStatic(method.getContainingClass())) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(parameter.getIdentifier()) - .descriptionAndTooltip(JavaErrorLocalize.receiverStaticContext()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.receiverStaticContext()) .create(); } @@ -801,7 +790,7 @@ public static HighlightInfo checkReceiverPlacement(PsiReceiverParameter paramete if (leftNeighbour != null && !PsiUtil.isJavaToken(leftNeighbour, JavaTokenType.LPARENTH)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(parameter.getIdentifier()) - .descriptionAndTooltip(JavaErrorLocalize.receiverWrongPosition()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.receiverWrongPosition()) .create(); } @@ -812,11 +801,10 @@ public static HighlightInfo checkReceiverPlacement(PsiReceiverParameter paramete @RequiredReadAction public static HighlightInfo checkReceiverType(PsiReceiverParameter parameter) { PsiElement owner = parameter.getParent().getParent(); - if (!(owner instanceof PsiMethod)) { + if (!(owner instanceof PsiMethod method)) { return null; } - PsiMethod method = (PsiMethod)owner; PsiClass enclosingClass = method.getContainingClass(); if (method.isConstructor() && enclosingClass != null) { enclosingClass = enclosingClass.getContainingClass(); @@ -826,7 +814,7 @@ public static HighlightInfo checkReceiverType(PsiReceiverParameter parameter) { PsiElement range = ObjectUtil.notNull(parameter.getTypeElement(), parameter); return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(range) - .descriptionAndTooltip(JavaErrorLocalize.receiverTypeMismatch()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.receiverTypeMismatch()) .create(); } @@ -834,13 +822,15 @@ public static HighlightInfo checkReceiverType(PsiReceiverParameter parameter) { if (enclosingClass != null && !enclosingClass.equals(PsiUtil.resolveClassInType(identifier.getType()))) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(identifier) - .descriptionAndTooltip(JavaErrorLocalize.receiverNameMismatch()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.receiverNameMismatch()) .create(); } return null; } + @RequiredReadAction + @SuppressWarnings("SimplifiableIfStatement") private static boolean isStatic(PsiModifierListOwner owner) { if (owner == null) { return false; @@ -848,8 +838,7 @@ private static boolean isStatic(PsiModifierListOwner owner) { if (owner instanceof PsiClass psiClass && ClassUtil.isTopLevelClass(psiClass)) { return true; } - PsiModifierList modifierList = owner.getModifierList(); - return modifierList != null && modifierList.hasModifierProperty(PsiModifier.STATIC); + return owner.hasModifierProperty(PsiModifier.STATIC); } @Nullable @@ -935,6 +924,7 @@ public boolean isAvailable(@Nonnull Project project, Editor editor, PsiFile file } @Override + @RequiredWriteAction public void invoke(@Nonnull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { myAnnotation.delete(); } diff --git a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java index 1f8395ed82..26e6876ab6 100644 --- a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java +++ b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java @@ -32,6 +32,7 @@ import consulo.application.dumb.IndexNotReadyException; import consulo.document.util.TextRange; import consulo.java.language.impl.localize.JavaErrorLocalize; +import consulo.java.language.localize.JavaCompilationErrorLocalize; import consulo.language.content.FileIndexFacade; import consulo.language.editor.intention.IntentionAction; import consulo.language.editor.intention.QuickFixActionRegistrar; @@ -93,8 +94,8 @@ private static HighlightInfo.Builder checkInferredTypeArguments( String t1 = JavaHighlightUtil.formatType(extendsType); String t2 = JavaHighlightUtil.formatType(substitutor.substitute(typeParameter)); LocalizeValue description = boundClass == null || typeParameter.isInterface() == boundClass.isInterface() - ? JavaErrorLocalize.genericsInferredTypeForTypeParameterIsNotWithinItsBoundExtend(c, t1, t2) - : JavaErrorLocalize.genericsInferredTypeForTypeParameterIsNotWithinItsBoundImplement(c, t1, t2); + ? JavaCompilationErrorLocalize.typeParameterInferredTypeNotWithinExtendBound(c, t1, t2) + : JavaCompilationErrorLocalize.typeParameterInferredTypeNotWithinImplementBound(c, t1, t2); return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(call) .descriptionAndTooltip(description); @@ -140,7 +141,7 @@ public static HighlightInfo.Builder checkReferenceTypeArgumentList( if (!typeParameterListOwner.hasTypeParameters()) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(referenceParameterList) - .descriptionAndTooltip(JavaErrorLocalize.genericsDiamondNotApplicable()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.newExpressionDiamondNotApplicable()); } inferenceResult = diamondType.resolveInferredTypes(); String errorMessage = inferenceResult.getErrorMessage(); @@ -174,7 +175,7 @@ && detectExpectedType(referenceParameterList) instanceof PsiClassType expectedCl } } else { - description = JavaErrorLocalize.genericsWrongNumberOfTypeArguments(refParametersNum, targetParametersNum); + description = JavaCompilationErrorLocalize.typeParameterCountMismatch(refParametersNum, targetParametersNum); } if (description != LocalizeValue.empty()) { @@ -300,7 +301,7 @@ private static HighlightInfo.Builder checkTypeParameterWithinItsBound( && GenericsUtil.checkNotInBounds(type, psiType, referenceParameterList)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(typeElement2Highlight) - .descriptionAndTooltip(JavaErrorLocalize.actualTypeArgumentContradictInferredType()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.typeParameterActualInferredMismatch()); } PsiClassType[] bounds = classParameter.getSuperTypes(); @@ -314,8 +315,8 @@ private static HighlightInfo.Builder checkTypeParameterWithinItsBound( String t = JavaHighlightUtil.formatType(bound); LocalizeValue description = boundClass == null || referenceClass == null || referenceClass.isInterface() == boundClass.isInterface() - ? JavaErrorLocalize.genericsTypeParameterIsNotWithinItsBoundExtend(c, t) - : JavaErrorLocalize.genericsTypeParameterIsNotWithinItsBoundImplement(c, t); + ? JavaCompilationErrorLocalize.typeParameterTypeNotWithinExtendBound(c, t) + : JavaCompilationErrorLocalize.typeParameterTypeNotWithinImplementBound(c, t); HighlightInfo.Builder hlBuilder = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(typeElement2Highlight) @@ -360,7 +361,7 @@ public static HighlightInfo.Builder checkElementInTypeParameterExtendsList( @Nonnull PsiElement element ) { PsiJavaCodeReferenceElement[] referenceElements = referenceList.getReferenceElements(); - PsiClass extendFrom = (PsiClass)resolveResult.getElement(); + PsiClass extendFrom = (PsiClass) resolveResult.getElement(); if (extendFrom == null) { return null; } @@ -378,7 +379,7 @@ else if (referenceElements.length != 0 && element != referenceElements[0] .createType(extendFrom, resolveResult.getSubstitutor()); return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(element) - .descriptionAndTooltip(JavaErrorLocalize.typeParameterCannotBeFollowedByOtherBounds()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.typeParameterCannotBeFollowedByOtherBounds()) .registerFix(QuickFixFactory.getInstance().createExtendsListFix(aClass, type, false)); } return null; @@ -421,7 +422,7 @@ private static HighlightInfo checkInterfaceMultipleInheritance( PsiType type2 = superTypeSubstitutor.substitute(typeParameter); if (!Objects.equals(type1, type2)) { - LocalizeValue description = JavaErrorLocalize.genericsCannotBeInheritedWithDifferentTypeArguments( + LocalizeValue description = JavaCompilationErrorLocalize.classInheritanceDifferentTypeArguments( HighlightUtil.formatClass(superClass), JavaHighlightUtil.formatType(type1), JavaHighlightUtil.formatType(type2) @@ -494,12 +495,12 @@ public static HighlightInfo checkDefaultMethodOverrideEquivalentToObjectNonPriva HierarchicalMethodSignature sig = method.getHierarchicalMethodSignature(); for (HierarchicalMethodSignature methodSignature : sig.getSuperSignatures()) { PsiMethod objectMethod = methodSignature.getMethod(); - PsiClass containingClass = objectMethod.getContainingClass(); - if (containingClass != null && CommonClassNames.JAVA_LANG_OBJECT.equals(containingClass.getQualifiedName()) + if (objectMethod.getContainingClass() instanceof PsiClass containingClass + && CommonClassNames.JAVA_LANG_OBJECT.equals(containingClass.getQualifiedName()) && objectMethod.isPublic()) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(methodIdentifier) - .descriptionAndTooltip("Default method '" + sig.getName() + "' overrides a member of 'java.lang.Object'") + .descriptionAndTooltip(JavaCompilationErrorLocalize.methodDefaultOverridesObjectMember(sig.getName())) .create(); } } @@ -569,8 +570,8 @@ public static HighlightInfo.Builder checkUnrelatedDefaultMethods(@Nonnull PsiCla String m = JavaHighlightUtil.formatMethod(abstracts.get(0)); String c2 = HighlightUtil.formatClass(unrelatedMethodContainingClass, false); LocalizeValue message = aClass instanceof PsiEnumConstantInitializer - ? JavaErrorLocalize.enumConstantShouldImplementMethod(c1, m, c2) - : JavaErrorLocalize.classMustBeAbstract(c1, m, c2); + ? JavaCompilationErrorLocalize.classMustImplementMethod(c1, m, c2) + : JavaCompilationErrorLocalize.classMustImplementMethodOrAbstract(c1, m, c2); return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(classIdentifier) .descriptionAndTooltip(message) @@ -588,7 +589,7 @@ public static HighlightInfo.Builder checkUnrelatedDefaultMethods(@Nonnull PsiCla String m = JavaHighlightUtil.formatMethod(defaultMethod); LocalizeValue description = unrelatedDefaults != null ? JavaErrorLocalize.textClassInheritsUnrelatedDefaults(c, m, unrelatedDefaults) - : JavaErrorLocalize.textClassInheritsAbstractAndDefault( + : JavaCompilationErrorLocalize.classInheritsAbstractAndDefault( c, m, HighlightUtil.formatClass(defaultMethodContainingClass), @@ -674,7 +675,7 @@ public static HighlightInfo.Builder checkUnrelatedConcrete(@Nonnull PsiClass psi //TODO: override fix return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(classIdentifier) - .descriptionAndTooltip(JavaErrorLocalize.classInheritanceMethodClash( + .descriptionAndTooltip(JavaCompilationErrorLocalize.classInheritanceMethodClash( JavaHighlightUtil.formatMethod(foundMethod), HighlightUtil.formatClass(foundMethodContainingClass), JavaHighlightUtil.formatMethod(method), @@ -841,12 +842,12 @@ private static HighlightInfo.Builder getSameErasureMessage( @Nonnull PsiMethod superMethod, TextRange textRange ) { - String clashMethodMessage = HighlightMethodUtil.createClashMethodMessage(method, superMethod, !sameClass); + LocalizeValue clashMethodMessage = HighlightMethodUtil.createClashMethodMessage(method, superMethod, !sameClass); LocalizeValue description = sameClass - ? JavaErrorLocalize.genericsMethodsHaveSameErasure(clashMethodMessage) + ? JavaCompilationErrorLocalize.methodGenericSameErasure(clashMethodMessage) : method.isStatic() - ? JavaErrorLocalize.genericsMethodsHaveSameErasureHide(clashMethodMessage) - : JavaErrorLocalize.genericsMethodsHaveSameErasureOverride(clashMethodMessage); + ? JavaCompilationErrorLocalize.methodGenericSameErasureHide(clashMethodMessage) + : JavaCompilationErrorLocalize.methodGenericSameErasureOverride(clashMethodMessage); return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(textRange) .descriptionAndTooltip(description); @@ -863,7 +864,7 @@ public static HighlightInfo checkTypeParameterInstantiation(PsiNewExpression exp if (element instanceof PsiTypeParameter typeParam) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(classReference) - .descriptionAndTooltip(JavaErrorLocalize.genericsTypeParameterCannotBeInstantiated(HighlightUtil.formatClass(typeParam))) + .descriptionAndTooltip(JavaCompilationErrorLocalize.newExpressionTypeParameter(HighlightUtil.formatClass(typeParam))) .create(); } return null; @@ -884,7 +885,9 @@ public static HighlightInfo checkWildcardUsage(PsiTypeElement typeElement) { if (!(newExpr.getType() instanceof PsiArrayType)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(typeElement) - .descriptionAndTooltip(JavaErrorLocalize.wildcardTypeCannotBeInstantiated(JavaHighlightUtil.formatType(type))) + .descriptionAndTooltip(JavaCompilationErrorLocalize.typeWildcardCannotBeInstantiated( + JavaHighlightUtil.formatType(type) + )) .create(); } } @@ -892,7 +895,7 @@ else if (refParent instanceof PsiReferenceList refList) { if (!(refList.getParent() instanceof PsiTypeParameter typeParam) || refList != typeParam.getExtendsList()) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(typeElement) - .descriptionAndTooltip(JavaErrorLocalize.genericsWildcardNotExpected()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.typeWildcardNotExpected()) .create(); } } @@ -958,7 +961,7 @@ public static HighlightInfo.Builder checkForeachExpressionTypeIsIterable(PsiExpr if (itemType == null) { HighlightInfo.Builder hlBuilder = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.foreachNotApplicable(JavaHighlightUtil.formatType(expression.getType()))); + .descriptionAndTooltip(JavaCompilationErrorLocalize.foreachNotApplicable(JavaHighlightUtil.formatType(expression.getType()))); IntentionAction fix = QuickFixFactory.getInstance().createNotIterableForEachLoopFix(expression); if (fix != null) { hlBuilder.registerFix(fix); @@ -1028,7 +1031,7 @@ else if (field.getContainingClass() != aClass) { return null; } - if (PsiUtil.isCompileTimeConstant((PsiVariable)field)) { + if (PsiUtil.isCompileTimeConstant((PsiVariable) field)) { return null; } @@ -1049,7 +1052,7 @@ public static HighlightInfo checkEnumInstantiation(PsiElement expression, PsiCla || newExpr.getArrayDimensions().length == 0 && newExpr.getArrayInitializer() == null)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.enumTypesCannotBeInstantiated()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.instantiationEnum()) .create(); } return null; @@ -1061,7 +1064,7 @@ public static HighlightInfo checkGenericArrayCreation(PsiElement element, PsiTyp if (type instanceof PsiArrayType arrayType && !JavaGenericsUtil.isReifiableType(arrayType.getComponentType())) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(element) - .descriptionAndTooltip(JavaErrorLocalize.genericArrayCreation()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.arrayGeneric()) .create(); } return null; @@ -1095,17 +1098,17 @@ public static HighlightInfo.Builder checkTypeParametersList( if (parent instanceof PsiClass psiClass && psiClass.isEnum()) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(list) - .descriptionAndTooltip(JavaErrorLocalize.genericsEnumMayNotHaveTypeParameters()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.typeParameterOnEnum()); } if (PsiUtil.isAnnotationMethod(parent)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(list) - .descriptionAndTooltip(JavaErrorLocalize.genericsAnnotationMembersMayNotHaveTypeParameters()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.typeParameterOnAnnotationMember()); } if (parent instanceof PsiClass psiClass && psiClass.isAnnotationType()) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(list) - .descriptionAndTooltip(JavaErrorLocalize.annotationMayNotHaveTypeParameters()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.typeParameterOnAnnotation()); } for (int i = 0; i < parameters.length; i++) { @@ -1121,7 +1124,7 @@ public static HighlightInfo.Builder checkTypeParametersList( if (Comparing.strEqual(name1, name2)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(typeParameter2) - .descriptionAndTooltip(JavaErrorLocalize.genericsDuplicateTypeParameter(name1)); + .descriptionAndTooltip(JavaCompilationErrorLocalize.typeParameterDuplicate(name1)); } } if (!level.isAtLeast(LanguageLevel.JDK_1_7)) { @@ -1151,7 +1154,7 @@ public static Collection checkCatchParameterIsClass(PsiParameter if (aClass instanceof PsiTypeParameter) { result.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(typeElement) - .descriptionAndTooltip(JavaErrorLocalize.genericsCannotCatchTypeParameters()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.catchTypeParameter()) .create()); } } @@ -1179,13 +1182,13 @@ private static HighlightInfo.Builder isIllegalForInstanceOf(PsiType type, PsiTyp if (PsiUtil.resolveClassInClassTypeOnly(type) instanceof PsiTypeParameter) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(typeElement) - .descriptionAndTooltip(JavaErrorLocalize.genericsCannotInstanceofTypeParameters()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.instanceofTypeParameter()); } if (!JavaGenericsUtil.isReifiableType(type)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(typeElement) - .descriptionAndTooltip(JavaErrorLocalize.illegalGenericTypeForInstanceof()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.instanceofIllegalGenericType()); } return null; @@ -1243,7 +1246,7 @@ public static HighlightInfo.Builder checkOverrideAnnotation( if (superMethod == null) { HighlightInfo.Builder hlBuilder = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(overrideAnnotation) - .descriptionAndTooltip(JavaErrorLocalize.methodDoesNotOverrideSuper()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.overrideOnNonOverridingMethod()); QuickFixFactory.getInstance().registerPullAsAbstractUpFixes(method, QuickFixActionRegistrar.create(hlBuilder)); return hlBuilder; } @@ -1294,7 +1297,7 @@ public static HighlightInfo.Builder checkSafeVarargsAnnotation(PsiMethod method, } LOG.assertTrue(varParameter.isVarArgs()); - PsiEllipsisType ellipsisType = (PsiEllipsisType)varParameter.getType(); + PsiEllipsisType ellipsisType = (PsiEllipsisType) varParameter.getType(); PsiType componentType = ellipsisType.getComponentType(); if (JavaGenericsUtil.isReifiableType(componentType)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.WARNING) @@ -1372,7 +1375,7 @@ public static HighlightInfo.Builder checkVarArgParameterIsLast(@Nonnull PsiParam if (params[params.length - 1] != parameter) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(parameter) - .descriptionAndTooltip(JavaErrorLocalize.varargNotLastParameter()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.varargNotLastParameter()) .registerFix(QuickFixFactory.getInstance().createMakeVarargParameterLastFix(parameter)); } } @@ -1408,7 +1411,7 @@ public static HighlightInfo.Builder checkParametersAllowed(PsiReferenceParameter && !(refExpr instanceof PsiMethodReferenceExpression)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(refParamList) - .descriptionAndTooltip(JavaErrorLocalize.genericsReferenceParametersNotAllowed()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.typeArgumentNotAllowed()); } return null; @@ -1442,7 +1445,7 @@ else if (parent instanceof PsiCallExpression call) { if (qualifier instanceof PsiJavaCodeReferenceElement javaCodeRef && javaCodeRef.resolve() instanceof PsiTypeParameter) { return null; } - PsiClass containingClass = ((PsiMember)element).getContainingClass(); + PsiClass containingClass = ((PsiMember) element).getContainingClass(); if (containingClass != null && PsiUtil.isRawSubstitutor(containingClass, resolveResult.getSubstitutor())) { if ((parent instanceof PsiCallExpression || parent instanceof PsiMethodReferenceExpression) && PsiUtil.isLanguageLevel7OrHigher(parent)) { @@ -1467,7 +1470,7 @@ else if (parent instanceof PsiCallExpression call) { for (PsiClassType classType : typeParameter.getExtendsListTypes()) { PsiClass resolve = classType.resolve(); if (resolve != null) { - PsiMethod[] superMethods = resolve.findMethodsBySignature((PsiMethod)element, true); + PsiMethod[] superMethods = resolve.findMethodsBySignature((PsiMethod) element, true); for (PsiMethod superMethod : superMethods) { if (!PsiUtil.isRawSubstitutor(superMethod, resolveResult.getSubstitutor())) { return null; @@ -1479,8 +1482,8 @@ else if (parent instanceof PsiCallExpression call) { } } LocalizeValue message = element instanceof PsiClass - ? JavaErrorLocalize.genericsTypeArgumentsOnRawType() - : JavaErrorLocalize.genericsTypeArgumentsOnRawMethod(); + ? JavaCompilationErrorLocalize.typeArgumentOnRawType() + : JavaCompilationErrorLocalize.typeArgumentOnRawMethod(); return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(refParamList) @@ -1527,7 +1530,7 @@ public static HighlightInfo.Builder checkGenericCannotExtendException(PsiReferen .createType(psiClass); return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(referenceElement) - .descriptionAndTooltip(JavaErrorLocalize.genericExtendException()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.classGenericExtendsException()) .registerFix(QuickFixFactory.getInstance().createExtendsListFix(aClass, classType, false)); } } @@ -1596,7 +1599,7 @@ public static HighlightInfo.Builder checkCannotInheritFromTypeParameter(PsiClass if (superClass instanceof PsiTypeParameter) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(toHighlight) - .descriptionAndTooltip(JavaErrorLocalize.classCannotInheritFromItsTypeParameter()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.classInheritsTypeParameter()); } return null; } @@ -1644,7 +1647,7 @@ public static HighlightInfo.Builder checkCannotPassInner(PsiJavaCodeReferenceEle if (!(referenceElement.resolve() instanceof PsiClass typeClass)) { return null; } - PsiClass resolvedClass = (PsiClass)ref.resolve(); + PsiClass resolvedClass = (PsiClass) ref.resolve(); PsiClass containingClass = resolvedClass != null ? resolvedClass.getContainingClass() : null; if (containingClass == null) { return null; @@ -1726,7 +1729,7 @@ public static HighlightInfo.Builder checkInferredIntersections(PsiSubstitutor su if (conflictingConjunctsMessage != null) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .descriptionAndTooltip( - JavaErrorLocalize.typeParameterHasIncompatibleUpperBounds(parameterName, conflictingConjunctsMessage) + JavaCompilationErrorLocalize.typeParameterIncompatibleUpperBounds(parameterName, conflictingConjunctsMessage) ) .range(ref); } @@ -1750,22 +1753,21 @@ public static HighlightInfo.Builder areSupersAccessible(@Nonnull PsiClass aClass return hlBuilder; } - String message = null; + LocalizeValue message = LocalizeValue.empty(); PsiElement parent = ref.getParent(); if (parent instanceof PsiMethodCallExpression methodCall) { JavaResolveResult resolveResult = methodCall.resolveMethodGenerics(); - PsiMethod method = (PsiMethod)resolveResult.getElement(); + PsiMethod method = (PsiMethod) resolveResult.getElement(); if (method != null) { - HashSet classes = new HashSet<>(); + Set classes = new HashSet<>(); JavaPsiFacade facade = JavaPsiFacade.getInstance(aClass.getProject()); PsiSubstitutor substitutor = resolveResult.getSubstitutor(); message = isSuperTypeAccessible(substitutor.substitute(method.getReturnType()), classes, false, resolveScope, facade); - if (message == null) { + if (message == LocalizeValue.empty()) { for (PsiType type : method.getSignature(substitutor).getParameterTypes()) { - message = isSuperTypeAccessible(type, classes, false, resolveScope, facade); - if (message != null) { + if (message != LocalizeValue.empty()) { break; } } @@ -1782,7 +1784,7 @@ else if (ref.resolve() instanceof PsiField field) { ); } - if (message != null) { + if (message != LocalizeValue.empty()) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .descriptionAndTooltip(message) .range(ref.getTextRange()); @@ -1791,6 +1793,7 @@ else if (ref.resolve() instanceof PsiField field) { return null; } + @RequiredReadAction private static HighlightInfo.Builder areSupersAccessible( @Nonnull PsiClass aClass, GlobalSearchScope resolveScope, @@ -1799,8 +1802,9 @@ private static HighlightInfo.Builder areSupersAccessible( ) { JavaPsiFacade factory = JavaPsiFacade.getInstance(aClass.getProject()); for (PsiClassType superType : aClass.getSuperTypes()) { - String notAccessibleErrorMessage = isSuperTypeAccessible(superType, new HashSet<>(), checkParameters, resolveScope, factory); - if (notAccessibleErrorMessage != null) { + LocalizeValue notAccessibleErrorMessage = + isSuperTypeAccessible(superType, new HashSet<>(), checkParameters, resolveScope, factory); + if (notAccessibleErrorMessage != LocalizeValue.empty()) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .descriptionAndTooltip(notAccessibleErrorMessage) .range(range); @@ -1809,10 +1813,11 @@ private static HighlightInfo.Builder areSupersAccessible( return null; } - @Nullable - private static String isSuperTypeAccessible( + @Nonnull + @RequiredReadAction + private static LocalizeValue isSuperTypeAccessible( PsiType superType, - HashSet classes, + Set classes, boolean checkParameters, GlobalSearchScope resolveScope, JavaPsiFacade factory @@ -1821,38 +1826,38 @@ private static String isSuperTypeAccessible( if (aClass != null && classes.add(aClass)) { VirtualFile vFile = PsiUtilCore.getVirtualFile(aClass); if (vFile == null) { - return null; + return LocalizeValue.empty(); } FileIndexFacade index = FileIndexFacade.getInstance(aClass.getProject()); if (!index.isInSource(vFile) && !index.isInLibraryClasses(vFile)) { - return null; + return LocalizeValue.empty(); } String qualifiedName = aClass.getQualifiedName(); if (qualifiedName != null && factory.findClass(qualifiedName, resolveScope) == null) { - return "Cannot access " + HighlightUtil.formatClass(aClass); + return JavaCompilationErrorLocalize.classNotAccessible(HighlightUtil.formatClass(aClass)); } if (checkParameters) { boolean isInLibrary = !index.isInContent(vFile); if (superType instanceof PsiClassType classType) { for (PsiType psiType : classType.getParameters()) { - String notAccessibleMessage = isSuperTypeAccessible(psiType, classes, true, resolveScope, factory); - if (notAccessibleMessage != null) { + LocalizeValue notAccessibleMessage = isSuperTypeAccessible(psiType, classes, true, resolveScope, factory); + if (notAccessibleMessage != LocalizeValue.empty()) { return notAccessibleMessage; } } } for (PsiClassType type : aClass.getSuperTypes()) { - String notAccessibleMessage = isSuperTypeAccessible(type, classes, !isInLibrary, resolveScope, factory); - if (notAccessibleMessage != null) { + LocalizeValue notAccessibleMessage = isSuperTypeAccessible(type, classes, !isInLibrary, resolveScope, factory); + if (notAccessibleMessage != LocalizeValue.empty()) { return notAccessibleMessage; } } } } - return null; + return LocalizeValue.empty(); } @RequiredReadAction @@ -1862,7 +1867,7 @@ public static HighlightInfo checkTypeParameterOverrideEquivalentMethods(PsiClass if (extendsList != null && extendsList.getReferenceElements().length > 1) { //todo suppress erased methods which come from the same class Collection result = checkOverrideEquivalentMethods(aClass); - if (result != null && !result.isEmpty()) { + if (!result.isEmpty()) { return result.iterator().next(); } } diff --git a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/HighlightClassUtil.java b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/HighlightClassUtil.java index 763faa384d..0b2c0b3eb9 100644 --- a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/HighlightClassUtil.java +++ b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/HighlightClassUtil.java @@ -35,13 +35,13 @@ import consulo.annotation.access.RequiredReadAction; import consulo.document.util.TextRange; import consulo.java.language.impl.localize.JavaErrorLocalize; +import consulo.java.language.localize.JavaCompilationErrorLocalize; import consulo.language.editor.rawHighlight.HighlightInfo; import consulo.language.editor.rawHighlight.HighlightInfoType; import consulo.language.psi.*; import consulo.language.psi.scope.GlobalSearchScope; import consulo.language.psi.util.PsiMatcherImpl; import consulo.language.psi.util.PsiTreeUtil; -import consulo.language.util.ModuleUtilCore; import consulo.localize.LocalizeValue; import consulo.module.Module; import consulo.project.Project; @@ -93,8 +93,8 @@ public static HighlightInfo.Builder checkClassWithAbstractMethods(PsiClass aClas String methodName = JavaHighlightUtil.formatMethod(abstractMethod); String c = HighlightUtil.formatClass(superClass, false); LocalizeValue description = aClass instanceof PsiEnumConstantInitializer || implementsFixElement instanceof PsiEnumConstant - ? JavaErrorLocalize.enumConstantShouldImplementMethod(baseClassName, methodName, c) - : JavaErrorLocalize.classMustBeAbstract(baseClassName, methodName, c); + ? JavaCompilationErrorLocalize.classMustImplementMethod(baseClassName, methodName, c) + : JavaCompilationErrorLocalize.classMustImplementMethodOrAbstract(baseClassName, methodName, c); HighlightInfo.Builder hlBuilder = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(range) @@ -138,7 +138,7 @@ public static HighlightInfo.Builder checkInstantiationOfAbstractClass(PsiClass a && !(highlightElement instanceof PsiNewExpression newExpr && newExpr.getType() instanceof PsiArrayType)) { HighlightInfo.Builder hlBuilder = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(highlightElement) - .descriptionAndTooltip(JavaErrorLocalize.abstractCannotBeInstantiated(aClass.getName())); + .descriptionAndTooltip(JavaCompilationErrorLocalize.instantiationAbstract(aClass.getName())); PsiMethod anyAbstractMethod = ClassUtil.getAnyAbstractMethod(aClass); QuickFixFactory factory = QuickFixFactory.getInstance(); if (!aClass.isInterface() && anyAbstractMethod == null) { @@ -179,7 +179,7 @@ public static HighlightInfo checkDuplicateTopLevelClass(PsiClass aClass) { numOfClassesToFind = 1; } PsiManager manager = aClass.getManager(); - Module module = ModuleUtilCore.findModuleForPsiElement(aClass); + Module module = aClass.getModule(); if (module == null) { return null; } @@ -206,7 +206,7 @@ public static HighlightInfo checkDuplicateTopLevelClass(PsiClass aClass) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(HighlightNamesUtil.getClassDeclarationTextRange(aClass)) - .descriptionAndTooltip(JavaErrorLocalize.duplicateClassInOtherFile(dupFileName)) + .descriptionAndTooltip(JavaCompilationErrorLocalize.classDuplicateInOtherFile(dupFileName)) .create(); } @@ -260,7 +260,7 @@ public static HighlightInfo.Builder checkDuplicateNestedClass(PsiClass aClass) { TextRange textRange = HighlightNamesUtil.getClassDeclarationTextRange(aClass); return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(textRange) - .descriptionAndTooltip(JavaErrorLocalize.duplicateClass(name)); + .descriptionAndTooltip(JavaCompilationErrorLocalize.classDuplicate(name)); } return null; } @@ -307,7 +307,7 @@ public static HighlightInfo.Builder checkClassAndPackageConflict(@Nonnull PsiCla if (CommonClassNames.DEFAULT_PACKAGE.equals(name)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(HighlightNamesUtil.getClassDeclarationTextRange(aClass)) - .descriptionAndTooltip(JavaErrorLocalize.classClashesWithPackage(name)); + .descriptionAndTooltip(JavaCompilationErrorLocalize.classClashesWithPackage(name)); } PsiElement file = aClass.getParent(); @@ -318,7 +318,7 @@ public static HighlightInfo.Builder checkClassAndPackageConflict(@Nonnull PsiCla if (subDirectory != null && simpleName.equals(subDirectory.getName())) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(HighlightNamesUtil.getClassDeclarationTextRange(aClass)) - .descriptionAndTooltip(JavaErrorLocalize.classClashesWithPackage(name)); + .descriptionAndTooltip(JavaCompilationErrorLocalize.classClashesWithPackage(name)); } } @@ -517,7 +517,7 @@ public static HighlightInfo.Builder checkExtendsClassAndImplementsInterface( if (extendFrom.isInterface() != mustBeInterface) { LocalizeValue message = mustBeInterface ? JavaErrorLocalize.interfaceExpected() - : JavaErrorLocalize.noInterfaceExpected(); + : JavaCompilationErrorLocalize.classExtendsInterface(); PsiClassType type = JavaPsiFacade.getInstance(aClass.getProject()).getElementFactory().createType(ref); return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(ref) @@ -651,7 +651,7 @@ public static HighlightInfo.Builder checkCyclicInheritance(PsiClass aClass) { if (circularClass != null) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(HighlightNamesUtil.getClassDeclarationTextRange(aClass)) - .descriptionAndTooltip(JavaErrorLocalize.cyclicInheritance(HighlightUtil.formatClass(circularClass))); + .descriptionAndTooltip(JavaCompilationErrorLocalize.classCyclicInheritance(HighlightUtil.formatClass(circularClass))); } return null; } @@ -713,7 +713,7 @@ public static HighlightInfo.Builder checkExtendsDuplicate( if (dupCount > 1) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(element) - .descriptionAndTooltip(JavaErrorLocalize.duplicateClass(HighlightUtil.formatClass(aClass))); + .descriptionAndTooltip(JavaCompilationErrorLocalize.classDuplicate(HighlightUtil.formatClass(aClass))); } return null; } @@ -743,7 +743,7 @@ public static HighlightInfo checkClassAlreadyImported(PsiClass aClass, PsiElemen && Objects.equals(aClass.getName(), importClass.getName())) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(elementToHighlight) - .descriptionAndTooltip(JavaErrorLocalize.classAlreadyImported(HighlightUtil.formatClass(aClass, false))) + .descriptionAndTooltip(JavaCompilationErrorLocalize.classAlreadyImported(HighlightUtil.formatClass(aClass, false))) .create(); } } @@ -758,7 +758,7 @@ public static HighlightInfo.Builder checkClassExtendsOnlyOneClass(PsiReferenceLi && referencedTypes.length > 1 && aClass.getExtendsList() == list) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(list) - .descriptionAndTooltip(JavaErrorLocalize.classCannotExtendMultipleClasses()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.classCannotExtendMultipleClasses()); } return null; @@ -766,13 +766,21 @@ public static HighlightInfo.Builder checkClassExtendsOnlyOneClass(PsiReferenceLi @Nullable @RequiredReadAction - public static HighlightInfo.Builder checkThingNotAllowedInInterface(PsiElement element, PsiClass aClass) { + public static HighlightInfo.Builder checkThingNotAllowedInInterface(PsiMember member) { + PsiClass aClass = member.getContainingClass(); if (aClass == null || !aClass.isInterface()) { return null; } - return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) - .range(element) - .descriptionAndTooltip(JavaErrorLocalize.notAllowedInInterface()); + if (member instanceof PsiMethod method && method.isConstructor()) { + return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) + .range(member) + .descriptionAndTooltip(JavaCompilationErrorLocalize.interfaceConstructor()); + } else if (member instanceof PsiClassInitializer initializer) { + return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) + .range(member) + .descriptionAndTooltip(JavaCompilationErrorLocalize.interfaceClassInitializer()); + } + return null; } @Nullable @@ -786,14 +794,14 @@ public static HighlightInfo.Builder checkQualifiedNew(PsiNewExpression expressio if (type instanceof PsiArrayType) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.invalidQualifiedNew()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.newExpressionQualifiedMalformed()) .registerFix(factory.createRemoveNewQualifierFix(expression, null)); } if (aClass != null) { if (aClass.isStatic()) { HighlightInfo.Builder hlBuilder = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.qualifiedNewOfStaticClass()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.newExpressionQualifiedStaticClass()); if (!aClass.isEnum()) { hlBuilder.registerFix(factory.createModifierFixBuilder(aClass).remove(PsiModifier.STATIC).create()); } @@ -844,7 +852,7 @@ public static HighlightInfo.Builder checkClassExtendsForeignInnerClass(PsiJavaCo if (!(resolved instanceof PsiClass)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(extendRef) - .descriptionAndTooltip(JavaErrorLocalize.classNameExpected()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.classReferenceListNameExpected()); } SimpleReference infos = SimpleReference.create(); extendRef.accept(new JavaRecursiveElementWalkingVisitor() { @@ -886,7 +894,9 @@ public void visitReferenceElement(@Nonnull PsiJavaCodeReferenceElement reference infos.set( HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(extendRef) - .descriptionAndTooltip(JavaErrorLocalize.noEnclosingInstanceInScope(HighlightUtil.formatClass(baseClass))) + .descriptionAndTooltip(JavaCompilationErrorLocalize.classReferenceListNoEnclosingInstance( + HighlightUtil.formatClass(baseClass) + )) ); } } @@ -1062,7 +1072,7 @@ public static HighlightInfo reportIllegalEnclosingUsage( QuickFixFactory factory = QuickFixFactory.getInstance(); HighlightInfo.Builder highlightInfo = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(elementToHighlight) - .descriptionAndTooltip(JavaErrorLocalize.cannotBeReferencedFromStaticContext(element)) + .descriptionAndTooltip(JavaCompilationErrorLocalize.classCannotBeReferencedFromStaticContext(element)) // make context not static or referenced class static .registerFix(factory.createModifierFixBuilder(staticParent).remove(PsiModifier.STATIC).create()); if (aClass != null diff --git a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java index 949914125b..d1b68e668d 100644 --- a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java +++ b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java @@ -29,11 +29,13 @@ import consulo.document.util.TextRange; import consulo.java.analysis.impl.localize.JavaQuickFixLocalize; import consulo.java.language.impl.localize.JavaErrorLocalize; +import consulo.java.language.localize.JavaCompilationErrorLocalize; import consulo.language.ast.IElementType; import consulo.language.editor.rawHighlight.HighlightInfo; import consulo.language.editor.rawHighlight.HighlightInfoType; import consulo.language.psi.PsiElement; import consulo.language.psi.PsiFile; +import consulo.language.psi.PsiManager; import consulo.language.psi.PsiReference; import consulo.language.psi.scope.LocalSearchScope; import consulo.language.psi.search.ReferencesSearch; @@ -51,7 +53,7 @@ /** * @author cdr - * @since Aug 8, 2002 + * @since 2022-08-08 */ public class HighlightControlFlowUtil { private HighlightControlFlowUtil() { @@ -72,7 +74,7 @@ public static HighlightInfo checkMissingReturnStatement(@Nullable PsiCodeBlock b PsiJavaToken rBrace = body.getRBrace(); HighlightInfo.Builder info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(rBrace == null ? body.getLastChild() : rBrace) - .descriptionAndTooltip(JavaErrorLocalize.missingReturnStatement()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.returnMissing()); if (body.getParent() instanceof PsiMethod method) { info.registerFix(QuickFixFactory.getInstance().createAddReturnFix(method)); info.registerFix(QuickFixFactory.getInstance().createMethodReturnFix(method, PsiType.VOID, true)); @@ -119,7 +121,7 @@ public static HighlightInfo.Builder checkUnreachableStatement(@Nullable PsiCodeB PsiElement element = keyword != null ? keyword : unreachableStatement; return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(element) - .descriptionAndTooltip(JavaErrorLocalize.unreachableStatement()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.statementUnreachable()) .registerFix(QuickFixFactory.getInstance().createDeleteFix( unreachableStatement, JavaQuickFixLocalize.deleteUnreachableStatementFixText() @@ -226,8 +228,7 @@ private static class ParamWriteProcessor implements Predicate { @Override @RequiredReadAction public boolean test(PsiReference reference) { - PsiElement element = reference.getElement(); - if (element instanceof PsiReferenceExpression && PsiUtil.isAccessedForWriting((PsiExpression)element)) { + if (reference.getElement() instanceof PsiReferenceExpression refExpr && PsiUtil.isAccessedForWriting(refExpr)) { myIsWriteRefFound = true; return false; } @@ -276,17 +277,12 @@ public static HighlightInfo checkFinalFieldInitialized(@Nonnull PsiField field) TextRange range = HighlightNamesUtil.getFieldDeclarationTextRange(field); QuickFixFactory factory = QuickFixFactory.getInstance(); + TextRange fixRange = HighlightMethodUtil.getFixRange(field); HighlightInfo.Builder highlightInfo = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(range) - .descriptionAndTooltip(JavaErrorLocalize.variableNotInitialized(field.getName())) - .registerFix( - factory.createCreateConstructorParameterFromFieldFix(field), - HighlightMethodUtil.getFixRange(field) - ) - .registerFix( - factory.createInitializeFinalFieldInConstructorFix(field), - HighlightMethodUtil.getFixRange(field) - ); + .descriptionAndTooltip(JavaCompilationErrorLocalize.variableNotInitialized(field.getName())) + .newFix(factory.createCreateConstructorParameterFromFieldFix(field)).fixRange(fixRange).register() + .newFix(factory.createInitializeFinalFieldInConstructorFix(field)).fixRange(fixRange).register(); PsiClass containingClass = field.getContainingClass(); if (containingClass != null && !containingClass.isInterface()) { highlightInfo.registerFix(factory.createModifierFixBuilder(field).remove(PsiModifier.FINAL).create()); @@ -498,7 +494,7 @@ && isFieldInitializedInClassInitializer(field, true, aClass.getInitializers())) QuickFixFactory factory = QuickFixFactory.getInstance(); HighlightInfo.Builder hlBuilder = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.variableNotInitialized(name)) + .descriptionAndTooltip(JavaCompilationErrorLocalize.variableNotInitialized(name)) .registerFix(factory.createAddVariableInitializerFix(variable)); if (variable instanceof PsiLocalVariable) { //highlightInfo.registerFix(HighlightFixUtil.createInsertSwitchDefaultFix(variable, topBlock, expression)); @@ -548,7 +544,7 @@ private static boolean insideClassInitialization(@Nullable PsiClass containingCl while (member != null) { if (member.getContainingClass() == containingClass) { return member instanceof PsiField - || member instanceof PsiMethod && ((PsiMethod)member).isConstructor() + || member instanceof PsiMethod method && method.isConstructor() || member instanceof PsiClassInitializer; } member = PsiTreeUtil.getParentOfType(member, PsiMember.class, true); @@ -676,7 +672,7 @@ public static HighlightInfo checkFinalVariableMightAlreadyHaveBeenAssignedTo( QuickFixFactory factory = QuickFixFactory.getInstance(); return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.variableAlreadyAssigned(variable.getName())) + .descriptionAndTooltip(JavaCompilationErrorLocalize.variableAlreadyAssigned(variable.getName())) .registerFix(factory.createModifierFixBuilder(variable).remove(PsiModifier.FINAL).create()) .registerFix(factory.createDeferFinalAssignmentFix(variable, expression)) .create(); @@ -714,8 +710,11 @@ public static HighlightInfo checkFinalVariableInitializedInLoop( if (ControlFlowUtil.isVariableAssignedInLoop(expression, resolved)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.variableAssignedInLoop(((PsiVariable)resolved).getName())) - .registerFix(QuickFixFactory.getInstance().createModifierFixBuilder((PsiVariable)resolved).remove(PsiModifier.FINAL).create()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.variableAssignedInLoop(((PsiVariable) resolved).getName())) + .registerFix(QuickFixFactory.getInstance() + .createModifierFixBuilder((PsiVariable) resolved) + .remove(PsiModifier.FINAL) + .create()) .create(); } return null; @@ -758,8 +757,8 @@ else if (expression instanceof PsiPrefixExpression prefixExpr) { if (readBeforeWrite || !canWrite) { String name = variable.getName(); LocalizeValue description = canWrite - ? JavaErrorLocalize.variableNotInitialized(name) - : JavaErrorLocalize.assignmentToFinalVariable(name); + ? JavaCompilationErrorLocalize.variableNotInitialized(name) + : JavaCompilationErrorLocalize.assignmentToFinalVariable(name); PsiElement innerClass = getInnerClassVariableReferencedFrom(variable, expression); QuickFixFactory factory = QuickFixFactory.getInstance(); return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) @@ -816,8 +815,8 @@ private static boolean isSameField( @Nonnull PsiReferenceExpression reference, @Nonnull PsiFile containingFile ) { - if (!containingFile.getManager() - .areElementsEquivalent(enclosingCtrOrInitializer.getContainingClass(), field.getContainingClass())) { + PsiManager manager = containingFile.getManager(); + if (!manager.areElementsEquivalent(enclosingCtrOrInitializer.getContainingClass(), field.getContainingClass())) { return false; } return LocalsOrMyInstanceFieldsControlFlowPolicy.isLocalOrMyInstanceReference(reference); @@ -833,8 +832,7 @@ public static HighlightInfo.Builder checkVariableMustBeFinal( if (variable.hasModifierProperty(PsiModifier.FINAL)) { return null; } - PsiElement innerClass = getInnerClassVariableReferencedFrom(variable, context); - if (innerClass instanceof PsiClass) { + if (getInnerClassVariableReferencedFrom(variable, context) instanceof PsiClass innerClass) { if (variable instanceof PsiParameter param && variable.getParent() instanceof PsiParameterList paramList && paramList instanceof PsiLambdaExpression @@ -846,12 +844,15 @@ && notAccessedForWriting(variable, new LocalSearchScope(param.getDeclarationScop return null; } LocalizeValue description = isToBeEffectivelyFinal - ? JavaErrorLocalize.variableMustBeFinalOrEffectivelyFinal(context.getText()) - : JavaErrorLocalize.variableMustBeFinal(context.getText()); + ? JavaCompilationErrorLocalize.variableMustBeEffectivelyFinal(context.getText()) + : JavaCompilationErrorLocalize.variableMustBeFinal(context.getText()); return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(context) .descriptionAndTooltip(description) - .registerFix(QuickFixFactory.getInstance().createVariableAccessFromInnerClassFix(variable, innerClass)); + .registerFix(QuickFixFactory.getInstance().createVariableAccessFromInnerClassFix( + variable, + getInnerClassVariableReferencedFrom(variable, context) + )); } return checkWriteToFinalInsideLambda(variable, context); } @@ -871,7 +872,7 @@ private static HighlightInfo.Builder checkWriteToFinalInsideLambda( if (!isEffectivelyFinal(variable, lambdaExpression, context)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(context) - .descriptionAndTooltip(JavaErrorLocalize.lambdaVariableMustBeFinal()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.variableMustBeEffectivelyFinalLambda()) .registerFix(QuickFixFactory.getInstance().createVariableAccessFromInnerClassFix(variable, lambdaExpression)); } } @@ -885,8 +886,8 @@ public static boolean isEffectivelyFinal( @Nullable PsiJavaCodeReferenceElement context ) { boolean effectivelyFinal; - if (variable instanceof PsiParameter) { - effectivelyFinal = notAccessedForWriting(variable, new LocalSearchScope(((PsiParameter)variable).getDeclarationScope())); + if (variable instanceof PsiParameter param) { + effectivelyFinal = notAccessedForWriting(param, new LocalSearchScope(param.getDeclarationScope())); } else { ControlFlow controlFlow; @@ -920,8 +921,7 @@ public static boolean isEffectivelyFinal( @RequiredReadAction private static boolean notAccessedForWriting(@Nonnull PsiVariable variable, @Nonnull LocalSearchScope searchScope) { for (PsiReference reference : ReferencesSearch.search(variable, searchScope)) { - PsiElement element = reference.getElement(); - if (element instanceof PsiExpression && PsiUtil.isAccessedForWriting((PsiExpression)element)) { + if (reference.getElement() instanceof PsiExpression expr && PsiUtil.isAccessedForWriting(expr)) { return false; } } @@ -980,7 +980,7 @@ public static HighlightInfo checkInitializerCompleteNormally(@Nonnull PsiClassIn if ((completionReasons & ControlFlowUtil.NORMAL_COMPLETION_REASON) == 0) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(body) - .descriptionAndTooltip(JavaErrorLocalize.initializerMustBeAbleToCompleteNormally()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.classInitializerMustCompleteNormally()) .create(); } } diff --git a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java index b01ba70cde..989d9bd3fb 100644 --- a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java +++ b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java @@ -22,7 +22,6 @@ import com.intellij.java.language.LanguageLevel; import com.intellij.java.language.codeInsight.daemon.impl.analysis.JavaGenericsUtil; import com.intellij.java.language.impl.codeInsight.ExceptionUtil; -import com.intellij.java.language.impl.codeInsight.daemon.JavaErrorBundle; import com.intellij.java.language.impl.psi.impl.PsiSuperMethodImplUtil; import com.intellij.java.language.impl.refactoring.util.RefactoringChangeUtil; import com.intellij.java.language.projectRoots.JavaSdkVersion; @@ -32,10 +31,12 @@ import com.intellij.java.language.psi.util.*; import com.intellij.java.language.util.VisibilityUtil; import consulo.annotation.access.RequiredReadAction; +import consulo.annotation.access.RequiredWriteAction; import consulo.application.dumb.IndexNotReadyException; import consulo.document.util.TextRange; import consulo.document.util.TextRangeUtil; import consulo.java.language.impl.localize.JavaErrorLocalize; +import consulo.java.language.localize.JavaCompilationErrorLocalize; import consulo.language.editor.inspection.LocalQuickFixOnPsiElementAsIntentionAdapter; import consulo.language.editor.intention.IntentionAction; import consulo.language.editor.intention.QuickFixActionRegistrar; @@ -52,6 +53,7 @@ import consulo.ui.ex.JBColor; import consulo.ui.ex.awt.UIUtil; import consulo.ui.ex.awt.util.ColorUtil; +import consulo.ui.style.StyleManager; import consulo.util.collection.MostlySingularMultiMap; import consulo.util.lang.Comparing; import consulo.util.lang.ObjectUtil; @@ -78,17 +80,18 @@ public class HighlightMethodUtil { private HighlightMethodUtil() { } - public static String createClashMethodMessage(PsiMethod method1, PsiMethod method2, boolean showContainingClasses) { + @Nonnull + public static LocalizeValue createClashMethodMessage(PsiMethod method1, PsiMethod method2, boolean showContainingClasses) { String m1 = JavaHighlightUtil.formatMethod(method1); String m2 = JavaHighlightUtil.formatMethod(method2); return showContainingClasses - ? JavaErrorLocalize.clashMethodsMessageShowClasses( + ? JavaCompilationErrorLocalize.clashMethodsMessageShowClasses( m1, m2, HighlightUtil.formatClass(method1.getContainingClass()), HighlightUtil.formatClass(method2.getContainingClass()) - ).get() - : JavaErrorLocalize.clashMethodsMessage(m1, m2).get(); + ) + : JavaCompilationErrorLocalize.clashMethodsMessage(m1, m2); } @Nullable @@ -320,7 +323,7 @@ private static HighlightInfo.Builder checkSuperMethodIsFinal(PsiMethod method, P QuickFixFactory factory = QuickFixFactory.getInstance(); return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(HighlightNamesUtil.getMethodDeclarationTextRange(method)) - .descriptionAndTooltip(JavaErrorLocalize.finalMethodOverride( + .descriptionAndTooltip(JavaCompilationErrorLocalize.methodOverridesFinal( JavaHighlightUtil.formatMethod(method), JavaHighlightUtil.formatMethod(superMethod), HighlightUtil.formatClass(superMethod.getContainingClass()) @@ -382,10 +385,10 @@ public static HighlightInfo checkMethodIncompatibleThrows( } } PsiClassType exception = checkedExceptions.get(index); - String description = JavaErrorLocalize.overriddenMethodDoesNotThrow( + LocalizeValue description = JavaCompilationErrorLocalize.methodInheritanceClashDoesNotThrow( createClashMethodMessage(method, superMethod, true), JavaHighlightUtil.formatType(exception) - ).get(); + ); TextRange textRange; if (includeRealPositionInfo) { PsiElement exceptionContext = exceptionContexts.get(index); @@ -457,7 +460,7 @@ private static boolean isMethodThrows( } @Nullable - @RequiredReadAction + @RequiredWriteAction public static HighlightInfo.Builder checkMethodCall( @Nonnull PsiMethodCallExpression methodCall, @Nonnull PsiResolveHelper resolveHelper, @@ -505,21 +508,21 @@ public static HighlightInfo.Builder checkMethodCall( } if (hlBuilder == null) { - hlBuilder = checkVarargParameterErasureToBeAccessible((MethodCandidateInfo)resolveResult, methodCall); + hlBuilder = checkVarargParameterErasureToBeAccessible((MethodCandidateInfo) resolveResult, methodCall); } if (hlBuilder == null) { - String errorMessage = ((MethodCandidateInfo)resolveResult).getInferenceErrorMessage(); + String errorMessage = ((MethodCandidateInfo) resolveResult).getInferenceErrorMessage(); if (errorMessage != null) { hlBuilder = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .descriptionAndTooltip(errorMessage) .range(fixRange); registerMethodCallIntentions(hlBuilder, methodCall, list, resolveHelper); - registerMethodReturnFixAction(hlBuilder, (MethodCandidateInfo)resolveResult, methodCall); + registerMethodReturnFixAction(hlBuilder, (MethodCandidateInfo) resolveResult, methodCall); registerTargetTypeFixesBasedOnApplicabilityInference( methodCall, - (MethodCandidateInfo)resolveResult, - (PsiMethod)resolved, + (MethodCandidateInfo) resolveResult, + method, hlBuilder ); } @@ -543,12 +546,12 @@ else if (candidateInfo != null && !candidateInfo.isApplicable()) { LocalizeValue containerName = parent == null ? LocalizeValue.empty() : HighlightMessageUtil.getSymbolName(parent, substitutor); String argTypes = buildArgTypesList(list); - String description = JavaErrorLocalize.wrongMethodArguments(methodName, containerName, argTypes).get(); + LocalizeValue description = JavaCompilationErrorLocalize.callWrongArguments(methodName, containerName, argTypes); SimpleReference elementToHighlight = SimpleReference.create(list); - String toolTip; + LocalizeValue toolTip; if (parent instanceof PsiClass) { toolTip = buildOneLineMismatchDescription(list, candidateInfo, elementToHighlight); - if (toolTip == null) { + if (toolTip == LocalizeValue.empty()) { toolTip = createMismatchedArgumentsHtmlTooltip(candidateInfo, list); } } @@ -588,20 +591,21 @@ else if (candidateInfo != null && !candidateInfo.isApplicable()) { else { hlBuilder = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(methodCall) - .descriptionAndTooltip(JavaErrorLocalize.methodCallExpected()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.callExpected()); + QuickFixFactory fixFactory = QuickFixFactory.getInstance(); if (resolved instanceof PsiClass psiClass) { - hlBuilder.registerFix(QuickFixFactory.getInstance().createInsertNewFix(methodCall, psiClass)); + hlBuilder.registerFix(fixFactory.createInsertNewFix(methodCall, psiClass)); } else { TextRange range = getFixRange(methodCall); - hlBuilder.registerFix(QuickFixFactory.getInstance().createCreateMethodFromUsageFix(methodCall), range); - hlBuilder.registerFix(QuickFixFactory.getInstance().createCreateAbstractMethodFromUsageFix(methodCall), range); - hlBuilder.registerFix(QuickFixFactory.getInstance().createCreatePropertyFromUsageFix(methodCall), range); - hlBuilder.registerFix(QuickFixFactory.getInstance().createStaticImportMethodFix(methodCall), range); + hlBuilder.newFix(fixFactory.createCreateMethodFromUsageFix(methodCall)).fixRange(range).register() + .newFix(fixFactory.createCreateAbstractMethodFromUsageFix(methodCall)).fixRange(range).register() + .newFix(fixFactory.createCreatePropertyFromUsageFix(methodCall)).fixRange(range).register() + .newFix(fixFactory.createStaticImportMethodFix(methodCall)).fixRange(range).register(); if (resolved instanceof PsiVariable variable && languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) { PsiMethod method = LambdaUtil.getFunctionalInterfaceMethod(variable.getType()); if (method != null) { - hlBuilder.registerFix(QuickFixFactory.getInstance().createInsertMethodCallFix(methodCall, method), range); + hlBuilder.newFix(fixFactory.createInsertMethodCallFix(methodCall, method)).fixRange(range).register(); } } } @@ -704,21 +708,18 @@ private static void registerMethodReturnFixAction( .createRawSubstitutor(method) .substitute(methodCallTypeByArgs); if (methodCallTypeByArgs != null) { - highlightInfo.registerFix( - QuickFixFactory.getInstance().createMethodReturnFix( - containerMethod, - methodCallTypeByArgs, - true - ), - getFixRange(methodCall) - ); + QuickFixFactory fixFactory = QuickFixFactory.getInstance(); + highlightInfo.newFix(fixFactory.createMethodReturnFix(containerMethod, methodCallTypeByArgs, true)) + .fixRange(getFixRange(methodCall)) + .register(); } } } } + @Nonnull @RequiredReadAction - private static String buildOneLineMismatchDescription( + private static LocalizeValue buildOneLineMismatchDescription( @Nonnull PsiExpressionList list, @Nonnull MethodCandidateInfo candidateInfo, @Nonnull SimpleReference elementToHighlight @@ -760,16 +761,18 @@ private static String buildOneLineMismatchDescription( argType.getCanonicalText() ); - return XmlStringUtil.wrapInHtml("" + XmlStringUtil.escapeString(message.get()) + " " + - DaemonLocalize.inspectionExtendedDescription() + ""); + return LocalizeValue.of("" + + message.map((localizeManager, s) -> XmlStringUtil.escapeString(s)) + + " XmlStringUtil.escapeString(s)) + + "\"" + (StyleManager.get().getCurrentStyle().isDark() ? " color=\"7AB4C9\" " : "") + ">" + + DaemonLocalize.inspectionExtendedDescription() + "" + ); } } } - return null; + return LocalizeValue.empty(); } public static boolean isDummyConstructorCall( @@ -850,7 +853,7 @@ else if (element != null && !resolveResult.isStaticsScopeCorrect()) { return HighlightInfo.newHighlightInfo(highlightInfoType) .range(elementToHighlight) .description(description) - .escapedToolTip(XmlStringUtil.escapeString(description.get())) + .escapedToolTip(description.map((localizeManager, s) -> XmlStringUtil.escapeString(s))) .registerFix(QuickFixFactory.getInstance().createAccessStaticViaInstanceFix(referenceToMethod, resolveResult)); } } @@ -860,7 +863,7 @@ else if (element != null && !resolveResult.isStaticsScopeCorrect()) { } else { String methodName = referenceToMethod.getReferenceName() + buildArgTypesList(list); - description = JavaErrorLocalize.cannotResolveMethod(methodName); + description = JavaCompilationErrorLocalize.methodReferenceUnresolvedMethod(methodName); if (candidates.length == 0) { highlightInfoType = HighlightInfoType.WRONG_REF; } @@ -869,11 +872,10 @@ else if (element != null && !resolveResult.isStaticsScopeCorrect()) { } } - String toolTip = XmlStringUtil.escapeString(description.get()); HighlightInfo.Builder hlBuilder = HighlightInfo.newHighlightInfo(highlightInfoType) .range(elementToHighlight) .description(description) - .escapedToolTip(toolTip); + .escapedToolTip(description.map((localizeManager, s) -> XmlStringUtil.escapeString(s))); registerMethodCallIntentions(hlBuilder, methodCall, list, resolveHelper); if (element != null && !resolveResult.isStaticsScopeCorrect()) { HighlightUtil.registerStaticProblemQuickFixAction(element, hlBuilder, referenceToMethod); @@ -888,7 +890,7 @@ else if (element != null && !resolveResult.isStaticsScopeCorrect()) { PermuteArgumentsFix.registerFix(hlBuilder, methodCall, candidates, fixRange); WrapExpressionFix.registerWrapAction(candidates, list.getExpressions(), hlBuilder); registerChangeParameterClassFix(methodCall, list, hlBuilder); - if (candidates.length == 0 && hlBuilder != null) { + if (candidates.length == 0) { UnresolvedReferenceQuickFixProvider.registerReferenceFixes( methodCall.getMethodExpression(), QuickFixActionRegistrar.create(hlBuilder) @@ -927,8 +929,8 @@ public static HighlightInfo.Builder checkAmbiguousMethodCallArguments( } MethodCandidateInfo[] candidates = toMethodCandidates(resolveResults); - String description; - String toolTip; + LocalizeValue description; + LocalizeValue toolTip; HighlightInfoType highlightInfoType = HighlightInfoType.ERROR; if (methodCandidate2 != null) { PsiMethod element1 = methodCandidate1.getElement(); @@ -955,11 +957,8 @@ public static HighlightInfo.Builder checkAmbiguousMethodCallArguments( m2 += " (In " + virtualFile2.getPresentableUrl() + ")"; } } - description = JavaErrorLocalize.ambiguousMethodCall(m1, m2).get(); - toolTip = createAmbiguousMethodHtmlTooltip(new MethodCandidateInfo[]{ - methodCandidate1, - methodCandidate2 - }).get(); + description = JavaCompilationErrorLocalize.callAmbiguous(m1, m2); + toolTip = createAmbiguousMethodHtmlTooltip(new MethodCandidateInfo[]{methodCandidate1, methodCandidate2}); } else { if (element != null && !resolveResult.isAccessible()) { @@ -969,11 +968,11 @@ public static HighlightInfo.Builder checkAmbiguousMethodCallArguments( return null; } String methodName = referenceToMethod.getReferenceName() + buildArgTypesList(list); - description = JavaErrorLocalize.cannotResolveMethod(methodName).get(); + description = JavaCompilationErrorLocalize.methodReferenceUnresolvedMethod(methodName); if (candidates.length == 0) { return null; } - toolTip = XmlStringUtil.escapeString(description); + toolTip = description.map((localizeManager, s) -> XmlStringUtil.escapeString(s)); } HighlightInfo.Builder hlBuilder = HighlightInfo.newHighlightInfo(highlightInfoType) .range(elementToHighlight) @@ -984,7 +983,7 @@ public static HighlightInfo.Builder checkAmbiguousMethodCallArguments( } if (!resolveResult.isAccessible() && resolveResult.isStaticsScopeCorrect() && methodCandidate2 != null) { HighlightUtil.registerAccessQuickFixAction( - (PsiMember)element, + (PsiMember) element, referenceToMethod, hlBuilder, elementToHighlight.getTextRange(), @@ -1036,12 +1035,12 @@ private static void registerMethodCallIntentions( hlBuilder.registerFix(factory.createModifierFixBuilder(psiClass).add(PsiModifier.STATIC).create()); } - hlBuilder.registerFix(factory.createCreateMethodFromUsageFix(methodCall), fixRange) - .registerFix(factory.createCreateAbstractMethodFromUsageFix(methodCall), fixRange) - .registerFix(factory.createCreateConstructorFromSuperFix(methodCall), fixRange) - .registerFix(factory.createCreateConstructorFromThisFix(methodCall), fixRange) - .registerFix(factory.createCreatePropertyFromUsageFix(methodCall), fixRange) - .registerFix(factory.createCreateGetterSetterPropertyFromUsageFix(methodCall), fixRange); + hlBuilder.newFix(factory.createCreateMethodFromUsageFix(methodCall)).fixRange(fixRange).register() + .newFix(factory.createCreateAbstractMethodFromUsageFix(methodCall)).fixRange(fixRange).register() + .newFix(factory.createCreateConstructorFromSuperFix(methodCall)).fixRange(fixRange).register() + .newFix(factory.createCreateConstructorFromThisFix(methodCall)).fixRange(fixRange).register() + .newFix(factory.createCreatePropertyFromUsageFix(methodCall)).fixRange(fixRange).register() + .newFix(factory.createCreateGetterSetterPropertyFromUsageFix(methodCall)).fixRange(fixRange).register(); CandidateInfo[] methodCandidates = resolveHelper.getReferencedMethodCandidates(methodCall, false); CastMethodArgumentFix.REGISTRAR.registerCastActions(methodCandidates, methodCall, hlBuilder, fixRange); @@ -1058,14 +1057,14 @@ private static void registerMethodCallIntentions( WrapExpressionFix.registerWrapAction(methodCandidates, list.getExpressions(), hlBuilder); registerChangeParameterClassFix(methodCall, list, hlBuilder); if (methodCandidates.length == 0) { - hlBuilder.registerFix(factory.createStaticImportMethodFix(methodCall), fixRange); - hlBuilder.registerFix(factory.addMethodQualifierFix(methodCall), fixRange); + hlBuilder.newFix(factory.createStaticImportMethodFix(methodCall)).fixRange(fixRange).register(); + hlBuilder.newFix(factory.addMethodQualifierFix(methodCall)).fixRange(fixRange).register(); } for (IntentionAction action : factory.getVariableTypeFromCallFixes(methodCall, list)) { - hlBuilder.registerFix(action, fixRange); + hlBuilder.newFix(action).fixRange(fixRange).register(); } - hlBuilder.registerFix(factory.createReplaceAddAllArrayToCollectionFix(methodCall), fixRange); - hlBuilder.registerFix(factory.createSurroundWithArrayFix(methodCall, null), fixRange); + hlBuilder.newFix(factory.createReplaceAddAllArrayToCollectionFix(methodCall)).fixRange(fixRange).register(); + hlBuilder.newFix(factory.createSurroundWithArrayFix(methodCall, null)).fixRange(fixRange).register(); QualifyThisArgumentFix.registerQuickFixAction(methodCandidates, methodCall, hlBuilder, fixRange); CandidateInfo[] candidates = resolveHelper.getReferencedMethodCandidates(methodCall, true); @@ -1081,7 +1080,7 @@ private static void registerMethodAccessLevelIntentions( @Nonnull TextRange fixRange ) { for (CandidateInfo methodCandidate : methodCandidates) { - PsiMethod method = (PsiMethod)methodCandidate.getElement(); + PsiMethod method = (PsiMethod) methodCandidate.getElement(); if (!methodCandidate.isAccessible() && PsiUtil.isApplicable(method, methodCandidate.getSubstitutor(), exprList)) { HighlightUtil.registerAccessQuickFixAction( method, @@ -1099,8 +1098,7 @@ private static void registerMethodAccessLevelIntentions( private static LocalizeValue createAmbiguousMethodHtmlTooltip(MethodCandidateInfo[] methodCandidates) { return JavaErrorLocalize.ambiguousMethodHtmlTooltip( methodCandidates[0].getElement().getParameterList().getParametersCount() + 2, - createAmbiguousMethodHtmlTooltipMethodRow - (methodCandidates[0]), + createAmbiguousMethodHtmlTooltipMethodRow(methodCandidates[0]), getContainingClassName(methodCandidates[0]), createAmbiguousMethodHtmlTooltipMethodRow(methodCandidates[1]), getContainingClassName(methodCandidates[1]) @@ -1133,8 +1131,9 @@ private static String createAmbiguousMethodHtmlTooltipMethodRow(MethodCandidateI return ms; } + @Nonnull @RequiredReadAction - private static String createMismatchedArgumentsHtmlTooltip(MethodCandidateInfo info, PsiExpressionList list) { + private static LocalizeValue createMismatchedArgumentsHtmlTooltip(MethodCandidateInfo info, PsiExpressionList list) { PsiMethod method = info.getElement(); PsiSubstitutor substitutor = info.getSubstitutor(); PsiClass aClass = method.getContainingClass(); @@ -1143,7 +1142,8 @@ private static String createMismatchedArgumentsHtmlTooltip(MethodCandidateInfo i return createMismatchedArgumentsHtmlTooltip(list, info, parameters, methodName, substitutor, aClass); } - private static String createShortMismatchedArgumentsHtmlTooltip( + @Nonnull + private static LocalizeValue createShortMismatchedArgumentsHtmlTooltip( PsiExpressionList list, @Nullable MethodCandidateInfo info, PsiParameter[] parameters, @@ -1154,18 +1154,17 @@ private static String createShortMismatchedArgumentsHtmlTooltip( PsiExpression[] expressions = list.getExpressions(); int cols = Math.max(parameters.length, expressions.length); - @Language("HTML") String parensizedName = methodName + (parameters.length == 0 ? "( ) " : ""); + @Language("HTML") String parenthesizedName = methodName + (parameters.length == 0 ? "( ) " : ""); String errorMessage = info != null ? info.getParentInferenceErrorMessage(list) : null; - return JavaErrorBundle.message( - "argument.mismatch.html.tooltip", + return JavaErrorLocalize.argumentMismatchHtmlTooltip( cols - parameters.length + 1, - parensizedName, + parenthesizedName, HighlightUtil.formatClass(aClass, false), createMismatchedArgsHtmlTooltipParamsRow(parameters, substitutor, expressions), - createMismatchedArgsHtmlTooltipArgumentsRow(expressions, parameters, substitutor, cols), - errorMessage != null + createMismatchedArgsHtmlTooltipArgumentsRow(expressions, parameters, substitutor, cols)//, + /*errorMessage != null ? "
reason: " + XmlStringUtil.escapeString(errorMessage).replaceAll("\n", "
") - : "" + : ""*/ ); } @@ -1198,8 +1197,9 @@ private static String trimNicely(String s) { return StringUtil.last(s, 40, true).toString(); } + @Nonnull @RequiredReadAction - private static String createMismatchedArgumentsHtmlTooltip( + private static LocalizeValue createMismatchedArgumentsHtmlTooltip( PsiExpressionList list, MethodCandidateInfo info, PsiParameter[] parameters, @@ -1212,10 +1212,10 @@ private static String createMismatchedArgumentsHtmlTooltip( : createLongMismatchedArgumentsHtmlTooltip(list, info, parameters, methodName, substitutor, aClass); } + @Nonnull @RequiredReadAction @SuppressWarnings("StringContatenationInLoop") - @Language("HTML") - private static String createLongMismatchedArgumentsHtmlTooltip( + private static LocalizeValue createLongMismatchedArgumentsHtmlTooltip( PsiExpressionList list, @Nullable MethodCandidateInfo info, PsiParameter[] parameters, @@ -1244,10 +1244,7 @@ private static String createLongMismatchedArgumentsHtmlTooltip( "'" : "") + ">"; s += ""; if (parameter != null) { - String name = parameter.getName(); - if (name != null) { - s += esctrim(name) + ":"; - } + s += esctrim(parameter.getName()) + ":"; } s += ""; @@ -1282,7 +1279,7 @@ private static String createLongMismatchedArgumentsHtmlTooltip( s += XmlStringUtil.escapeString(errorMessage).replaceAll("\n", "
"); } s += ""; - return s; + return LocalizeValue.localizeTODO(s); } @SuppressWarnings("StringContatenationInLoop") @@ -1373,7 +1370,7 @@ public static HighlightInfo checkAbstractMethodInConcreteClass(PsiMethod method, QuickFixFactory factory = QuickFixFactory.getInstance(); HighlightInfo.Builder errorResult = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(elementToHighlight) - .descriptionAndTooltip(JavaErrorLocalize.abstractMethodInNonAbstractClass()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.methodAbstractInNonAbstractClass()); if (method.getBody() != null) { errorResult.registerFix(factory.createModifierFixBuilder(method).remove(PsiModifier.ABSTRACT).create()); } @@ -1416,7 +1413,7 @@ public static HighlightInfo.Builder checkDuplicateMethod( } MethodSignature methodSignature = method.getSignature(PsiSubstitutor.EMPTY); int methodCount = 1; - List methods = (List)duplicateMethods.get(methodSignature); + List methods = (List) duplicateMethods.get(methodSignature); if (methods.size() > 1) { methodCount++; } @@ -1428,7 +1425,7 @@ public static HighlightInfo.Builder checkDuplicateMethod( TextRange textRange = HighlightNamesUtil.getMethodDeclarationTextRange(method); return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(method, textRange.getStartOffset(), textRange.getEndOffset()) - .descriptionAndTooltip(JavaErrorLocalize.duplicateMethod( + .descriptionAndTooltip(JavaCompilationErrorLocalize.methodDuplicate( JavaHighlightUtil.formatMethod(method), HighlightUtil.formatClass(aClass) )); @@ -1451,15 +1448,15 @@ public static HighlightInfo.Builder checkMethodCanHaveBody(@Nonnull PsiMethod me QuickFixFactory factory = QuickFixFactory.getInstance(); if (hasNoBody) { if (isExtension) { - description = JavaErrorLocalize.extensionMethodShouldHaveABody(); + description = JavaCompilationErrorLocalize.methodDefaultShouldHaveBody(); additionalFixes.add(factory.createAddMethodBodyFix(method)); } else if (isInterface) { if (isStatic && languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) { - description = JavaErrorLocalize.methodStaticInInterfaceShouldHaveBody(); + description = JavaCompilationErrorLocalize.methodStaticInInterfaceShouldHaveBody(); } else if (isPrivate && languageLevel.isAtLeast(LanguageLevel.JDK_1_9)) { - description = JavaErrorLocalize.methodPrivateInInterfaceShouldHaveBody(); + description = JavaCompilationErrorLocalize.methodPrivateInInterfaceShouldHaveBody(); } else { return null; @@ -1482,13 +1479,13 @@ else if (isInterface) { } } else if (isExtension) { - description = JavaErrorLocalize.extensionMethodInClass(); + description = JavaCompilationErrorLocalize.methodDefaultInClass(); } else if (method.isAbstract()) { - description = JavaErrorLocalize.abstractMethodsCannotHaveABody(); + description = JavaCompilationErrorLocalize.methodAbstractBody(); } else if (method.hasModifierProperty(PsiModifier.NATIVE)) { - description = JavaErrorLocalize.nativeMethodsCannotHaveABody(); + description = JavaCompilationErrorLocalize.methodNativeBody(); } else { return null; @@ -1531,7 +1528,7 @@ public static HighlightInfo.Builder checkConstructorCallMustBeFirstStatement(@No PsiReferenceExpression expression = methodCall.getMethodExpression(); return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(methodCall) - .descriptionAndTooltip(JavaErrorLocalize.constructorCallMustBeFirstStatement(expression.getText() + "()")); + .descriptionAndTooltip(JavaCompilationErrorLocalize.callConstructorMustBeFirstStatement(expression.getText() + "()")); } @Nullable @@ -1661,8 +1658,8 @@ private static HighlightInfo.Builder checkStaticMethodOverride( String c1 = HighlightUtil.formatClass(aClass); String c2 = HighlightUtil.formatClass(superClass); LocalizeValue description = isMethodStatic - ? JavaErrorLocalize.staticMethodCannotOverrideInstanceMethod(m1, c1, m2, c2) - : JavaErrorLocalize.instanceMethodCannotOverrideStaticMethod(m1, c1, m2, c2); + ? JavaCompilationErrorLocalize.methodStaticOverridesInstance(m1, c1, m2, c2) + : JavaCompilationErrorLocalize.methodInstanceOverridesStatic(m1, c1, m2, c2); HighlightInfo.Builder hlBuilder = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(HighlightNamesUtil.getMethodDeclarationTextRange(method)) @@ -1819,7 +1816,7 @@ public static HighlightInfo.Builder checkOverrideEquivalentInheritedMethods( for (HierarchicalMethodSignature superSignature : superSignatures) { PsiMethod superMethod = superSignature.getMethod(); if (!superMethod.isStatic()) { - description = JavaErrorLocalize.staticMethodCannotOverrideInstanceMethod( + description = JavaCompilationErrorLocalize.methodStaticOverridesInstance( JavaHighlightUtil.formatMethod(method), HighlightUtil.formatClass(containingClass), JavaHighlightUtil.formatMethod(superMethod), @@ -1907,7 +1904,7 @@ public static HighlightInfo.Builder checkRecursiveConstructorInvocation(@Nonnull } return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(HighlightNamesUtil.getMethodDeclarationTextRange(method)) - .descriptionAndTooltip(JavaErrorLocalize.recursiveConstructorInvocation()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.callConstructorRecursive()); } @Nonnull @@ -1941,7 +1938,7 @@ public static void checkNewExpression( } if (aClass instanceof PsiAnonymousClass anonymousClass) { type = anonymousClass.getBaseClassType(); - typeResult = ((PsiClassType)type).resolveGenerics(); + typeResult = ((PsiClassType) type).resolveGenerics(); aClass = typeResult.getElement(); if (aClass == null) { return; @@ -1974,7 +1971,7 @@ public static void checkConstructorCall( if (constructorCall instanceof PsiNewExpression newExpr) { PsiExpression qualifier = newExpr.getQualifier(); if (qualifier != null) { - accessObjectClass = (PsiClass)PsiUtil.getAccessObjectClass(qualifier).getElement(); + accessObjectClass = (PsiClass) PsiUtil.getAccessObjectClass(qualifier).getElement(); } } if (classReference != null && !resolveHelper.isAccessible(aClass, constructorCall, accessObjectClass)) { @@ -1992,7 +1989,7 @@ public static void checkConstructorCall( if (list.getExpressions().length != 0) { String constructorName = aClass.getName(); String argTypes = buildArgTypesList(list); - String tooltip = createMismatchedArgumentsHtmlTooltip( + LocalizeValue tooltip = createMismatchedArgumentsHtmlTooltip( list, null, PsiParameter.EMPTY_ARRAY, @@ -2005,10 +2002,9 @@ public static void checkConstructorCall( .description(JavaErrorLocalize.wrongConstructorArguments(constructorName + "()", argTypes)) .escapedToolTip(tooltip) .navigationShift(+1); - hlBuilder.registerFix( - QuickFixFactory.getInstance().createCreateConstructorFromCallFix(constructorCall), - constructorCall.getTextRange() - ); + hlBuilder.newFix(QuickFixFactory.getInstance().createCreateConstructorFromCallFix(constructorCall)) + .fixRange(constructorCall.getTextRange()) + .register(); if (classReference != null) { ConstructorParametersFixer.registerFixActions(classReference, constructorCall, hlBuilder, getFixRange(list)); } @@ -2038,10 +2034,10 @@ else if (aClass.isInterface() && constructorCall instanceof PsiNewExpression new } } - JavaResolveResult[] results = resolveHelper.multiResolveConstructor((PsiClassType)type, list, place); + JavaResolveResult[] results = resolveHelper.multiResolveConstructor((PsiClassType) type, list, place); MethodCandidateInfo result = null; if (results.length == 1) { - result = (MethodCandidateInfo)results[0]; + result = (MethodCandidateInfo) results[0]; } PsiMethod constructor = result == null ? null : result.getElement(); @@ -2065,7 +2061,7 @@ else if (aClass.isInterface() && constructorCall instanceof PsiNewExpression new name += buildArgTypesList(list); HighlightInfo.Builder info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(list) - .descriptionAndTooltip(JavaErrorLocalize.cannotResolveConstructor(name)) + .descriptionAndTooltip(JavaCompilationErrorLocalize.methodReferenceUnresolvedConstructor(name)) .navigationShift(+1); WrapExpressionFix.registerWrapAction(results, list.getExpressions(), info); registerFixesOnInvalidConstructorCall( @@ -2088,12 +2084,12 @@ else if (!applicable) { LocalizeValue constructorName = HighlightMessageUtil.getSymbolName(constructor, result.getSubstitutor()); LocalizeValue containerName = HighlightMessageUtil.getSymbolName(constructor.getContainingClass(), result.getSubstitutor()); String argTypes = buildArgTypesList(list); - String toolTip = createMismatchedArgumentsHtmlTooltip(result, list); + LocalizeValue tooltip = createMismatchedArgumentsHtmlTooltip(result, list); HighlightInfo.Builder hlBuilder = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(infoElement) - .description(JavaErrorLocalize.wrongMethodArguments(constructorName, containerName, argTypes)) - .escapedToolTip(toolTip) + .description(JavaCompilationErrorLocalize.callWrongArguments(constructorName, containerName, argTypes)) + .escapedToolTip(tooltip) .navigationShift(+1); JavaResolveResult[] methodCandidates = results; if (constructorCall instanceof PsiNewExpression newExpr) { @@ -2144,15 +2140,14 @@ private static HighlightInfo.Builder checkVarargParameterErasureToBeAccessible(M PsiMethod method = info.getElement(); if (info.isVarargs() || method.isVarArgs() && !PsiUtil.isLanguageLevel8OrHigher(place)) { PsiParameter[] parameters = method.getParameterList().getParameters(); - PsiType componentType = ((PsiEllipsisType)parameters[parameters.length - 1].getType()).getComponentType(); + PsiType componentType = ((PsiEllipsisType) parameters[parameters.length - 1].getType()).getComponentType(); PsiType substitutedTypeErasure = TypeConversionUtil.erasure(info.getSubstitutor().substitute(componentType)); PsiClass targetClass = PsiUtil.resolveClassInClassTypeOnly(substitutedTypeErasure); if (targetClass != null && !PsiUtil.isAccessible(targetClass, place, null)) { PsiExpressionList argumentList = place.getArgumentList(); return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) - .descriptionAndTooltip(LocalizeValue.localizeTODO( - "Formal varargs element type " + PsiFormatUtil.formatClass(targetClass, PsiFormatUtilBase.SHOW_FQ_NAME) + - " is inaccessible here" + .descriptionAndTooltip(JavaCompilationErrorLocalize.callFormalVarargsElementTypeInaccessibleHere( + PsiFormatUtil.formatClass(targetClass, PsiFormatUtilBase.SHOW_FQ_NAME) )) .range(argumentList != null ? argumentList : place); } @@ -2171,10 +2166,9 @@ private static void registerFixesOnInvalidConstructorCall( PsiElement infoElement, @Nonnull HighlightInfo.Builder hlBuilder ) { - hlBuilder.registerFix( - QuickFixFactory.getInstance().createCreateConstructorFromCallFix(constructorCall), - constructorCall.getTextRange() - ); + hlBuilder.newFix(QuickFixFactory.getInstance().createCreateConstructorFromCallFix(constructorCall)) + .fixRange(constructorCall.getTextRange()) + .register(); if (classReference != null) { ConstructorParametersFixer.registerFixActions(classReference, constructorCall, hlBuilder, getFixRange(infoElement)); ChangeTypeArgumentsFix.registerIntentions(results, list, hlBuilder, aClass); @@ -2183,7 +2177,9 @@ private static void registerFixesOnInvalidConstructorCall( registerChangeMethodSignatureFromUsageIntentions(results, list, hlBuilder, null); PermuteArgumentsFix.registerFix(hlBuilder, constructorCall, toMethodCandidates(results), getFixRange(list)); registerChangeParameterClassFix(constructorCall, list, hlBuilder); - hlBuilder.registerFix(QuickFixFactory.getInstance().createSurroundWithArrayFix(constructorCall, null), getFixRange(list)); + hlBuilder.newFix(QuickFixFactory.getInstance().createSurroundWithArrayFix(constructorCall, null)) + .fixRange(getFixRange(list)) + .register(); ChangeStringLiteralToCharInMethodCallFix.registerFixes(constructors, constructorCall, hlBuilder); } @@ -2254,7 +2250,7 @@ private static void registerChangeParameterClassFix( HighlightInfo.Builder hlBuilder ) { JavaResolveResult result = methodCall.resolveMethodGenerics(); - PsiMethod method = (PsiMethod)result.getElement(); + PsiMethod method = (PsiMethod) result.getElement(); PsiSubstitutor substitutor = result.getSubstitutor(); PsiExpression[] expressions = list.getExpressions(); if (method == null) { @@ -2292,7 +2288,7 @@ private static void registerChangeParameterClassFix( continue; } hlBuilder.registerFix(QuickFixFactory.getInstance() - .createChangeParameterClassFix(expressionClass, (PsiClassType)parameterType)); + .createChangeParameterClassFix(expressionClass, (PsiClassType) parameterType)); } } @@ -2321,38 +2317,26 @@ private static void registerChangeMethodSignatureFromUsageIntention( if (hlBuilder == null || !candidate.isStaticsScopeCorrect()) { return; } - PsiMethod method = (PsiMethod)candidate.getElement(); + PsiMethod method = (PsiMethod) candidate.getElement(); PsiSubstitutor substitutor = candidate.getSubstitutor(); if (method != null && context.getManager().isInProject(method)) { QuickFixFactory factory = QuickFixFactory.getInstance(); - hlBuilder.registerFix( - factory.createChangeMethodSignatureFromUsageFix( + hlBuilder.newFix(factory.createChangeMethodSignatureFromUsageFix( method, expressions, substitutor, context, false, 2 - ), - null, - LocalizeValue.of(), - fixRange, - null - ); - hlBuilder.registerFix( - factory.createChangeMethodSignatureFromUsageReverseOrderFix( + )).fixRange(fixRange).register() + .newFix(factory.createChangeMethodSignatureFromUsageReverseOrderFix( method, expressions, substitutor, context, false, 2 - ), - null, - LocalizeValue.of(), - fixRange, - null - ); + )).fixRange(fixRange).register(); } } } diff --git a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/HighlightUtil.java b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/HighlightUtil.java index 64beb9e148..94a52062ec 100644 --- a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/HighlightUtil.java +++ b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/HighlightUtil.java @@ -28,7 +28,6 @@ import com.intellij.java.language.LanguageLevel; import com.intellij.java.language.codeInsight.daemon.impl.analysis.JavaGenericsUtil; import com.intellij.java.language.impl.codeInsight.ExceptionUtil; -import com.intellij.java.language.impl.codeInsight.daemon.JavaErrorBundle; import com.intellij.java.language.impl.codeInsight.daemon.impl.analysis.HighlightUtilBase; import com.intellij.java.language.impl.psi.impl.source.resolve.JavaResolveUtil; import com.intellij.java.language.impl.psi.impl.source.resolve.graphInference.InferenceSession; @@ -45,9 +44,11 @@ import consulo.annotation.access.RequiredReadAction; import consulo.document.util.TextRange; import consulo.java.language.impl.localize.JavaErrorLocalize; +import consulo.java.language.localize.JavaCompilationErrorLocalize; import consulo.language.ast.IElementType; import consulo.language.editor.CodeInsightUtilCore; import consulo.language.editor.highlight.HighlightUsagesDescriptionLocation; +import consulo.language.editor.inspection.LocalQuickFixAndIntentionActionOnPsiElement; import consulo.language.editor.inspection.LocalQuickFixOnPsiElementAsIntentionAdapter; import consulo.language.editor.inspection.PriorityActionWrapper; import consulo.language.editor.intention.*; @@ -296,7 +297,7 @@ public static void registerAccessQuickFixAction( PsiClass accessObjectClass = null; PsiElement qualifier = place.getQualifier(); if (qualifier instanceof PsiExpression qExpr) { - accessObjectClass = (PsiClass)PsiUtil.getAccessObjectClass(qExpr).getElement(); + accessObjectClass = (PsiClass) PsiUtil.getAccessObjectClass(qExpr).getElement(); } registerReplaceInaccessibleFieldWithGetterSetterFix(refElement, place, accessObjectClass, hlBuilder); @@ -351,10 +352,9 @@ public static void registerAccessQuickFixAction( if (ref != null) { fixRange = fixRange.union(ref.getTextRange()); } - hlBuilder.registerFix( - QuickFixFactory.getInstance().createModifierFixBuilder(refElement).add(modifier).showContainingClass().create(), - fixRange - ); + LocalQuickFixAndIntentionActionOnPsiElement action = + QuickFixFactory.getInstance().createModifierFixBuilder(refElement).add(modifier).showContainingClass().create(); + hlBuilder.newFix(action).fixRange(fixRange).register(); } } } @@ -376,8 +376,7 @@ private static PsiClass getPackageLocalClassInTheMiddle(@Nonnull PsiElement plac return aClass; } } - PsiExpression qualifier = refExpr.getQualifierExpression(); - if (!(qualifier instanceof PsiReferenceExpression qualifierRefExpr)) { + if (!(refExpr.getQualifierExpression() instanceof PsiReferenceExpression qualifierRefExpr)) { break; } refExpr = qualifierRefExpr; @@ -405,7 +404,7 @@ public static HighlightInfo.Builder checkInstanceOfApplicable(@Nonnull PsiInstan || !TypeConversionUtil.areTypesConvertible(operandType, checkType)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.inconvertibleTypeCast( + .descriptionAndTooltip(JavaCompilationErrorLocalize.castInconvertible( JavaHighlightUtil.formatType(operandType), JavaHighlightUtil.formatType(checkType) )); @@ -418,7 +417,7 @@ public static HighlightInfo.Builder checkInstanceOfApplicable(@Nonnull PsiInstan * ( ReferenceType {AdditionalBound} ) expression, where AdditionalBound: & InterfaceType then all must be true * - ReferenceType must denote a class or interface type. * - The erasures of all the listed types must be pairwise different. - * - No two listed types may be subtypes of different parameterization of the same generic interface. + * - No two listed types may be subtypes of different parametrization of the same generic interface. */ @Nullable @RequiredReadAction @@ -454,12 +453,12 @@ public static HighlightInfo.Builder checkIntersectionInTypeCast( else { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(conjunct) - .descriptionAndTooltip(JavaErrorLocalize.unexpectedTypeClassExpected()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.castIntersectionUnexpectedType()); } if (!erasures.add(TypeConversionUtil.erasure(conjType))) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(conjunct) - .descriptionAndTooltip(JavaErrorLocalize.repeatedInterface()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.castIntersectionRepeatedInterface()) .registerFix(new DeleteRepeatedInterfaceFix(conjunct, conjList)); } } @@ -519,7 +518,7 @@ public static HighlightInfo checkInconvertibleTypeCast(@Nonnull PsiTypeCastExpre && !RedundantCastUtil.isInPolymorphicCall(expression)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.inconvertibleTypeCast( + .descriptionAndTooltip(JavaCompilationErrorLocalize.castInconvertible( JavaHighlightUtil.formatType(operandType), JavaHighlightUtil.formatType(castType) )) @@ -540,7 +539,7 @@ public static HighlightInfo checkVariableExpected(@Nonnull PsiExpression express else if (PsiUtil.isIncrementDecrementOperation(expression)) { lValue = expression instanceof PsiPostfixExpression postfixExpr ? postfixExpr.getOperand() - : ((PsiPrefixExpression)expression).getOperand(); + : ((PsiPrefixExpression) expression).getOperand(); } else { lValue = null; @@ -549,7 +548,7 @@ else if (PsiUtil.isIncrementDecrementOperation(expression)) { if (lValue != null && !TypeConversionUtil.isLValue(lValue)) { errorResult = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(lValue) - .descriptionAndTooltip(JavaErrorLocalize.variableExpected()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.lvalueVariableExpected()) .create(); } @@ -573,7 +572,7 @@ public static HighlightInfo checkAssignmentOperatorApplicable(@Nonnull PsiAssign PsiType rType = rExpression.getType(); if (!TypeConversionUtil.isBinaryOperatorApplicable(opSign, lType, rType, true)) { String operatorText = operationSign.getText().substring(0, operationSign.getText().length() - 1); - LocalizeValue message = JavaErrorLocalize.binaryOperatorNotApplicable( + LocalizeValue message = JavaCompilationErrorLocalize.binaryOperatorNotApplicable( operatorText, JavaHighlightUtil.formatType(lType), JavaHighlightUtil.formatType(rType) @@ -772,7 +771,7 @@ public static HighlightInfo.Builder checkReturnStatementType(@Nonnull PsiReturnS else if (method == null && !(parent instanceof ServerPageFile)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(statement) - .descriptionAndTooltip(JavaErrorLocalize.returnOutsideMethod()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.returnOutsideMethod()); } else { PsiType returnType = method != null ? method.getReturnType() : null/*JSP page returns void*/; @@ -783,7 +782,7 @@ else if (method == null && !(parent instanceof ServerPageFile)) { if (isMethodVoid) { HighlightInfo.Builder errorResult = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(statement) - .descriptionAndTooltip(JavaErrorLocalize.returnFromVoidMethod()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.returnFromVoidMethod()); if (valueType != null) { errorResult.registerFix(QuickFixFactory.getInstance().createMethodReturnFix(method, valueType, true)); } @@ -813,7 +812,7 @@ else if (method == null && !(parent instanceof ServerPageFile)) { else if (!isMethodVoid) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(statement) - .descriptionAndTooltip(JavaErrorLocalize.missingReturnValue()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.returnValueMissing()) .navigationShift(PsiKeyword.RETURN.length()) .registerFix(QuickFixFactory.getInstance().createMethodReturnFix(method, PsiType.VOID, true)); } @@ -849,8 +848,8 @@ public static LocalizeValue getUnhandledExceptionsDescriptor(@Nonnull Collection private static LocalizeValue getUnhandledExceptionsDescriptor(@Nonnull Collection unhandled, @Nullable String source) { String exceptions = formatTypes(unhandled); return source != null - ? JavaErrorLocalize.unhandledCloseExceptions(exceptions, unhandled.size(), source) - : JavaErrorLocalize.unhandledExceptions(exceptions, unhandled.size()); + ? JavaCompilationErrorLocalize.exceptionUnhandledClose(exceptions, unhandled.size()) + : JavaCompilationErrorLocalize.exceptionUnhandled(exceptions, unhandled.size()); } @Nonnull @@ -867,7 +866,7 @@ public static HighlightInfo checkVariableAlreadyDefined(@Nonnull PsiVariable var assert identifier != null : variable; HighlightInfo.Builder highlightInfo = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(identifier) - .descriptionAndTooltip(JavaErrorLocalize.variableAlreadyDefined(variable.getName())); + .descriptionAndTooltip(JavaCompilationErrorLocalize.variableAlreadyDefined(variable.getName())); if (variable instanceof PsiLocalVariable localVar) { highlightInfo.registerFix(QuickFixFactory.getInstance().createReuseVariableDeclarationFix(localVar)); } @@ -883,15 +882,14 @@ public static HighlightInfo checkUnderscore(@Nonnull PsiIdentifier identifier, @ if (languageLevel.isAtLeast(LanguageLevel.JDK_1_9)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(identifier) - .descriptionAndTooltip(JavaErrorLocalize.underscoreIdentifierError()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.underscoreIdentifier()) .create(); } else if (languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) { - PsiElement parent = identifier.getParent(); - if (parent instanceof PsiParameter parameter && parameter.getDeclarationScope() instanceof PsiLambdaExpression) { + if (identifier.getParent() instanceof PsiParameter param && param.getDeclarationScope() instanceof PsiLambdaExpression) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(identifier) - .descriptionAndTooltip(JavaErrorLocalize.underscoreLambdaIdentifier()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.underscoreIdentifierLambda()) .create(); } } @@ -999,7 +997,7 @@ public static HighlightInfo checkBreakOutsideLoop(@Nonnull PsiBreakStatement sta if (new PsiMatcherImpl(statement).ancestor(EnclosingLoopOrSwitchMatcherExpression.INSTANCE).getElement() == null) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(statement) - .descriptionAndTooltip(JavaErrorLocalize.breakOutsideSwitchOrLoop()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.breakOutsideSwitchOrLoop()) .create(); } } @@ -1017,7 +1015,7 @@ public static HighlightInfo checkContinueOutsideLoop(@Nonnull PsiContinueStateme if (new PsiMatcherImpl(statement).ancestor(EnclosingLoopMatcherExpression.INSTANCE).getElement() == null) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(statement) - .descriptionAndTooltip(JavaErrorLocalize.continueOutsideLoop()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.continueOutsideLoop()) .create(); } } @@ -1047,7 +1045,7 @@ public static HighlightInfo checkIllegalModifierCombination(@Nonnull PsiKeyword if (incompatible != null) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(keyword) - .descriptionAndTooltip(JavaErrorLocalize.incompatibleModifiers(modifier, incompatible)) + .descriptionAndTooltip(JavaCompilationErrorLocalize.modifierIncompatible(modifier, incompatible)) .registerFix(QuickFixFactory.getInstance().createModifierFixBuilder(modifierList).remove(modifier).create()) .create(); } @@ -1056,6 +1054,7 @@ public static HighlightInfo checkIllegalModifierCombination(@Nonnull PsiKeyword } @Contract("null -> null") + @RequiredReadAction private static Map> getIncompatibleModifierMap(@Nullable PsiElement modifierListOwner) { if (modifierListOwner == null || PsiUtilCore.hasErrorElementChild(modifierListOwner)) { return null; @@ -1147,11 +1146,11 @@ else if (modifierOwner instanceof PsiMethod method) { if (PsiModifier.PRIVATE.equals(modifier)) { isAllowed &= modifierOwnerParent instanceof PsiClass modifierClass && (!modifierClass.isInterface() - || PsiUtil.isLanguageLevel9OrHigher(modifierOwner) && !modifierClass.isAnnotationType()); + || PsiUtil.isLanguageLevel9OrHigher(method) && !modifierClass.isAnnotationType()); } else if (PsiModifier.STRICTFP.equals(modifier)) { isAllowed &= modifierOwnerParent instanceof PsiClass modifierClass - && (!modifierClass.isInterface() || PsiUtil.isLanguageLevel8OrHigher(modifierOwner)); + && (!modifierClass.isInterface() || PsiUtil.isLanguageLevel8OrHigher(method)); } else if (PsiModifier.PROTECTED.equals(modifier) || PsiModifier.TRANSIENT.equals(modifier) @@ -1191,7 +1190,7 @@ else if (modifierOwner instanceof PsiReceiverParameter) { if (!isAllowed) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(keyword) - .descriptionAndTooltip(JavaErrorLocalize.modifierNotAllowed(modifier)) + .descriptionAndTooltip(JavaCompilationErrorLocalize.modifierNotAllowed(modifier)) .registerFix(QuickFixFactory.getInstance().createModifierFixBuilder(modifierList).remove(modifier).create()) .create(); } @@ -1208,7 +1207,7 @@ public static HighlightInfo.Builder checkLiteralExpressionParsingError( ) { PsiElement literal = expression.getFirstChild(); assert literal instanceof PsiJavaToken : literal; - IElementType type = ((PsiJavaToken)literal).getTokenType(); + IElementType type = ((PsiJavaToken) literal).getTokenType(); if (type == JavaTokenType.TRUE_KEYWORD || type == JavaTokenType.FALSE_KEYWORD || type == JavaTokenType.NULL_KEYWORD) { return null; } @@ -1255,17 +1254,17 @@ public static HighlightInfo.Builder checkLiteralExpressionParsingError( if (cleanText.equals(PsiLiteralUtil.HEX_PREFIX)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.hexadecimalNumbersMustContainAtLeastOneHexadecimalDigit()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.literalHexadecimalNoDigits()); } if (cleanText.equals(PsiLiteralUtil.BIN_PREFIX)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.binaryNumbersMustContainAtLeastOneHexadecimalDigit()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.literalBinaryNoDigits()); } if (value == null || cleanText.equals(PsiLiteralUtil._2_IN_31)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.integerNumberTooLarge()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.literalIntegerTooLarge()); } } } @@ -1278,17 +1277,17 @@ else if (type == JavaTokenType.LONG_LITERAL) { if (cleanText.equals(PsiLiteralUtil.HEX_PREFIX)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.hexadecimalNumbersMustContainAtLeastOneHexadecimalDigit()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.literalHexadecimalNoDigits()); } if (cleanText.equals(PsiLiteralUtil.BIN_PREFIX)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.binaryNumbersMustContainAtLeastOneHexadecimalDigit()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.literalBinaryNoDigits()); } if (value == null || cleanText.equals(PsiLiteralUtil._2_IN_63)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.longNumberTooLarge()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.literalLongTooLarge()); } } } @@ -1296,7 +1295,7 @@ else if (isFP) { if (value == null) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.malformedFloatingPointLiteral().get()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.literalFloatingMalformed()); } } else if (type == JavaTokenType.CHARACTER_LITERAL) { @@ -1307,7 +1306,7 @@ else if (type == JavaTokenType.CHARACTER_LITERAL) { if (!StringUtil.endsWithChar(text, '\'') || text.length() == 1) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.unclosedCharLiteral()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.literalCharacterUnclosed()); } text = text.substring(1, text.length() - 1); @@ -1315,19 +1314,19 @@ else if (type == JavaTokenType.CHARACTER_LITERAL) { if (chars == null) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.illegalEscapeCharacterInCharacterLiteral()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.literalCharacterIllegalEscape()); } int length = chars.length(); if (length > 1) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.tooManyCharactersInCharacterLiteral()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.literalCharacterTooLong()) .registerFix(QuickFixFactory.getInstance().createConvertToStringLiteralAction()); } else if (length == 0) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.emptyCharacterLiteral()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.literalCharacterEmpty()); } } } @@ -1360,7 +1359,7 @@ else if (type == JavaTokenType.STRING_LITERAL || type == JavaTokenType.TEXT_BLOC if (CodeInsightUtilCore.parseStringCharacters(text, null) == null) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.illegalEscapeCharacterInStringLiteral()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.literalStringIllegalEscape()); } } } @@ -1370,7 +1369,7 @@ else if (value == null) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(p, p) .endOfLine() - .descriptionAndTooltip(JavaErrorLocalize.textBlockUnclosed()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.literalTextBlockUnclosed()); } else { StringBuilder chars = new StringBuilder(text.length()); @@ -1382,12 +1381,12 @@ else if (value == null) { : expression.getTextRange(); return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression, textRange) - .descriptionAndTooltip(JavaErrorLocalize.illegalEscapeCharacterInStringLiteral()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.literalStringIllegalEscape()); } else { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.textBlockNewLine()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.literalTextBlockNoNewLine()); } } } @@ -1411,24 +1410,24 @@ else if (value == null) { if (number.isInfinite()) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.floatingPointNumberTooLarge()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.literalFloatingTooLarge()); } if (number == 0 && !TypeConversionUtil.isFPZero(text)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.floatingPointNumberTooSmall()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.literalFloatingTooSmall()); } } else if (value instanceof Double number) { if (number.isInfinite()) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.floatingPointNumberTooLarge()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.literalFloatingTooLarge()); } if (number == 0 && !TypeConversionUtil.isFPZero(text)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.floatingPointNumberTooSmall()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.literalFloatingTooSmall()); } } @@ -1491,7 +1490,7 @@ private static HighlightInfo.Builder checkUnderscores(@Nonnull PsiElement expres if (part != null && (StringUtil.startsWithChar(part, '_') || StringUtil.endsWithChar(part, '_'))) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.illegalUnderscore()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.literalIllegalUnderscore()); } } @@ -1527,6 +1526,7 @@ else if (expr instanceof PsiAssignmentExpression assignment && assignment.getOpe } @Nonnull + @RequiredReadAction public static Set collectUnhandledExceptions(@Nonnull PsiTryStatement statement) { Set thrownTypes = new HashSet<>(); @@ -1581,7 +1581,7 @@ private static HighlightInfo checkSimpleCatchParameter( return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(parameter) - .descriptionAndTooltip(JavaErrorLocalize.exceptionNeverThrownTry(JavaHighlightUtil.formatType(caughtType))) + .descriptionAndTooltip(JavaCompilationErrorLocalize.exceptionNeverThrownTry(JavaHighlightUtil.formatType(caughtType))) .registerFix(QuickFixFactory.getInstance().createDeleteCatchFix(parameter)) .create(); } @@ -1611,7 +1611,7 @@ private static List checkMultiCatchParameter( if (!used) { HighlightInfo highlight = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(typeElement) - .descriptionAndTooltip(JavaErrorLocalize.exceptionNeverThrownTry(JavaHighlightUtil.formatType(catchType))) + .descriptionAndTooltip(JavaCompilationErrorLocalize.exceptionNeverThrownTry(JavaHighlightUtil.formatType(catchType))) .registerFix(QuickFixFactory.getInstance().createDeleteMultiCatchFix(typeElement)) .create(); highlights.add(highlight); @@ -1705,8 +1705,8 @@ public static HighlightInfo checkNotAStatement(@Nonnull PsiStatement statement) } LocalizeValue description = isDeclarationNotAllowed - ? JavaErrorLocalize.declarationNotAllowed() - : JavaErrorLocalize.notAStatement(); + ? JavaCompilationErrorLocalize.statementDeclarationNotAllowed() + : JavaCompilationErrorLocalize.statementBadExpression(); HighlightInfo.Builder error = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(statement) .descriptionAndTooltip(description); @@ -1749,7 +1749,7 @@ public static HighlightInfo.Builder checkSwitchBlockStatements( levelChecked = true; } if (classicLabels) { - alien = (PsiStatement)element; + alien = (PsiStatement) element; break; } enhancedLabels = true; @@ -1828,7 +1828,7 @@ public static HighlightInfo checkSwitchSelectorType(@Nonnull PsiSwitchBlock swit : JavaErrorLocalize.validSwitchSelectorTypes(); HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.incompatibleTypes(expected, JavaHighlightUtil.formatType(type))) + .descriptionAndTooltip(JavaCompilationErrorLocalize.typeIncompatible(expected, JavaHighlightUtil.formatType(type))) .create(); if (switchBlock instanceof PsiSwitchStatement switchStmt) { QuickFixAction.registerQuickFixAction( @@ -1897,7 +1897,7 @@ public static HighlightInfo checkPolyadicOperatorApplicable(@Nonnull PsiPolyadic PsiType rType = operand.getType(); if (!TypeConversionUtil.isBinaryOperatorApplicable(operationSign, lType, rType, false)) { PsiJavaToken token = expression.getTokenBeforeOperand(operand); - LocalizeValue message = JavaErrorLocalize.binaryOperatorNotApplicable( + LocalizeValue message = JavaCompilationErrorLocalize.binaryOperatorNotApplicable( token.getText(), JavaHighlightUtil.formatType(lType), JavaHighlightUtil.formatType(rType) @@ -1925,7 +1925,7 @@ public static HighlightInfo checkUnaryOperatorApplicable(@Nullable PsiJavaToken PsiElement parentExpr = token.getParent(); HighlightInfo highlightInfo = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(parentExpr) - .descriptionAndTooltip(JavaErrorLocalize.unaryOperatorNotApplicable(token.getText(), JavaHighlightUtil.formatType(type))) + .descriptionAndTooltip(JavaCompilationErrorLocalize.unaryOperatorNotApplicable(token.getText(), JavaHighlightUtil.formatType(type))) .create(); if (parentExpr instanceof PsiPrefixExpression prefixExpr && token.getTokenType() == JavaTokenType.EXCL) { QuickFixAction.registerQuickFixAction( @@ -1950,7 +1950,7 @@ public static HighlightInfo checkThisOrSuperExpressionInIllegalContext( int o = expr.getTextRange().getEndOffset(); return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(o, o + 1) - .descriptionAndTooltip(JavaErrorLocalize.dotExpectedAfterSuperOrThis()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.expressionSuperDotExpected()) .create(); } @@ -1963,7 +1963,7 @@ public static HighlightInfo checkThisOrSuperExpressionInIllegalContext( else if (resolved != null) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(qualifier) - .descriptionAndTooltip(JavaErrorLocalize.classExpected()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.expressionQualifiedClassExpected()) .create(); } } @@ -2033,7 +2033,7 @@ else if (resolved instanceof PsiMethod method if (!classT.isInheritor(aClass, false)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(qualifier) - .descriptionAndTooltip(JavaErrorLocalize.noEnclosingInstanceInScope(format(aClass))) + .descriptionAndTooltip(JavaCompilationErrorLocalize.expressionSuperNoEnclosingInstance(format(aClass))) .create(); } } @@ -2067,12 +2067,11 @@ public static HighlightInfo checkUnqualifiedSuperInDefaultMethod( if (languageLevel.isAtLeast(LanguageLevel.JDK_1_8) && qualifier instanceof PsiSuperExpression superExpr) { PsiMethod method = PsiTreeUtil.getParentOfType(expr, PsiMethod.class); if (method != null && method.hasModifierProperty(PsiModifier.DEFAULT) && superExpr.getQualifier() == null) { - HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) + HighlightInfo.Builder hlBuilder = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expr) - .descriptionAndTooltip(JavaErrorLocalize.unqualifiedSuperDisallowed()) - .create(); - QualifySuperArgumentFix.registerQuickFixAction((PsiSuperExpression)qualifier, info); - return info; + .descriptionAndTooltip(JavaCompilationErrorLocalize.expressionSuperUnqualifiedDefaultMethod()); + QualifySuperArgumentFix.registerQuickFixAction(superExpr, hlBuilder); + return hlBuilder.create(); } } return null; @@ -2099,15 +2098,11 @@ private static boolean resolvesToImmediateSuperInterface( @Nonnull PsiClass aClass, @Nonnull LanguageLevel languageLevel ) { - if (!(expr instanceof PsiSuperExpression) || qualifier == null || !languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) { - return false; - } - PsiType superType = expr.getType(); - if (!(superType instanceof PsiClassType classType)) { - return false; - } - PsiClass superClass = classType.resolve(); - return superClass != null && aClass.equals(superClass) + return expr instanceof PsiSuperExpression + && qualifier != null + && languageLevel.isAtLeast(LanguageLevel.JDK_1_8) + && expr.getType() instanceof PsiClassType superClassType + && aClass.equals(superClassType.resolve()) && PsiUtil.getEnclosingStaticElement(expr, PsiTreeUtil.getParentOfType(expr, PsiClass.class)) == null; } @@ -2116,7 +2111,7 @@ private static boolean resolvesToImmediateSuperInterface( public static LocalizeValue buildProblemWithStaticDescription(@Nonnull PsiElement refElement) { String type = FindUsagesProvider.forLanguage(JavaLanguage.INSTANCE).getType(refElement); LocalizeValue name = HighlightMessageUtil.getSymbolName(refElement, PsiSubstitutor.EMPTY); - return JavaErrorLocalize.nonStaticSymbolReferencedFromStaticContext(type, name); + return JavaCompilationErrorLocalize.referenceNonStaticFromStaticContext(type, name); } @RequiredReadAction @@ -2155,8 +2150,8 @@ private static boolean isInstanceReference(@Nonnull PsiJavaCodeReferenceElement if (q != null) { return true; } - String qname = codeReferenceElement.getQualifiedName(); - return qname == null || !Character.isLowerCase(qname.charAt(0)); + String qName = codeReferenceElement.getQualifiedName(); + return qName == null || !Character.isLowerCase(qName.charAt(0)); } @Nonnull @@ -2173,7 +2168,7 @@ private static LocalizeValue buildProblemWithAccessDescription( @Nonnull PsiElement resolved ) { assert resolved instanceof PsiModifierListOwner : resolved; - PsiModifierListOwner refElement = (PsiModifierListOwner)resolved; + PsiModifierListOwner refElement = (PsiModifierListOwner) resolved; LocalizeValue symbolName = HighlightMessageUtil.getSymbolName(refElement, result.getSubstitutor()); if (refElement.hasModifierProperty(PsiModifier.PRIVATE)) { @@ -2225,7 +2220,7 @@ public static HighlightInfo.Builder checkValidArrayAccessExpression(@Nonnull Psi if (arrayExpressionType != null && !(arrayExpressionType instanceof PsiArrayType)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(arrayExpression) - .descriptionAndTooltip(JavaErrorLocalize.arrayTypeExpected(JavaHighlightUtil.formatType(arrayExpressionType))) + .descriptionAndTooltip(JavaCompilationErrorLocalize.arrayTypeExpected(JavaHighlightUtil.formatType(arrayExpressionType))) .registerFix(QuickFixFactory.getInstance().createReplaceWithListAccessFix(arrayAccessExpression)); } @@ -2240,8 +2235,7 @@ public static HighlightInfo.Builder checkValidArrayAccessExpression(@Nonnull Psi @RequiredReadAction public static HighlightInfo.Builder checkCatchParameterIsThrowable(@Nonnull PsiParameter parameter) { if (parameter.getDeclarationScope() instanceof PsiCatchSection) { - PsiType type = parameter.getType(); - return checkMustBeThrowable(type, parameter, true); + return checkMustBeThrowable(parameter.getType(), parameter, true); } return null; } @@ -2279,13 +2273,12 @@ public static HighlightInfo checkResourceVariableIsFinal(@Nonnull PsiResourceExp } if (target instanceof PsiVariable variable) { - PsiModifierList modifierList = variable.getModifierList(); - if (modifierList != null && modifierList.hasModifierProperty(PsiModifier.FINAL)) { + if (variable.hasModifierProperty(PsiModifier.FINAL)) { return null; } if (!(variable instanceof PsiField) - && HighlightControlFlowUtil.isEffectivelyFinal(variable, resource, (PsiJavaCodeReferenceElement)expression)) { + && HighlightControlFlowUtil.isEffectivelyFinal(variable, resource, refExpr)) { return null; } } @@ -2343,7 +2336,7 @@ private static HighlightInfo.Builder checkArrayInitializerCompatibleTypes(@Nonnu if (initializerType == null) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(initializer) - .descriptionAndTooltip(JavaErrorLocalize.illegalInitializer(JavaHighlightUtil.formatType(componentType))); + .descriptionAndTooltip(JavaCompilationErrorLocalize.arrayIllegalInitializer(JavaHighlightUtil.formatType(componentType))); } PsiExpression expression = initializer instanceof PsiArrayInitializerExpression ? null : initializer; return checkAssignability(componentType, initializerType, expression, initializer); @@ -2399,7 +2392,7 @@ else if (parent instanceof PsiNewExpression || parent instanceof PsiArrayInitial return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.arrayInitializerNotAllowed()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.arrayInitializerNotAllowed()) .registerFix(QuickFixFactory.getInstance().createAddNewArrayExpressionFix(expression)) .create(); } @@ -2411,7 +2404,7 @@ public static HighlightInfo checkCaseStatement(@Nonnull PsiSwitchLabelStatementB if (switchBlock == null) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(statement) - .descriptionAndTooltip(JavaErrorLocalize.caseStatementOutsideSwitch()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.statementCaseOutsideSwitch()) .create(); } @@ -2476,7 +2469,7 @@ public static Collection checkSwitchLabelValues(@Nonnull PsiSwitc results.add( HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expr) - .descriptionAndTooltip(JavaErrorLocalize.constantExpressionRequired()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.switchLabelConstantExpected()) .create() ); continue; @@ -2492,8 +2485,8 @@ public static Collection checkSwitchLabelValues(@Nonnull PsiSwitc if (entry.getValue().size() > 1) { Object value = entry.getKey(); LocalizeValue description = value == defaultValue - ? JavaErrorLocalize.duplicateDefaultSwitchLabel() - : JavaErrorLocalize.duplicateSwitchLabel(value); + ? JavaCompilationErrorLocalize.switchLabelDuplicateDefault() + : JavaCompilationErrorLocalize.switchLabelDuplicate(value); for (PsiElement element : entry.getValue()) { results.add( HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) @@ -2553,9 +2546,9 @@ public static HighlightInfo checkIllegalForwardReferenceToField( if (isIllegalForwardReference == null) { return null; } - String description = isIllegalForwardReference - ? JavaErrorLocalize.illegalForwardReference().get() - : JavaErrorBundle.message("illegal.self.reference"); + LocalizeValue description = isIllegalForwardReference + ? JavaErrorLocalize.illegalForwardReference() + : JavaErrorLocalize.illegalSelfReference(); return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) .descriptionAndTooltip(description) @@ -2659,7 +2652,7 @@ public static HighlightInfo checkIllegalType(@Nullable PsiTypeElement typeElemen String canonicalText = type.getCanonicalText(); HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(typeElement) - .descriptionAndTooltip(JavaErrorLocalize.unknownClass(canonicalText)) + .descriptionAndTooltip(JavaCompilationErrorLocalize.typeUnknownClass(canonicalText)) .create(); PsiJavaCodeReferenceElement referenceElement = typeElement.getInnermostComponentReferenceElement(); @@ -2708,7 +2701,7 @@ else if (typeOwner instanceof JavaCodeFragment) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(type) - .descriptionAndTooltip(JavaErrorLocalize.illegalTypeVoid()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.typeVoidIllegal()); } @Nullable @@ -2734,14 +2727,14 @@ public static HighlightInfo.Builder checkMemberReferencedBeforeConstructorCalled if (resolved == null && isSuperCall) { if (qualifier instanceof PsiReferenceExpression qRefExpr) { resolved = qRefExpr.resolve(); - expression = qualifier; + expression = qRefExpr; type = qRefExpr.getType(); referencedClass = PsiUtil.resolveClassInType(type); } else if (qualifier == null) { resolved = PsiTreeUtil.getParentOfType(expression, PsiMethod.class, true, PsiMember.class); if (resolved != null) { - referencedClass = ((PsiMethod)resolved).getContainingClass(); + referencedClass = ((PsiMethod) resolved).getContainingClass(); } } else if (qualifier instanceof PsiThisExpression thisExpr) { @@ -2765,7 +2758,7 @@ else if (resolved instanceof PsiMethod method) { } PsiElement nameElement = expression instanceof PsiThisExpression ? expression - : ((PsiJavaCodeReferenceElement)expression).getReferenceNameElement(); + : ((PsiJavaCodeReferenceElement) expression).getReferenceNameElement(); String name = nameElement == null ? null : nameElement.getText(); if (isSuperCall) { if (referencedClass == null) { @@ -2863,7 +2856,7 @@ private static HighlightInfo.Builder checkReferenceToOurInstanceInsideThisOrSupe } // only this class/superclasses instance methods are not allowed to call - PsiClass aClass = (PsiClass)parentClass; + PsiClass aClass = (PsiClass) parentClass; if (PsiUtil.isInnerClass(aClass) && referencedClass == aClass.getContainingClass()) { return null; } @@ -2904,7 +2897,7 @@ private static HighlightInfo.Builder checkReferenceToOurInstanceInsideThisOrSupe if (element instanceof PsiReferenceExpression refExpr) { PsiElement resolve; - if (element instanceof PsiReferenceExpressionImpl refExprImpl) { + if (refExpr instanceof PsiReferenceExpressionImpl refExprImpl) { JavaResolveResult[] results = JavaResolveUtil.resolveWithContainingFile( refExprImpl, PsiReferenceExpressionImpl.OurGenericsResolver.INSTANCE, @@ -2923,8 +2916,7 @@ private static HighlightInfo.Builder checkReferenceToOurInstanceInsideThisOrSupe } } - element = element.getParent(); - if (element instanceof PsiClass psiClass && InheritanceUtil.isInheritorOrSelf(psiClass, referencedClass, true)) { + if (element.getParent() instanceof PsiClass psiClass && InheritanceUtil.isInheritorOrSelf(psiClass, referencedClass, true)) { return null; } } @@ -2940,7 +2932,10 @@ private static HighlightInfo.Builder createMemberReferencedError(String resolved @Nullable @RequiredReadAction - public static HighlightInfo.Builder checkImplicitThisReferenceBeforeSuper(@Nonnull PsiClass aClass, @Nonnull JavaSdkVersion javaSdkVersion) { + public static HighlightInfo.Builder checkImplicitThisReferenceBeforeSuper( + @Nonnull PsiClass aClass, + @Nonnull JavaSdkVersion javaSdkVersion + ) { if (javaSdkVersion.isAtLeast(JavaSdkVersion.JDK_1_7)) { return null; } @@ -3020,7 +3015,7 @@ public static HighlightInfo.Builder checkLabelWithoutStatement(@Nonnull PsiLabel if (statement.getStatement() == null) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(statement) - .descriptionAndTooltip(JavaErrorLocalize.labelWithoutStatement()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.labelWithoutStatement()); } return null; } @@ -3035,11 +3030,12 @@ public static HighlightInfo.Builder checkLabelAlreadyInUse(@Nonnull PsiLabeledSt if (element instanceof PsiMethod || element instanceof PsiClass) { break; } - if (element instanceof PsiLabeledStatement labeledStmt && element != statement + if (element instanceof PsiLabeledStatement labeledStmt + && labeledStmt != statement && Objects.equals(labeledStmt.getLabelIdentifier().getText(), text)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(identifier) - .descriptionAndTooltip(JavaErrorLocalize.duplicateLabel(text)); + .descriptionAndTooltip(JavaCompilationErrorLocalize.labelDuplicate(text)); } element = element.getParent(); } @@ -3057,7 +3053,7 @@ public static HighlightInfo checkUnclosedComment(@Nonnull PsiComment comment) { int end = start + 1; return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(start, end) - .descriptionAndTooltip(JavaErrorLocalize.unclosedComment()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.commentUnclosed()) .create(); } return null; @@ -3090,7 +3086,7 @@ public static Collection checkCatchTypeIsDisjoint(@Nonnull PsiPar PsiTypeElement element = typeElements.get(sub ? i : j); HighlightInfo highlight = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(element) - .descriptionAndTooltip(JavaErrorLocalize.exceptionMustBeDisjoint(sub ? name1 : name2, sub ? name2 : name1).get()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.exceptionMustBeDisjoint(sub ? name1 : name2, sub ? name2 : name1)) .registerFix(QuickFixFactory.getInstance().createDeleteMultiCatchFix(element)) .create(); result.add(highlight); @@ -3138,7 +3134,7 @@ public static Collection checkExceptionAlreadyCaught(@Nonnull Psi PsiFormatUtil.formatClass(catchClass, PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_FQ_NAME); HighlightInfo highlightInfo = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(typeElement) - .descriptionAndTooltip(JavaErrorLocalize.exceptionAlreadyCaught(className)) + .descriptionAndTooltip(JavaCompilationErrorLocalize.exceptionAlreadyCaught(className)) .registerFix(QuickFixFactory.getInstance().createMoveCatchUpFix(catchSection, upperCatchSection)) .registerFix( isInMultiCatch @@ -3216,7 +3212,7 @@ public static HighlightInfo.Builder checkAssertOperatorTypes(@Nonnull PsiExpress if (expression == assertStatement.getAssertDescription() && TypeConversionUtil.isVoidType(type)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.voidTypeIsNotAllowed()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.typeVoidNotAllowed()); } return null; } @@ -3242,22 +3238,21 @@ public static HighlightInfo.Builder checkSynchronizedExpressionType( @Nullable @RequiredReadAction public static HighlightInfo.Builder checkConditionalExpressionBranchTypesMatch(@Nonnull PsiExpression expression, PsiType type) { - PsiElement parent = expression.getParent(); - if (!(parent instanceof PsiConditionalExpression conditionalExpr)) { + if (!(expression.getParent() instanceof PsiConditionalExpression conditional)) { return null; } // check else branches only - if (conditionalExpr.getElseExpression() != expression) { + if (conditional.getElseExpression() != expression) { return null; } - PsiExpression thenExpression = conditionalExpr.getThenExpression(); + PsiExpression thenExpression = conditional.getThenExpression(); assert thenExpression != null; PsiType thenType = thenExpression.getType(); if (thenType == null || type == null) { return null; } - if (conditionalExpr.getType() == null) { - if (PsiUtil.isLanguageLevel8OrHigher(conditionalExpr) && PsiPolyExpressionUtil.isPolyExpression(conditionalExpr)) { + if (conditional.getType() == null) { + if (PsiUtil.isLanguageLevel8OrHigher(conditional) && PsiPolyExpressionUtil.isPolyExpression(conditional)) { return null; } // cannot derive type of conditional expression @@ -3285,7 +3280,7 @@ public static HighlightInfo.Builder createIncompatibleTypeHighlightInfo( PsiClass psiClass = resolveResult.getElement(); if (psiClass instanceof PsiAnonymousClass anonymousClass) { lType1 = anonymousClass.getBaseClassType(); - resolveResult = ((PsiClassType)lType1).resolveGenerics(); + resolveResult = ((PsiClassType) lType1).resolveGenerics(); lTypeSubstitutor = resolveResult.getSubstitutor(); psiClass = resolveResult.getElement(); } @@ -3299,7 +3294,7 @@ public static HighlightInfo.Builder createIncompatibleTypeHighlightInfo( PsiClass psiClass = resolveResult.getElement(); if (psiClass instanceof PsiAnonymousClass anonymousClass) { rType1 = anonymousClass.getBaseClassType(); - resolveResult = ((PsiClassType)rType1).resolveGenerics(); + resolveResult = ((PsiClassType) rType1).resolveGenerics(); rTypeSubstitutor = resolveResult.getSubstitutor(); psiClass = resolveResult.getElement(); } @@ -3337,7 +3332,7 @@ public static HighlightInfo.Builder createIncompatibleTypeHighlightInfo( return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(textRange) - .description(JavaErrorLocalize.incompatibleTypes(JavaHighlightUtil.formatType(lType1), JavaHighlightUtil.formatType(rType1))) + .description(JavaCompilationErrorLocalize.typeIncompatible(JavaHighlightUtil.formatType(lType1), JavaHighlightUtil.formatType(rType1))) .escapedToolTip(toolTip) .navigationShift(navigationShift); } @@ -3352,17 +3347,16 @@ public static HighlightInfo.Builder checkSingleImportClassConflict( if (statement.isOnDemand()) { return null; } - PsiElement element = statement.resolve(); - if (element instanceof PsiClass psiClass) { + if (statement.resolve() instanceof PsiClass psiClass) { String name = psiClass.getName(); Pair imported = importedClasses.get(name); PsiClass importedClass = imported == null ? null : imported.getSecond(); - if (importedClass != null && !containingFile.getManager().areElementsEquivalent(importedClass, element)) { + if (importedClass != null && !containingFile.getManager().areElementsEquivalent(importedClass, psiClass)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(statement) .descriptionAndTooltip(JavaErrorLocalize.singleImportClassConflict(formatClass(importedClass))); } - importedClasses.put(name, Pair.create(null, (PsiClass)element)); + importedClasses.put(name, Pair.create(null, psiClass)); } return null; } @@ -3397,8 +3391,8 @@ public static HighlightInfo.Builder checkMustBeThrowable( if (!TypeConversionUtil.isAssignable(throwable, type)) { HighlightInfo.Builder hlBuilder = createIncompatibleTypeHighlightInfo(throwable, type, context.getTextRange(), 0); if (addCastIntention && TypeConversionUtil.areTypesConvertible(type, throwable) - && context instanceof PsiExpression contextErpr) { - hlBuilder.registerFix(QuickFixFactory.getInstance().createAddTypeCastFix(throwable, contextErpr)); + && context instanceof PsiExpression contextExpr) { + hlBuilder.registerFix(QuickFixFactory.getInstance().createAddTypeCastFix(throwable, contextExpr)); } PsiClass aClass = PsiUtil.resolveClassInClassTypeOnly(type); @@ -3433,7 +3427,7 @@ public static HighlightInfo checkLabelDefined(@Nullable PsiIdentifier labelIdent if (exitedStatement == null) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(labelIdentifier) - .descriptionAndTooltip(JavaErrorLocalize.unresolvedLabel(label)) + .descriptionAndTooltip(JavaCompilationErrorLocalize.labelUnresolved(label)) .create(); } return null; @@ -3461,13 +3455,13 @@ public static HighlightInfo.Builder checkReference( } PsiElement refParent = ref.getParent(); - if (refParent instanceof PsiReferenceExpression && refParent.getParent() instanceof PsiMethodCallExpression methodCall) { + if (refParent instanceof PsiReferenceExpression refExpr && refExpr.getParent() instanceof PsiMethodCallExpression methodCall) { PsiReferenceExpression referenceToMethod = methodCall.getMethodExpression(); PsiExpression qualifierExpression = referenceToMethod.getQualifierExpression(); if (qualifierExpression == ref && resolved != null && !(resolved instanceof PsiClass) && !(resolved instanceof PsiVariable)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF) .range(qualifierExpression) - .descriptionAndTooltip(JavaErrorLocalize.qualifierMustBeExpression()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.referenceQualifierNotExpression()); } } else if (refParent instanceof PsiMethodCallExpression) { @@ -3489,10 +3483,10 @@ else if (refParent instanceof PsiMethodCallExpression) { if (results.length > 1) { String t1 = format(ObjectUtil.notNull(results[0].getElement())); String t2 = format(ObjectUtil.notNull(results[1].getElement())); - description = JavaErrorLocalize.ambiguousReference(refName.getText(), t1, t2); + description = JavaCompilationErrorLocalize.referenceAmbiguous(refName.getText(), t1, t2); } else { - description = JavaErrorLocalize.cannotResolveSymbol(refName.getText()); + description = JavaCompilationErrorLocalize.referenceUnresolved(refName.getText()); } HighlightInfo.Builder hlBuilder = HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF) @@ -3509,7 +3503,7 @@ else if (refParent instanceof PsiMethodCallExpression) { .descriptionAndTooltip(buildProblemWithAccessDescription(ref, result, resolved)); if (result.isStaticsScopeCorrect()) { registerAccessQuickFixAction( - (PsiMember)resolved, + (PsiMember) resolved, ref, hlBuilder, refName.getTextRange(), @@ -3536,14 +3530,14 @@ else if (refParent instanceof PsiMethodCallExpression) { } if ((resolved instanceof PsiLocalVariable || resolved instanceof PsiParameter) && !(resolved instanceof ImplicitVariable)) { - return HighlightControlFlowUtil.checkVariableMustBeFinal((PsiVariable)resolved, ref, languageLevel); + return HighlightControlFlowUtil.checkVariableMustBeFinal((PsiVariable) resolved, ref, languageLevel); } if (resolved instanceof PsiClass resolvedClass && resolvedClass.getContainingClass() == null && PsiTreeUtil.getParentOfType(ref, PsiImportStatementBase.class) != null && PsiUtil.isFromDefaultPackage(resolvedClass)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF) .range(refName) - .descriptionAndTooltip(JavaErrorLocalize.cannotResolveSymbol(refName.getText())); + .descriptionAndTooltip(JavaCompilationErrorLocalize.referenceUnresolved(refName.getText())); } return null; @@ -3584,7 +3578,7 @@ public static HighlightInfo checkPackageAndClassConflict(@Nonnull PsiJavaCodeRef if (aClass != null) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(ref) - .descriptionAndTooltip(JavaErrorLocalize.packageClashesWithClass(ref.getText())) + .descriptionAndTooltip(JavaCompilationErrorLocalize.packageClashesWithClass(ref.getText())) .create(); } } @@ -3633,7 +3627,7 @@ else if (refGrandParent instanceof PsiMethod method && method.getThrowsList() == else if (refGrandParent instanceof PsiMethod method && referenceList == method.getThrowsList()) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(ref) - .descriptionAndTooltip(JavaErrorLocalize.classNameExpected()); + .descriptionAndTooltip(JavaCompilationErrorLocalize.classReferenceListNameExpected()); } return null; } @@ -3668,7 +3662,7 @@ public static HighlightInfo checkClassReferenceAfterQualifier(@Nonnull PsiRefere } return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(qualifier) - .descriptionAndTooltip(JavaErrorLocalize.expectedClassOrPackage()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.classOrPackageExpected()) .registerFix(QuickFixFactory.getInstance().createRemoveQualifierFix(qualifier, expression, resolvedClass)) .create(); } @@ -3687,11 +3681,7 @@ public static void registerChangeVariableTypeFixes( if (method != null) { highlightInfo.registerFix(PriorityActionWrapper.lowPriority( method, - QuickFixFactory.getInstance().createMethodReturnFix( - method, - parameter.getType(), - true - ) + QuickFixFactory.getInstance().createMethodReturnFix(method, parameter.getType(), true) )); } } @@ -3721,8 +3711,8 @@ public static HighlightInfo checkAnnotationMethodParameters(@Nonnull PsiParamete if (PsiUtil.isAnnotationMethod(parent) && list.getParametersCount() > 0) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(list) - .descriptionAndTooltip(JavaErrorLocalize.annotationInterfaceMembersMayNotHaveParameters()) - .registerFix(QuickFixFactory.getInstance().createRemoveParameterListFix((PsiMethod)parent)) + .descriptionAndTooltip(JavaCompilationErrorLocalize.annotationMemberMayNotHaveParameters()) + .registerFix(QuickFixFactory.getInstance().createRemoveParameterListFix((PsiMethod) parent)) .create(); } return null; @@ -3743,7 +3733,7 @@ public static HighlightInfo checkForStatement(@Nonnull PsiForStatement statement return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(init) - .descriptionAndTooltip(JavaErrorLocalize.invalidStatement()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.statementInvalid()) .create(); } @@ -3767,7 +3757,7 @@ private static IntentionAction getChangeParameterClassFix(PsiType lType, PsiType return null; } - return QuickFixFactory.getInstance().createChangeParameterClassFix(rClass, (PsiClassType)lType); + return QuickFixFactory.getInstance().createChangeParameterClassFix(rClass, (PsiClassType) lType); } private static void registerReplaceInaccessibleFieldWithGetterSetterFix( @@ -3828,7 +3818,7 @@ public static HighlightInfo.Builder checkFeature( @RequiredReadAction private static LocalizeValue getUnsupportedFeatureMessage(PsiElement element, JavaFeature feature, LanguageLevel level, PsiFile file) { String name = feature.getFeatureName(); - LocalizeValue message = JavaErrorLocalize.insufficientLanguageLevel(name, level.getCompilerComplianceDefaultOption()); + LocalizeValue message = JavaCompilationErrorLocalize.insufficientLanguageLevel(name, level.getCompilerComplianceDefaultOption()); Module module = element.getModule(); if (module != null) { diff --git a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java index 0d5d719115..575f967aaa 100644 --- a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java +++ b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java @@ -41,6 +41,7 @@ import consulo.document.Document; import consulo.document.util.TextRange; import consulo.java.language.impl.localize.JavaErrorLocalize; +import consulo.java.language.localize.JavaCompilationErrorLocalize; import consulo.language.editor.DaemonCodeAnalyzer; import consulo.language.editor.Pass; import consulo.language.editor.rawHighlight.HighlightInfo; @@ -243,9 +244,10 @@ public static JavaResolveResult resolveJavaReference(@Nonnull PsiReference refer if (reference instanceof PsiJavaReference javaRef) { return javaRef.advancedResolve(false); } - if (reference instanceof PsiPolyVariantReference polyVariantReference && - reference instanceof ResolvingHint hint && hint.canResolveTo(PsiClass.class)) { - ResolveResult[] resolve = polyVariantReference.multiResolve(false); + if (reference instanceof PsiPolyVariantReference polyRef + && reference instanceof ResolvingHint hint + && hint.canResolveTo(PsiClass.class)) { + ResolveResult[] resolve = polyRef.multiResolve(false); if (resolve.length == 1 && resolve[0] instanceof JavaResolveResult resolveResult) { return resolveResult; } @@ -282,9 +284,7 @@ public void visitAnnotation(@Nonnull PsiAnnotation annotation) { add(AnnotationsHighlightUtil.checkRepeatableAnnotation(annotation)); } if (CommonClassNames.JAVA_LANG_OVERRIDE.equals(annotation.getQualifiedName())) { - PsiAnnotationOwner owner = annotation.getOwner(); - PsiElement parent = owner instanceof PsiModifierList modifierList ? modifierList.getParent() : null; - if (parent instanceof PsiMethod method) { + if (annotation.getOwner() instanceof PsiModifierList modifierList && modifierList.getParent() instanceof PsiMethod method) { add(GenericsHighlightUtil.checkOverrideAnnotation(method, annotation, myLanguageLevel)); } } @@ -332,7 +332,7 @@ public void visitAnnotationMethod(PsiAnnotationMethod method) { add(AnnotationsHighlightUtil.checkCyclicMemberType(method.getReturnTypeElement(), aClass)); add(AnnotationsHighlightUtil.checkClashesWithSuperMethods(method)); - if (!myHolder.hasErrorResults() && aClass != null) { + if (!myHolder.hasErrorResults()) { add(HighlightMethodUtil.checkDuplicateMethod(aClass, method, getDuplicateMethods(aClass))); } } @@ -344,10 +344,8 @@ public void visitArrayInitializerExpression(@Nonnull PsiArrayInitializerExpressi if (!myHolder.hasErrorResults()) { myHolder.add(HighlightUtil.checkArrayInitializerApplicable(expression)); } - if (!(expression.getParent() instanceof PsiNewExpression)) { - if (!myHolder.hasErrorResults()) { - myHolder.add(GenericsHighlightUtil.checkGenericArrayCreation(expression, expression.getType())); - } + if (!(expression.getParent() instanceof PsiNewExpression) && !myHolder.hasErrorResults()) { + myHolder.add(GenericsHighlightUtil.checkGenericArrayCreation(expression, expression.getType())); } } @@ -385,7 +383,7 @@ public void visitLambdaExpression(@Nonnull PsiLambdaExpression expression) { if (!myHolder.hasErrorResults() && !LambdaUtil.isValidLambdaContext(parent)) { myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip("Lambda expression not expected here") + .descriptionAndTooltip(JavaCompilationErrorLocalize.lambdaNotExpected()) .create()); } @@ -393,8 +391,8 @@ public void visitLambdaExpression(@Nonnull PsiLambdaExpression expression) { if (!myHolder.hasErrorResults()) { functionalInterfaceType = expression.getFunctionalInterfaceType(); if (functionalInterfaceType != null) { - String notFunctionalMessage = LambdaHighlightingUtil.checkInterfaceFunctional(functionalInterfaceType); - if (notFunctionalMessage != null) { + LocalizeValue notFunctionalMessage = LambdaHighlightingUtil.checkInterfaceFunctional(functionalInterfaceType); + if (notFunctionalMessage != LocalizeValue.empty()) { myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) .descriptionAndTooltip(notFunctionalMessage) @@ -407,7 +405,7 @@ public void visitLambdaExpression(@Nonnull PsiLambdaExpression expression) { else if (LambdaUtil.getFunctionalInterfaceType(expression, true) != null) { myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip("Cannot infer functional interface type") + .descriptionAndTooltip(JavaCompilationErrorLocalize.lambdaTypeInferenceFailure()) .create()); } } @@ -515,7 +513,7 @@ public void visitClassInitializer(@Nonnull PsiClassInitializer initializer) { add(HighlightControlFlowUtil.checkUnreachableStatement(initializer.getBody())); } if (!myHolder.hasErrorResults()) { - add(HighlightClassUtil.checkThingNotAllowedInInterface(initializer, initializer.getContainingClass())); + add(HighlightClassUtil.checkThingNotAllowedInInterface(initializer)); } } @@ -772,10 +770,9 @@ public void visitIdentifier(PsiIdentifier identifier) { } } - boolean isMethodParameter = variable instanceof PsiParameter parameter - && parameter.getDeclarationScope() instanceof PsiMethod; - if (isMethodParameter) { - myReassignedParameters.putInt((PsiParameter)variable, 1); // mark param as present in current file + if (variable instanceof PsiParameter parameter + && parameter.getDeclarationScope() instanceof PsiMethod) { + myReassignedParameters.putInt(parameter, 1); // mark param as present in current file } // method params are highlighted in visitMethod since we should make sure the method body was visited before else if (HighlightControlFlowUtil.isReassigned(variable, myFinalVarProblems)) { @@ -839,7 +836,7 @@ public void visitImportStaticReferenceElement(@Nonnull PsiImportStaticReferenceE PsiElement referenceNameElement = ref.getReferenceNameElement(); if (results.length == 0) { - LocalizeValue description = JavaErrorLocalize.cannotResolveSymbol(refName); + LocalizeValue description = JavaCompilationErrorLocalize.referenceUnresolved(refName); assert referenceNameElement != null : ref; HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF) .range(referenceNameElement) @@ -859,8 +856,8 @@ public void visitImportStaticReferenceElement(@Nonnull PsiImportStaticReferenceE LocalizeValue description = imported.first == null ? JavaErrorLocalize.singleImportClassConflict(refName) : imported.first.equals(ref) - ? JavaErrorLocalize.classIsAmbiguousInSingleStaticImport(refName) - : JavaErrorLocalize.classIsAlreadyDefinedInSingleStaticImport(refName); + ? JavaCompilationErrorLocalize.importSingleStaticClassAmbiguous(refName) + : JavaCompilationErrorLocalize.importSingleStaticClassAlreadyDefined(refName); myHolder.add( HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(ref) @@ -875,8 +872,8 @@ else if (element instanceof PsiField field) { PsiField importedField = imported == null ? null : imported.getSecond(); if (importedField != null && !manager.areElementsEquivalent(importedField, field)) { LocalizeValue description = imported.first.equals(ref) - ? JavaErrorLocalize.fieldIsAmbiguousInSingleStaticImport(refName) - : JavaErrorLocalize.fieldIsAlreadyDefinedInSingleStaticImport(refName); + ? JavaCompilationErrorLocalize.importSingleStaticFieldAmbiguous(refName) + : JavaCompilationErrorLocalize.importSingleStaticFieldAlreadyDefined(refName); myHolder.add( HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(ref) @@ -1015,7 +1012,7 @@ public void visitMethod(@Nonnull PsiMethod method) { PsiClass aClass = method.getContainingClass(); if (!myHolder.hasErrorResults() && method.isConstructor()) { - add(HighlightClassUtil.checkThingNotAllowedInInterface(method, aClass)); + add(HighlightClassUtil.checkThingNotAllowedInInterface(method)); } if (!myHolder.hasErrorResults() && method.hasModifierProperty(PsiModifier.DEFAULT)) { add(checkFeature(method, JavaFeature.EXTENSION_METHODS)); @@ -1083,9 +1080,9 @@ else if (parent instanceof PsiConstructorCall constructorCall) { catch (IndexNotReadyException ignored) { } } - else if (resolved instanceof PsiPackage) { + else if (resolved instanceof PsiPackage aPackage) { // highlight package (and following dot) as a class - myHolder.add(HighlightNamesUtil.highlightPackage(resolved, element, colorsScheme)); + myHolder.add(HighlightNamesUtil.highlightPackage(aPackage, element, colorsScheme)); } else if (resolved instanceof PsiClass psiClass) { myHolder.add(HighlightNamesUtil.highlightClassName(psiClass, element, colorsScheme)); @@ -1404,7 +1401,7 @@ private JavaResolveResult doVisitReferenceElement(@Nonnull PsiJavaCodeReferenceE } if (!canSelectFromTypeParameter) { myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) - .descriptionAndTooltip(LocalizeValue.localizeTODO("Cannot select from a type parameter")) + .descriptionAndTooltip(JavaCompilationErrorLocalize.referenceSelectFromTypeParameter()) .range(ref) .create()); } @@ -1449,7 +1446,8 @@ private JavaResolveResult doVisitReferenceElement(@Nonnull PsiJavaCodeReferenceE PsiElement containingClass = PsiTreeUtil.getNonStrictParentOfType(ref, PsiClass.class, PsiLambdaExpression.class); if ((containingClass instanceof PsiAnonymousClass || containingClass instanceof PsiLambdaExpression) && !PsiTreeUtil.isAncestor(containingClass, variable, false) - && !(variable instanceof PsiField) && (containingClass instanceof PsiLambdaExpression + && !(variable instanceof PsiField) + && (containingClass instanceof PsiLambdaExpression || !PsiTreeUtil.isAncestor(((PsiAnonymousClass)containingClass).getArgumentList(), ref, false))) { myHolder.add(HighlightInfo.newHighlightInfo(JavaHighlightInfoTypes.IMPLICIT_ANONYMOUS_CLASS_PARAMETER).range(ref).create()); } @@ -1481,16 +1479,15 @@ private JavaResolveResult doVisitReferenceElement(@Nonnull PsiJavaCodeReferenceE add( HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(ref) - .descriptionAndTooltip(JavaErrorLocalize.cannotResolveSymbol(namedElem.getName())) + .descriptionAndTooltip(JavaCompilationErrorLocalize.referenceUnresolved(namedElem.getName())) ); } if (!myHolder.hasErrorResults() && resolved instanceof PsiClass psiClass) { PsiClass containingClass = psiClass.getContainingClass(); if (containingClass != null) { - PsiElement qualifier = ref.getQualifier(); PsiElement place; - if (qualifier instanceof PsiJavaCodeReferenceElement javaCodeRef) { + if (ref.getQualifier() instanceof PsiJavaCodeReferenceElement javaCodeRef) { place = javaCodeRef.resolve(); } else if (parent instanceof PsiNewExpression newExpr) { @@ -1506,10 +1503,8 @@ else if (parent instanceof PsiNewExpression newExpr) { } else if (resolved instanceof PsiTypeParameter typeParam) { PsiTypeParameterListOwner owner = typeParam.getOwner(); - if (owner instanceof PsiClass outerClass) { - if (!InheritanceUtil.hasEnclosingInstanceInScope(outerClass, ref, false, false)) { - myHolder.add(HighlightClassUtil.reportIllegalEnclosingUsage(ref, null, (PsiClass)owner, ref)); - } + if (owner instanceof PsiClass outerClass && !InheritanceUtil.hasEnclosingInstanceInScope(outerClass, ref, false, false)) { + myHolder.add(HighlightClassUtil.reportIllegalEnclosingUsage(ref, null, (PsiClass) owner, ref)); } } } @@ -1725,7 +1720,7 @@ public void visitMethodReferenceExpression(@Nonnull PsiMethodReferenceExpression add( HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(LocalizeValue.localizeTODO("Method reference expression is not expected here")) + .descriptionAndTooltip(JavaCompilationErrorLocalize.methodReferenceNotExpected()) ); } @@ -1737,8 +1732,8 @@ public void visitMethodReferenceExpression(@Nonnull PsiMethodReferenceExpression add( HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(LocalizeValue.localizeTODO( - functionalInterfaceType.getPresentableText() + " is not a functional interface" + .descriptionAndTooltip(JavaCompilationErrorLocalize.lambdaNotAFunctionalInterface( + functionalInterfaceType.getPresentableText() )) ); } @@ -1753,7 +1748,7 @@ public void visitMethodReferenceExpression(@Nonnull PsiMethodReferenceExpression add( HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(qualifier) - .descriptionAndTooltip(LocalizeValue.localizeTODO("Cannot find class " + qualifier.getText())) + .descriptionAndTooltip(JavaCompilationErrorLocalize.methodReferenceQualifierClassUnresolved(qualifier.getText())) ); } } @@ -1764,8 +1759,8 @@ public void visitMethodReferenceExpression(@Nonnull PsiMethodReferenceExpression } if (!myHolder.hasErrorResults() && functionalInterfaceType != null) { - String errorMessage = PsiMethodReferenceUtil.checkMethodReferenceContext(expression); - if (errorMessage != null) { + LocalizeValue errorMessage = PsiMethodReferenceUtil.checkMethodReferenceContext(expression); + if (errorMessage != LocalizeValue.empty()) { HighlightInfo.Builder info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) .descriptionAndTooltip(errorMessage); @@ -1773,7 +1768,7 @@ public void visitMethodReferenceExpression(@Nonnull PsiMethodReferenceExpression boolean shouldHave = !method1.isStatic(); info.registerFix( QuickFixFactory.getInstance() - .createModifierFixBuilder((PsiModifierListOwner)method) + .createModifierFixBuilder(method1) .toggle(PsiModifier.STATIC, shouldHave) .create() ); @@ -1789,8 +1784,8 @@ public void visitMethodReferenceExpression(@Nonnull PsiMethodReferenceExpression myHolder.add(genericArrayCreationInfo); } else { - String wildcardMessage = PsiMethodReferenceUtil.checkTypeArguments(typeElem, psiType); - if (wildcardMessage != null) { + LocalizeValue wildcardMessage = PsiMethodReferenceUtil.checkTypeArguments(typeElem, psiType); + if (wildcardMessage != LocalizeValue.empty()) { add( HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(typeElem) @@ -1809,8 +1804,8 @@ public void visitMethodReferenceExpression(@Nonnull PsiMethodReferenceExpression } if (!myHolder.hasErrorResults()) { - String badReturnTypeMessage = PsiMethodReferenceUtil.checkReturnType(expression, result, functionalInterfaceType); - if (badReturnTypeMessage != null) { + LocalizeValue badReturnTypeMessage = PsiMethodReferenceUtil.checkReturnType(expression, result, functionalInterfaceType); + if (badReturnTypeMessage != LocalizeValue.empty()) { myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) .descriptionAndTooltip(badReturnTypeMessage) @@ -1821,9 +1816,9 @@ public void visitMethodReferenceExpression(@Nonnull PsiMethodReferenceExpression if (!myHolder.hasErrorResults()) { if (results.length == 0 || results[0] instanceof MethodCandidateInfo candidate && !candidate.isApplicable() && functionalInterfaceType != null) { - String description = null; + LocalizeValue description = null; if (results.length == 1) { - description = ((MethodCandidateInfo)results[0]).getInferenceErrorMessage(); + description = LocalizeValue.ofNullable(((MethodCandidateInfo) results[0]).getInferenceErrorMessage()); } if (expression.isConstructor()) { PsiClass containingClass = PsiMethodReferenceUtil.getQualifierResolveResult(expression).getContainingClass(); @@ -1832,11 +1827,11 @@ public void visitMethodReferenceExpression(@Nonnull PsiMethodReferenceExpression && !add(HighlightClassUtil.checkInstantiationOfAbstractClass(containingClass, expression)) && !myHolder.add(GenericsHighlightUtil.checkEnumInstantiation(expression, containingClass)) && containingClass.isPhysical() && description == null) { - description = JavaErrorLocalize.cannotResolveConstructor(containingClass.getName()).get(); + description = JavaCompilationErrorLocalize.methodReferenceUnresolvedConstructor(containingClass.getName()); } } else if (description == null) { - description = JavaErrorLocalize.cannotResolveMethod(expression.getReferenceName()).get(); + description = JavaCompilationErrorLocalize.methodReferenceUnresolvedMethod(expression.getReferenceName()); } if (description != null) { @@ -1845,10 +1840,9 @@ else if (description == null) { HighlightInfo.Builder hlBuilder = HighlightInfo.newHighlightInfo(type) .descriptionAndTooltip(description) .range(referenceNameElement) - .registerFix( - QuickFixFactory.getInstance().createCreateMethodFromUsageFix(expression), - HighlightMethodUtil.getFixRange(referenceNameElement) - ); + .newFix(QuickFixFactory.getInstance().createCreateMethodFromUsageFix(expression)) + .fixRange(HighlightMethodUtil.getFixRange(referenceNameElement)) + .register(); myHolder.add(hlBuilder.create()); } } diff --git a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/LambdaHighlightingUtil.java b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/LambdaHighlightingUtil.java index 3222135c5c..ccbb660426 100644 --- a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/LambdaHighlightingUtil.java +++ b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/LambdaHighlightingUtil.java @@ -20,144 +20,163 @@ import com.intellij.java.language.psi.util.PsiTypesUtil; import com.intellij.java.language.psi.util.PsiUtil; import com.intellij.java.language.psi.util.TypeConversionUtil; +import consulo.annotation.access.RequiredReadAction; +import consulo.java.language.localize.JavaCompilationErrorLocalize; import consulo.language.editor.rawHighlight.HighlightInfo; import consulo.language.editor.rawHighlight.HighlightInfoType; import consulo.language.psi.PsiElement; +import consulo.localize.LocalizeValue; import consulo.logging.Logger; import jakarta.annotation.Nonnull; - import jakarta.annotation.Nullable; + import java.util.HashSet; import java.util.List; import java.util.Set; /** - * User: anna + * @author anna */ public class LambdaHighlightingUtil { - private static final Logger LOG = Logger.getInstance(LambdaHighlightingUtil.class); + private static final Logger LOG = Logger.getInstance(LambdaHighlightingUtil.class); - @Nullable - public static String checkInterfaceFunctional(@Nonnull PsiClass psiClass) { - return checkInterfaceFunctional(psiClass, "Target type of a lambda conversion must be an interface"); - } - - @Nullable - public static String checkInterfaceFunctional(@Nonnull PsiClass psiClass, String interfaceNonFunctionalMessage) { - if (psiClass instanceof PsiTypeParameter) { - return null; //should be logged as cyclic inference - } - final List signatures = LambdaUtil.findFunctionCandidates(psiClass); - if (signatures == null) { - return interfaceNonFunctionalMessage; + @Nonnull + public static LocalizeValue checkInterfaceFunctional(@Nonnull PsiClass psiClass) { + return checkInterfaceFunctional(psiClass, JavaCompilationErrorLocalize.lambdaTargetNotInterface()); } - if (signatures.isEmpty()) { - return "No target method found"; - } - if (signatures.size() == 1) { - return null; + + @Nonnull + public static LocalizeValue checkInterfaceFunctional(@Nonnull PsiClass psiClass, @Nonnull LocalizeValue interfaceNonFunctionalMessage) { + if (psiClass instanceof PsiTypeParameter) { + return LocalizeValue.empty(); //should be logged as cyclic inference + } + List signatures = LambdaUtil.findFunctionCandidates(psiClass); + if (signatures == null) { + return interfaceNonFunctionalMessage; + } + if (signatures.isEmpty()) { + return JavaCompilationErrorLocalize.lambdaNoTargetMethodFound(); + } + if (signatures.size() == 1) { + return LocalizeValue.empty(); + } + return JavaCompilationErrorLocalize.lambdaMultipleSamCandidates(HighlightUtil.formatClass(psiClass)); } - return "Multiple non-overriding abstract methods found in interface " + HighlightUtil.formatClass(psiClass); - } - @Nullable - public static HighlightInfo checkParametersCompatible(PsiLambdaExpression expression, PsiParameter[] methodParameters, PsiSubstitutor substitutor) { - final PsiParameter[] lambdaParameters = expression.getParameterList().getParameters(); - String incompatibleTypesMessage = "Incompatible parameter types in lambda expression: "; - if (lambdaParameters.length != methodParameters.length) { - incompatibleTypesMessage += "wrong number of parameters: expected " + methodParameters.length + " but found " + lambdaParameters.length; - return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression.getParameterList()).descriptionAndTooltip(incompatibleTypesMessage).create(); + @Nullable + @RequiredReadAction + public static HighlightInfo checkParametersCompatible( + PsiLambdaExpression expression, + PsiParameter[] methodParams, + PsiSubstitutor substitutor + ) { + PsiParameter[] lambdaParams = expression.getParameterList().getParameters(); + if (lambdaParams.length != methodParams.length) { + return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) + .range(expression.getParameterList()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.lambdaWrongNumberOfParameters(methodParams.length, lambdaParams.length)) + .create(); + } + boolean hasFormalParameterTypes = expression.hasFormalParameterTypes(); + for (int i = 0; i < lambdaParams.length; i++) { + PsiParameter lambdaParameter = lambdaParams[i]; + PsiType lambdaParameterType = lambdaParameter.getType(); + PsiType substitutedParamType = substitutor.substitute(methodParams[i].getType()); + if (hasFormalParameterTypes && !PsiTypesUtil.compareTypes(lambdaParameterType, substitutedParamType, true) + || !TypeConversionUtil.isAssignable(substitutedParamType, lambdaParameterType)) { + String expectedType = substitutedParamType != null ? substitutedParamType.getPresentableText() : null; + String actualType = lambdaParameterType.getPresentableText(); + return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) + .range(expression.getParameterList()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.lambdaIncompatibleParameterTypes(expectedType, actualType)) + .create(); + } + } + return null; } - boolean hasFormalParameterTypes = expression.hasFormalParameterTypes(); - for (int i = 0; i < lambdaParameters.length; i++) { - PsiParameter lambdaParameter = lambdaParameters[i]; - PsiType lambdaParameterType = lambdaParameter.getType(); - PsiType substitutedParamType = substitutor.substitute(methodParameters[i].getType()); - if (hasFormalParameterTypes && !PsiTypesUtil.compareTypes(lambdaParameterType, substitutedParamType, true) || !TypeConversionUtil.isAssignable(substitutedParamType, lambdaParameterType)) { - final String expectedType = substitutedParamType != null ? substitutedParamType.getPresentableText() : null; - final String actualType = lambdaParameterType.getPresentableText(); - return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression.getParameterList()).descriptionAndTooltip(incompatibleTypesMessage + "expected " + expectedType + " " + - "but found " + actualType).create(); - } + + public static boolean insertSemicolonAfter(PsiLambdaExpression lambdaExpression) { + return lambdaExpression.getBody() instanceof PsiCodeBlock || !insertSemicolon(lambdaExpression.getParent()); } - return null; - } - public static boolean insertSemicolonAfter(PsiLambdaExpression lambdaExpression) { - return lambdaExpression.getBody() instanceof PsiCodeBlock || !insertSemicolon(lambdaExpression.getParent()); - } + public static boolean insertSemicolon(PsiElement parent) { + return parent instanceof PsiExpressionList || parent instanceof PsiExpression; + } - public static boolean insertSemicolon(PsiElement parent) { - return parent instanceof PsiExpressionList || parent instanceof PsiExpression; - } + @Nonnull + public static LocalizeValue checkInterfaceFunctional(PsiType functionalInterfaceType) { + if (functionalInterfaceType instanceof PsiIntersectionType) { + Set signatures = new HashSet<>(); + for (PsiType type : ((PsiIntersectionType) functionalInterfaceType).getConjuncts()) { + if (checkInterfaceFunctional(type) == LocalizeValue.empty()) { + MethodSignature signature = LambdaUtil.getFunction(PsiUtil.resolveClassInType(type)); + LOG.assertTrue(signature != null, type.getCanonicalText()); + signatures.add(signature); + } + } - @Nullable - public static String checkInterfaceFunctional(PsiType functionalInterfaceType) { - if (functionalInterfaceType instanceof PsiIntersectionType) { - final Set signatures = new HashSet(); - for (PsiType type : ((PsiIntersectionType) functionalInterfaceType).getConjuncts()) { - if (checkInterfaceFunctional(type) == null) { - final MethodSignature signature = LambdaUtil.getFunction(PsiUtil.resolveClassInType(type)); - LOG.assertTrue(signature != null, type.getCanonicalText()); - signatures.add(signature); + if (signatures.size() > 1) { + return JavaCompilationErrorLocalize.lambdaMultipleSamCandidates(functionalInterfaceType.getPresentableText()); + } + return LocalizeValue.empty(); } - } - - if (signatures.size() > 1) { - return "Multiple non-overriding abstract methods found in " + functionalInterfaceType.getPresentableText(); - } - return null; - } - final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType); - final PsiClass aClass = resolveResult.getElement(); - if (aClass != null) { - if (aClass instanceof PsiTypeParameter) { - return null; //should be logged as cyclic inference - } - final List signatures = LambdaUtil.findFunctionCandidates(aClass); - if (signatures != null && signatures.size() == 1) { - final MethodSignature functionalMethod = signatures.get(0); - if (functionalMethod.getTypeParameters().length > 0) { - return "Target method is generic"; + PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType); + PsiClass aClass = resolveResult.getElement(); + if (aClass != null) { + if (aClass instanceof PsiTypeParameter) { + return LocalizeValue.empty(); //should be logged as cyclic inference + } + List signatures = LambdaUtil.findFunctionCandidates(aClass); + if (signatures != null && signatures.size() == 1) { + MethodSignature functionalMethod = signatures.get(0); + if (functionalMethod.getTypeParameters().length > 0) { + return JavaCompilationErrorLocalize.lambdaSamGeneric(); + } + } + if (checkReturnTypeApplicable(resolveResult, aClass)) { + return LocalizeValue.localizeTODO( + "No instance of type " + functionalInterfaceType.getPresentableText() + + " exists so that lambda expression can be type-checked" + ); + } + return checkInterfaceFunctional(aClass); } - } - if (checkReturnTypeApplicable(resolveResult, aClass)) { - return "No instance of type " + functionalInterfaceType.getPresentableText() + " exists so that lambda expression can be type-checked"; - } - return checkInterfaceFunctional(aClass); + return JavaCompilationErrorLocalize.lambdaNotAFunctionalInterface(functionalInterfaceType.getPresentableText()); } - return functionalInterfaceType.getPresentableText() + " is not a functional interface"; - } - private static boolean checkReturnTypeApplicable(PsiClassType.ClassResolveResult resolveResult, final PsiClass aClass) { - final MethodSignature methodSignature = LambdaUtil.getFunction(aClass); - if (methodSignature == null) { - return false; - } + private static boolean checkReturnTypeApplicable(PsiClassType.ClassResolveResult resolveResult, final PsiClass aClass) { + MethodSignature methodSignature = LambdaUtil.getFunction(aClass); + if (methodSignature == null) { + return false; + } - for (PsiTypeParameter parameter : aClass.getTypeParameters()) { - if (parameter.getExtendsListTypes().length == 0) { - continue; - } - final PsiType substitution = resolveResult.getSubstitutor().substitute(parameter); - if (substitution instanceof PsiWildcardType && !((PsiWildcardType) substitution).isBounded()) { - boolean depends = false; - for (PsiType paramType : methodSignature.getParameterTypes()) { - if (LambdaUtil.depends(paramType, new LambdaUtil.TypeParamsChecker((PsiMethod) null, aClass) { - @Override - public boolean startedInference() { - return true; + for (PsiTypeParameter parameter : aClass.getTypeParameters()) { + if (parameter.getExtendsListTypes().length == 0) { + continue; + } + PsiType substitution = resolveResult.getSubstitutor().substitute(parameter); + if (substitution instanceof PsiWildcardType wildcardType && !wildcardType.isBounded()) { + boolean depends = false; + for (PsiType paramType : methodSignature.getParameterTypes()) { + if (LambdaUtil.depends( + paramType, + new LambdaUtil.TypeParamsChecker((PsiMethod) null, aClass) { + @Override + public boolean startedInference() { + return true; + } + }, + parameter + )) { + depends = true; + break; + } + } + if (!depends) { + return true; + } } - }, parameter)) { - depends = true; - break; - } - } - if (!depends) { - return true; } - } + return false; } - return false; - } } diff --git a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/ModuleHighlightUtil.java b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/ModuleHighlightUtil.java index 6a677d4cab..f61416d738 100644 --- a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/ModuleHighlightUtil.java +++ b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/ModuleHighlightUtil.java @@ -28,11 +28,10 @@ import com.intellij.java.language.psi.util.InheritanceUtil; import com.intellij.java.language.psi.util.PsiUtil; import consulo.annotation.access.RequiredReadAction; -import consulo.application.Application; import consulo.document.util.TextRange; import consulo.java.analysis.impl.localize.JavaQuickFixLocalize; import consulo.java.language.impl.localize.JavaErrorLocalize; -import consulo.language.editor.intention.QuickFixAction; +import consulo.java.language.localize.JavaCompilationErrorLocalize; import consulo.language.editor.rawHighlight.HighlightInfo; import consulo.language.editor.rawHighlight.HighlightInfoType; import consulo.language.psi.*; @@ -80,7 +79,7 @@ public static HighlightInfo checkPackageStatement( if (PsiUtil.isModuleFile(file)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(statement) - .descriptionAndTooltip(JavaErrorLocalize.moduleNoPackage()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.moduleNoPackage()) .registerFix(factory().createDeleteFix(statement)) .create(); } @@ -92,7 +91,7 @@ public static HighlightInfo checkPackageStatement( if (origin != null) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(statement) - .descriptionAndTooltip(JavaErrorLocalize.moduleConflictingPackages(packageName, origin.getName())) + .descriptionAndTooltip(JavaCompilationErrorLocalize.moduleConflictingPackages(packageName, origin.getName())) .create(); } } @@ -107,7 +106,7 @@ public static HighlightInfo checkFileName(@Nonnull PsiJavaModule element, @Nonnu if (!MODULE_INFO_FILE.equals(file.getName())) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(range(element)) - .descriptionAndTooltip(JavaErrorLocalize.moduleFileWrongName()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.moduleFileWrongName()) .registerFix(factory().createRenameFileFix(MODULE_INFO_FILE)) .create(); } @@ -124,19 +123,15 @@ public static HighlightInfo checkFileDuplicates(@Nonnull PsiJavaModule element, Collection others = FilenameIndex.getVirtualFilesByName(project, MODULE_INFO_FILE, GlobalSearchScope.moduleScope(module)); if (others.size() > 1) { - HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) + HighlightInfo.Builder hlBuilder = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(range(element)) - .descriptionAndTooltip(JavaErrorLocalize.moduleFileDuplicate()) - .create(); + .descriptionAndTooltip(JavaCompilationErrorLocalize.moduleFileDuplicate()); others.stream() .map(f -> PsiManager.getInstance(project).findFile(f)) .filter(f -> f != file) .findFirst() - .ifPresent(duplicate -> QuickFixAction.registerQuickFixAction( - info, - new GoToSymbolFix(duplicate, JavaErrorLocalize.moduleOpenDuplicateText()) - )); - return info; + .ifPresent(duplicate -> hlBuilder.registerFix(new GoToSymbolFix(duplicate, JavaErrorLocalize.moduleOpenDuplicateText()))); + return hlBuilder.create(); } } @@ -151,35 +146,35 @@ public static List checkDuplicateStatements(@Nonnull PsiJavaModul checkDuplicateRefs( module.getRequires(), st -> Optional.ofNullable(st.getReferenceElement()).map(PsiJavaModuleReferenceElement::getReferenceText), - JavaErrorLocalize::moduleDuplicateRequires, + JavaCompilationErrorLocalize::moduleDuplicateRequires, results ); checkDuplicateRefs( module.getExports(), st -> Optional.ofNullable(st.getPackageReference()).map(ModuleHighlightUtil::refText), - JavaErrorLocalize::moduleDuplicateExports, + JavaCompilationErrorLocalize::moduleDuplicateExports, results ); checkDuplicateRefs( module.getOpens(), st -> Optional.ofNullable(st.getPackageReference()).map(ModuleHighlightUtil::refText), - JavaErrorLocalize::moduleDuplicateOpens, + JavaCompilationErrorLocalize::moduleDuplicateOpens, results ); checkDuplicateRefs( module.getUses(), st -> Optional.ofNullable(st.getClassReference()).map(ModuleHighlightUtil::refText), - JavaErrorLocalize::moduleDuplicateUses, + JavaCompilationErrorLocalize::moduleDuplicateUses, results ); checkDuplicateRefs( module.getProvides(), st -> Optional.ofNullable(st.getInterfaceReference()).map(ModuleHighlightUtil::refText), - JavaErrorLocalize::moduleDuplicateProvides, + JavaCompilationErrorLocalize::moduleDuplicateProvides, results ); @@ -258,7 +253,7 @@ public static HighlightInfo checkFileLocation(@Nonnull PsiJavaModule element, @N if (root != null && !root.equals(vFile.getParent())) { return HighlightInfo.newHighlightInfo(HighlightInfoType.WARNING) .range(range(element)) - .descriptionAndTooltip(JavaErrorLocalize.moduleFileWrongLocation()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.moduleFileWrongLocation()) .registerFix(new MoveFileFix(vFile, root, JavaQuickFixLocalize.moveFileToSourceRootText())) .create(); } @@ -280,19 +275,19 @@ public static HighlightInfo checkModuleReference(@Nullable PsiJavaModuleReferenc else if (target == container) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(refElement) - .descriptionAndTooltip(JavaErrorLocalize.moduleCyclicDependence(container.getName())) + .descriptionAndTooltip(JavaCompilationErrorLocalize.moduleCyclicDependence(container.getName())) .create(); } else { Collection cycle = JavaModuleGraphUtil.findCycle((PsiJavaModule)target); - if (cycle != null && cycle.contains(container)) { + if (cycle.contains(container)) { Stream stream = cycle.stream().map(PsiJavaModule::getName); - if (Application.get().isUnitTestMode()) { + if (container.getApplication().isUnitTestMode()) { stream = stream.sorted(); } return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(refElement) - .descriptionAndTooltip(JavaErrorLocalize.moduleCyclicDependence(stream.collect(Collectors.joining(", ")))) + .descriptionAndTooltip(JavaCompilationErrorLocalize.moduleCyclicDependence(stream.collect(Collectors.joining(", ")))) .create(); } } @@ -338,7 +333,7 @@ public static HighlightInfo checkPackageReference(@Nonnull PsiPackageAccessibili if (PsiUtil.isPackageEmpty(directories, packageName)) { return HighlightInfo.newHighlightInfo(type) .range(refElement) - .descriptionAndTooltip(JavaErrorLocalize.packageIsEmpty(packageName)) + .descriptionAndTooltip(JavaCompilationErrorLocalize.moduleReferencePackageEmpty(packageName)) .create(); } } @@ -359,8 +354,8 @@ public static List checkPackageAccessTargets(@Nonnull PsiPackageA if (!targets.add(refText)) { boolean exports = statement.getRole() == Role.EXPORTS; LocalizeValue message = exports - ? JavaErrorLocalize.moduleDuplicateExportsTarget(refText) - : JavaErrorLocalize.moduleDuplicateOpensTarget(refText); + ? JavaCompilationErrorLocalize.moduleDuplicateExportsTarget(refText) + : JavaCompilationErrorLocalize.moduleDuplicateOpensTarget(refText); HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(refElement) .descriptionAndTooltip(message) @@ -371,7 +366,7 @@ public static List checkPackageAccessTargets(@Nonnull PsiPackageA else if (ref.multiResolve(true).length == 0) { results.add(HighlightInfo.newHighlightInfo(HighlightInfoType.WARNING) .range(refElement) - .descriptionAndTooltip(JavaErrorLocalize.moduleNotFound(refElement.getReferenceText())) + .descriptionAndTooltip(JavaCompilationErrorLocalize.moduleNotFound(refElement.getReferenceText())) .create()); } } @@ -387,13 +382,13 @@ public static HighlightInfo checkServiceReference(@Nullable PsiJavaCodeReference if (target == null) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(range(refElement)) - .descriptionAndTooltip(JavaErrorLocalize.cannotResolveSymbol(refElement.getReferenceName())) + .descriptionAndTooltip(JavaCompilationErrorLocalize.referenceUnresolved(refElement.getReferenceName())) .create(); } else if (target instanceof PsiClass psiClass && psiClass.isEnum()) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(range(refElement)) - .descriptionAndTooltip(JavaErrorLocalize.moduleServiceEnum(psiClass.getName())) + .descriptionAndTooltip(JavaCompilationErrorLocalize.moduleServiceEnum(psiClass.getName())) .create(); } } @@ -419,7 +414,7 @@ public static List checkServiceImplementations(@Nonnull PsiProvid if (!filter.add(refText)) { HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(implRef) - .descriptionAndTooltip(JavaErrorLocalize.moduleDuplicateImpl(refText)) + .descriptionAndTooltip(JavaCompilationErrorLocalize.moduleDuplicateImplementation(refText)) .registerFix(factory().createDeleteFix(implRef, JavaQuickFixLocalize.deleteReferenceFixText())) .create(); results.add(info); @@ -435,7 +430,7 @@ public static List checkServiceImplementations(@Nonnull PsiProvid if (findModule(statement) != findModule(implClass)) { results.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(range(implRef)) - .descriptionAndTooltip(JavaErrorLocalize.moduleServiceAlien()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.moduleServiceAlien()) .create()); } @@ -450,7 +445,7 @@ public static List checkServiceImplementations(@Nonnull PsiProvid if (!InheritanceUtil.isInheritorOrSelf(typeClass, (PsiClass)intTarget, true)) { results.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(range(implRef)) - .descriptionAndTooltip(JavaErrorLocalize.moduleServiceProviderType(implClass.getName())) + .descriptionAndTooltip(JavaCompilationErrorLocalize.moduleServiceProviderType(implClass.getName())) .create()); } } @@ -458,26 +453,26 @@ else if (InheritanceUtil.isInheritorOrSelf(implClass, (PsiClass)intTarget, true) if (implClass.isAbstract()) { results.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(range(implRef)) - .descriptionAndTooltip(JavaErrorLocalize.moduleServiceAbstract(implClass.getName())) + .descriptionAndTooltip(JavaCompilationErrorLocalize.moduleServiceAbstract(implClass.getName())) .create()); } else if (!(ClassUtil.isTopLevelClass(implClass) || implClass.isStatic())) { results.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(range(implRef)) - .descriptionAndTooltip(JavaErrorLocalize.moduleServiceInner(implClass.getName())) + .descriptionAndTooltip(JavaCompilationErrorLocalize.moduleServiceInner(implClass.getName())) .create()); } else if (!PsiUtil.hasDefaultConstructor(implClass)) { results.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(range(implRef)) - .descriptionAndTooltip(JavaErrorLocalize.moduleServiceNoCtor(implClass.getName())) + .descriptionAndTooltip(JavaCompilationErrorLocalize.moduleServiceNoConstructor(implClass.getName())) .create()); } } else { results.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(range(implRef)) - .descriptionAndTooltip(JavaErrorLocalize.moduleServiceImpl()) + .descriptionAndTooltip(JavaCompilationErrorLocalize.moduleServiceImplementationType()) .create()); } } @@ -564,7 +559,7 @@ public static HighlightInfo checkClashingReads(@Nonnull PsiJavaModule module) { if (conflict != null) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(range(module)) - .descriptionAndTooltip(JavaErrorLocalize.moduleConflictingReads( + .descriptionAndTooltip(JavaCompilationErrorLocalize.moduleConflictingReads( module.getName(), conflict.first, conflict.second.getName(), @@ -588,7 +583,7 @@ private static HighlightInfo moduleResolveError(PsiJavaModuleReferenceElement re if (ref.multiResolve(true).length == 0) { return HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF) .range(refElement) - .descriptionAndTooltip(JavaErrorLocalize.moduleNotFound(refElement.getReferenceText())) + .descriptionAndTooltip(JavaCompilationErrorLocalize.moduleNotFound(refElement.getReferenceText())) .create(); } else if (ref.multiResolve(false).length > 1) { diff --git a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/PostHighlightingVisitor.java b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/PostHighlightingVisitor.java index 3a46eb9fb5..38461a129b 100644 --- a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/PostHighlightingVisitor.java +++ b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/PostHighlightingVisitor.java @@ -155,9 +155,11 @@ public PostHighlightingVisitor( HighlightInfoType.RAW_UNUSED_SYMBOL.getAttributesKey() ); - InspectionToolWrapper unusedImportTool = Objects.requireNonNull(profile.getToolById(UnusedImportLocalInspection.SHORT_NAME, myFile)); + InspectionToolWrapper unusedImportTool = + Objects.requireNonNull(profile.getToolById(UnusedImportLocalInspection.SHORT_NAME, myFile)); - myUnusedImportHighlightType = new HighlightInfoTypeSeverityByKey(unusedImportTool.getHighlightDisplayKey(), CodeInsightColors.NOT_USED_ELEMENT_ATTRIBUTES); + myUnusedImportHighlightType = + new HighlightInfoTypeSeverityByKey(unusedImportTool.getHighlightDisplayKey(), CodeInsightColors.NOT_USED_ELEMENT_ATTRIBUTES); } @RequiredReadAction @@ -315,7 +317,7 @@ private HighlightInfo processLocalVariable( ? QuickFixFactory.getInstance().createRenameToIgnoredFix(variable) : QuickFixFactory.getInstance().createRemoveUnusedVariableFix(variable); return UnusedSymbolUtil.createUnusedSymbolInfo(identifier, message, myDeadCodeInfoType) - .registerFix(fix, null, LocalizeValue.of(), null, myDeadCodeKey) + .newFix(fix).key(myDeadCodeKey).register() .create(); } @@ -323,7 +325,7 @@ private HighlightInfo processLocalVariable( if (!referenced && !UnusedSymbolUtil.isImplicitRead(myProject, variable, progress)) { LocalizeValue message = JavaErrorLocalize.localVariableIsNotUsedForReading(identifier.getText()); return UnusedSymbolUtil.createUnusedSymbolInfo(identifier, message, myDeadCodeInfoType) - .registerFix(QuickFixFactory.getInstance().createRemoveUnusedVariableFix(variable), null, LocalizeValue.of(), null, myDeadCodeKey) + .newFix(QuickFixFactory.getInstance().createRemoveUnusedVariableFix(variable)).key(myDeadCodeKey).register() .create(); } @@ -332,7 +334,7 @@ private HighlightInfo processLocalVariable( if (!referenced && !UnusedSymbolUtil.isImplicitWrite(myProject, variable, progress)) { LocalizeValue message = JavaErrorLocalize.localVariableIsNotAssigned(identifier.getText()); return UnusedSymbolUtil.createUnusedSymbolInfo(identifier, message, myDeadCodeInfoType) - .registerFix(new EmptyIntentionAction(UnusedSymbolLocalInspectionBase.DISPLAY_NAME), null, LocalizeValue.of(), null, myDeadCodeKey) + .newFix(new EmptyIntentionAction(UnusedSymbolLocalInspectionBase.DISPLAY_NAME)).key(myDeadCodeKey).register() .create(); } } @@ -359,10 +361,9 @@ private HighlightInfo processField( HighlightInfo.Builder hlBuilder = suggestionsToMakeFieldUsed(field, identifier, message); if (!field.hasInitializer() && !field.isFinal()) { - hlBuilder.registerFix( - quickFixFactory.createCreateConstructorParameterFromFieldFix(field), - HighlightMethodUtil.getFixRange(field) - ); + hlBuilder.newFix(quickFixFactory.createCreateConstructorParameterFromFieldFix(field)) + .fixRange(HighlightMethodUtil.getFixRange(field)) + .register(); } return hlBuilder.create(); } @@ -381,12 +382,11 @@ private HighlightInfo processField( LocalizeValue message = JavaErrorLocalize.privateFieldIsNotAssigned(identifier.getText()); HighlightInfo.Builder hlBuilder = UnusedSymbolUtil.createUnusedSymbolInfo(identifier, message, myDeadCodeInfoType); - hlBuilder.registerFix(quickFixFactory.createCreateGetterOrSetterFix(false, true, field), null, LocalizeValue.of(), null, myDeadCodeKey); + hlBuilder.newFix(quickFixFactory.createCreateGetterOrSetterFix(false, true, field)).key(myDeadCodeKey).register(); if (!field.isFinal()) { - hlBuilder.registerFix( - quickFixFactory.createCreateConstructorParameterFromFieldFix(field), - HighlightMethodUtil.getFixRange(field) - ); + hlBuilder.newFix(quickFixFactory.createCreateConstructorParameterFromFieldFix(field)) + .fixRange(HighlightMethodUtil.getFixRange(field)) + .register(); } SpecialAnnotationsUtilBase.createAddToSpecialAnnotationFixes( field, @@ -406,7 +406,7 @@ else if (UnusedSymbolUtil.isFieldUnused(myProject, myFile, field, progress, help if (UnusedSymbolUtil.isImplicitWrite(myProject, field, progress)) { LocalizeValue message = JavaErrorLocalize.privateFieldIsNotUsedForReading(identifier.getText()); return UnusedSymbolUtil.createUnusedSymbolInfo(identifier, message, myDeadCodeInfoType) - .registerFix(QuickFixFactory.getInstance().createSafeDeleteFix(field), null, LocalizeValue.of(), null, myDeadCodeKey) + .newFix(QuickFixFactory.getInstance().createSafeDeleteFix(field)).key(myDeadCodeKey).register() .create(); } return formatUnusedSymbolHighlightInfo( @@ -431,10 +431,10 @@ private HighlightInfo.Builder suggestionsToMakeFieldUsed( ) { QuickFixFactory fixFactory = QuickFixFactory.getInstance(); return UnusedSymbolUtil.createUnusedSymbolInfo(identifier, message, myDeadCodeInfoType) - .registerFix(fixFactory.createRemoveUnusedVariableFix(field), null, LocalizeValue.of(), null, myDeadCodeKey) - .registerFix(fixFactory.createCreateGetterOrSetterFix(true, false, field), null, LocalizeValue.of(), null, myDeadCodeKey) - .registerFix(fixFactory.createCreateGetterOrSetterFix(false, true, field), null, LocalizeValue.of(), null, myDeadCodeKey) - .registerFix(fixFactory.createCreateGetterOrSetterFix(true, true, field), null, LocalizeValue.of(), null, myDeadCodeKey); + .newFix(fixFactory.createRemoveUnusedVariableFix(field)).key(myDeadCodeKey).register() + .newFix(fixFactory.createCreateGetterOrSetterFix(true, false, field)).key(myDeadCodeKey).register() + .newFix(fixFactory.createCreateGetterOrSetterFix(false, true, field)).key(myDeadCodeKey).register() + .newFix(fixFactory.createCreateGetterOrSetterFix(true, true, field)).key(myDeadCodeKey).register(); } private final Map isOverriddenOrOverrides = ConcurrentFactoryMap.createMap(method -> { @@ -481,7 +481,7 @@ else if (declarationScope instanceof PsiForeachStatement && !PsiUtil.isIgnoredNa HighlightInfo.Builder hlBuilder = checkUnusedParameter(parameter, identifier, progress); if (hlBuilder != null) { return hlBuilder - .registerFix(QuickFixFactory.getInstance().createRenameToIgnoredFix(parameter), null, LocalizeValue.of(), null, myDeadCodeKey) + .newFix(QuickFixFactory.getInstance().createRenameToIgnoredFix(parameter)).key(myDeadCodeKey).register() .create(); } } @@ -524,12 +524,13 @@ private HighlightInfo processMethod( } LocalizeValue symbolName = HighlightMessageUtil.getSymbolName(method, PsiSubstitutor.EMPTY); LocalizeValue message = key.apply(symbolName); - HighlightInfo.Builder hlBuilder = UnusedSymbolUtil.createUnusedSymbolInfo(identifier, message, myDeadCodeInfoType); - hlBuilder.registerFix(QuickFixFactory.getInstance().createSafeDeleteFix(method), null, LocalizeValue.of(), null, myDeadCodeKey); + QuickFixFactory fixFactory = QuickFixFactory.getInstance(); + HighlightInfo.Builder hlBuilder = UnusedSymbolUtil.createUnusedSymbolInfo(identifier, message, myDeadCodeInfoType) + .newFix(fixFactory.createSafeDeleteFix(method)).key(myDeadCodeKey).register(); SpecialAnnotationsUtilBase.createAddToSpecialAnnotationFixes( method, annoName -> { - hlBuilder.registerFix(QuickFixFactory.getInstance().createAddToDependencyInjectionAnnotationsFix(project, annoName, "methods")); + hlBuilder.registerFix(fixFactory.createAddToDependencyInjectionAnnotationsFix(project, annoName, "methods")); return true; } ); @@ -580,9 +581,9 @@ private static HighlightInfo.Builder formatUnusedSymbolHighlightInfo( ) { String symbolName = aClass.getName(); LocalizeValue message = pattern.apply(symbolName); - HighlightInfo.Builder hlBuilder = UnusedSymbolUtil.createUnusedSymbolInfo(identifier, message, highlightInfoType); QuickFixFactory fixFactory = QuickFixFactory.getInstance(); - hlBuilder.registerFix(fixFactory.createSafeDeleteFix(aClass), null, LocalizeValue.of(), null, highlightDisplayKey); + HighlightInfo.Builder hlBuilder = UnusedSymbolUtil.createUnusedSymbolInfo(identifier, message, highlightInfoType) + .newFix(fixFactory.createSafeDeleteFix(aClass)).key(highlightDisplayKey).register(); SpecialAnnotationsUtilBase.createAddToSpecialAnnotationFixes( (PsiModifierListOwner) aClass, annoName -> { @@ -641,15 +642,14 @@ private HighlightInfo registerRedundantImport( @Nonnull PsiImportStatementBase importStatement, @Nonnull HighlightDisplayKey unusedImportKey ) { - HighlightInfo info = HighlightInfo.newHighlightInfo(myUnusedImportHighlightType) + myHasRedundantImports = true; + + QuickFixFactory fixFactory = QuickFixFactory.getInstance(); + return HighlightInfo.newHighlightInfo(myUnusedImportHighlightType) .range(importStatement) .descriptionAndTooltip(InspectionLocalize.unusedImportStatement()) - .registerFix(QuickFixFactory.getInstance().createOptimizeImportsFix(false), null, LocalizeValue.of(), null, unusedImportKey) - .registerFix(QuickFixFactory.getInstance().createEnableOptimizeImportsOnTheFlyFix(), null, LocalizeValue.of(), null, unusedImportKey) + .newFix(fixFactory.createOptimizeImportsFix(false)).key(unusedImportKey).register() + .newFix(fixFactory.createEnableOptimizeImportsOnTheFlyFix()).key(unusedImportKey).register() .create(); - - myHasRedundantImports = true; - - return info; } } diff --git a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/AddTypeArgumentsConditionalFix.java b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/AddTypeArgumentsConditionalFix.java index 105a794052..e36b8cc001 100644 --- a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/AddTypeArgumentsConditionalFix.java +++ b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/AddTypeArgumentsConditionalFix.java @@ -131,9 +131,9 @@ public static void register(@Nonnull HighlightInfo.Builder hlBuilder, PsiExpress @RequiredReadAction private static void inferTypeArgs(@Nonnull HighlightInfo.Builder highlightInfo, PsiType lType, PsiExpression thenExpression) { - PsiMethodCallExpression thenMethodCall = (PsiMethodCallExpression)thenExpression; + PsiMethodCallExpression thenMethodCall = (PsiMethodCallExpression) thenExpression; JavaResolveResult result = thenMethodCall.resolveMethodGenerics(); - PsiMethod method = (PsiMethod)result.getElement(); + PsiMethod method = (PsiMethod) result.getElement(); if (method != null) { PsiType returnType = method.getReturnType(); PsiClass aClass = method.getContainingClass(); @@ -141,7 +141,7 @@ private static void inferTypeArgs(@Nonnull HighlightInfo.Builder highlightInfo, JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(method.getProject()); PsiDeclarationStatement variableDeclarationStatement = javaPsiFacade.getElementFactory() .createVariableDeclarationStatement("xxx", lType, thenExpression); - PsiExpression initializer = ((PsiLocalVariable)variableDeclarationStatement.getDeclaredElements()[0]).getInitializer(); + PsiExpression initializer = ((PsiLocalVariable) variableDeclarationStatement.getDeclaredElements()[0]).getInitializer(); LOG.assertTrue(initializer != null); PsiSubstitutor substitutor = javaPsiFacade.getResolveHelper().inferTypeArguments( @@ -154,10 +154,9 @@ private static void inferTypeArgs(@Nonnull HighlightInfo.Builder highlightInfo, ); PsiType substitutedType = substitutor.substitute(returnType); if (substitutedType != null && TypeConversionUtil.isAssignable(lType, substitutedType)) { - highlightInfo.registerFix( - new AddTypeArgumentsConditionalFix(substitutor, thenMethodCall, method), - thenExpression.getTextRange() - ); + highlightInfo.newFix(new AddTypeArgumentsConditionalFix(substitutor, thenMethodCall, method)) + .fixRange(thenExpression.getTextRange()) + .register(); } } } diff --git a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/ArgumentFixerActionFactory.java b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/ArgumentFixerActionFactory.java index 8879451524..ba922ad87e 100644 --- a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/ArgumentFixerActionFactory.java +++ b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/ArgumentFixerActionFactory.java @@ -17,8 +17,8 @@ import com.intellij.java.language.psi.*; import com.intellij.java.language.psi.infos.CandidateInfo; +import consulo.annotation.access.RequiredWriteAction; import consulo.document.util.TextRange; -import consulo.language.editor.intention.QuickFixAction; import consulo.language.editor.rawHighlight.HighlightInfo; import consulo.language.psi.PsiElement; import consulo.language.util.IncorrectOperationException; @@ -37,6 +37,7 @@ public abstract class ArgumentFixerActionFactory { @Nullable protected abstract PsiExpression getModifiedArgument(PsiExpression expression, PsiType toType) throws IncorrectOperationException; + @RequiredWriteAction public void registerCastActions(CandidateInfo[] candidates, PsiCall call, HighlightInfo.Builder hlBuilder, TextRange fixRange) { if (candidates.length == 0) { return; @@ -53,7 +54,6 @@ public void registerCastActions(CandidateInfo[] candidates, PsiCall call, Highli CandidateInfo candidate = methodCandidates.get(i); PsiMethod method = (PsiMethod)candidate.getElement(); PsiSubstitutor substitutor = candidate.getSubstitutor(); - assert method != null; PsiParameter[] parameters = method.getParameterList().getParameters(); if (expressions.length != parameters.length) { methodCandidates.remove(i); @@ -87,7 +87,6 @@ public void registerCastActions(CandidateInfo[] candidates, PsiCall call, Highli for (CandidateInfo candidate : methodCandidates) { PsiMethod method = (PsiMethod)candidate.getElement(); PsiSubstitutor substitutor = candidate.getSubstitutor(); - assert method != null; PsiParameter[] parameters = method.getParameterList().getParameters(); PsiType originalParameterType = parameters[i].getType(); PsiType parameterType = substitutor.substitute(originalParameterType); @@ -113,7 +112,7 @@ public void registerCastActions(CandidateInfo[] candidates, PsiCall call, Highli JavaResolveResult resolveResult = newCall.resolveMethodGenerics(); if (resolveResult.getElement() != null && resolveResult.isValidResult()) { suggestedCasts.add(parameterType.getCanonicalText()); - hlBuilder.registerFix(createFix(list, i, parameterType), fixRange); + hlBuilder.newFix(createFix(list, i, parameterType)).fixRange(fixRange).register(); } } } diff --git a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/ConvertDoubleToFloatFix.java b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/ConvertDoubleToFloatFix.java index 75ee486b81..f65bc016b2 100644 --- a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/ConvertDoubleToFloatFix.java +++ b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/ConvertDoubleToFloatFix.java @@ -56,8 +56,7 @@ public boolean isAvailable(@Nonnull Project project, Editor editor, PsiFile file if (myExpression.isValid()) { if (!StringUtil.endsWithIgnoreCase(myExpression.getText(), "f")) { PsiLiteralExpression expression = (PsiLiteralExpression)createFloatingPointExpression(project); - final Object value = expression.getValue(); - return value instanceof Float floatValue + return expression.getValue() instanceof Float floatValue && !floatValue.isInfinite() && !(floatValue == 0 && !TypeConversionUtil.isFPZero(expression.getText())); } @@ -73,7 +72,7 @@ public void invoke(@Nonnull Project project, Editor editor, PsiFile file) throws @RequiredReadAction private PsiExpression createFloatingPointExpression(Project project) { - final String text = myExpression.getText(); + String text = myExpression.getText(); if (StringUtil.endsWithIgnoreCase(text, "d")) { return JavaPsiFacade.getElementFactory(project) .createExpressionFromText(text.substring(0, text.length() - 1) + "f", myExpression); @@ -119,11 +118,10 @@ private static void registerIntention( if (parameters.length == expressions.length) { for (int i = 0, length = parameters.length; i < length; i++) { PsiParameter parameter = parameters[i]; - PsiExpression expression = expressions[i]; - if (expression instanceof PsiLiteralExpression + if (expressions[i] instanceof PsiLiteralExpression literal && PsiType.FLOAT.equals(parameter.getType()) - && PsiType.DOUBLE.equals(expression.getType())) { - hlBuilder.registerFix(new ConvertDoubleToFloatFix(expression), fixRange); + && PsiType.DOUBLE.equals(literal.getType())) { + hlBuilder.newFix(new ConvertDoubleToFloatFix(literal)).fixRange(fixRange).register(); } } } diff --git a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/PermuteArgumentsFix.java b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/PermuteArgumentsFix.java index d2417ebec2..65cd10d55c 100644 --- a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/PermuteArgumentsFix.java +++ b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/PermuteArgumentsFix.java @@ -136,7 +136,7 @@ public static void registerFix(HighlightInfo.Builder hlBuilder, PsiCall callExpr } } if (permutations.size() == 1) { - hlBuilder.registerFix(new PermuteArgumentsFix(callExpression, permutations.get(0)), fixRange); + hlBuilder.newFix(new PermuteArgumentsFix(callExpression, permutations.get(0))).fixRange(fixRange).register(); } } diff --git a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/QualifySuperArgumentFix.java b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/QualifySuperArgumentFix.java index d3b7a09f3d..d8e4b3c92b 100644 --- a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/QualifySuperArgumentFix.java +++ b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/QualifySuperArgumentFix.java @@ -25,13 +25,10 @@ import com.intellij.java.language.impl.refactoring.util.RefactoringChangeUtil; import com.intellij.java.language.psi.*; -import consulo.annotation.access.RequiredReadAction; import consulo.annotation.access.RequiredWriteAction; -import consulo.language.editor.intention.QuickFixAction; import consulo.language.editor.rawHighlight.HighlightInfo; import consulo.language.psi.PsiManager; import consulo.language.psi.util.PsiTreeUtil; - import jakarta.annotation.Nonnull; public class QualifySuperArgumentFix extends QualifyThisOrSuperArgumentFix { @@ -50,30 +47,24 @@ protected PsiExpression getQualifier(PsiManager manager) { return RefactoringChangeUtil.createSuperExpression(manager, myPsiClass); } - @RequiredReadAction - public static void registerQuickFixAction(@Nonnull PsiSuperExpression expr, HighlightInfo highlightInfo) { + @RequiredWriteAction + public static void registerQuickFixAction(@Nonnull PsiSuperExpression expr, HighlightInfo.Builder hlBuilder) { LOG.assertTrue(expr.getQualifier() == null); PsiClass containingClass = PsiTreeUtil.getParentOfType(expr, PsiClass.class); if (containingClass != null && containingClass.isInterface()) { - PsiMethodCallExpression callExpression = PsiTreeUtil.getParentOfType( - expr, - PsiMethodCallExpression.class - ); + PsiMethodCallExpression callExpression = PsiTreeUtil.getParentOfType(expr, PsiMethodCallExpression.class); if (callExpression != null) { PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(callExpression.getProject()); for (PsiClass superClass : containingClass.getSupers()) { if (superClass.isInterface()) { - PsiMethodCallExpression copy = (PsiMethodCallExpression)callExpression.copy(); + PsiMethodCallExpression copy = (PsiMethodCallExpression) callExpression.copy(); PsiExpression superQualifierCopy = copy.getMethodExpression().getQualifierExpression(); LOG.assertTrue(superQualifierCopy != null); superQualifierCopy.delete(); - PsiMethodCallExpression expressionFromText = - (PsiMethodCallExpression)elementFactory.createExpressionFromText(copy.getText(), superClass); - if (expressionFromText.resolveMethod() != null) { - QuickFixAction.registerQuickFixAction( - highlightInfo, - new QualifySuperArgumentFix(expr, superClass) - ); + PsiMethodCallExpression expressionFromText = + (PsiMethodCallExpression) elementFactory.createExpressionFromText(copy.getText(), superClass); + if (expressionFromText.resolveMethod() != null) { + hlBuilder.registerFix(new QualifySuperArgumentFix(expr, superClass)); } } } diff --git a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/QualifyThisArgumentFix.java b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/QualifyThisArgumentFix.java index f73859cd91..04685e58b7 100644 --- a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/QualifyThisArgumentFix.java +++ b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/QualifyThisArgumentFix.java @@ -28,6 +28,7 @@ import com.intellij.java.language.psi.infos.CandidateInfo; import com.intellij.java.language.psi.util.PsiUtil; import com.intellij.java.language.psi.util.TypeConversionUtil; +import consulo.annotation.access.RequiredReadAction; import consulo.annotation.access.RequiredWriteAction; import consulo.codeEditor.Editor; import consulo.document.util.TextRange; @@ -54,6 +55,7 @@ public QualifyThisArgumentFix(@Nonnull PsiThisExpression expression, @Nonnull Ps } @Override + @RequiredReadAction public boolean isAvailable(@Nonnull Project project, Editor editor, @Nonnull PsiElement element) { if (!myExpression.isValid()) { return false; @@ -75,13 +77,13 @@ public static void registerQuickFixAction( CandidateInfo[] candidates, PsiCall call, HighlightInfo.Builder highlightInfo, - final TextRange fixRange + TextRange fixRange ) { if (candidates.length == 0) { return; } - final Set containingClasses = new HashSet<>(); + Set containingClasses = new HashSet<>(); PsiClass parentClass = PsiTreeUtil.getParentOfType(call, PsiClass.class); while (parentClass != null) { if (parentClass.isStatic()) { @@ -96,20 +98,18 @@ public static void registerQuickFixAction( return; } - final PsiExpressionList list = call.getArgumentList(); - final PsiExpression[] expressions = list.getExpressions(); + PsiExpressionList list = call.getArgumentList(); + PsiExpression[] expressions = list.getExpressions(); if (expressions.length == 0) { return; } for (int i1 = 0, expressionsLength = expressions.length; i1 < expressionsLength; i1++) { - final PsiExpression expression = expressions[i1]; - if (expression instanceof PsiThisExpression) { - final PsiType exprType = expression.getType(); + if (expressions[i1] instanceof PsiThisExpression thisExpr) { + PsiType exprType = thisExpr.getType(); for (CandidateInfo candidate : candidates) { PsiMethod method = (PsiMethod)candidate.getElement(); PsiSubstitutor substitutor = candidate.getSubstitutor(); - assert method != null; PsiParameter[] parameters = method.getParameterList().getParameters(); if (expressions.length != parameters.length) { continue; @@ -123,9 +123,9 @@ public static void registerQuickFixAction( } if (!TypeConversionUtil.isAssignable(parameterType, exprType)) { - final PsiClass psiClass = PsiUtil.resolveClassInClassTypeOnly(parameterType); + PsiClass psiClass = PsiUtil.resolveClassInClassTypeOnly(parameterType); if (psiClass != null && containingClasses.contains(psiClass)) { - highlightInfo.registerFix(new QualifyThisArgumentFix((PsiThisExpression)expression, psiClass), fixRange); + highlightInfo.newFix(new QualifyThisArgumentFix(thisExpr, psiClass)).fixRange(fixRange).register(); } } } diff --git a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/RemoveRedundantArgumentsFix.java b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/RemoveRedundantArgumentsFix.java index 5ba5799333..2944b03363 100644 --- a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/RemoveRedundantArgumentsFix.java +++ b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/RemoveRedundantArgumentsFix.java @@ -150,7 +150,9 @@ private static void registerIntention( PsiMethod method = (PsiMethod)candidate.getElement(); PsiSubstitutor substitutor = candidate.getSubstitutor(); if (method != null && context.getManager().isInProject(method)) { - hlBuilder.registerFix(new RemoveRedundantArgumentsFix(method, arguments.getExpressions(), substitutor), fixRange); + hlBuilder.newFix(new RemoveRedundantArgumentsFix(method, arguments.getExpressions(), substitutor)) + .fixRange(fixRange) + .register(); } } } diff --git a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/WrapExpressionFix.java b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/WrapExpressionFix.java index bac1e093d8..3757a68587 100644 --- a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/WrapExpressionFix.java +++ b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/WrapExpressionFix.java @@ -188,7 +188,7 @@ && findWrapper(exprType, classType, paramType instanceof PsiPrimitiveType) != nu } if (expectedType != null) { - hlBuilder.registerFix(new WrapExpressionFix(expectedType, expr), expr.getTextRange()); + hlBuilder.newFix(new WrapExpressionFix(expectedType, expr)).fixRange(expr.getTextRange()).register(); } } } diff --git a/java-language-api/src/main/java/com/intellij/java/language/psi/PsiMethodReferenceUtil.java b/java-language-api/src/main/java/com/intellij/java/language/psi/PsiMethodReferenceUtil.java index ca44b83c90..f2b73ea84b 100644 --- a/java-language-api/src/main/java/com/intellij/java/language/psi/PsiMethodReferenceUtil.java +++ b/java-language-api/src/main/java/com/intellij/java/language/psi/PsiMethodReferenceUtil.java @@ -16,336 +16,391 @@ package com.intellij.java.language.psi; import com.intellij.java.language.psi.util.*; +import consulo.annotation.access.RequiredReadAction; +import consulo.java.language.localize.JavaCompilationErrorLocalize; import consulo.language.editor.PsiEquivalenceUtil; import consulo.language.psi.PsiElement; import consulo.language.psi.util.PsiTreeUtil; +import consulo.localize.LocalizeValue; import consulo.logging.Logger; -import consulo.util.lang.ref.Ref; - +import consulo.util.lang.ref.SimpleReference; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; /** - * User: anna + * @author anna */ public class PsiMethodReferenceUtil { - private static final Logger LOG = Logger.getInstance(PsiMethodReferenceUtil.class); - - public static boolean isSecondSearchPossible(PsiType[] parameterTypes, QualifierResolveResult qualifierResolveResult, PsiMethodReferenceExpression methodRef) { - if (parameterTypes.length > 0 && - !(parameterTypes[0] instanceof PsiPrimitiveType) && - !methodRef.isConstructor() && - isStaticallyReferenced(methodRef) && - isReceiverType(parameterTypes[0], qualifierResolveResult.getContainingClass(), qualifierResolveResult.getSubstitutor())) { - return true; + private static final Logger LOG = Logger.getInstance(PsiMethodReferenceUtil.class); + + @RequiredReadAction + public static boolean isSecondSearchPossible( + PsiType[] parameterTypes, + QualifierResolveResult qualifierResolveResult, + PsiMethodReferenceExpression methodRef + ) { + return parameterTypes.length > 0 + && !(parameterTypes[0] instanceof PsiPrimitiveType) + && !methodRef.isConstructor() + && isStaticallyReferenced(methodRef) + && isReceiverType(parameterTypes[0], qualifierResolveResult.getContainingClass(), qualifierResolveResult.getSubstitutor()); } - return false; - } - public static boolean isResolvedBySecondSearch(@Nonnull PsiMethodReferenceExpression methodRef, @Nullable MethodSignature signature, boolean varArgs, boolean isStatic, int parametersCount) { - if (signature == null) { - return false; - } - final QualifierResolveResult qualifierResolveResult = getQualifierResolveResult(methodRef); - final PsiType[] functionalMethodParameterTypes = signature.getParameterTypes(); - return (parametersCount + 1 == functionalMethodParameterTypes.length && !varArgs || varArgs && functionalMethodParameterTypes.length > 0 && !isStatic) && isSecondSearchPossible - (functionalMethodParameterTypes, qualifierResolveResult, methodRef); - } - - @Nullable - public static PsiType getQualifierType(PsiMethodReferenceExpression expression) { - final PsiTypeElement typeElement = expression.getQualifierType(); - if (typeElement != null) { - return typeElement.getType(); - } else { - PsiType qualifierType = null; - final PsiElement qualifier = expression.getQualifier(); - if (qualifier instanceof PsiExpression) { - qualifierType = ((PsiExpression) qualifier).getType(); - } - if (qualifierType == null && qualifier instanceof PsiReferenceExpression) { - return JavaPsiFacade.getElementFactory(expression.getProject()).createType((PsiReferenceExpression) qualifier); - } - return qualifierType; - } - } - - public static boolean isReturnTypeCompatible(PsiMethodReferenceExpression expression, JavaResolveResult result, PsiType functionalInterfaceType) { - return isReturnTypeCompatible(expression, result, functionalInterfaceType, null); - } - - private static boolean isReturnTypeCompatible(PsiMethodReferenceExpression expression, JavaResolveResult result, PsiType functionalInterfaceType, Ref errorMessage) { - final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType); - final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult); - if (interfaceMethod != null) { - final PsiType interfaceReturnType = LambdaUtil.getFunctionalInterfaceReturnType(functionalInterfaceType); - - if (PsiType.VOID.equals(interfaceReturnType) || interfaceReturnType == null) { - return true; - } - - PsiSubstitutor subst = result.getSubstitutor(); - - PsiType methodReturnType = null; - PsiClass containingClass = null; - final PsiElement resolve = result.getElement(); - if (resolve instanceof PsiMethod) { - containingClass = ((PsiMethod) resolve).getContainingClass(); - methodReturnType = PsiTypesUtil.patchMethodGetClassReturnType(expression, (PsiMethod) resolve); - if (methodReturnType == null) { - methodReturnType = ((PsiMethod) resolve).getReturnType(); - if (PsiType.VOID.equals(methodReturnType)) { + @RequiredReadAction + public static boolean isResolvedBySecondSearch( + @Nonnull PsiMethodReferenceExpression methodRef, + @Nullable MethodSignature signature, + boolean varArgs, + boolean isStatic, + int parametersCount + ) { + if (signature == null) { return false; - } - - PsiClass qContainingClass = getQualifierResolveResult(expression).getContainingClass(); - if (qContainingClass != null && containingClass != null && - isReceiverType(getFirstParameterType(functionalInterfaceType, expression), qContainingClass, subst)) { - subst = TypeConversionUtil.getClassSubstitutor(containingClass, qContainingClass, subst); - LOG.assertTrue(subst != null); - } + } + QualifierResolveResult qualifierResolveResult = getQualifierResolveResult(methodRef); + PsiType[] functionalMethodParameterTypes = signature.getParameterTypes(); + return (parametersCount + 1 == functionalMethodParameterTypes.length && !varArgs || varArgs && functionalMethodParameterTypes.length > 0 && !isStatic) + && isSecondSearchPossible(functionalMethodParameterTypes, qualifierResolveResult, methodRef); + } - methodReturnType = subst.substitute(methodReturnType); + @Nullable + public static PsiType getQualifierType(PsiMethodReferenceExpression expression) { + PsiTypeElement typeElement = expression.getQualifierType(); + if (typeElement != null) { + return typeElement.getType(); } - } else if (resolve instanceof PsiClass) { - if (PsiEquivalenceUtil.areElementsEquivalent(resolve, JavaPsiFacade.getElementFactory(expression.getProject()).getArrayClass(PsiUtil.getLanguageLevel(expression)))) { - final PsiTypeParameter[] typeParameters = ((PsiClass) resolve).getTypeParameters(); - if (typeParameters.length == 1) { - final PsiType arrayComponentType = subst.substitute(typeParameters[0]); - if (arrayComponentType == null) { - return false; + else { + PsiType qualifierType = null; + PsiElement qualifier = expression.getQualifier(); + if (qualifier instanceof PsiExpression qualifierExpr) { + qualifierType = qualifierExpr.getType(); } - methodReturnType = arrayComponentType.createArrayType(); - } + if (qualifierType == null && qualifier instanceof PsiReferenceExpression qRefExpr) { + return JavaPsiFacade.getElementFactory(expression.getProject()).createType(qRefExpr); + } + return qualifierType; } - containingClass = (PsiClass) resolve; - } + } - if (methodReturnType == null) { - if (containingClass == null) { - return false; - } - methodReturnType = JavaPsiFacade.getElementFactory(expression.getProject()).createType(containingClass, subst); - } + @RequiredReadAction + public static boolean isReturnTypeCompatible( + PsiMethodReferenceExpression expression, + JavaResolveResult result, + PsiType functionalInterfaceType + ) { + return isReturnTypeCompatible(expression, result, functionalInterfaceType, null); + } - methodReturnType = PsiUtil.captureToplevelWildcards(methodReturnType, expression); + @RequiredReadAction + private static boolean isReturnTypeCompatible( + PsiMethodReferenceExpression expression, + JavaResolveResult result, + PsiType functionalInterfaceType, + SimpleReference errorMessage + ) { + PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType); + PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult); + if (interfaceMethod != null) { + PsiType interfaceReturnType = LambdaUtil.getFunctionalInterfaceReturnType(functionalInterfaceType); + + if (PsiType.VOID.equals(interfaceReturnType) || interfaceReturnType == null) { + return true; + } - if (TypeConversionUtil.isAssignable(interfaceReturnType, methodReturnType)) { - return true; - } + PsiSubstitutor subst = result.getSubstitutor(); + + PsiType methodReturnType = null; + PsiClass containingClass = null; + PsiElement resolve = result.getElement(); + if (resolve instanceof PsiMethod method) { + containingClass = method.getContainingClass(); + methodReturnType = PsiTypesUtil.patchMethodGetClassReturnType(expression, method); + if (methodReturnType == null) { + methodReturnType = method.getReturnType(); + if (PsiType.VOID.equals(methodReturnType)) { + return false; + } + + PsiClass qContainingClass = getQualifierResolveResult(expression).getContainingClass(); + if (qContainingClass != null && containingClass != null + && isReceiverType(getFirstParameterType(functionalInterfaceType, expression), qContainingClass, subst)) { + subst = TypeConversionUtil.getClassSubstitutor(containingClass, qContainingClass, subst); + LOG.assertTrue(subst != null); + } + + methodReturnType = subst.substitute(methodReturnType); + } + } + else if (resolve instanceof PsiClass psiClass) { + if (PsiEquivalenceUtil.areElementsEquivalent( + psiClass, + JavaPsiFacade.getElementFactory(expression.getProject()).getArrayClass(PsiUtil.getLanguageLevel(expression)) + )) { + PsiTypeParameter[] typeParameters = psiClass.getTypeParameters(); + if (typeParameters.length == 1) { + PsiType arrayComponentType = subst.substitute(typeParameters[0]); + if (arrayComponentType == null) { + return false; + } + methodReturnType = arrayComponentType.createArrayType(); + } + } + containingClass = (PsiClass) resolve; + } - if (errorMessage != null) { - errorMessage.set("Bad return type in method reference: " + - "cannot convert " + methodReturnType.getCanonicalText() + " to " + interfaceReturnType.getCanonicalText()); - } - } - return false; - } - - public static class QualifierResolveResult { - private final PsiClass myContainingClass; - private final PsiSubstitutor mySubstitutor; - private final boolean myReferenceTypeQualified; - - public QualifierResolveResult(PsiClass containingClass, PsiSubstitutor substitutor, boolean referenceTypeQualified) { - myContainingClass = containingClass; - mySubstitutor = substitutor; - myReferenceTypeQualified = referenceTypeQualified; - } + if (methodReturnType == null) { + if (containingClass == null) { + return false; + } + methodReturnType = JavaPsiFacade.getElementFactory(expression.getProject()).createType(containingClass, subst); + } - @Nullable - public PsiClass getContainingClass() { - return myContainingClass; - } + methodReturnType = PsiUtil.captureToplevelWildcards(methodReturnType, expression); - public PsiSubstitutor getSubstitutor() { - return mySubstitutor; - } + if (TypeConversionUtil.isAssignable(interfaceReturnType, methodReturnType)) { + return true; + } - public boolean isReferenceTypeQualified() { - return myReferenceTypeQualified; - } - } - - public static boolean isValidQualifier(PsiMethodReferenceExpression expression) { - final PsiElement referenceNameElement = expression.getReferenceNameElement(); - if (referenceNameElement instanceof PsiKeyword) { - final PsiElement qualifier = expression.getQualifier(); - if (qualifier instanceof PsiTypeElement) { - return true; - } - if (qualifier instanceof PsiReferenceExpression && ((PsiReferenceExpression) qualifier).resolve() instanceof PsiClass) { - return true; - } + if (errorMessage != null) { + errorMessage.set(LocalizeValue.localizeTODO( + "Bad return type in method reference: " + + "cannot convert " + methodReturnType.getCanonicalText() + " to " + interfaceReturnType.getCanonicalText() + )); + } + } + return false; } - return false; - } - - @Nonnull - public static QualifierResolveResult getQualifierResolveResult(@Nonnull PsiMethodReferenceExpression methodReferenceExpression) { - PsiClass containingClass = null; - PsiSubstitutor substitutor = PsiSubstitutor.EMPTY; - final PsiExpression expression = methodReferenceExpression.getQualifierExpression(); - if (expression != null) { - PsiType expressionType = expression.getType(); - if (expressionType instanceof PsiCapturedWildcardType) { - expressionType = ((PsiCapturedWildcardType) expressionType).getUpperBound(); - } else { - expressionType = replaceArrayType(expressionType, expression); - } - PsiClassType.ClassResolveResult result = PsiUtil.resolveGenericsClassInType(expressionType); - containingClass = result.getElement(); - if (containingClass != null) { - substitutor = result.getSubstitutor(); - } - if (containingClass == null && expression instanceof PsiReferenceExpression) { - final JavaResolveResult resolveResult = ((PsiReferenceExpression) expression).advancedResolve(false); - final PsiElement resolve = resolveResult.getElement(); - if (resolve instanceof PsiClass) { - containingClass = (PsiClass) resolve; - substitutor = resolveResult.getSubstitutor(); - return new QualifierResolveResult(containingClass, substitutor, true); + + public static class QualifierResolveResult { + private final PsiClass myContainingClass; + private final PsiSubstitutor mySubstitutor; + private final boolean myReferenceTypeQualified; + + public QualifierResolveResult(PsiClass containingClass, PsiSubstitutor substitutor, boolean referenceTypeQualified) { + myContainingClass = containingClass; + mySubstitutor = substitutor; + myReferenceTypeQualified = referenceTypeQualified; } - } - } else { - final PsiTypeElement typeElement = methodReferenceExpression.getQualifierType(); - if (typeElement != null) { - PsiType type = replaceArrayType(typeElement.getType(), typeElement); - PsiClassType.ClassResolveResult result = PsiUtil.resolveGenericsClassInType(type); - containingClass = result.getElement(); - if (containingClass != null) { - return new QualifierResolveResult(containingClass, result.getSubstitutor(), true); + + @Nullable + public PsiClass getContainingClass() { + return myContainingClass; } - } - } - return new QualifierResolveResult(containingClass, substitutor, false); - } - public static boolean isStaticallyReferenced(@Nonnull PsiMethodReferenceExpression methodReferenceExpression) { - final PsiExpression qualifierExpression = methodReferenceExpression.getQualifierExpression(); - if (qualifierExpression != null) { - return qualifierExpression instanceof PsiReferenceExpression && ((PsiReferenceExpression) qualifierExpression).resolve() instanceof PsiClass; - } - return true; - } - - //if P1, ..., Pn is not empty and P1 is a subtype of ReferenceType, then the method reference expression is treated as - // if it were a method invocation expression with argument expressions of types P2, ...,Pn. - public static boolean isReceiverType(@Nullable PsiType receiverType, PsiClass containingClass, PsiSubstitutor psiSubstitutor) { - if (receiverType == null) { - return false; - } - return TypeConversionUtil.isAssignable(JavaPsiFacade.getElementFactory(containingClass.getProject()).createType(containingClass, psiSubstitutor), replaceArrayType(receiverType, - containingClass)); - } - - public static PsiType getFirstParameterType(PsiType functionalInterfaceType, PsiElement context) { - final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType); - final MethodSignature function = LambdaUtil.getFunction(resolveResult.getElement()); - if (function != null) { - final int interfaceMethodParamsLength = function.getParameterTypes().length; - if (interfaceMethodParamsLength > 0) { - PsiType type = resolveResult.getSubstitutor().substitute(function.getParameterTypes()[0]); - return type != null ? PsiUtil.captureToplevelWildcards(type, context) : null; - } - } - return null; - } + public PsiSubstitutor getSubstitutor() { + return mySubstitutor; + } - private static PsiType replaceArrayType(PsiType type, @Nonnull PsiElement context) { - if (type instanceof PsiArrayType) { - type = JavaPsiFacade.getElementFactory(context.getProject()).getArrayClassType(((PsiArrayType) type).getComponentType(), PsiUtil.getLanguageLevel(context)); + public boolean isReferenceTypeQualified() { + return myReferenceTypeQualified; + } } - return type; - } - public static String checkMethodReferenceContext(PsiMethodReferenceExpression methodRef) { - final PsiElement resolve = methodRef.resolve(); + @RequiredReadAction + public static boolean isValidQualifier(PsiMethodReferenceExpression expression) { + if (expression.getReferenceNameElement() instanceof PsiKeyword) { + PsiElement qualifier = expression.getQualifier(); + if (qualifier instanceof PsiTypeElement) { + return true; + } + if (qualifier instanceof PsiReferenceExpression qRefExpr && qRefExpr.resolve() instanceof PsiClass) { + return true; + } + } + return false; + } - if (resolve == null) { - return null; + @Nonnull + @RequiredReadAction + public static QualifierResolveResult getQualifierResolveResult(@Nonnull PsiMethodReferenceExpression methodReferenceExpression) { + PsiClass containingClass = null; + PsiSubstitutor substitutor = PsiSubstitutor.EMPTY; + PsiExpression expression = methodReferenceExpression.getQualifierExpression(); + if (expression != null) { + PsiType expressionType = expression.getType(); + if (expressionType instanceof PsiCapturedWildcardType capturedWildcardType) { + expressionType = capturedWildcardType.getUpperBound(); + } + else { + expressionType = replaceArrayType(expressionType, expression); + } + PsiClassType.ClassResolveResult result = PsiUtil.resolveGenericsClassInType(expressionType); + containingClass = result.getElement(); + if (containingClass != null) { + substitutor = result.getSubstitutor(); + } + if (containingClass == null && expression instanceof PsiReferenceExpression refExpr) { + JavaResolveResult resolveResult = refExpr.advancedResolve(false); + if (resolveResult.getElement() instanceof PsiClass psiClass) { + containingClass = psiClass; + substitutor = resolveResult.getSubstitutor(); + return new QualifierResolveResult(containingClass, substitutor, true); + } + } + } + else { + PsiTypeElement typeElement = methodReferenceExpression.getQualifierType(); + if (typeElement != null) { + PsiType type = replaceArrayType(typeElement.getType(), typeElement); + PsiClassType.ClassResolveResult result = PsiUtil.resolveGenericsClassInType(type); + containingClass = result.getElement(); + if (containingClass != null) { + return new QualifierResolveResult(containingClass, result.getSubstitutor(), true); + } + } + } + return new QualifierResolveResult(containingClass, substitutor, false); } - return checkMethodReferenceContext(methodRef, resolve, methodRef.getFunctionalInterfaceType()); - } - public static String checkMethodReferenceContext(PsiMethodReferenceExpression methodRef, PsiElement resolve, PsiType functionalInterfaceType) { - final PsiClass containingClass = resolve instanceof PsiMethod ? ((PsiMethod) resolve).getContainingClass() : (PsiClass) resolve; - final boolean isStaticSelector = isStaticallyReferenced(methodRef); - final PsiElement qualifier = methodRef.getQualifier(); + @RequiredReadAction + public static boolean isStaticallyReferenced(@Nonnull PsiMethodReferenceExpression methodReferenceExpression) { + PsiExpression qualifierExpression = methodReferenceExpression.getQualifierExpression(); + return qualifierExpression == null + || qualifierExpression instanceof PsiReferenceExpression refExpr && refExpr.resolve() instanceof PsiClass; + } - boolean isMethodStatic = false; - boolean receiverReferenced = false; - boolean isConstructor = true; + //if P1, ..., Pn is not empty and P1 is a subtype of ReferenceType, then the method reference expression is treated as + // if it were a method invocation expression with argument expressions of types P2, ...,Pn. + @RequiredReadAction + public static boolean isReceiverType(@Nullable PsiType receiverType, PsiClass containingClass, PsiSubstitutor psiSubstitutor) { + if (receiverType == null) { + return false; + } + return TypeConversionUtil.isAssignable( + JavaPsiFacade.getElementFactory(containingClass.getProject()).createType(containingClass, psiSubstitutor), + replaceArrayType(receiverType, containingClass) + ); + } - if (resolve instanceof PsiMethod) { - final PsiMethod method = (PsiMethod) resolve; + public static PsiType getFirstParameterType(PsiType functionalInterfaceType, PsiElement context) { + PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType); + MethodSignature function = LambdaUtil.getFunction(resolveResult.getElement()); + if (function != null) { + int interfaceMethodParamsLength = function.getParameterTypes().length; + if (interfaceMethodParamsLength > 0) { + PsiType type = resolveResult.getSubstitutor().substitute(function.getParameterTypes()[0]); + return type != null ? PsiUtil.captureToplevelWildcards(type, context) : null; + } + } + return null; + } - isMethodStatic = method.hasModifierProperty(PsiModifier.STATIC); - isConstructor = method.isConstructor(); + @RequiredReadAction + private static PsiType replaceArrayType(PsiType type, @Nonnull PsiElement context) { + if (type instanceof PsiArrayType arrayType) { + type = JavaPsiFacade.getElementFactory(context.getProject()) + .getArrayClassType(arrayType.getComponentType(), PsiUtil.getLanguageLevel(context)); + } + return type; + } - final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType); - final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult); - receiverReferenced = isResolvedBySecondSearch(methodRef, interfaceMethod != null ? interfaceMethod.getSignature(LambdaUtil.getSubstitutor(interfaceMethod, resolveResult)) : null, method - .isVarArgs(), isMethodStatic, method.getParameterList().getParametersCount()); + @Nonnull + @RequiredReadAction + public static LocalizeValue checkMethodReferenceContext(PsiMethodReferenceExpression methodRef) { + PsiElement resolve = methodRef.resolve(); - if (method.hasModifierProperty(PsiModifier.ABSTRACT) && qualifier instanceof PsiSuperExpression) { - return "Abstract method '" + method.getName() + "' cannot be accessed directly"; - } + if (resolve == null) { + return LocalizeValue.empty(); + } + return checkMethodReferenceContext(methodRef, resolve, methodRef.getFunctionalInterfaceType()); } - if (!receiverReferenced && isStaticSelector && !isMethodStatic && !isConstructor) { - return "Non-static method cannot be referenced from a static context"; - } + @Nonnull + @RequiredReadAction + public static LocalizeValue checkMethodReferenceContext( + PsiMethodReferenceExpression methodRef, + PsiElement resolve, + PsiType functionalInterfaceType + ) { + PsiClass containingClass = resolve instanceof PsiMethod method ? method.getContainingClass() : (PsiClass) resolve; + boolean isStaticSelector = isStaticallyReferenced(methodRef); + PsiElement qualifier = methodRef.getQualifier(); + + boolean isMethodStatic = false; + boolean receiverReferenced = false; + boolean isConstructor = true; + + if (resolve instanceof PsiMethod method) { + isMethodStatic = method.isStatic(); + isConstructor = method.isConstructor(); + + PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType); + PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult); + receiverReferenced = isResolvedBySecondSearch( + methodRef, + interfaceMethod != null ? interfaceMethod.getSignature(LambdaUtil.getSubstitutor(interfaceMethod, resolveResult)) : null, + method.isVarArgs(), + isMethodStatic, + method.getParameterList().getParametersCount() + ); + + if (method.isAbstract() && qualifier instanceof PsiSuperExpression) { + return JavaCompilationErrorLocalize.methodReferenceAbstractMethod(method.getName()); + } + } - if (!receiverReferenced && !isStaticSelector && isMethodStatic) { - return "Static method referenced through non-static qualifier"; - } + if (!receiverReferenced && isStaticSelector && !isMethodStatic && !isConstructor) { + return JavaCompilationErrorLocalize.methodReferenceNonStaticMethodInStaticContext(); + } - if (receiverReferenced && isStaticSelector && isMethodStatic && !isConstructor) { - return "Static method referenced through receiver"; - } + if (!receiverReferenced && !isStaticSelector && isMethodStatic) { + return JavaCompilationErrorLocalize.methodReferenceStaticMethodNonStaticQualifier(); + } - if (isMethodStatic && isStaticSelector && qualifier instanceof PsiTypeElement) { - final PsiJavaCodeReferenceElement referenceElement = PsiTreeUtil.getChildOfType(qualifier, PsiJavaCodeReferenceElement.class); - if (referenceElement != null) { - final PsiReferenceParameterList parameterList = referenceElement.getParameterList(); - if (parameterList != null && parameterList.getTypeArguments().length > 0) { - return "Parameterized qualifier on static method reference"; + if (receiverReferenced && isStaticSelector && isMethodStatic && !isConstructor) { + return JavaCompilationErrorLocalize.methodReferenceStaticMethodReceiver(); + } + + if (isMethodStatic && isStaticSelector && qualifier instanceof PsiTypeElement) { + PsiJavaCodeReferenceElement referenceElement = PsiTreeUtil.getChildOfType(qualifier, PsiJavaCodeReferenceElement.class); + if (referenceElement != null) { + PsiReferenceParameterList parameterList = referenceElement.getParameterList(); + if (parameterList != null && parameterList.getTypeArguments().length > 0) { + return JavaCompilationErrorLocalize.methodReferenceParameterizedQualifier(); + } + } } - } - } - if (isConstructor) { - if (containingClass != null && PsiUtil.isInnerClass(containingClass) && containingClass.isPhysical()) { - PsiClass outerClass = containingClass.getContainingClass(); - if (outerClass != null && !InheritanceUtil.hasEnclosingInstanceInScope(outerClass, methodRef, true, false)) { - return "An enclosing instance of type " + PsiFormatUtil.formatClass(outerClass, PsiFormatUtilBase.SHOW_NAME) + " is not in scope"; + if (isConstructor) { + if (containingClass != null && PsiUtil.isInnerClass(containingClass) && containingClass.isPhysical()) { + PsiClass outerClass = containingClass.getContainingClass(); + if (outerClass != null && !InheritanceUtil.hasEnclosingInstanceInScope(outerClass, methodRef, true, false)) { + return JavaCompilationErrorLocalize.methodReferenceEnclosingInstanceNotInScope( + PsiFormatUtil.formatClass(outerClass, PsiFormatUtilBase.SHOW_NAME) + ); + } + } } - } + return LocalizeValue.empty(); } - return null; - } - - public static String checkTypeArguments(PsiTypeElement qualifier, PsiType psiType) { - if (psiType instanceof PsiClassType) { - final PsiJavaCodeReferenceElement referenceElement = qualifier.getInnermostComponentReferenceElement(); - if (referenceElement != null) { - PsiType[] typeParameters = referenceElement.getTypeParameters(); - for (PsiType typeParameter : typeParameters) { - if (typeParameter instanceof PsiWildcardType) { - return "Unexpected wildcard"; - } + + @Nonnull + public static LocalizeValue checkTypeArguments(PsiTypeElement qualifier, PsiType psiType) { + if (psiType instanceof PsiClassType) { + PsiJavaCodeReferenceElement referenceElement = qualifier.getInnermostComponentReferenceElement(); + if (referenceElement != null) { + PsiType[] typeParameters = referenceElement.getTypeParameters(); + for (PsiType typeParameter : typeParameters) { + if (typeParameter instanceof PsiWildcardType) { + return JavaCompilationErrorLocalize.methodReferenceQualifierWildcard(); + } + } + } } - } + return LocalizeValue.empty(); } - return null; - } - public static String checkReturnType(PsiMethodReferenceExpression expression, JavaResolveResult result, PsiType functionalInterfaceType) { - final Ref errorMessage = Ref.create(); - if (!isReturnTypeCompatible(expression, result, functionalInterfaceType, errorMessage)) { - return errorMessage.get(); + @Nonnull + @RequiredReadAction + public static LocalizeValue checkReturnType( + PsiMethodReferenceExpression expression, + JavaResolveResult result, + PsiType functionalInterfaceType + ) { + SimpleReference errorMessage = SimpleReference.create(LocalizeValue.empty()); + if (!isReturnTypeCompatible(expression, result, functionalInterfaceType, errorMessage)) { + return errorMessage.get(); + } + return LocalizeValue.empty(); } - return null; - } } diff --git a/java-language-api/src/main/java/com/intellij/java/language/psi/infos/MethodCandidateInfo.java b/java-language-api/src/main/java/com/intellij/java/language/psi/infos/MethodCandidateInfo.java index bffc3af3e4..af5986becc 100644 --- a/java-language-api/src/main/java/com/intellij/java/language/psi/infos/MethodCandidateInfo.java +++ b/java-language-api/src/main/java/com/intellij/java/language/psi/infos/MethodCandidateInfo.java @@ -15,695 +15,639 @@ */ package com.intellij.java.language.psi.infos; -import com.intellij.java.language.psi.*; +import com.intellij.java.language.LanguageLevel; import com.intellij.java.language.projectRoots.JavaSdkVersion; import com.intellij.java.language.projectRoots.JavaVersionService; -import consulo.application.util.RecursionManager; -import consulo.application.util.function.Computable; -import consulo.application.util.RecursionGuard; -import com.intellij.java.language.LanguageLevel; +import com.intellij.java.language.psi.*; import com.intellij.java.language.psi.impl.source.resolve.DefaultParameterTypeInferencePolicy; import com.intellij.java.language.psi.impl.source.resolve.ParameterTypeInferencePolicy; import com.intellij.java.language.psi.util.PsiUtil; -import consulo.util.collection.ContainerUtil; -import consulo.util.lang.ThreeState; +import consulo.annotation.access.RequiredReadAction; +import consulo.application.util.RecursionGuard; +import consulo.application.util.RecursionManager; import consulo.language.psi.PsiElement; import consulo.language.psi.util.PsiTreeUtil; import consulo.project.Project; +import consulo.util.collection.Maps; +import consulo.util.lang.ThreeState; import jakarta.annotation.Nonnull; +import jakarta.annotation.Nullable; import org.intellij.lang.annotations.MagicConstant; -import jakarta.annotation.Nullable; import java.util.Map; +import java.util.function.Supplier; /** * @author ik, dsl */ -public class MethodCandidateInfo extends CandidateInfo -{ - public static final RecursionGuard ourOverloadGuard = RecursionManager.createGuard("overload.guard"); - public static final ThreadLocal> CURRENT_CANDIDATE = new ThreadLocal<>(); - @ApplicabilityLevelConstant - private volatile int myApplicabilityLevel; - @ApplicabilityLevelConstant - private volatile int myPertinentApplicabilityLevel; - private final PsiElement myArgumentList; - private final PsiType[] myArgumentTypes; - private final PsiType[] myTypeArguments; - private PsiSubstitutor myCalcedSubstitutor; - - private volatile String myInferenceError; - private final LanguageLevel myLanguageLevel; - - public MethodCandidateInfo(@Nonnull PsiElement candidate, - PsiSubstitutor substitutor, - boolean accessProblem, - boolean staticsProblem, - PsiElement argumentList, - PsiElement currFileContext, - @Nullable PsiType[] argumentTypes, - PsiType[] typeArguments) - { - this(candidate, substitutor, accessProblem, staticsProblem, argumentList, currFileContext, argumentTypes, typeArguments, PsiUtil.getLanguageLevel(argumentList)); - } - - public MethodCandidateInfo(@Nonnull PsiElement candidate, - @Nonnull PsiSubstitutor substitutor, - boolean accessProblem, - boolean staticsProblem, - PsiElement argumentList, - PsiElement currFileContext, - @Nullable PsiType[] argumentTypes, - PsiType[] typeArguments, - @Nonnull LanguageLevel languageLevel) - { - super(candidate, substitutor, accessProblem, staticsProblem, currFileContext); - myArgumentList = argumentList; - myArgumentTypes = argumentTypes; - myTypeArguments = typeArguments; - myLanguageLevel = languageLevel; - } - - public boolean isVarargs() - { - return false; - } - - public boolean isApplicable() - { - return getPertinentApplicabilityLevel() != ApplicabilityLevel.NOT_APPLICABLE; - } - - @ApplicabilityLevelConstant - private int getApplicabilityLevelInner() - { - final PsiType[] argumentTypes = getArgumentTypes(); - - if(argumentTypes == null) - { - return ApplicabilityLevel.NOT_APPLICABLE; - } - - int level = PsiUtil.getApplicabilityLevel(getElement(), getSubstitutor(), argumentTypes, myLanguageLevel); - if(level > ApplicabilityLevel.NOT_APPLICABLE && !isTypeArgumentsApplicable()) - { - level = ApplicabilityLevel.NOT_APPLICABLE; - } - return level; - } - - - @ApplicabilityLevelConstant - public int getApplicabilityLevel() - { - int result = myApplicabilityLevel; - if(result == 0) - { - result = getApplicabilityLevelInner(); - myApplicabilityLevel = result; - } - return result; - } - - @ApplicabilityLevelConstant - public int getPertinentApplicabilityLevel() - { - int result = myPertinentApplicabilityLevel; - if(result == 0) - { - myPertinentApplicabilityLevel = result = pullInferenceErrorMessagesFromSubexpressions(getPertinentApplicabilityLevelInner()); - } - return result; - } - - /** - * 15.12.2.2 Identify Matching Arity Methods Applicable by Strict Invocation - */ - @ApplicabilityLevelConstant - public int getPertinentApplicabilityLevelInner() - { - if(myArgumentList == null || !PsiUtil.isLanguageLevel8OrHigher(myArgumentList)) - { - return getApplicabilityLevel(); - } - - final PsiMethod method = getElement(); - - if(isToInferApplicability()) - { - if(!isOverloadCheck()) - { - //ensure applicability check is performed - getSubstitutor(false); - } - - //already performed checks, so if inference failed, error message should be saved - if(myInferenceError != null || isPotentiallyCompatible() != ThreeState.YES) - { - return ApplicabilityLevel.NOT_APPLICABLE; - } - return isVarargs() ? ApplicabilityLevel.VARARGS : ApplicabilityLevel.FIXED_ARITY; - } - - final PsiSubstitutor substitutor = getSubstitutor(false); - @ApplicabilityLevelConstant int level = computeForOverloadedCandidate(() -> - { - //arg types are calculated here without additional constraints: - //non-pertinent to applicability arguments of arguments would be skipped - PsiType[] argumentTypes = getArgumentTypes(); - if(argumentTypes == null) - { - return ApplicabilityLevel.NOT_APPLICABLE; - } - - int level1 = PsiUtil.getApplicabilityLevel(method, substitutor, argumentTypes, myLanguageLevel); - if(!isVarargs() && level1 < ApplicabilityLevel.FIXED_ARITY) - { - return ApplicabilityLevel.NOT_APPLICABLE; - } - return level1; - }, substitutor, isVarargs(), true); - if(level > ApplicabilityLevel.NOT_APPLICABLE && !isTypeArgumentsApplicable(() -> substitutor)) - { - level = ApplicabilityLevel.NOT_APPLICABLE; - } - return level; - } - - //If m is a generic method and the method invocation does not provide explicit type - //arguments, then the applicability of the method is inferred as specified in §18.5.1 - public boolean isToInferApplicability() - { - return myTypeArguments == null && getElement().hasTypeParameters() && !isRawSubstitution(); - } - - /** - * 15.12.2.1 Identify Potentially Applicable Methods - */ - public ThreeState isPotentiallyCompatible() - { - if(myArgumentList instanceof PsiExpressionList) - { - final PsiMethod method = getElement(); - final PsiParameter[] parameters = method.getParameterList().getParameters(); - final PsiExpression[] expressions = ((PsiExpressionList) myArgumentList).getExpressions(); - - if(!isVarargs() && myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8)) - { - if(expressions.length != parameters.length) - { - return ThreeState.NO; - } - } - else - { - if(expressions.length < parameters.length - 1) - { - return ThreeState.NO; - } - - if(parameters.length == 0 && expressions.length != parameters.length) - { - return ThreeState.NO; - } - } - - boolean unsure = false; - - for(int i = 0; i < expressions.length; i++) - { - final PsiExpression expression = expressions[i]; - PsiType formalParameterType = i < parameters.length ? parameters[i].getType() : parameters[parameters.length - 1].getType(); - - if(formalParameterType instanceof PsiEllipsisType && isVarargs()) - { - formalParameterType = ((PsiEllipsisType) formalParameterType).getComponentType(); - } - - ThreeState compatible = isPotentialCompatible(expression, getSiteSubstitutor().substitute(formalParameterType), method); - if(compatible == ThreeState.NO) - { - return ThreeState.NO; - } - - if(compatible == ThreeState.UNSURE) - { - unsure = true; - } - } - - if(unsure) - { - return ThreeState.UNSURE; - } - - if(method.hasTypeParameters() && myTypeArguments != null) - { - return ThreeState.fromBoolean(method.getTypeParameters().length == myTypeArguments.length); //todo - } - } - return ThreeState.YES; - } - - private static ThreeState isPotentialCompatible(PsiExpression expression, PsiType formalType, PsiMethod method) - { - if(expression instanceof PsiFunctionalExpression) - { - final PsiClass targetTypeParameter = PsiUtil.resolveClassInClassTypeOnly(formalType); - if(targetTypeParameter instanceof PsiTypeParameter && method.equals(((PsiTypeParameter) targetTypeParameter).getOwner())) - { - return ThreeState.YES; - } - - if(!LambdaUtil.isFunctionalType(formalType)) - { - return ThreeState.NO; - } - - if(!((PsiFunctionalExpression) expression).isPotentiallyCompatible(formalType)) - { - return ThreeState.UNSURE; - } - } - else if(expression instanceof PsiParenthesizedExpression) - { - return isPotentialCompatible(((PsiParenthesizedExpression) expression).getExpression(), formalType, method); - } - else if(expression instanceof PsiConditionalExpression) - { - ThreeState thenCompatible = isPotentialCompatible(((PsiConditionalExpression) expression).getThenExpression(), formalType, method); - ThreeState elseCompatible = isPotentialCompatible(((PsiConditionalExpression) expression).getElseExpression(), formalType, method); - if(thenCompatible == ThreeState.NO || elseCompatible == ThreeState.NO) - { - return ThreeState.NO; - } - if(thenCompatible == ThreeState.UNSURE || elseCompatible == ThreeState.UNSURE) - { - return ThreeState.UNSURE; - } - } - return ThreeState.YES; - } - - private T computeForOverloadedCandidate(final Computable computable, final PsiSubstitutor substitutor, boolean varargs, boolean applicabilityCheck) - { - Map map = CURRENT_CANDIDATE.get(); - if(map == null) - { - map = ContainerUtil.createConcurrentWeakMap(); - CURRENT_CANDIDATE.set(map); - } - final PsiElement argumentList = getMarkerList(); - final CurrentCandidateProperties alreadyThere = map.put(argumentList, new CurrentCandidateProperties(this, substitutor, varargs, applicabilityCheck)); - try - { - return computable.compute(); - } - finally - { - if(alreadyThere == null) - { - map.remove(argumentList); - } - else - { - map.put(argumentList, alreadyThere); - } - } - } - - @Nonnull - public PsiSubstitutor getSiteSubstitutor() - { - PsiSubstitutor incompleteSubstitutor = super.getSubstitutor(); - if(myTypeArguments != null) - { - PsiMethod method = getElement(); - PsiTypeParameter[] typeParams = method.getTypeParameters(); - for(int i = 0; i < myTypeArguments.length && i < typeParams.length; i++) - { - incompleteSubstitutor = incompleteSubstitutor.put(typeParams[i], myTypeArguments[i]); - } - } - return incompleteSubstitutor; - } - - @Nonnull - @Override - public PsiSubstitutor getSubstitutor() - { - return getSubstitutor(true); - } - - @Nonnull - public PsiSubstitutor getSubstitutor(boolean includeReturnConstraint) - { - PsiSubstitutor substitutor = myCalcedSubstitutor; - if(substitutor == null || !includeReturnConstraint && myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8) || isOverloadCheck()) - { - - PsiSubstitutor incompleteSubstitutor = super.getSubstitutor(); - PsiMethod method = getElement(); - if(myTypeArguments == null) - { - RecursionGuard.StackStamp stackStamp = RecursionManager.markStack(); - - final PsiSubstitutor inferredSubstitutor = inferTypeArguments(DefaultParameterTypeInferencePolicy.INSTANCE, includeReturnConstraint); - - if(!stackStamp.mayCacheNow() || isOverloadCheck() || !includeReturnConstraint && myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8) || getMarkerList() != null && PsiResolveHelper - .ourGraphGuard.currentStack().contains(getMarkerList().getParent()) || LambdaUtil.isLambdaParameterCheck()) - { - return inferredSubstitutor; - } - - myCalcedSubstitutor = substitutor = inferredSubstitutor; - } - else - { - PsiTypeParameter[] typeParams = method.getTypeParameters(); - for(int i = 0; i < myTypeArguments.length && i < typeParams.length; i++) - { - incompleteSubstitutor = incompleteSubstitutor.put(typeParams[i], myTypeArguments[i]); - } - myCalcedSubstitutor = substitutor = incompleteSubstitutor; - } - } - - return substitutor; - } - - public static boolean isOverloadCheck() - { - return !ourOverloadGuard.currentStack().isEmpty(); - } - - public static boolean isOverloadCheck(PsiElement argumentList) - { - return ourOverloadGuard.currentStack().contains(argumentList); - } - - public boolean isTypeArgumentsApplicable() - { - return isTypeArgumentsApplicable(() -> getSubstitutor(false)); - } - - private boolean isTypeArgumentsApplicable(Computable computable) - { - final PsiMethod psiMethod = getElement(); - PsiTypeParameter[] typeParams = psiMethod.getTypeParameters(); - if(myTypeArguments != null && typeParams.length != myTypeArguments.length && !PsiUtil.isLanguageLevel7OrHigher(psiMethod)) - { - return typeParams.length == 0 && JavaVersionService.getInstance().isAtLeast(psiMethod, JavaSdkVersion.JDK_1_7); - } - return GenericsUtil.isTypeArgumentsApplicable(typeParams, computable.compute(), getParent()); - } - - protected PsiElement getParent() - { - return myArgumentList != null ? myArgumentList.getParent() : null; - } - - @Override - public boolean isValidResult() - { - return super.isValidResult() && isApplicable(); - } - - @Nonnull - @Override - public PsiMethod getElement() - { - return (PsiMethod) super.getElement(); - } - - @Nonnull - public PsiSubstitutor inferTypeArguments(@Nonnull ParameterTypeInferencePolicy policy, boolean includeReturnConstraint) - { - return inferTypeArguments(policy, myArgumentList instanceof PsiExpressionList ? ((PsiExpressionList) myArgumentList).getExpressions() : PsiExpression.EMPTY_ARRAY, includeReturnConstraint); - } - - public PsiSubstitutor inferSubstitutorFromArgs(@Nonnull ParameterTypeInferencePolicy policy, final PsiExpression[] arguments) - { - if(myTypeArguments == null) - { - return inferTypeArguments(policy, arguments, true); - } - else - { - return getSiteSubstitutor(); - } - } - - /** - * If iterated through all candidates, should be called under {@link #ourOverloadGuard} guard so results won't be cached on the top level call - */ - @Nonnull - public PsiSubstitutor inferTypeArguments(@Nonnull final ParameterTypeInferencePolicy policy, @Nonnull final PsiExpression[] arguments, boolean includeReturnConstraint) - { - return computeForOverloadedCandidate(() -> - { - final PsiMethod method = this.getElement(); - PsiTypeParameter[] typeParameters = method.getTypeParameters(); - - if(this.isRawSubstitution()) - { - return JavaPsiFacade.getInstance(method.getProject()).getElementFactory().createRawSubstitutor(mySubstitutor, typeParameters); - } - - final PsiElement parent = this.getParent(); - if(parent == null) - { - return PsiSubstitutor.EMPTY; - } - Project project = method.getProject(); - JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(project); - return javaPsiFacade.getResolveHelper().inferTypeArguments(typeParameters, method.getParameterList().getParameters(), arguments, mySubstitutor, parent, policy, myLanguageLevel); - }, super.getSubstitutor(), policy.isVarargsIgnored() || isVarargs(), !includeReturnConstraint); - } - - public boolean isRawSubstitution() - { - final PsiMethod method = getElement(); - if(!method.hasModifierProperty(PsiModifier.STATIC)) - { - final PsiClass containingClass = method.getContainingClass(); - if(containingClass != null && PsiUtil.isRawSubstitutor(containingClass, mySubstitutor)) - { - return true; - } - } - return false; - } - - protected PsiElement getMarkerList() - { - return myArgumentList; - } - - public boolean isInferencePossible() - { - return myArgumentList != null && myArgumentList.isValid(); - } - - - public static CurrentCandidateProperties getCurrentMethod(PsiElement context) - { - final Map currentMethodCandidates = CURRENT_CANDIDATE.get(); - return currentMethodCandidates != null ? currentMethodCandidates.get(context) : null; - } - - public static void updateSubstitutor(PsiElement context, PsiSubstitutor newSubstitutor) - { - CurrentCandidateProperties candidateProperties = getCurrentMethod(context); - if(candidateProperties != null) - { - candidateProperties.setSubstitutor(newSubstitutor); - } - } - - @Nullable - public PsiType[] getArgumentTypes() - { - return myArgumentTypes; - } - - @Override - public boolean equals(Object o) - { - return super.equals(o) && isVarargs() == ((MethodCandidateInfo) o).isVarargs(); - } - - @Override - public int hashCode() - { - return 31 * super.hashCode() + (isVarargs() ? 1 : 0); - } - - public void setInferenceError(String inferenceError) - { - myInferenceError = inferenceError; - } - - public String getInferenceErrorMessage() - { - return myInferenceError; - } - - public String getParentInferenceErrorMessage(PsiExpressionList list) - { - String errorMessage = getInferenceErrorMessage(); - while(errorMessage == null) - { - list = PsiTreeUtil.getParentOfType(list, PsiExpressionList.class, true, PsiCodeBlock.class); - if(list == null) - { - break; - } - final PsiElement parent = list.getParent(); - if(!(parent instanceof PsiCallExpression)) - { - break; - } - final JavaResolveResult resolveResult = ((PsiCallExpression) parent).resolveMethodGenerics(); - if(resolveResult instanceof MethodCandidateInfo) - { - errorMessage = ((MethodCandidateInfo) resolveResult).getInferenceErrorMessage(); - } - } - return errorMessage; - } - - @ApplicabilityLevelConstant - private int pullInferenceErrorMessagesFromSubexpressions(@ApplicabilityLevelConstant int level) - { - if(myArgumentList instanceof PsiExpressionList && level == ApplicabilityLevel.NOT_APPLICABLE) - { - String errorMessage = null; - for(PsiExpression expression : ((PsiExpressionList) myArgumentList).getExpressions()) - { - final String message = clearErrorMessageInSubexpressions(expression); - if(message != null) - { - errorMessage = message; - } - } - if(errorMessage != null) - { - setInferenceError(errorMessage); - } - } - return level; - } - - private static String clearErrorMessageInSubexpressions(PsiExpression expression) - { - expression = PsiUtil.skipParenthesizedExprDown(expression); - if(expression instanceof PsiConditionalExpression) - { - String thenErrorMessage = clearErrorMessageInSubexpressions(((PsiConditionalExpression) expression).getThenExpression()); - String elseErrorMessage = clearErrorMessageInSubexpressions(((PsiConditionalExpression) expression).getElseExpression()); - if(thenErrorMessage != null) - { - return thenErrorMessage; - } - return elseErrorMessage; - } - else if(expression instanceof PsiCallExpression) - { - final JavaResolveResult result; - if(expression instanceof PsiNewExpression) - { - PsiDiamondType diamondType = PsiDiamondType.getDiamondType((PsiNewExpression) expression); - result = diamondType != null ? diamondType.getStaticFactory() : ((PsiCallExpression) expression).resolveMethodGenerics(); - } - else - { - result = ((PsiCallExpression) expression).resolveMethodGenerics(); - } - if(result instanceof MethodCandidateInfo) - { - final String message = ((MethodCandidateInfo) result).getInferenceErrorMessage(); - ((MethodCandidateInfo) result).setInferenceError(null); - return message; - } - } - return null; - } - - public CurrentCandidateProperties createProperties() - { - return new CurrentCandidateProperties(this, getSiteSubstitutor(), isVarargs(), false); - } - - public static class CurrentCandidateProperties - { - private final MethodCandidateInfo myMethod; - private PsiSubstitutor mySubstitutor; - private boolean myVarargs; - private boolean myApplicabilityCheck; - - private CurrentCandidateProperties(MethodCandidateInfo info, PsiSubstitutor substitutor, boolean varargs, boolean applicabilityCheck) - { - myMethod = info; - mySubstitutor = substitutor; - myVarargs = varargs; - myApplicabilityCheck = applicabilityCheck; - } - - public PsiMethod getMethod() - { - return myMethod.getElement(); - } - - public MethodCandidateInfo getInfo() - { - return myMethod; - } - - public PsiSubstitutor getSubstitutor() - { - return mySubstitutor; - } - - public void setSubstitutor(PsiSubstitutor substitutor) - { - mySubstitutor = substitutor; - } - - public boolean isVarargs() - { - return myVarargs; - } - - public void setVarargs(boolean varargs) - { - myVarargs = varargs; - } - - public boolean isApplicabilityCheck() - { - return myApplicabilityCheck; - } - - public void setApplicabilityCheck(boolean applicabilityCheck) - { - myApplicabilityCheck = applicabilityCheck; - } - } - - public static class ApplicabilityLevel - { - public static final int NOT_APPLICABLE = 1; - public static final int VARARGS = 2; - public static final int FIXED_ARITY = 3; - } - - @MagicConstant(intValues = { - ApplicabilityLevel.NOT_APPLICABLE, - ApplicabilityLevel.VARARGS, - ApplicabilityLevel.FIXED_ARITY - }) - public @interface ApplicabilityLevelConstant - { - } +public class MethodCandidateInfo extends CandidateInfo { + public static final RecursionGuard ourOverloadGuard = RecursionManager.createGuard("overload.guard"); + public static final ThreadLocal> CURRENT_CANDIDATE = new ThreadLocal<>(); + @ApplicabilityLevelConstant + private volatile int myApplicabilityLevel; + @ApplicabilityLevelConstant + private volatile int myPertinentApplicabilityLevel; + private final PsiElement myArgumentList; + private final PsiType[] myArgumentTypes; + private final PsiType[] myTypeArguments; + private PsiSubstitutor myCalcedSubstitutor; + + private volatile String myInferenceError; + private final LanguageLevel myLanguageLevel; + + @RequiredReadAction + public MethodCandidateInfo( + @Nonnull PsiElement candidate, + PsiSubstitutor substitutor, + boolean accessProblem, + boolean staticsProblem, + PsiElement argumentList, + PsiElement currFileContext, + @Nullable PsiType[] argumentTypes, + PsiType[] typeArguments + ) { + this( + candidate, + substitutor, + accessProblem, + staticsProblem, + argumentList, + currFileContext, + argumentTypes, + typeArguments, + PsiUtil.getLanguageLevel(argumentList) + ); + } + + public MethodCandidateInfo( + @Nonnull PsiElement candidate, + @Nonnull PsiSubstitutor substitutor, + boolean accessProblem, + boolean staticsProblem, + PsiElement argumentList, + PsiElement currFileContext, + @Nullable PsiType[] argumentTypes, + PsiType[] typeArguments, + @Nonnull LanguageLevel languageLevel + ) { + super(candidate, substitutor, accessProblem, staticsProblem, currFileContext); + myArgumentList = argumentList; + myArgumentTypes = argumentTypes; + myTypeArguments = typeArguments; + myLanguageLevel = languageLevel; + } + + public boolean isVarargs() { + return false; + } + + public boolean isApplicable() { + return getPertinentApplicabilityLevel() != ApplicabilityLevel.NOT_APPLICABLE; + } + + @ApplicabilityLevelConstant + @RequiredReadAction + private int getApplicabilityLevelInner() { + PsiType[] argumentTypes = getArgumentTypes(); + + if (argumentTypes == null) { + return ApplicabilityLevel.NOT_APPLICABLE; + } + + int level = PsiUtil.getApplicabilityLevel(getElement(), getSubstitutor(), argumentTypes, myLanguageLevel); + if (level > ApplicabilityLevel.NOT_APPLICABLE && !isTypeArgumentsApplicable()) { + level = ApplicabilityLevel.NOT_APPLICABLE; + } + return level; + } + + @ApplicabilityLevelConstant + @RequiredReadAction + public int getApplicabilityLevel() { + int result = myApplicabilityLevel; + if (result == 0) { + result = getApplicabilityLevelInner(); + myApplicabilityLevel = result; + } + return result; + } + + @ApplicabilityLevelConstant + @RequiredReadAction + public int getPertinentApplicabilityLevel() { + int result = myPertinentApplicabilityLevel; + if (result == 0) { + myPertinentApplicabilityLevel = result = pullInferenceErrorMessagesFromSubexpressions(getPertinentApplicabilityLevelInner()); + } + return result; + } + + /** + * 15.12.2.2 Identify Matching Arity Methods Applicable by Strict Invocation + */ + @ApplicabilityLevelConstant + @RequiredReadAction + public int getPertinentApplicabilityLevelInner() { + if (myArgumentList == null || !PsiUtil.isLanguageLevel8OrHigher(myArgumentList)) { + return getApplicabilityLevel(); + } + + PsiMethod method = getElement(); + + if (isToInferApplicability()) { + if (!isOverloadCheck()) { + //ensure applicability check is performed + getSubstitutor(false); + } + + //already performed checks, so if inference failed, error message should be saved + if (myInferenceError != null || isPotentiallyCompatible() != ThreeState.YES) { + return ApplicabilityLevel.NOT_APPLICABLE; + } + return isVarargs() ? ApplicabilityLevel.VARARGS : ApplicabilityLevel.FIXED_ARITY; + } + + PsiSubstitutor substitutor = getSubstitutor(false); + @ApplicabilityLevelConstant + int level = computeForOverloadedCandidate( + () -> { + //arg types are calculated here without additional constraints: + //non-pertinent to applicability arguments of arguments would be skipped + PsiType[] argumentTypes = getArgumentTypes(); + if (argumentTypes == null) { + return ApplicabilityLevel.NOT_APPLICABLE; + } + + int level1 = PsiUtil.getApplicabilityLevel(method, substitutor, argumentTypes, myLanguageLevel); + if (!isVarargs() && level1 < ApplicabilityLevel.FIXED_ARITY) { + return ApplicabilityLevel.NOT_APPLICABLE; + } + return level1; + }, + substitutor, + isVarargs(), + true + ); + if (level > ApplicabilityLevel.NOT_APPLICABLE && !isTypeArgumentsApplicable(() -> substitutor)) { + level = ApplicabilityLevel.NOT_APPLICABLE; + } + return level; + } + + //If m is a generic method and the method invocation does not provide explicit type + //arguments, then the applicability of the method is inferred as specified in §18.5.1 + public boolean isToInferApplicability() { + return myTypeArguments == null && getElement().hasTypeParameters() && !isRawSubstitution(); + } + + /** + * 15.12.2.1 Identify Potentially Applicable Methods + */ + public ThreeState isPotentiallyCompatible() { + if (myArgumentList instanceof PsiExpressionList exprList) { + PsiMethod method = getElement(); + PsiParameter[] parameters = method.getParameterList().getParameters(); + PsiExpression[] expressions = exprList.getExpressions(); + + if (!isVarargs() && myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8)) { + if (expressions.length != parameters.length) { + return ThreeState.NO; + } + } + else { + if (expressions.length < parameters.length - 1) { + return ThreeState.NO; + } + + if (parameters.length == 0 && expressions.length != parameters.length) { + return ThreeState.NO; + } + } + + boolean unsure = false; + + for (int i = 0; i < expressions.length; i++) { + PsiExpression expression = expressions[i]; + PsiType formalParameterType = i < parameters.length ? parameters[i].getType() : parameters[parameters.length - 1].getType(); + + if (formalParameterType instanceof PsiEllipsisType && isVarargs()) { + formalParameterType = ((PsiEllipsisType) formalParameterType).getComponentType(); + } + + ThreeState compatible = isPotentialCompatible(expression, getSiteSubstitutor().substitute(formalParameterType), method); + if (compatible == ThreeState.NO) { + return ThreeState.NO; + } + + if (compatible == ThreeState.UNSURE) { + unsure = true; + } + } + + if (unsure) { + return ThreeState.UNSURE; + } + + if (method.hasTypeParameters() && myTypeArguments != null) { + return ThreeState.fromBoolean(method.getTypeParameters().length == myTypeArguments.length); //todo + } + } + return ThreeState.YES; + } + + private static ThreeState isPotentialCompatible(PsiExpression expression, PsiType formalType, PsiMethod method) { + if (expression instanceof PsiFunctionalExpression funcExpr) { + PsiClass targetTypeParameter = PsiUtil.resolveClassInClassTypeOnly(formalType); + if (targetTypeParameter instanceof PsiTypeParameter typeParam && method.equals(typeParam.getOwner())) { + return ThreeState.YES; + } + + if (!LambdaUtil.isFunctionalType(formalType)) { + return ThreeState.NO; + } + + if (!funcExpr.isPotentiallyCompatible(formalType)) { + return ThreeState.UNSURE; + } + } + else if (expression instanceof PsiParenthesizedExpression parenExpr) { + return isPotentialCompatible(parenExpr.getExpression(), formalType, method); + } + else if (expression instanceof PsiConditionalExpression conditional) { + ThreeState thenCompatible = isPotentialCompatible(conditional.getThenExpression(), formalType, method); + ThreeState elseCompatible = isPotentialCompatible(conditional.getElseExpression(), formalType, method); + if (thenCompatible == ThreeState.NO || elseCompatible == ThreeState.NO) { + return ThreeState.NO; + } + if (thenCompatible == ThreeState.UNSURE || elseCompatible == ThreeState.UNSURE) { + return ThreeState.UNSURE; + } + } + return ThreeState.YES; + } + + private T computeForOverloadedCandidate( + Supplier computable, + PsiSubstitutor substitutor, + boolean varargs, + boolean applicabilityCheck + ) { + Map map = CURRENT_CANDIDATE.get(); + if (map == null) { + map = Maps.newConcurrentWeakHashMap(); + CURRENT_CANDIDATE.set(map); + } + PsiElement argumentList = getMarkerList(); + CurrentCandidateProperties alreadyThere = + map.put(argumentList, new CurrentCandidateProperties(this, substitutor, varargs, applicabilityCheck)); + try { + return computable.get(); + } + finally { + if (alreadyThere == null) { + map.remove(argumentList); + } + else { + map.put(argumentList, alreadyThere); + } + } + } + + @Nonnull + public PsiSubstitutor getSiteSubstitutor() { + PsiSubstitutor incompleteSubstitutor = super.getSubstitutor(); + if (myTypeArguments != null) { + PsiMethod method = getElement(); + PsiTypeParameter[] typeParams = method.getTypeParameters(); + for (int i = 0; i < myTypeArguments.length && i < typeParams.length; i++) { + incompleteSubstitutor = incompleteSubstitutor.put(typeParams[i], myTypeArguments[i]); + } + } + return incompleteSubstitutor; + } + + @Nonnull + @Override + public PsiSubstitutor getSubstitutor() { + return getSubstitutor(true); + } + + @Nonnull + public PsiSubstitutor getSubstitutor(boolean includeReturnConstraint) { + PsiSubstitutor substitutor = myCalcedSubstitutor; + if (substitutor == null || !includeReturnConstraint && myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8) || isOverloadCheck()) { + + PsiSubstitutor incompleteSubstitutor = super.getSubstitutor(); + PsiMethod method = getElement(); + if (myTypeArguments == null) { + RecursionGuard.StackStamp stackStamp = RecursionManager.markStack(); + + PsiSubstitutor inferredSubstitutor = + inferTypeArguments(DefaultParameterTypeInferencePolicy.INSTANCE, includeReturnConstraint); + + if (!stackStamp.mayCacheNow() + || isOverloadCheck() + || !includeReturnConstraint && myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8) + || getMarkerList() != null && PsiResolveHelper.ourGraphGuard.currentStack().contains(getMarkerList().getParent()) + || LambdaUtil.isLambdaParameterCheck()) { + return inferredSubstitutor; + } + + myCalcedSubstitutor = substitutor = inferredSubstitutor; + } + else { + PsiTypeParameter[] typeParams = method.getTypeParameters(); + for (int i = 0; i < myTypeArguments.length && i < typeParams.length; i++) { + incompleteSubstitutor = incompleteSubstitutor.put(typeParams[i], myTypeArguments[i]); + } + myCalcedSubstitutor = substitutor = incompleteSubstitutor; + } + } + + return substitutor; + } + + public static boolean isOverloadCheck() { + return !ourOverloadGuard.currentStack().isEmpty(); + } + + public static boolean isOverloadCheck(PsiElement argumentList) { + return ourOverloadGuard.currentStack().contains(argumentList); + } + + @RequiredReadAction + public boolean isTypeArgumentsApplicable() { + return isTypeArgumentsApplicable(() -> getSubstitutor(false)); + } + + @RequiredReadAction + private boolean isTypeArgumentsApplicable(Supplier computable) { + PsiMethod psiMethod = getElement(); + PsiTypeParameter[] typeParams = psiMethod.getTypeParameters(); + if (myTypeArguments != null && typeParams.length != myTypeArguments.length && !PsiUtil.isLanguageLevel7OrHigher(psiMethod)) { + return typeParams.length == 0 && JavaVersionService.getInstance().isAtLeast(psiMethod, JavaSdkVersion.JDK_1_7); + } + return GenericsUtil.isTypeArgumentsApplicable(typeParams, computable.get(), getParent()); + } + + protected PsiElement getParent() { + return myArgumentList != null ? myArgumentList.getParent() : null; + } + + @Override + public boolean isValidResult() { + return super.isValidResult() && isApplicable(); + } + + @Nonnull + @Override + public PsiMethod getElement() { + return (PsiMethod) super.getElement(); + } + + @Nonnull + public PsiSubstitutor inferTypeArguments(@Nonnull ParameterTypeInferencePolicy policy, boolean includeReturnConstraint) { + return inferTypeArguments( + policy, + myArgumentList instanceof PsiExpressionList ? ((PsiExpressionList) myArgumentList).getExpressions() : PsiExpression.EMPTY_ARRAY, + includeReturnConstraint + ); + } + + public PsiSubstitutor inferSubstitutorFromArgs(@Nonnull ParameterTypeInferencePolicy policy, PsiExpression[] arguments) { + if (myTypeArguments == null) { + return inferTypeArguments(policy, arguments, true); + } + else { + return getSiteSubstitutor(); + } + } + + /** + * If iterated through all candidates, should be called under {@link #ourOverloadGuard} guard so results won't be cached on the top level call + */ + @Nonnull + public PsiSubstitutor inferTypeArguments( + @Nonnull ParameterTypeInferencePolicy policy, + @Nonnull PsiExpression[] arguments, + boolean includeReturnConstraint + ) { + return computeForOverloadedCandidate( + () -> { + PsiMethod method = this.getElement(); + PsiTypeParameter[] typeParameters = method.getTypeParameters(); + + if (this.isRawSubstitution()) { + return JavaPsiFacade.getInstance(method.getProject()) + .getElementFactory() + .createRawSubstitutor(mySubstitutor, typeParameters); + } + + PsiElement parent = this.getParent(); + if (parent == null) { + return PsiSubstitutor.EMPTY; + } + Project project = method.getProject(); + JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(project); + return javaPsiFacade.getResolveHelper().inferTypeArguments( + typeParameters, + method.getParameterList().getParameters(), + arguments, + mySubstitutor, + parent, + policy, + myLanguageLevel + ); + }, + super.getSubstitutor(), + policy.isVarargsIgnored() || isVarargs(), + !includeReturnConstraint + ); + } + + public boolean isRawSubstitution() { + PsiMethod method = getElement(); + if (!method.isStatic()) { + PsiClass containingClass = method.getContainingClass(); + if (containingClass != null && PsiUtil.isRawSubstitutor(containingClass, mySubstitutor)) { + return true; + } + } + return false; + } + + protected PsiElement getMarkerList() { + return myArgumentList; + } + + @RequiredReadAction + public boolean isInferencePossible() { + return myArgumentList != null && myArgumentList.isValid(); + } + + public static CurrentCandidateProperties getCurrentMethod(PsiElement context) { + Map currentMethodCandidates = CURRENT_CANDIDATE.get(); + return currentMethodCandidates != null ? currentMethodCandidates.get(context) : null; + } + + public static void updateSubstitutor(PsiElement context, PsiSubstitutor newSubstitutor) { + CurrentCandidateProperties candidateProperties = getCurrentMethod(context); + if (candidateProperties != null) { + candidateProperties.setSubstitutor(newSubstitutor); + } + } + + @Nullable + public PsiType[] getArgumentTypes() { + return myArgumentTypes; + } + + @Override + public boolean equals(Object o) { + return super.equals(o) && isVarargs() == ((MethodCandidateInfo) o).isVarargs(); + } + + @Override + public int hashCode() { + return 31 * super.hashCode() + (isVarargs() ? 1 : 0); + } + + public void setInferenceError(String inferenceError) { + myInferenceError = inferenceError; + } + + public String getInferenceErrorMessage() { + return myInferenceError; + } + + public String getParentInferenceErrorMessage(PsiExpressionList list) { + String errorMessage = getInferenceErrorMessage(); + while (errorMessage == null) { + list = PsiTreeUtil.getParentOfType(list, PsiExpressionList.class, true, PsiCodeBlock.class); + if (list == null) { + break; + } + if (!(list.getParent() instanceof PsiCallExpression call)) { + break; + } + if (call.resolveMethodGenerics() instanceof MethodCandidateInfo methodCandidateInfo) { + errorMessage = methodCandidateInfo.getInferenceErrorMessage(); + } + } + return errorMessage; + } + + @ApplicabilityLevelConstant + private int pullInferenceErrorMessagesFromSubexpressions(@ApplicabilityLevelConstant int level) { + if (myArgumentList instanceof PsiExpressionList exprList && level == ApplicabilityLevel.NOT_APPLICABLE) { + String errorMessage = null; + for (PsiExpression expression : exprList.getExpressions()) { + String message = clearErrorMessageInSubexpressions(expression); + if (message != null) { + errorMessage = message; + } + } + if (errorMessage != null) { + setInferenceError(errorMessage); + } + } + return level; + } + + private static String clearErrorMessageInSubexpressions(PsiExpression expression) { + expression = PsiUtil.skipParenthesizedExprDown(expression); + if (expression instanceof PsiConditionalExpression conditional) { + String thenErrorMessage = clearErrorMessageInSubexpressions(conditional.getThenExpression()); + String elseErrorMessage = clearErrorMessageInSubexpressions(conditional.getElseExpression()); + if (thenErrorMessage != null) { + return thenErrorMessage; + } + return elseErrorMessage; + } + else if (expression instanceof PsiCallExpression callExpr) { + JavaResolveResult result; + if (callExpr instanceof PsiNewExpression newExpr) { + PsiDiamondType diamondType = PsiDiamondType.getDiamondType(newExpr); + result = diamondType != null ? diamondType.getStaticFactory() : newExpr.resolveMethodGenerics(); + } + else { + result = callExpr.resolveMethodGenerics(); + } + if (result instanceof MethodCandidateInfo methodCandidateInfo) { + String message = methodCandidateInfo.getInferenceErrorMessage(); + methodCandidateInfo.setInferenceError(null); + return message; + } + } + return null; + } + + public CurrentCandidateProperties createProperties() { + return new CurrentCandidateProperties(this, getSiteSubstitutor(), isVarargs(), false); + } + + public static class CurrentCandidateProperties { + private final MethodCandidateInfo myMethod; + private PsiSubstitutor mySubstitutor; + private boolean myVarargs; + private boolean myApplicabilityCheck; + + private CurrentCandidateProperties( + MethodCandidateInfo info, + PsiSubstitutor substitutor, + boolean varargs, + boolean applicabilityCheck + ) { + myMethod = info; + mySubstitutor = substitutor; + myVarargs = varargs; + myApplicabilityCheck = applicabilityCheck; + } + + public PsiMethod getMethod() { + return myMethod.getElement(); + } + + public MethodCandidateInfo getInfo() { + return myMethod; + } + + public PsiSubstitutor getSubstitutor() { + return mySubstitutor; + } + + public void setSubstitutor(PsiSubstitutor substitutor) { + mySubstitutor = substitutor; + } + + public boolean isVarargs() { + return myVarargs; + } + + public void setVarargs(boolean varargs) { + myVarargs = varargs; + } + + public boolean isApplicabilityCheck() { + return myApplicabilityCheck; + } + + public void setApplicabilityCheck(boolean applicabilityCheck) { + myApplicabilityCheck = applicabilityCheck; + } + } + + public static class ApplicabilityLevel { + public static final int NOT_APPLICABLE = 1; + public static final int VARARGS = 2; + public static final int FIXED_ARITY = 3; + } + + @MagicConstant(intValues = { + ApplicabilityLevel.NOT_APPLICABLE, + ApplicabilityLevel.VARARGS, + ApplicabilityLevel.FIXED_ARITY + }) + public @interface ApplicabilityLevelConstant { + } } diff --git a/java-language-api/src/main/resources/LOCALIZE-LIB/en_US/consulo.java.language.JavaCompilationErrorLocalize.yaml b/java-language-api/src/main/resources/LOCALIZE-LIB/en_US/consulo.java.language.JavaCompilationErrorLocalize.yaml new file mode 100644 index 0000000000..c65ccd9d5f --- /dev/null +++ b/java-language-api/src/main/resources/LOCALIZE-LIB/en_US/consulo.java.language.JavaCompilationErrorLocalize.yaml @@ -0,0 +1,996 @@ +# This bundle contains only messages referred from JavaErrorKinds or context objects used there +# Do not add unrelated messages to this bundle +insufficient.language.level: + text: '{0} are not supported at language level ''''{1}''''' +illegal.unicode.escape: + text: Illegal Unicode escape sequence +illegal.character: + text: 'Illegal character: {0}' +preview.api.usage: + text: '{0} is a preview API and is disabled by default' +syntax.error: + text: '{0}' +annotation.not.allowed.here: + text: Annotations are not allowed here +annotation.not.applicable: + text: '''''@{0}'''' not applicable to {1}' +annotation.not.allowed.void: + text: '''void'' type may not be annotated' +annotation.not.allowed.var: + text: '''var'' type may not be annotated' +annotation.not.allowed.class: + text: Class literal type may not be annotated +annotation.not.allowed.ref: + text: Annotation is not applicable to this kind of reference +annotation.not.allowed.static: + text: Static member qualifying type may not be annotated +annotation.not.allowed.on.package: + text: Package annotations only allowed in a 'package-info.java' file +annotation.not.allowed.in.permit.list: + text: Annotations not allowed in 'permits' list +annotation.type.expected: + text: Annotation type expected +annotation.missing.attribute: + text: '{0} missing but required' +annotation.repeated.target: + text: Repeated annotation target +annotation.attribute.name.missing: + text: Annotation attribute of the form 'name=value' expected +annotation.attribute.unknown.method: + text: Cannot find @interface method ''{0}()'' +annotation.attribute.duplicate: + text: Duplicate attribute ''{0}'' +annotation.attribute.non.class.literal: + text: Attribute value must be a class literal +annotation.attribute.incompatible.type: + text: 'Incompatible types. Found: ''''{1}'''', required: ''''{0}''''' +annotation.attribute.illegal.array.initializer: + text: Illegal initializer for ''{0}'' +annotation.attribute.non.enum.constant: + text: Attribute value must be an enum constant +annotation.attribute.non.constant: + text: Attribute value must be constant +annotation.member.may.not.have.throws.list: + text: '''throws'' not allowed on @interface method' +annotation.member.may.not.have.parameters: + text: '@interface members may not have parameters' +annotation.member.invalid.type: + text: Invalid type ''{0}'' for annotation member +annotation.member.clash: + text: '@interface member clashes with ''''{0}'''' in {1}' +annotation.may.not.have.extends.list: + text: '''extends'' not allowed on @interface' +annotation.cyclic.element.type: + text: Cyclic annotation element type +annotation.container.wrong.place: + text: Container annotation ''{0}'' must not be present together with the element it contains +annotation.container.not.applicable: + text: Container annotation ''@{0}'' is not applicable to {1} +annotation.duplicate: + text: Duplicate annotation +annotation.duplicate.explained: + text: Duplicate annotation. {0} +annotation.duplicate.non.repeatable: + text: Duplicate annotation. The declaration of ''{0}'' does not have a valid java.lang.annotation.Repeatable annotation +annotation.malformed.repeatable.explained: + text: '{0}' +annotation.cannot.be.local: + text: Local annotations are not allowed +annotation.permits: + text: '''permits'' not allowed on @interface' +annotation.container.missed.annotation: + text: Container annotation ''{0}'' does not have required @{1} annotation +annotation.container.no.value: + text: 'Invalid container annotation ''''{0}'''': no ''''value'''' method declared' +annotation.container.bad.type: + text: 'Invalid container annotation ''''{0}'''': ''''value'''' method should have type ''''{1}''''' +annotation.container.low.retention: + text: Container annotation ''{0}'' has shorter retention (''{1}'') than the contained annotation +annotation.container.wide.target: + text: Target of container annotation ''{0}'' is not a subset of this annotation’s target +annotation.container.abstract: + text: Container annotation ''{0}'' does not have a default value for ''{1}'' +lambda.not.a.functional.interface: + text: '{0} is not a functional interface' +lambda.no.target.method.found: + text: No target method found +lambda.multiple.sam.candidates: + text: Multiple non-overriding abstract methods found in {0} +lambda.sam.generic: + text: Target method is generic +lambda.sealed.functional.interface: + text: Functional interface cannot be declared as 'sealed' +lambda.not.expected: + text: Unexpected lambda expression +lambda.parameters.inconsistent.var: + text: Cannot mix 'var' and explicitly typed parameters in lambda expression +lambda.sealed: + text: Lambda cannot implement a sealed interface +lambda.type.inference.failure: + text: Cannot infer functional interface type +lambda.inference.error: + text: '{0}' +lambda.return.type.error: + text: '{0}' +lambda.target.not.interface: + text: Target type of a lambda conversion must be an interface +lambda.incompatible.parameter.types: + text: 'Incompatible parameter type in lambda expression: expected {0} but found {1}' +lambda.wrong.number.of.parameters: + text: 'Wrong number of parameters in lambda expression: expected {0} but found {1}' +method.reference.not.expected: + text: Method reference expression is not expected here +method.reference.sealed: + text: Method reference cannot implement a sealed interface +method.reference.return.type.error: + text: '{0}' +method.reference.unresolved.constructor: + text: Cannot resolve constructor ''{0}'' +method.reference.unresolved.method: + text: Cannot resolve method ''{0}'' +method.reference.inference.error: + text: '{0}' +method.reference.raw.constructor: + text: Raw constructor reference with explicit type parameters for constructor +method.reference.qualifier.class.unresolved: + text: Cannot find class {0} +method.reference.qualifier.wildcard: + text: Unexpected wildcard +method.reference.abstract.method: + text: Abstract method ''{0}'' cannot be accessed directly +method.reference.non.static.method.in.static.context: + text: Non-static method cannot be referenced from a static context +method.reference.static.method.non.static.qualifier: + text: Static method referenced through non-static qualifier +method.reference.static.method.receiver: + text: Static method referenced through receiver +method.reference.parameterized.qualifier: + text: Parameterized qualifier on static method reference +method.reference.enclosing.instance.not.in.scope: + text: An enclosing instance of type {0} is not in scope +safe.varargs.on.record.component: + text: '@SafeVarargs is not allowed on a record component' +safe.varargs.on.fixed.arity: + text: '@SafeVarargs is not allowed on methods with fixed arity' +safe.varargs.on.non.final.method: + text: '@SafeVarargs is not allowed on non-final instance methods' +receiver.wrong.context: + text: Receivers are not allowed outside of method’s parameter list +receiver.static.context: + text: The receiver cannot be used in a static context +receiver.wrong.position: + text: The receiver should be the first parameter +receiver.type.mismatch: + text: The receiver type does not match the enclosing class type +receiver.name.mismatch: + text: The receiver name does not match the enclosing class type +override.on.static.method: + text: Static methods cannot be annotated with @Override +override.on.non.overriding.method: + text: Method does not override method from its superclass +class.must.implement.method: + text: Class ''{0}'' must implement abstract method ''{1}'' in ''{2}'' +class.must.implement.method.or.abstract: + text: Class ''{0}'' must either be declared abstract or implement abstract method ''{1}'' in ''{2}'' +class.must.implement.method.enum.constant: + text: Enum constant ''{0}'' must implement abstract method ''{1}'' in ''{2}'' +class.duplicate: + text: 'Duplicate class: ''''{0}''''' +class.duplicate.in.other.file: + text: Duplicate class found in the file ''{0}'' +class.cyclic.inheritance: + text: Cyclic inheritance involving ''{0}'' +class.reference.list.duplicate: + text: Duplicate reference to ''{0}'' in ''{1}'' list +class.reference.list.name.expected: + text: Class name expected +class.reference.list.inner.private: + text: '''''{0}'''' has private access in ''''{1}''''' +class.reference.list.no.enclosing.instance: + text: No enclosing instance of type ''{0}'' is in scope +class.clashes.with.package: + text: Class ''{0}'' clashes with package of same name +class.wrong.filename: + text: Class ''{0}'' is public, should be declared in a file named ''{0}.java'' +class.sealed.no.inheritors: + text: Sealed class must have subclasses +class.sealed.incomplete.permits: + text: Sealed class permits clause must contain all subclasses +class.sealed.inheritor.expected.modifiers.can.be.final: + text: Modifier 'sealed', 'non-sealed' or 'final' expected +class.sealed.inheritor.expected.modifiers: + text: Modifier 'sealed' or 'non-sealed' expected +class.sealed.permits.on.non.sealed: + text: 'Invalid ''''permits'''' clause: ''''{0}'''' must be sealed' +class.cannot.extend.multiple.classes: + text: Class cannot extend multiple classes +class.implements.class: + text: Interface expected here +class.extends.interface: + text: No interface expected here +class.extends.final: + text: Cannot inherit from {1, choice, 1#final class|2#enum|3#record|4#non-abstract value class} ''{0}'' +class.extends.prohibited.class: + text: Classes cannot directly extend ''{0}'' +class.extends.sealed.local: + text: Local classes must not extend sealed classes +class.extends.sealed.another.package: + text: '{0} ''''{1}'''' from another package not allowed to extend sealed {2} ''''{3}'''' in unnamed module' +class.extends.sealed.another.module: + text: Class is not allowed to extend sealed class from another module +class.extends.sealed.not.permitted: + text: '''''{0}'''' is not allowed in the sealed hierarchy' +class.inherits.type.parameter: + text: Class cannot inherit from its type parameter +class.anonymous.extends.sealed: + text: Anonymous classes must not extend sealed classes +class.already.imported: + text: '''''{0}'''' is already defined in this compilation unit' +class.not.enclosing: + text: '''''{0}'''' is not an enclosing class' +class.cannot.be.referenced.from.static.context: + text: '''''{0}'''' cannot be referenced from a static context' +class.inheritance.different.type.arguments: + text: '''''{0}'''' cannot be inherited with different type arguments: ''''{1}'''' and ''''{2}''''' +class.inheritance.raw.and.generic: + text: '''''{0}'''' cannot be inherited as a raw type and with generic type arguments ''''{1}''''' +class.inheritance.method.clash: + text: Methods {0} from {1} and {2} from {3} are inherited with the same signature +class.not.accessible: + text: Cannot access {0} +class.generic.extends.exception: + text: Generic class may not extend 'java.lang.Throwable' +class.initializer.must.complete.normally: + text: Initializer must be able to complete normally +class.permitted.not.direct.subclass: + text: 'Invalid ''''permits'''' clause: ''''{0}'''' must directly {1, choice, 1#extend|2#implement} ''''{2}''''' +class.permitted.must.have.modifier: + text: All sealed class subclasses must either be final, sealed or non-sealed +class.or.package.expected: + text: Expected class or package +class.inherits.abstract.and.default: + text: '{0} inherits abstract and default for {1} from types {2} and {3}' +class.inherits.unrelated.defaults: + text: '{0} inherits unrelated defaults for {1} from types {2} and {3}' +class.implicit.no.main.method: + text: Compact source file contains no 'main' method +class.implicit.invalid.file.name: + text: The name of a compact source file is not a valid identifier +class.implicit.initializer: + text: Initializers are not allowed in compact source files +class.implicit.package.statement: + text: Package statement is not allowed in compact source files +package.clashes.with.class: + text: Package ''{0}'' clashes with class of same name +value.class.extends.non.abstract: + text: Value classes may only extend abstract value classes or 'java.lang.Object' +interface.constructor: + text: Constructor is not allowed in interface +interface.class.initializer: + text: Class initializer is not allowed in interface +interface.implements: + text: '''implements'' not allowed on interface' +interface.extends.class: + text: Interface expected here +record.instance.initializer: + text: Instance initializer is not allowed in records +record.instance.field: + text: Instance field is not allowed in records +record.no.header: + text: Record has no header declared +record.header.regular.class: + text: Record header declared for non-record +record.extends: + text: '''extends'' not allowed on records' +record.permits: + text: '''permits'' not allowed on records' +record.component.vararg.not.last: + text: Vararg record component must be the last in the list +record.component.cstyle.declaration: + text: C-style array declaration not allowed in record component +record.component.restricted.name: + text: Illegal record component name ''{0}'' +record.component.not.initialized: + text: Record component ''{0}'' might not be initialized in canonical constructor +record.accessor.wrong.return.type: + text: 'Incorrect component accessor return type. Expected: ''''{0}'''', found: ''''{1}''''' +record.accessor.non.public: + text: Record component accessor must be 'public' +record.constructor.stronger.access: + text: '{0} access level cannot be more restrictive than the record access level (''''{1}'''')' +record.special.method.type.parameters: + text: '{0} cannot have type parameters' +record.special.method.throws: + text: '{0} should not declare a ''''throws'''' clause' +record.canonical.constructor.wrong.parameter.type: + text: 'Incorrect parameter type for record component ''''{0}''''. Expected: ''''{1}'''', found: ''''{2}''''' +record.canonical.constructor.wrong.parameter.name: + text: 'Canonical constructor parameter names must match record component names. Expected: ''''{0}'''', found: ''''{1}''''' +record.no.constructor.call.in.non.canonical: + text: Non-canonical record constructor must delegate to another constructor +record.canonical.constructor: + text: Canonical constructor +record.compact.constructor: + text: Compact constructor +record.accessor: + text: Record component accessor +vararg.not.last.parameter: + text: Vararg parameter must be the last in the list +vararg.cstyle.array.declaration: + text: C-style array declaration not allowed in vararg parameter +enum.extends: + text: '''extends'' not allowed on enum' +enum.permits: + text: '''permits'' not allowed on enum' +enum.constant.illegal.access.in.constructor: + text: Accessing {0, choice, 1#static field|2#enum constant} from enum {1, choice, 1#constructor|2#instance field initializer|3#instance initializer} is not allowed +enum.constant.modifier: + text: No modifiers allowed for enum constants +instantiation.enum: + text: Enum types cannot be instantiated +instantiation.abstract: + text: '''''{0}'''' is abstract; cannot be instantiated' +instantiation.local.class.wrong.static.context: + text: Local class ''{0}'' cannot be instantiated from a different static context +identifier.restricted: + text: '''''{0}'''' is a restricted identifier and cannot be used for type declarations' +type.parameter.extends.interface.expected: + text: Interface expected here +type.parameter.cannot.be.followed.by.other.bounds: + text: Type parameter cannot be followed by other bounds +type.parameter.on.enum: + text: Enum may not have type parameters +type.parameter.on.annotation.member: + text: '@interface members may not have type parameters' +type.parameter.on.annotation: + text: '@interface may not have type parameters' +type.parameter.duplicate: + text: 'Duplicate type parameter: ''''{0}''''' +type.parameter.incompatible.upper.bounds: + text: 'Type parameter {0} has incompatible upper bounds: {1}' +type.parameter.inferred.type.not.within.extend.bound: + text: Inferred type ''{2}'' for type parameter ''{0}'' is not within its bound; should extend ''{1}'' +type.parameter.inferred.type.not.within.implement.bound: + text: Inferred type ''{2}'' for type parameter ''{0}'' is not within its bound; should implement ''{1}'' +type.parameter.type.not.within.extend.bound: + text: Type parameter ''{0}'' is not within its bound; should extend ''{1}'' +type.parameter.type.not.within.implement.bound: + text: Type parameter ''{0}'' is not within its bound; should implement ''{1}'' +type.parameter.absent.class: + text: Type ''{0}'' does not have type parameters +type.parameter.absent.method: + text: Method ''{0}'' does not have type parameters +type.parameter.count.mismatch: + text: 'Wrong number of type arguments: {0}; required: {1}' +type.parameter.actual.inferred.mismatch: + text: Actual type argument and inferred type contradict each other +method.duplicate: + text: '''''{0}'''' is already defined in ''''{1}''''' +method.throws.class.name.expected: + text: Class name expected +method.interface.body: + text: Interface abstract methods cannot have a body +method.abstract.body: + text: Abstract methods cannot have a body +method.abstract.in.non.abstract.class: + text: Abstract method in non-abstract class +method.native.body: + text: Native methods cannot have a body +method.static.in.interface.should.have.body: + text: Static methods in interfaces should have a body +method.private.in.interface.should.have.body: + text: Private methods in interfaces should have a body +method.default.should.have.body: + text: Extension method should have a body +method.default.in.class: + text: Extension methods can only be used within an interface +method.default.overrides.object.member: + text: Default method ''{0}'' overrides a member of ''java.lang.Object'' +method.should.have.body.or.abstract: + text: Method body or 'abstract' modifier expected +method.should.have.body: + text: Method body expected +method.instance.overrides.static: + text: Instance method ''{0}'' in ''{1}'' cannot override static method ''{2}'' in ''{3}'' +method.static.overrides.instance: + text: Static method ''{0}'' in ''{1}'' cannot override instance method ''{2}'' in ''{3}'' +method.overrides.final: + text: '''''{0}'''' cannot override ''''{1}'''' in ''''{2}''''; overridden method is final' +method.inheritance.weaker.privileges: + text: '{0}; attempting to assign weaker access privileges (''''{1}''''); was ''''{2}''''' +method.inheritance.clash.unrelated.return.types: + text: '{0}; methods have unrelated return types' +method.inheritance.clash.incompatible.return.types: + text: '{0}; incompatible return type' +method.inheritance.clash.does.not.throw: + text: '{0}; overridden method does not throw ''''{1}''''' +method.no.parameter.list: + text: Parameter list expected +method.missing.return.type.not.constructor: + text: Method return type missing +method.missing.return.type: + text: Method return type missing or constructor name does not match class name +method.generic.same.erasure: + text: '{0}; both methods have same erasure' +method.generic.same.erasure.override: + text: '{0}; both methods have same erasure, yet neither overrides the other' +method.generic.same.erasure.hide: + text: '{0}; both methods have same erasure, yet neither hides the other' +clash.methods.message: + text: '''''{0}'''' clashes with ''''{1}''''' +clash.methods.message.show.classes: + text: '''''{0}'''' in ''''{2}'''' clashes with ''''{1}'''' in ''''{3}''''' +constructor.ambiguous.implicit.call: + text: 'Ambiguous implicit constructor call: both ''''{0}'''' and ''''{1}'''' match' +constructor.no.default: + text: There is no no-arg constructor available in ''{0}'' +constructor.in.implicit.class: + text: Explicit constructor in implicitly declared class of a compact source file is not allowed +type.incompatible: + text: 'Incompatible types. Found: ''''{1}'''', required: ''''{0}''''' +type.incompatible.tooltip.required.type: + text: 'Required type:' +type.incompatible.tooltip.provided.type: + text: 'Provided:' +type.incompatible.reason.ambiguous.method.reference: + text: 'reason: method reference is ambiguous: both ''''{0}'''' and ''''{1}'''' match' +type.incompatible.reason.inference: + text: 'reason: {0}' +type.void.not.allowed: + text: '''void'' type is not allowed here' +type.void.illegal: + text: 'Illegal type: ''void''' +type.inaccessible: + text: '''''{0}'''' is inaccessible from here' +type.restricted.identifier: + text: Illegal reference to restricted type ''{0}'' +type.unknown.class: + text: 'Unknown class: ''''{0}''''' +type.argument.primitive: + text: Type argument cannot be of a primitive type +type.argument.not.allowed: + text: Reference parameters are not allowed here +type.argument.on.raw.type: + text: Type arguments given on a raw type +type.argument.on.raw.method: + text: Type arguments given on a raw method +type.argument.in.permits.list: + text: Generics are not allowed in permits list +type.wildcard.cannot.be.instantiated: + text: Wildcard type ''{0}'' cannot be instantiated directly +type.wildcard.not.expected: + text: No wildcard expected +type.wildcard.may.be.used.only.as.reference.parameters: + text: Wildcards may only be used as reference parameters +lvti.no.initializer: + text: 'Cannot infer type: ''var'' on variable without an initializer' +lvti.lambda: + text: 'Cannot infer type: lambda expression requires an explicit target type' +lvti.method.reference: + text: 'Cannot infer type: method reference requires an explicit target type' +lvti.array: + text: '''var'' is not allowed as an element type of an array' +lvti.null: + text: 'Cannot infer type: variable initializer is ''null''' +lvti.void: + text: 'Cannot infer type: variable initializer is ''void''' +lvti.self.referenced: + text: Cannot infer type for ''{0}'', it is used in its own variable initializer +lvti.compound: + text: '''var'' is not allowed in a compound declaration' +label.without.statement: + text: Label without statement +label.duplicate: + text: Label ''{0}'' already in use +label.unresolved: + text: 'Undefined label: ''''{0}''''' +label.must.be.loop: + text: '''''continue'''' target must be a loop label: ''''{0}''''' +break.outside.switch.or.loop: + text: '''break'' outside of switch or loop' +break.out.of.switch.expression: + text: Break out of switch expression is not allowed +continue.outside.loop: + text: '''continue'' statement outside of loop' +continue.out.of.switch.expression: + text: Continue out of switch expression is not allowed +yield.unexpected: + text: '''yield'' outside of a switch expression' +yield.void: + text: Expression type should not be 'void' +foreach.not.applicable: + text: Foreach not applicable to type ''{0}'' +new.expression.qualified.malformed: + text: Invalid qualified new +new.expression.qualified.static.class: + text: Qualified new of static class +new.expression.qualified.anonymous.implements.interface: + text: Unexpected qualifier for anonymous class implementing interface +new.expression.qualified.qualified.class.reference: + text: Qualified class reference is not allowed in qualified new +new.expression.diamond.not.allowed: + text: Diamond operator is not allowed here +new.expression.diamond.not.applicable: + text: Diamond operator is not applicable to non-parameterized types +new.expression.diamond.inference.failure: + text: '{0}' +new.expression.diamond.anonymous.inner.non.private: + text: Cannot use '<>' due to a non-private method which doesn't override or implement a method from a supertype +new.expression.anonymous.implements.interface.with.type.arguments: + text: Anonymous class implements interface; cannot have type arguments +new.expression.unresolved.constructor: + text: Cannot resolve constructor ''{0}'' +new.expression.type.parameter: + text: Type parameter ''{0}'' cannot be instantiated directly +reference.type.argument.static.class: + text: Type arguments are not allowed here because class ''{0}'' is static +reference.type.needs.type.arguments: + text: 'Improperly formed type: ''''{0}'''' needs type arguments because its qualifier has type arguments' +reference.local.class.other.switch.branch: + text: Local class ''{0}'' cannot be referenced from another switch branch +reference.member.before.constructor: + text: Cannot reference ''{0}'' before superclass constructor is called +reference.field.forward: + text: Cannot read value of field ''{0}'' before the field''s definition +reference.field.self: + text: Cannot read value of field ''{0}'' from inside the field''s definition +reference.enum.forward: + text: Cannot refer to enum constant ''{0}'' before its definition +reference.enum.self: + text: Cannot refer to enum constant ''{0}'' from inside its own definition +reference.qualifier.not.expression: + text: Qualifier must be an expression +reference.qualifier.primitive: + text: Cannot access fields on ''{0}'' type +reference.unresolved: + text: Cannot resolve symbol ''{0}'' +reference.ambiguous: + text: Reference to ''{0}'' is ambiguous, both ''{1}'' and ''{2}'' match +reference.implicit.class: + text: Implicitly declared class of a compact source file ''{0}'' cannot be referenced +reference.class.in.default.package: + text: Class ''{0}'' is in the default package +reference.non.static.from.static.context: + text: Non-static {0} ''{1}'' cannot be referenced from a static context +reference.outer.type.parameter.from.static.context: + text: '''''{0}'''' cannot be referenced from a static context' +reference.select.from.type.parameter: + text: Cannot select from a type parameter +reference.package.not.found: + text: 'Package not found: {0}' +statement.case.outside.switch: + text: Case statement outside switch +statement.invalid: + text: Invalid statement +statement.declaration.not.allowed: + text: Declaration not allowed here +statement.bad.expression: + text: Not a statement +statement.unreachable: + text: Unreachable statement +statement.unreachable.loop.body: + text: Loop condition is always false making the loop body unreachable +switch.rule.should.produce.result: + text: Switch expression rule should produce a result in all execution paths +switch.expression.no.result: + text: '''switch'' expression does not have any result expressions' +switch.expression.should.produce.result: + text: Switch expression should produce a result in all execution paths +switch.expression.incompatible.type: + text: 'Bad type in switch expression: {0} cannot be converted to {1}' +switch.expression.cannot.be.void: + text: Target type for switch expression cannot be void +switch.label.expected: + text: Statement must be prepended with a case label +switch.different.case.kinds: + text: Different 'case' kinds used in 'switch' +switch.selector.type.invalid: + text: Selector type of ''{0}'' is not supported +switch.selector.type.invalid.level: + text: Selector type of ''{0}'' is not supported at language level ''{1}'' +switch.null.type.incompatible: + text: '''''null'''' cannot be converted to ''''{0}''''' +switch.null.label.not.allowed: + text: 'Invalid case label combination: ''null'' can only be used as a single case label or paired only with ''default''' +switch.label.qualified.enum: + text: An enum switch case label must be the unqualified name of an enumeration constant +switch.label.constant.expected: + text: Constant expression required +switch.label.pattern.expected: + text: Pattern expected for switch selector type ''{0}'' +switch.label.unexpected: + text: Constant expression, pattern or null is required +switch.label.duplicate.unconditional.pattern: + text: Duplicate unconditional pattern +switch.label.duplicate.default: + text: Duplicate default label +switch.label.duplicate: + text: Duplicate label ''{0}'' +switch.fallthrough.to.pattern: + text: Illegal fall-through to a pattern +switch.multiple.labels.with.pattern.variables: + text: Multiple switch labels are permitted for a switch labeled statement group only if none of them declare any pattern variables +switch.default.null.order: + text: 'Invalid case label order: ''null'' must be first and ''default'' must be second' +switch.default.label.not.allowed: + text: 'Default label not allowed here: ''default'' can only be used as a single case label or paired only with ''null''' +switch.label.combination.constants.and.patterns: + text: 'Invalid case label combination: a case label must consist of either a list of case constants or a single case pattern' +switch.label.combination.constants.and.patterns.unnamed: + text: 'Invalid case label combination: a case label must consist of either a list of case constants or a list of case patterns' +switch.label.multiple.patterns: + text: 'Invalid case label combination: a case label must not consist of more than one case pattern' +switch.label.multiple.patterns.unnamed: + text: 'Invalid case label combination: multiple patterns are allowed only if none of them declare any pattern variables' +switch.dominance.violation: + text: Label is dominated by a preceding case label ''{0}'' +switch.default.and.boolean: + text: '''switch'' has all boolean values and a default label' +switch.default.label.contains.case: + text: The label for the default case must only use the 'default' keyword, without 'case' +switch.unconditional.pattern.and.default: + text: '''switch'' has both an unconditional pattern and a default label' +switch.unconditional.pattern.and.boolean: + text: '''switch'' has all boolean values and an unconditional pattern' +switch.empty: + text: '''''switch'''' {0} does not have any case clauses' +switch.incomplete: + text: '''''switch'''' {0} does not cover all possible input values' +guard.misplaced: + text: Guard is allowed after patterns only +guard.evaluated.to.false: + text: Case label has a guard that is a constant expression with value 'false' +comment.shebang.java.file: + text: Shebang mechanism in .java files is not permitted +comment.unclosed: + text: Unclosed comment +literal.illegal.underscore: + text: Illegal underscore +literal.hexadecimal.no.digits: + text: Hexadecimal numbers must contain at least one hexadecimal digit +literal.binary.no.digits: + text: Binary numbers must contain at least one binary digit +literal.integer.too.large: + text: Integer number too large +literal.long.too.large: + text: Long number too large +literal.floating.malformed: + text: Malformed floating point literal +literal.floating.too.large: + text: Floating point number too large +literal.floating.too.small: + text: Floating point number too small +literal.character.too.long: + text: Too many characters in character literal +literal.character.unclosed: + text: Unclosed character literal +literal.character.illegal.escape: + text: Illegal escape character in character literal +literal.character.empty: + text: Empty character literal +literal.string.illegal.line.end: + text: Line end not allowed in string literals +literal.string.illegal.escape: + text: Illegal escape character in string literal +literal.text.block.unclosed: + text: Unclosed text block +literal.text.block.no.new.line: + text: 'Illegal text block start: missing new line after opening quotes' +exception.unhandled: + text: 'Unhandled {1, choice, 0#exception|2#exceptions}: {0}' +exception.unhandled.close: + text: 'Unhandled {1, choice, 0#exception|2#exceptions} from auto-closeable resource: {0}' +exception.must.be.disjoint: + text: 'Types in multi-catch must be disjoint: ''''{0}'''' is a subclass of ''''{1}''''' +exception.already.caught: + text: Exception ''{0}'' has already been caught +exception.never.thrown.try: + text: Exception ''{0}'' is never thrown in the corresponding try block +exception.never.thrown.try.multi: + text: Exception ''{0}'' is never thrown in the corresponding try block +call.super.enum.constructor: + text: Call to 'super' is not allowed in enum constructor +call.super.qualifier.not.inner.class: + text: Qualifier is not allowed because superclass ''{0}'' is not a non-static inner class +call.expected: + text: Method call expected +call.static.interface.method.qualifier: + text: Static method may only be called on its containing interface +call.formal.varargs.element.type.inaccessible.here: + text: Formal varargs element type {0} is inaccessible from here +call.type.inference.error: + text: '{0}' +call.wrong.arguments: + text: '''''{0}'''' in ''''{1}'''' cannot be applied to ''''{2}''''' +call.wrong.arguments.count.mismatch: + text: Expected {0, choice, 0#no arguments|1#1 argument|1<{0} arguments} but found {1} +call.direct.abstract.method.access: + text: Abstract method ''{0}'' cannot be accessed directly +call.constructor.must.be.first.statement: + text: Call to ''{0}'' must be first statement in constructor body +call.constructor.only.allowed.in.constructor: + text: Call to ''{0}'' only allowed in constructor body +call.constructor.must.be.top.level.statement: + text: Call to ''{0}'' must be top-level statement in constructor body +call.constructor.duplicate: + text: Only one explicit constructor call allowed in constructor +call.constructor.record.in.canonical: + text: Canonical constructor cannot delegate to another constructor +call.constructor.recursive: + text: Recursive constructor call +call.unresolved: + text: Cannot resolve method ''{0}'' +call.unresolved.name: + text: Cannot resolve method ''{0}'' +call.qualifier.primitive: + text: Cannot call methods on ''{0}'' type +call.ambiguous.no.match: + text: Cannot resolve method ''{0}'' in ''{1}'' +call.ambiguous: + text: 'Ambiguous method call: both ''''{0}'''' and ''''{1}'''' match' +call.ambiguous.tooltip: + text: {1}{3}
Ambiguous method call. Both
in {2}\ and
in {4}\ match
+call.parsed.as.deconstruction.pattern: + text: Constant expression, pattern or null is required +call.member.before.constructor: + text: Cannot call ''{0}'' before superclass constructor is called +array.illegal.initializer: + text: Illegal initializer for ''{0}'' +array.initializer.not.allowed: + text: Array initializer is not allowed here +array.type.expected: + text: 'Array type expected; found: ''''{0}''''' +array.generic: + text: Generic array creation not allowed +array.empty.diamond: + text: Array creation with '<>' not allowed +array.type.arguments: + text: Array creation with type arguments not allowed +array.too.many.dimensions: + text: Too many array dimensions +pattern.type.pattern.expected: + text: Type pattern expected +pattern.deconstruction.variable: + text: Identifier is not allowed here +pattern.deconstruction.annotation: + text: Annotations are not allowed in deconstruction pattern types +pattern.deconstruction.requires.record: + text: Deconstruction pattern can only be applied to a record, ''{0}'' is not a record +pattern.deconstruction.count.mismatch: + text: 'Incorrect number of nested patterns: expected {0} but found {1}' +pattern.not.exhaustive: + text: Pattern ''{0}'' is not exhaustive on ''{1}'' +pattern.unsafe.cast: + text: '''''{0}'''' cannot be safely cast to ''''{1}''''' +pattern.cannot.infer.type: + text: 'Cannot infer pattern type: {0}' +pattern.instanceof.supertype: + text: Pattern type ''{0}'' is a supertype of expression type ''{1}'' +pattern.instanceof.equals: + text: Pattern type ''{0}'' is the same as expression type +pattern.expected.class.or.array.type: + text: Class or array type is required +variable.must.be.final: + text: Variable ''{0}'' is accessed from within inner class, needs to be declared final +variable.must.be.final.resource: + text: Variable used as a try-with-resources resource should be final or effectively final +variable.must.be.effectively.final: + text: Variable ''{0}'' is accessed from within inner class, needs to be final or effectively final +variable.must.be.effectively.final.lambda: + text: Variable used in lambda expression should be final or effectively final +variable.must.be.effectively.final.guard: + text: Variable used in guard expression should be final or effectively final +variable.not.initialized: + text: Variable ''{0}'' might not have been initialized +variable.already.assigned: + text: Variable ''{0}'' might already have been assigned to +variable.already.assigned.constructor: + text: Cannot assign final field ''{0}'' {1, choice, 1#before|2#after} chained constructor call +variable.already.assigned.field: + text: Final field ''{0}'' is already initialized in another field initializer +variable.already.assigned.initializer: + text: Final field ''{0}'' is already initialized in a class initializer +variable.assigned.in.loop: + text: Variable ''{0}'' might be assigned in a loop +variable.already.defined: + text: Variable ''{0}'' is already defined in the scope +field.not.initialized: + text: Field ''{0}'' might not have been initialized +field.initialized.before.constructor.call: + text: Cannot assign initialized field ''{0}'' before superclass constructor is called +instanceof.type.parameter: + text: Class or array expected +instanceof.illegal.generic.type: + text: Illegal generic type for instanceof +instanceof.unsafe.cast: + text: '''''{0}'''' cannot be safely cast to ''''{1}''''' +cast.inconvertible: + text: Inconvertible types; cannot cast ''{0}'' to ''{1}'' +cast.intersection.not.interface: + text: Interface expected here +cast.intersection.unexpected.type: + text: 'Unexpected type: class is expected' +cast.intersection.repeated.interface: + text: Repeated interface +cast.intersection.inheritance.clash: + text: '{0} cannot be inherited with different arguments: {1} and {2}' +expression.expected: + text: Expression expected +expression.super.dot.expected: + text: '''.'' expected' +expression.super.not.enclosing.class: + text: '''''{0}'''' is not an enclosing class' +expression.super.bad.qualifier.method.overridden: + text: 'Bad type qualifier in default super call: method {0} is overridden in {1}' +expression.super.bad.qualifier.redundant.extended: + text: 'Bad type qualifier in default super call: redundant interface {0} is extended by {1}' +expression.super.no.enclosing.instance: + text: No enclosing instance of type ''{0}'' is in scope +expression.super.unqualified.default.method: + text: Unqualified super reference is not allowed in extension method +expression.qualified.class.expected: + text: Class name expected here +expression.class.type.parameter: + text: Cannot access class object of a type parameter +expression.class.parameterized.type: + text: Cannot access class object of a parameterized type +resource.declaration.or.variable.expected: + text: Declaration, final, or effectively final variable expected +assignment.declared.outside.guard: + text: Cannot assign a value to variable ''{0}'', because it is declared outside the guard +assignment.to.final.variable: + text: Cannot assign a value to final variable ''{0}'' +lvalue.variable.expected: + text: Variable expected +binary.operator.not.applicable: + text: Operator ''{0}'' cannot be applied to ''{1}'', ''{2}'' +unary.operator.not.applicable: + text: Operator ''{0}'' cannot be applied to ''{1}'' +string.template.void.not.allowed.in.embedded: + text: Expression with the 'void' type is not allowed as a string template embedded expression +string.template.processor.missing: + text: Processor missing from string template expression +string.template.raw.processor: + text: 'Raw processor type is not allowed: {0}' +modifier.not.allowed: + text: Modifier ''{0}'' not allowed here +modifier.not.allowed.local.class: + text: Modifier ''{0}'' not allowed on local classes +modifier.not.allowed.non.sealed: + text: Modifier 'non-sealed' is not allowed on classes that do not have a sealed superclass +modifier.repeated: + text: Repeated modifier ''{0}'' +modifier.incompatible: + text: Illegal combination of modifiers ''{0}'' and ''{1}'' +access.private: + text: '''''{0}'''' has private access in ''''{1}''''' +access.protected: + text: '''''{0}'''' has protected access in ''''{1}''''' +access.package.local: + text: '''''{0}'''' is not public in ''''{1}''''. Cannot be accessed from outside package' +incomplete.project.state.pending.reference: + text: Not resolved until the project is fully loaded +import.single.class.conflict: + text: '''''{0}'''' is already defined in a single-type import' +import.single.static.class.already.defined: + text: Class ''{0}'' is already defined in a single static import +import.single.static.class.ambiguous: + text: Class ''{0}'' is ambiguous in a single static import +import.single.static.field.already.defined: + text: Field ''{0}'' is already defined in a single static import +import.single.static.field.ambiguous: + text: Field ''{0}'' is ambiguous in a single static import +import.static.on.demand.resolves.to.class: + text: Class {0} not found +import.list.extra.semicolon: + text: Extra semicolons between import statements are not allowed +underscore.identifier: + text: Since Java 9, '_' is a keyword and may not be used as an identifier +underscore.identifier.unnamed: + text: Using '_' as a reference is not allowed +underscore.identifier.lambda: + text: Use of '_' as a lambda parameter name is not allowed +unnamed.field.not.allowed: + text: Unnamed field is not allowed +unnamed.method.parameter.not.allowed: + text: Unnamed method parameter is not allowed +unnamed.variable.not.allowed.in.this.context: + text: Unnamed variable declaration is not allowed in this context +unnamed.variable.brackets: + text: Brackets are not allowed after an unnamed variable declaration +unnamed.variable.without.initializer: + text: Unnamed variable declaration must have an initializer +return.outside.switch.expression: + text: Return outside of enclosing switch expression +return.compact.constructor: + text: '''return'' statement is not allowed in compact constructor' +return.outside.method: + text: Return outside method +return.before.explicit.constructor.call: + text: '''''return'''' not allowed before ''''{0}'''' call' +return.value.missing: + text: Missing return value +return.from.void.method: + text: Cannot return a value from a method with void result type +return.from.constructor: + text: Cannot return a value from a constructor +return.missing: + text: Missing return statement +catch.type.parameter: + text: Cannot catch type parameters +module.no.package: + text: A module file should not have a 'package' statement +module.conflicting.packages: + text: 'Package ''''{0}'''' exists in another module: {1}' +module.conflicting.reads: + text: Module ''{0}'' reads package ''{1}'' from both ''{2}'' and ''{3}'' +module.file.wrong.name: + text: Module declarations only allowed in a 'module-info.java' file +module.file.duplicate: + text: '''module-info.java'' already exists in the module' +module.duplicate.requires: + text: 'Duplicate ''''requires'''': {0}' +module.duplicate.exports: + text: 'Duplicate ''''exports'''': {0}' +module.duplicate.exports.target: + text: 'Duplicate ''''exports'''' target: {0}' +module.duplicate.opens: + text: 'Duplicate ''''opens'''': {0}' +module.duplicate.opens.target: + text: 'Duplicate ''''opens'''' target: {0}' +module.duplicate.uses: + text: 'Duplicate ''''uses'''': {0}' +module.duplicate.provides: + text: 'Duplicate ''''provides'''': {0}' +module.duplicate.implementation: + text: 'Duplicate implementation: {0}' +module.file.wrong.location: + text: Module declaration should be located in a module's source root +module.opens.in.weak.module: + text: '''opens'' is not allowed in an open module' +module.service.enum: + text: 'The service definition is an enum: {0}' +module.service.alien: + text: The service implementation must be defined in the same module as the provides directive +module.service.provider.type: + text: 'The ''''provider'''' method return type must be a subtype of the service interface type: {0}' +module.service.implementation.type: + text: The service implementation type must be a subtype of the service interface type, or have a public static no-args 'provider' method +module.service.abstract: + text: 'The service implementation is an abstract class: {0}' +module.service.inner: + text: 'The service implementation is an inner class: {0}' +module.service.no.constructor: + text: 'The service implementation does not have a public default constructor: {0}' +module.not.found: + text: 'Module not found: {0}' +module.not.on.path: + text: 'Module is not in dependencies: {0}' +module.cyclic.dependence: + text: 'Cyclic dependency: {0}' +module.reference.package.not.found: + text: 'Package not found: {0}' +module.reference.package.empty: + text: 'Package is empty: {0}' +module.access.from.named: + text: Package ''{0}'' is declared in module ''{1}'', which does not export it to module ''{2}'' +module.access.from.unnamed: + text: Package ''{0}'' is declared in module ''{1}'', which does not export it to the unnamed module +module.access.to.unnamed: + text: Package ''{0}'' is declared in the unnamed module, but module ''{1}'' does not read it +module.access.package.bad.name: + text: Package ''{0}'' is declared in module with an invalid name (''{1}'') +module.access.bad.name: + text: Module ''{0}'' has an invalid name +module.access.package.not.in.graph: + text: Package ''{0}'' is declared in module ''{1}'', which is not in the module graph +module.access.not.in.graph: + text: Module ''{0}'' is missing from the module graph +module.access.package.does.not.read: + text: Package ''{0}'' is declared in module ''{1}'', but module ''{2}'' does not read it +module.access.does.not.read: + text: Module ''{0}'' fails to read ''{1}'' +module.access.jps.dependency.problem: + text: Module dependency for ''{0}'' is not specified in project structure +module.import.not.allowed: + text: Module import is not allowed diff --git a/java-language-api/src/main/resources/LOCALIZE-LIB/en_US/consulo.java.language.JavaLanguageLocalize.yaml b/java-language-api/src/main/resources/LOCALIZE-LIB/en_US/consulo.java.language.JavaLanguageLocalize.yaml index 9350bc88b0..6588771c22 100644 --- a/java-language-api/src/main/resources/LOCALIZE-LIB/en_US/consulo.java.language.JavaLanguageLocalize.yaml +++ b/java-language-api/src/main/resources/LOCALIZE-LIB/en_US/consulo.java.language.JavaLanguageLocalize.yaml @@ -183,8 +183,6 @@ error.inference.variable.has.incompatible.bounds: {3}: {4} error.message.wildcard.not.expected: text: Unexpected wildcard -error.type.parameter.has.incompatible.upper.bounds: - text: 'Type parameter {0} has incompatible upper bounds: {1}' expected.array.initializer: text: Array initializer expected expected.boolean.expression: diff --git a/java-language-impl/src/main/resources/LOCALIZE-LIB/en_US/consulo.java.language.impl.JavaErrorLocalize.yaml b/java-language-impl/src/main/resources/LOCALIZE-LIB/en_US/consulo.java.language.impl.JavaErrorLocalize.yaml index 8eef3674f0..1b7f5413e5 100644 --- a/java-language-impl/src/main/resources/LOCALIZE-LIB/en_US/consulo.java.language.impl.JavaErrorLocalize.yaml +++ b/java-language-impl/src/main/resources/LOCALIZE-LIB/en_US/consulo.java.language.impl.JavaErrorLocalize.yaml @@ -1,421 +1,51 @@ -abstract.cannot.be.instantiated: - text: '''''{0}'''' is abstract; cannot be instantiated' -abstract.method.in.non.abstract.class: - text: Abstract method in non-abstract class -abstract.methods.cannot.have.a.body: - text: Abstract methods cannot have a body -actual.type.argument.contradict.inferred.type: - text: Actual type argument and inferred type contradict each other -ambiguous.method.call: - text: 'Ambiguous method call: both ''''{0}'''' and ''''{1}'''' match' ambiguous.method.html.tooltip: text: {1}{3}
Ambiguous method call. Both
in {2}\ and
in {4}\ match.
-ambiguous.reference: - text: Reference to ''{0}'' is ambiguous, both ''{1}'' and ''{2}'' match -annotation.annotation.type.expected: - text: Annotation type expected -annotation.container.bad.type: - text: 'Invalid container annotation ''''{0}'''': ''''value'''' method should have type ''''{1}''''' -annotation.container.low.retention: - text: Container annotation ''{0}'' has shorter retention (''{1}'') than the contained annotation -annotation.container.no.value: - text: 'Invalid container annotation ''''{0}'''': no ''''value'''' method declared' -annotation.container.not.applicable: - text: Container annotation ''@{0}'' is not applicable to {1} -annotation.container.wide.target: - text: Target of container annotation ''{0}'' is not a subset of target of this annotation -annotation.container.wrong.place: - text: Container annotation ''{0}'' must not be present at the same time as the element it contains -annotation.cyclic.element.type: - text: Cyclic annotation element type -annotation.duplicate.annotation: - text: Duplicate annotation -annotation.duplicate.attribute: - text: Duplicate attribute ''{0}'' -annotation.duplicate.explained: - text: Duplicate annotation. {0} -annotation.illegal.array.initializer: - text: Illegal initializer for ''{0}'' -annotation.incompatible.types: - text: 'Incompatible types. Found: ''''{0}'''', required: ''''{1}''''' -annotation.interface.members.may.not.have.parameters: - text: '@interface members may not have parameters' -annotation.invalid.annotation.member.type: - text: Invalid type ''{0}'' for annotation member -annotation.may.not.have.extends.list: - text: '@interface may not have extends list' -annotation.may.not.have.type.parameters: - text: '@interface may not have type parameters' -annotation.members.may.not.have.throws.list: - text: '@interface members may not have throws list' -annotation.missing.attribute: - text: '{0} missing though required' annotation.missing.method: text: Cannot find method ''{0}'' -annotation.name.is.missing: - text: Annotation attribute must be of the form 'name=value' -annotation.non.class.literal.attribute.value: - text: Attribute value must be a class literal -annotation.non.constant.attribute.value: - text: Attribute value must be constant -annotation.non.repeatable: - text: The declaration of ''{0}'' does not have a valid java.lang.annotation.Repeatable annotation -annotation.not.allowed.class: - text: Class literal type may not be annotated -annotation.not.allowed.here: - text: Annotations are not allowed here -annotation.not.allowed.ref: - text: Annotation not applicable to this kind of reference -annotation.not.allowed.static: - text: Static member qualifying type may not be annotated -annotation.not.allowed.void: - text: '''void'' type may not be annotated' -annotation.not.applicable: - text: '''''@{0}'''' not applicable to {1}' annotation.unknown.method: text: Cannot resolve method ''{0}'' argument.mismatch.html.tooltip: text: {3}{4}
{1}in {2}\ cannot be applied
to
-array.initializer.not.allowed: - text: Array initializer is not allowed here -array.type.expected: - text: 'Array type expected; found: ''''{0}''''' -assignment.to.final.variable: - text: Cannot assign a value to final variable ''{0}'' bad.qualifier.in.super.method.reference: text: 'Bad type qualifier in default super call: {0}' -binary.numbers.must.contain.at.least.one.hexadecimal.digit: - text: Binary numbers must contain at least one binary digit -binary.operator.not.applicable: - text: Operator ''{0}'' cannot be applied to ''{1}'', ''{2}'' -bound.not.expected: - text: Unexpected bound -break.outside.switch.or.loop: - text: Break outside switch or loop call.to.super.is.not.allowed.in.enum.constructor: text: Call to super is not allowed in enum constructor -cannot.be.referenced.from.static.context: - text: '''''{0}'''' cannot be referenced from a static context' -cannot.resolve.constructor: - text: Cannot resolve constructor ''{0}'' -cannot.resolve.method: - text: Cannot resolve method ''{0}'' -cannot.resolve.package: - text: Cannot resolve package {0} -cannot.resolve.symbol: - text: Cannot resolve symbol ''{0}'' cannot.select.dot.class.from.type.variable: text: Cannot select from a type variable cannot.select.from.parameterized.type: text: Cannot access class object of parameterized type -case.statement.outside.switch: - text: Case statement outside switch -catch.without.try: - text: '''catch'' without ''try''' -clash.methods.message: - text: '''''{0}'''' clashes with ''''{1}''''' -clash.methods.message.show.classes: - text: '''''{0}'''' in ''''{2}'''' clashes with ''''{1}'''' in ''''{3}''''' -class.already.imported: - text: '''''{0}'''' is already defined in this compilation unit' class.cannot.be.inherited.with.different.arguments: text: '{0} cannot be inherited with different arguments: {1}' -class.cannot.extend.multiple.classes: - text: Class cannot extend multiple classes -class.cannot.inherit.from.its.type.parameter: - text: Class cannot inherit from its type parameter -class.clashes.with.package: - text: Class ''{0}'' clashes with package of same name -class.expected: - text: Class name expected here -class.inheritance.method.clash: - text: Methods {0} from {1} and {2} from {3} are inherited with the same signature -class.is.already.defined.in.single.static.import: - text: Class ''{0}'' is already defined in a single static import -class.is.ambiguous.in.single.static.import: - text: Class ''{0}'' is ambiguous in a single static import class.is.not.used: text: Class ''{0}'' is never used -class.must.be.abstract: - text: Class ''{0}'' must either be declared abstract or implement abstract method ''{1}'' in ''{2}'' -class.name.expected: - text: Class name expected classes.extends.enum: text: Classes cannot directly extend 'java.lang.Enum' -constant.expression.required: - text: Constant expression required -constructor.call.must.be.first.statement: - text: Call to ''{0}'' must be first statement in constructor body constructor.is.not.used: text: Constructor ''{0}'' is never used -continue.outside.loop: - text: Continue outside of loop -cyclic.inheritance: - text: Cyclic inheritance involving ''{0}'' -declaration.not.allowed: - text: Declaration not allowed here declaration.or.variable.expected: text: Declaration, final or effectively final variable expected -deprecated.symbol: - text: '''''{0}'''' is deprecated' -deprecated.symbol.0: - text: '''''{0}'''' is deprecated. {1}' different.case.kinds.in.switch: text: Different case kinds used in the switch direct.abstract.method.access: text: Abstract method ''{0}'' cannot be accessed directly -dot.expected.after.super.or.this: - text: '''.'' expected' -duplicate.class: - text: 'Duplicate class: ''''{0}''''' -duplicate.class.in.other.file: - text: Duplicate class found in the file ''{0}'' -duplicate.default.switch.label: - text: Duplicate default label -duplicate.label: - text: Label ''{0}'' already in use -duplicate.method: - text: '''''{0}'''' is already defined in ''''{1}''''' -duplicate.switch.label: - text: Duplicate label ''{0}'' -else.without.if: - text: '''else'' without ''if''' -empty.character.literal: - text: Empty character literal -enum.constant.should.implement.method: - text: Class ''{0}'' must implement abstract method ''{1}'' in ''{2}'' -enum.types.cannot.be.instantiated: - text: Enum types cannot be instantiated -error.cannot.resolve.class: - text: Cannot resolve class ''{0}'' -error.cannot.resolve.class.or.package: - text: Cannot resolve class or package ''{0}'' -exception.already.caught: - text: Exception ''{0}'' has already been caught exception.already.caught.warn: text: 'Unreachable section: {1, choice, 0#exception|2#exceptions} ''''{0}'''' {1, choice, 0#has|2#have} already been caught' -exception.is.never.thrown: - text: Exception ''{0}'' is never thrown in the method -exception.must.be.disjoint: - text: 'Types in multi-catch must be disjoint: ''''{0}'''' is a subclass of ''''{1}''''' -exception.never.thrown.try: - text: Exception ''{0}'' is never thrown in the corresponding try block -expected.array.initializer: - text: Array initializer expected -expected.boolean.expression: - text: Boolean expression expected -expected.catch.or.finally: - text: '''catch'' or ''finally'' expected' -expected.class.or.interface: - text: '''class'' or ''interface'' expected' -expected.class.or.package: - text: Expected class or package -expected.class.reference: - text: Class reference expected -expected.colon: - text: ''':'' expected' -expected.comma: - text: ''','' expected' -expected.comma.or.rparen: - text: ''','' or '')'' expected' -expected.comma.or.semicolon: - text: ''','' or '';'' expected' -expected.dot: - text: '''.'' expected' -expected.eq: - text: '''='' expected' -expected.expression: - text: Expression expected -expected.gt: - text: '''>'' expected.' -expected.gt.or.comma: - text: '''>'' or '','' expected' -expected.identifier: - text: Identifier expected -expected.identifier.or.type: - text: Identifier or type expected -expected.lbrace: - text: '''{'' expected' -expected.lbrace.or.semicolon: - text: '''{'' or '';'' expected' -expected.lbracket: - text: '''['' expected' -expected.lparen: - text: '''('' expected' -expected.lparen.or.lbracket: - text: '''('' or ''['' expected' -expected.module.declaration: - text: Module declaration expected -expected.module.statement: - text: Module statement expected -expected.package.reference: - text: Package reference expected -expected.parameter: - text: Parameter expected -expected.rbrace: - text: '''}'' expected' -expected.rbracket: - text: ''']'' expected' -expected.resource: - text: Resource definition expected -expected.rparen: - text: ''')'' expected' -expected.semicolon: - text: ''';'' expected' -expected.statement: - text: Statement expected -expected.type: - text: Type expected -expected.type.parameter: - text: Type parameter expected -expected.value: - text: Value expected -expected.while: - text: '''while'' expected' -expected.with: - text: '''with'' expected' expression.expected: text: Expression expected extends.after.enum: text: No extends clause allowed for enum -extension.method.in.class: - text: Extension methods can only be used within an interface -extension.method.should.have.a.body: - text: Extension method should have a body -feature.annotations: - text: Annotations -feature.binary.literals: - text: Binary literals -feature.diamond.types: - text: Diamond types -feature.enhanced.switch: - text: Enhanced 'switch' blocks -feature.extension.methods: - text: Extension methods -feature.for.each: - text: For-each loops -feature.generics: - text: Generics -feature.guarded.and.parenthesised.patterns: - text: Guarded and parenthesized patterns -feature.hex.fp.literals: - text: Hexadecimal floating point literals -feature.inner.statics: - text: Static declarations in inner classes -feature.intersections.in.casts: - text: Intersection types in casts -feature.lambda.expressions: - text: Lambda expressions -feature.local.enums: - text: Local enums -feature.local.interfaces: - text: Local interfaces -feature.lvti: - text: Local variable type inference -feature.method.references: - text: Method references -feature.modules: - text: Modules -feature.multi.catch: - text: Multi-catches -feature.patterns.in.switch: - text: Patterns in switch -feature.patterns.instanceof: - text: Patterns in 'instanceof' -feature.records: - text: Records -feature.sealed.classes: - text: Sealed classes -feature.static.imports: - text: Static imports -feature.static.interface.calls: - text: Static interface method calls -feature.switch.expressions: - text: '''switch'' expressions' -feature.text.block.escape.sequences: - text: '''\s'' and ''\'' escape sequences' -feature.text.blocks: - text: Text block literals -feature.try.with.resources: - text: Try-with-resources -feature.try.with.resources.refs: - text: Resource references -feature.type.annotations: - text: Type annotations -feature.type.receivers: - text: Receiver parameters -feature.underscores.in.literals: - text: Underscores in literals -feature.var.lambda.parameter: - text: '''var'' in lambda parameters' -feature.varargs: - text: Variable arity methods -field.is.already.defined.in.single.static.import: - text: Field ''{0}'' is already defined in a single static import -field.is.ambiguous.in.single.static.import: - text: Field ''{0}'' is ambiguous in a single static import field.is.not.used: text: Field ''{0}'' is never used -final.method.override: - text: '''''{0}'''' cannot override ''''{1}'''' in ''''{2}''''; overridden method is final' -finally.without.try: - text: '''finally'' without ''try''' -floating.point.number.too.large: - text: Floating point number too large -floating.point.number.too.small: - text: Floating point number too small -foreach.not.applicable: - text: foreach not applicable to type ''{0}''. -generic.array.creation: - text: Generic array creation -generic.extend.exception: - text: Generic class may not extend 'java.lang.Throwable' -generics.annotation.members.may.not.have.type.parameters: - text: '@interface members may not have type parameters' -generics.cannot.be.inherited.with.different.type.arguments: - text: '''''{0}'''' cannot be inherited with different type arguments: ''''{1}'''' and ''''{2}''''' -generics.cannot.catch.type.parameters: - text: Cannot catch type parameters -generics.cannot.instanceof.type.parameters: - text: Class or array expected -generics.diamond.not.applicable: - text: Diamond operator is not applicable for non-parameterized types -generics.duplicate.type.parameter: - text: 'Duplicate type parameter: ''''{0}''''' -generics.enum.may.not.have.type.parameters: - text: Enum may not have type parameters generics.holder.method: text: Method generics.holder.type: text: Type -generics.inferred.type.for.type.parameter.is.not.within.its.bound.extend: - text: Inferred type ''{2}'' for type parameter ''{0}'' is not within its bound; should extend ''{1}'' -generics.inferred.type.for.type.parameter.is.not.within.its.bound.implement: - text: Inferred type ''{2}'' for type parameter ''{0}'' is not within its bound; should implement ''{1}'' -generics.methods.have.same.erasure: - text: '{0}; both methods have same erasure' -generics.methods.have.same.erasure.hide: - text: '{0}; both methods have same erasure, yet neither hides the other' -generics.methods.have.same.erasure.override: - text: '{0}; both methods have same erasure, yet neither overrides the other' -generics.reference.parameters.not.allowed: - text: Reference parameters are not allowed here generics.select.static.class.from.parameterized.type: text: Cannot select static class ''{0}'' from parameterized type generics.type.argument.cannot.be.of.primitive.type: text: Type argument cannot be of primitive type -generics.type.arguments.on.raw.method: - text: Type arguments given on a raw method -generics.type.arguments.on.raw.type: - text: Type arguments given on a raw type generics.type.or.method.does.not.have.type.parameters: text: '{0} ''''{1}'''' does not have type parameters' -generics.type.parameter.cannot.be.instantiated: - text: Type parameter ''{0}'' cannot be instantiated directly -generics.type.parameter.is.not.within.its.bound.extend: - text: Type parameter ''{0}'' is not within its bound; should extend ''{1}'' -generics.type.parameter.is.not.within.its.bound.implement: - text: Type parameter ''{0}'' is not within its bound; should implement ''{1}'' generics.unchecked.assignment: text: 'Unchecked assignment: ''''{0}'''' to ''''{1}''''' generics.unchecked.call: @@ -424,64 +54,30 @@ generics.unchecked.call.to.member.of.raw.type: text: Unchecked call to ''{0}'' as a member of raw type ''{1}'' generics.unchecked.cast: text: 'Unchecked cast: ''''{0}'''' to ''''{1}''''' -generics.wildcard.not.expected: - text: No wildcard expected generics.wildcards.may.be.used.only.as.reference.parameters: text: Wildcards may be used only as reference parameters -generics.wrong.number.of.type.arguments: - text: 'Wrong number of type arguments: {0}; required: {1}' -hexadecimal.numbers.must.contain.at.least.one.hexadecimal.digit: - text: Hexadecimal numbers must contain at least one hexadecimal digit -illegal.escape.character.in.character.literal: - text: Illegal escape character in character literal -illegal.escape.character.in.string.literal: - text: Illegal escape character in string literal illegal.forward.reference: text: Illegal forward reference -illegal.generic.type.for.instanceof: - text: Illegal generic type for instanceof -illegal.initializer: - text: Illegal initializer for ''{0}'' illegal.line.end.in.character.literal: text: Illegal line end in character literal illegal.line.end.in.string.literal: text: Illegal line end in string literal illegal.self.reference: - text: Cannot read value of field ''{0}'' from inside the fields''s definition + text: Illegal self reference illegal.to.access.static.member.from.enum.constructor.or.instance.initializer: text: It is illegal to access static member ''{0}'' from enum constructor or instance initializer -illegal.type.void: - text: 'Illegal type: ''void''' -illegal.underscore: - text: Illegal underscore implements.after.interface: text: No implements clause allowed for interface -import.statement.identifier.or.asterisk.expected.: - text: Identifier or '*' expected inaccessible.type: text: '''''{0}'''' is inaccessible here' incompatible.call.types: text: 'Wrong {0, choice, 1#1st|2#2nd|3#3rd|4#{0,number}th} argument type. Found: ''''{2}'''', required: ''''{1}''''' -incompatible.modifiers: - text: 'Illegal combination of modifiers: ''''{0}'''' and ''''{1}''''' incompatible.return.type: text: attempting to use incompatible return type -incompatible.types: - text: 'Incompatible types. Found: ''''{1}'''', required: ''''{0}''''' incompatible.types.html.tooltip: text: Incompatible types.{1}{3}
Required:{0}
Found:{2}
-inconvertible.type.cast: - text: Inconvertible types; cannot cast ''{0}'' to ''{1}'' inheritance.from.final.class: text: Cannot inherit from final ''{0}'' -initializer.must.be.able.to.complete.normally: - text: Initializer must be able to complete normally -instance.method.cannot.override.static.method: - text: Instance method ''{0}'' in ''{1}'' cannot override static method ''{2}'' in ''{3}'' -insufficient.language.level: - text: '{0} are not supported at language level ''''{1}''''' -integer.number.too.large: - text: Integer number too large interface.cannot.be.local: text: Modifier 'interface' not allowed here interface.expected: @@ -490,38 +86,8 @@ interface.methods.cannot.have.body: text: Interface methods cannot have body invalid.package.annotation.containing.file: text: Package annotations should be in file package-info.java -invalid.qualified.new: - text: Invalid qualified new -invalid.statement: - text: Invalid statement is.not.an.enclosing.class: text: '''''{0}'''' is not an enclosing class' -javadoc.exception.tag.class.is.not.throwable: - text: Class {0} is not a descendant of Throwable -javadoc.exception.tag.exception.class.expected: - text: Exception class expected -javadoc.exception.tag.exception.is.not.thrown: - text: '{0} is not declared to be thrown by method {1}' -javadoc.exception.tag.wrong.tag.value: - text: Wrong tag value -javadoc.param.tag.parameter.name.expected: - text: Parameter name expected -javadoc.param.tag.type.parameter.gt.expected: - text: '''>'' expected' -javadoc.param.tag.type.parameter.name.expected: - text: Type parameter name expected -javadoc.value.field.required: - text: '@value tag must reference a field' -javadoc.value.field.with.initializer.required: - text: '@value tag must reference a field with a constant initializer' -javadoc.value.static.field.required: - text: '@value tag must reference a static field' -javadoc.value.tag.jdk15.required: - text: '@value tag may not have any arguments when JDK 1.4 or earlier is used' -label.without.statement: - text: Label without statement -lambda.variable.must.be.final: - text: Variable used in lambda expression should be final or effectively final local.class.is.not.used: text: Local class ''{0}'' is never used local.enum: @@ -532,70 +98,18 @@ local.variable.is.not.assigned: text: Variable ''{0}'' is never assigned local.variable.is.not.used.for.reading: text: Variable ''{0}'' is assigned but never accessed -long.number.too.large: - text: Long number too large -malformed.floating.point.literal: - text: Malformed floating point literal member.referenced.before.constructor.called: text: Cannot reference ''{0}'' before supertype constructor has been called -method.call.expected: - text: Method call expected -method.does.not.override.super: - text: Method does not override method from its superclass method.is.not.used: text: Method ''{0}'' is never used -method.private.in.interface.should.have.body: - text: Private methods in interfaces should have a body -method.static.in.interface.should.have.body: - text: Static methods in interfaces should have a body missing.method.body: text: Missing method body, or declare abstract -missing.package.statement: - text: 'Missing package statement: ''''{0}''''' -missing.return.statement: - text: Missing return statement missing.return.type: text: Invalid method declaration; return type required -missing.return.value: - text: Missing return value -modifier.not.allowed: - text: Modifier ''{0}'' not allowed here modifiers.for.enum.constants: text: No modifiers allowed for enum constants module.ambiguous: text: 'Ambiguous module reference: {0}' -module.conflicting.packages: - text: 'Package ''''{0}'''' exists in another module: {1}' -module.conflicting.reads: - text: Module ''{0}'' reads package ''{1}'' from both ''{2}'' and ''{3}'' -module.cyclic.dependence: - text: 'Cyclic dependence: {0}' -module.duplicate.exports: - text: 'Duplicate ''''exports'''': {0}' -module.duplicate.exports.target: - text: 'Duplicate ''''exports'''' target: {0}' -module.duplicate.impl: - text: 'Duplicate implementation: {0}' -module.duplicate.opens: - text: 'Duplicate ''''opens'''': {0}' -module.duplicate.opens.target: - text: 'Duplicate ''''opens'''' target: {0}' -module.duplicate.provides: - text: 'Duplicate ''''provides'''': {0}' -module.duplicate.requires: - text: 'Duplicate ''''requires'''': {0}' -module.duplicate.uses: - text: 'Duplicate ''''uses'''': {0}' -module.file.duplicate: - text: '''module-info.java'' already exists in the module' -module.file.wrong.location: - text: Module declaration should be located in a module's source root -module.file.wrong.name: - text: Module declaration should be in a file named 'module-info.java' -module.no.package: - text: A module file should not have 'package' statement -module.not.found: - text: 'Module not found: {0}' module.not.in.requirements: text: The module ''{0}'' does not have the module ''{1}'' in requirements module.not.on.path: @@ -606,52 +120,14 @@ module.opens.in.weak.module: text: '''opens'' is not allowed in an open module' module.package.not.exported: text: The module ''{0}'' does not export the package ''{1}'' to the module ''{2}'' -module.package.not.open: - text: The module ''{0}'' does not open the package ''{1}'' to the module ''{2}'' module.package.on.classpath: text: A named module cannot access packages of an unnamed one -module.service.abstract: - text: 'The service implementation is an abstract class: {0}' -module.service.alien: - text: The service implementation must be defined in the same module as the provides directive -module.service.enum: - text: 'The service definition is an enum: {0}' -module.service.impl: - text: The service implementation type must be a subtype of the service interface type, or have a public static no-args 'provider' method -module.service.inner: - text: 'The service implementation is an inner class: {0}' -module.service.no.ctor: - text: 'The service implementation does not have a public default constructor: {0}' -module.service.provider.type: - text: 'The ''''provider'''' method return type must be a subtype of the service interface type: {0}' module.service.unused: text: Service interface provided but not exported or used -native.methods.cannot.have.a.body: - text: Native methods cannot have a body no.default.constructor.available: text: There is no default constructor available in ''{0}'' -no.enclosing.instance.in.scope: - text: No enclosing instance of type ''{0}'' is in scope -no.interface.expected: - text: No interface expected here -non.static.symbol.referenced.from.static.context: - text: Non-static {0} ''{1}'' cannot be referenced from a static context -not.a.statement: - text: Not a statement -not.allowed.in.interface: - text: Not allowed in interface not.loop.label: text: 'Not a loop label: ''''{0}''''' -numeric.overflow.in.expression: - text: Numeric overflow in expression -overridden.method.does.not.throw: - text: '{0}; overridden method does not throw ''''{1}''''' -overrides.deprecated.method: - text: Overrides deprecated method in ''{0}'' -package.clashes.with.class: - text: Package ''{0}'' clashes with class of same name -package.is.empty: - text: 'Package is empty: {0}' package.local.symbol: text: '''''{0}'''' is not public in ''''{1}''''. Cannot be accessed from outside package' package.name.file.path.mismatch: @@ -682,32 +158,8 @@ public.class.should.be.named.after.file: text: Class ''{0}'' is public, should be declared in a file named ''{0}.java'' qualified.enum.constant.in.switch: text: An enum switch case label must be the unqualified name of an enumeration constant -qualified.new.of.static.class: - text: Qualified new of static class -qualifier.must.be.expression: - text: Qualifier must be an expression -receiver.name.mismatch: - text: The receiver name does not match the enclosing class type -receiver.static.context: - text: The receiver cannot be used in a static context -receiver.type.mismatch: - text: The receiver type does not match the enclosing class type -receiver.wrong.context: - text: Receivers are not allowed outside of method parameter list -receiver.wrong.position: - text: The receiver should be the first parameter -recursive.constructor.invocation: - text: Recursive constructor invocation -repeated.annotation.target: - text: Repeated annotation target -repeated.interface: - text: Repeated interface resource.variable.must.be.final: text: Variable used as a try-with-resources resource should be final or effectively final -return.from.void.method: - text: Cannot return a value from a method with void result type -return.outside.method: - text: Return outside method safevararg.annotation.cannot.be.applied.for.record.component: text: '@SafeVarargs is not allowed on a record component' safevarargs.not.allowed.non.final.instance.methods: @@ -730,99 +182,27 @@ static.member.accessed.via.instance.reference: text: Static member ''{0}.{1}'' accessed via instance reference static.method.cannot.override.instance.method: text: Static method ''{0}'' in ''{1}'' cannot override instance method ''{2}'' in ''{3}'' -string.expected: - text: String literal expected -switch.colon.expected.after.case.label: - text: ''':'' expected' switch.expr.empty: text: '''switch'' expression does not have any case clauses' switch.expr.incomplete: text: '''switch'' expression does not cover all possible input values' -text.block.new.line: - text: 'Illegal text block start: missing new line after opening quotes' -text.block.unclosed: - text: Unclosed text block -text.class.inherits.abstract.and.default: - text: '{0} inherits abstract and default for {1} from types {2} and {3}' text.class.inherits.unrelated.defaults: text: '{0} inherits unrelated defaults for {1} from types {2}' text.improper.formed.type: text: Improper formed type; some type parameters are missing -too.many.characters.in.character.literal: - text: Too many characters in character literal -type.parameter.cannot.be.followed.by.other.bounds: - text: Type parameter cannot be followed by other bounds -type.parameter.has.incompatible.upper.bounds: - text: 'Type parameter {0} has incompatible upper bounds: {1}' type.parameter.is.not.used: text: Type parameter ''{0}'' is never used -unary.operator.not.applicable: - text: Operator ''{0}'' cannot be applied to ''{1}'' unchecked.overriding.incompatible.return.type: text: 'Unchecked overriding: return type requires unchecked conversion. Found ''''{0}'''', required ''''{1}''''' -unclosed.char.literal: - text: Unclosed character literal -unclosed.comment: - text: Unclosed comment -underscore.identifier.error: - text: As of Java 9, '_' is a keyword, and may not be used as an identifier -underscore.identifier.warn: - text: Use of '_' as an identifier might not be supported in releases after Java 8 -underscore.lambda.identifier: - text: Use of '_' as a lambda parameter name is not allowed -unexpected.identifier: - text: Unexpected identifier -unexpected.token: - text: Unexpected token -unexpected.tokens: - text: Unexpected tokens -unexpected.type.class.expected: - text: 'Unexpected type: class is expected' -unhandled.close.exceptions: - text: 'Unhandled {1, choice, 0#exception|2#exceptions} from {2}: {0}' -unhandled.exceptions: - text: 'Unhandled {1, choice, 0#exception|2#exceptions}: {0}' -unknown.class: - text: 'Unknown class: ''''{0}''''' -unqualified.super.disallowed: - text: Unqualified super reference is not allowed in extension method -unreachable.statement: - text: Unreachable statement unrelated.overriding.methods.return.types: text: methods have unrelated return types -unresolved.label: - text: 'Undefined label: ''''{0}''''' valid.switch.1_7.selector.types: text: char, byte, short, int, Character, Byte, Short, Integer, String, or an enum valid.switch.selector.types: text: byte, char, short or int -vararg.not.last.parameter: - text: Vararg parameter must be the last in the list -variable.already.assigned: - text: Variable ''{0}'' might already have been assigned to -variable.already.defined: - text: Variable ''{0}'' is already defined in the scope -variable.assigned.in.loop: - text: Variable ''{0}'' might be assigned in loop -variable.expected: - text: Variable expected -variable.must.be.final: - text: Variable ''{0}'' is accessed from within inner class. Needs to be declared final. -variable.must.be.final.or.effectively.final: - text: Variable ''{0}'' is accessed from within inner class, needs to be final or effectively final -variable.not.initialized: - text: Variable ''{0}'' might not have been initialized visibility.access.problem: text: Cannot access ''{0}'' in ''{1}'' -void.type.is.not.allowed: - text: '''void'' type is not allowed here' weaker.privileges: text: '{0}; attempting to assign weaker access privileges (''''{1}''''); was ''''{2}''''' -wildcard.not.expected: - text: Unexpected wildcard -wildcard.type.cannot.be.instantiated: - text: Wildcard type ''{0}'' cannot be instantiated directly wrong.constructor.arguments: text: '''''{0}'''' cannot be applied to ''''{1}''''' -wrong.method.arguments: - text: '''''{0}'''' in ''''{1}'''' cannot be applied to ''''{2}''''' diff --git a/plugin/src/main/java/com/intellij/java/impl/codeInsight/completion/MethodReferenceCompletionProvider.java b/plugin/src/main/java/com/intellij/java/impl/codeInsight/completion/MethodReferenceCompletionProvider.java index 4d56a234dd..1cba992b77 100644 --- a/plugin/src/main/java/com/intellij/java/impl/codeInsight/completion/MethodReferenceCompletionProvider.java +++ b/plugin/src/main/java/com/intellij/java/impl/codeInsight/completion/MethodReferenceCompletionProvider.java @@ -20,6 +20,8 @@ import com.intellij.java.language.impl.psi.impl.source.resolve.graphInference.FunctionalInterfaceParameterizationUtil; import com.intellij.java.language.psi.*; import com.intellij.java.language.psi.util.PsiUtil; +import consulo.annotation.access.RequiredReadAction; +import consulo.annotation.access.RequiredWriteAction; import consulo.language.editor.PsiEquivalenceUtil; import consulo.language.editor.completion.CompletionParameters; import consulo.language.editor.completion.CompletionProvider; @@ -28,88 +30,120 @@ import consulo.language.editor.completion.lookup.TailType; import consulo.language.psi.PsiElement; import consulo.language.util.ProcessingContext; +import consulo.localize.LocalizeValue; import consulo.logging.Logger; import jakarta.annotation.Nonnull; + import java.util.Map; import java.util.function.Consumer; public class MethodReferenceCompletionProvider implements CompletionProvider { - private static final Logger LOG = Logger.getInstance(MethodReferenceCompletionProvider.class); + private static final Logger LOG = Logger.getInstance(MethodReferenceCompletionProvider.class); - @Override - public void addCompletions(@Nonnull CompletionParameters parameters, ProcessingContext context, @Nonnull final CompletionResultSet result) { - if (!PsiUtil.isLanguageLevel8OrHigher(parameters.getOriginalFile())) { - return; - } + @Override + @RequiredReadAction + public void addCompletions( + @Nonnull CompletionParameters parameters, + ProcessingContext context, + @Nonnull final CompletionResultSet result + ) { + if (!PsiUtil.isLanguageLevel8OrHigher(parameters.getOriginalFile())) { + return; + } - final PsiElement rulezzRef = parameters.getPosition().getParent(); - if (rulezzRef == null || !LambdaUtil.isValidLambdaContext(rulezzRef.getParent())) { - return; - } + PsiElement rulezzRef = parameters.getPosition().getParent(); + if (rulezzRef == null || !LambdaUtil.isValidLambdaContext(rulezzRef.getParent())) { + return; + } - final ExpectedTypeInfo[] expectedTypes = JavaSmartCompletionContributor.getExpectedTypes(parameters); - for (ExpectedTypeInfo expectedType : expectedTypes) { - final PsiType defaultType = expectedType.getDefaultType(); - if (LambdaUtil.isFunctionalType(defaultType)) { - final PsiType functionalType = FunctionalInterfaceParameterizationUtil.getGroundTargetType(defaultType); - final PsiType returnType = LambdaUtil.getFunctionalInterfaceReturnType(functionalType); - if (returnType != null) { - final PsiElement position = parameters.getPosition(); - final PsiElement refPlace = position.getParent(); - final ExpectedTypeInfoImpl typeInfo = new ExpectedTypeInfoImpl(returnType, ExpectedTypeInfo.TYPE_OR_SUBTYPE, returnType, TailType.UNKNOWN, null, ExpectedTypeInfoImpl.NULL); - final Map map = LambdaUtil.getFunctionalTypeMap(); - Consumer noTypeCheck = new Consumer() { - @Override - public void accept(final LookupElement lookupElement) { - final PsiElement element = lookupElement.getPsiElement(); - if (element instanceof PsiMethod) { - final PsiMethodReferenceExpression referenceExpression = createMethodReferenceExpression((PsiMethod) element); - if (referenceExpression == null) { - return; - } + ExpectedTypeInfo[] expectedTypes = JavaSmartCompletionContributor.getExpectedTypes(parameters); + for (ExpectedTypeInfo expectedType : expectedTypes) { + PsiType defaultType = expectedType.getDefaultType(); + if (LambdaUtil.isFunctionalType(defaultType)) { + final PsiType functionalType = FunctionalInterfaceParameterizationUtil.getGroundTargetType(defaultType); + PsiType returnType = LambdaUtil.getFunctionalInterfaceReturnType(functionalType); + if (returnType != null) { + PsiElement position = parameters.getPosition(); + final PsiElement refPlace = position.getParent(); + ExpectedTypeInfoImpl typeInfo = new ExpectedTypeInfoImpl( + returnType, + ExpectedTypeInfo.TYPE_OR_SUBTYPE, + returnType, + TailType.UNKNOWN, + null, + ExpectedTypeInfoImpl.NULL + ); + final Map map = LambdaUtil.getFunctionalTypeMap(); + Consumer noTypeCheck = new Consumer<>() { + @Override + @RequiredReadAction + public void accept(LookupElement lookupElement) { + if (lookupElement.getPsiElement() instanceof PsiMethod method) { + PsiMethodReferenceExpression referenceExpression = createMethodReferenceExpression(method); + if (referenceExpression == null) { + return; + } - final PsiType added = map.put(referenceExpression, functionalType); - try { - final PsiElement resolve = referenceExpression.resolve(); - if (resolve != null && PsiEquivalenceUtil.areElementsEquivalent(element, resolve) && PsiMethodReferenceUtil.checkMethodReferenceContext(referenceExpression, - resolve, functionalType) == null) { - result.addElement(new JavaMethodReferenceElement((PsiMethod) element, refPlace)); - } - } finally { - if (added == null) { - map.remove(referenceExpression); - } - } - } - } + PsiType added = map.put(referenceExpression, functionalType); + try { + PsiElement resolve = referenceExpression.resolve(); + if (resolve != null + && PsiEquivalenceUtil.areElementsEquivalent(method, resolve) + && PsiMethodReferenceUtil.checkMethodReferenceContext( + referenceExpression, + resolve, + functionalType + ) == LocalizeValue.empty()) { + result.addElement(new JavaMethodReferenceElement(method, refPlace)); + } + } + finally { + if (added == null) { + map.remove(referenceExpression); + } + } + } + } - private PsiMethodReferenceExpression createMethodReferenceExpression(PsiMethod method) { - PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(method.getProject()); - if (refPlace instanceof PsiMethodReferenceExpression) { - final PsiMethodReferenceExpression referenceExpression = (PsiMethodReferenceExpression) refPlace.copy(); - final PsiElement referenceNameElement = referenceExpression.getReferenceNameElement(); - LOG.assertTrue(referenceNameElement != null, referenceExpression); - referenceNameElement.replace(method.isConstructor() ? elementFactory.createKeyword("new") : elementFactory.createIdentifier(method.getName())); - return referenceExpression; - } else if (method.hasModifierProperty(PsiModifier.STATIC)) { - final PsiClass aClass = method.getContainingClass(); - LOG.assertTrue(aClass != null); - final String qualifiedName = aClass.getQualifiedName(); - return (PsiMethodReferenceExpression) elementFactory.createExpressionFromText(qualifiedName + "::" + (method.isConstructor() ? "new" : method.getName()), refPlace); - } else { - return null; - } - } - }; + @RequiredWriteAction + private PsiMethodReferenceExpression createMethodReferenceExpression(PsiMethod method) { + PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(method.getProject()); + if (refPlace instanceof PsiMethodReferenceExpression methodRef) { + PsiMethodReferenceExpression referenceExpression = (PsiMethodReferenceExpression) methodRef.copy(); + PsiElement referenceNameElement = referenceExpression.getReferenceNameElement(); + LOG.assertTrue(referenceNameElement != null, referenceExpression); + referenceNameElement.replace( + method.isConstructor() + ? elementFactory.createKeyword("new") + : elementFactory.createIdentifier(method.getName()) + ); + return referenceExpression; + } + else if (method.isStatic()) { + PsiClass aClass = method.getContainingClass(); + LOG.assertTrue(aClass != null); + String qualifiedName = aClass.getQualifiedName(); + return (PsiMethodReferenceExpression) elementFactory.createExpressionFromText( + qualifiedName + "::" + (method.isConstructor() ? "new" : method.getName()), + refPlace + ); + } + else { + return null; + } + } + }; - final Runnable runnable = ReferenceExpressionCompletionContributor.fillCompletionVariants(new JavaSmartCompletionParameters(parameters, typeInfo), noTypeCheck); - if (runnable != null) { - runnable.run(); - } + Runnable runnable = ReferenceExpressionCompletionContributor.fillCompletionVariants( + new JavaSmartCompletionParameters(parameters, typeInfo), + noTypeCheck + ); + if (runnable != null) { + runnable.run(); + } + } + } } - } } - } - } diff --git a/plugin/src/test/java_/com/intellij/codeInsight/daemon/lambda/FunctionalInterfaceTest.java b/plugin/src/test/java_/com/intellij/codeInsight/daemon/lambda/FunctionalInterfaceTest.java index b8093923ea..82e8f49697 100644 --- a/plugin/src/test/java_/com/intellij/codeInsight/daemon/lambda/FunctionalInterfaceTest.java +++ b/plugin/src/test/java_/com/intellij/codeInsight/daemon/lambda/FunctionalInterfaceTest.java @@ -18,6 +18,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import consulo.localize.LocalizeValue; import org.jetbrains.annotations.NonNls; import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase; import com.intellij.java.analysis.impl.codeInsight.daemon.impl.analysis.LambdaHighlightingUtil; @@ -32,11 +33,11 @@ public abstract class FunctionalInterfaceTest extends LightDaemonAnalyzerTestCas private void doTestFunctionalInterface(@Nullable String expectedErrorMessage) throws Exception { String filePath = BASE_PATH + "/" + getTestName(false) + ".java"; configureByFile(filePath); - final PsiClass psiClass = getJavaFacade().findClass("Foo", GlobalSearchScope.projectScope(getProject())); + PsiClass psiClass = getJavaFacade().findClass("Foo", GlobalSearchScope.projectScope(getProject())); assertNotNull("Class Foo not found", psiClass); - final String errorMessage = LambdaHighlightingUtil.checkInterfaceFunctional(psiClass); - assertEquals(expectedErrorMessage, errorMessage); + LocalizeValue errorMessage = LambdaHighlightingUtil.checkInterfaceFunctional(psiClass); + assertEquals(expectedErrorMessage, errorMessage.get()); } public void testSimple() throws Exception {