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 afdb71b5a..c9178c70a 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 @@ -220,7 +220,10 @@ public static HighlightInfo checkMemberValueType(@Nullable PsiAnnotationMemberVa } @RequiredReadAction - public static HighlightInfo checkDuplicateAnnotations(@Nonnull PsiAnnotation annotationToCheck, @Nonnull LanguageLevel languageLevel) { + public static HighlightInfo.Builder checkDuplicateAnnotations( + @Nonnull PsiAnnotation annotationToCheck, + @Nonnull LanguageLevel languageLevel + ) { PsiAnnotationOwner owner = annotationToCheck.getOwner(); if (owner == null) { return null; @@ -244,8 +247,7 @@ else if (isAnnotationRepeatedTwice(owner, annotationType.getQualifiedName())) { if (!languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(element) - .descriptionAndTooltip(JavaErrorLocalize.annotationDuplicateAnnotation()) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.annotationDuplicateAnnotation()); } PsiAnnotation metaAnno = @@ -254,16 +256,14 @@ else if (isAnnotationRepeatedTwice(owner, annotationType.getQualifiedName())) { LocalizeValue explanation = JavaErrorLocalize.annotationNonRepeatable(annotationType.getQualifiedName()); return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(element) - .descriptionAndTooltip(JavaErrorLocalize.annotationDuplicateExplained(explanation)) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.annotationDuplicateExplained(explanation)); } String explanation = doCheckRepeatableAnnotation(metaAnno); if (explanation != null) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(element) - .descriptionAndTooltip(JavaErrorLocalize.annotationDuplicateExplained(explanation)) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.annotationDuplicateExplained(explanation)); } PsiClass container = getRepeatableContainer(metaAnno); @@ -381,14 +381,13 @@ public static HighlightInfo checkMissingAttributes(PsiAnnotation annotation) { @Nullable @RequiredReadAction - public static HighlightInfo checkConstantExpression(PsiExpression expression) { + public static HighlightInfo.Builder checkConstantExpression(PsiExpression expression) { PsiElement parent = expression.getParent(); if (PsiUtil.isAnnotationMethod(parent) || parent instanceof PsiNameValuePair || parent instanceof PsiArrayInitializerMemberValue) { if (!PsiUtil.isConstantExpression(expression)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.annotationNonConstantAttributeValue()) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.annotationNonConstantAttributeValue()); } } @@ -416,7 +415,11 @@ public static HighlightInfo checkValidAnnotationType(PsiType type, PsiTypeElemen @Nullable @RequiredReadAction - public static HighlightInfo checkApplicability(@Nonnull PsiAnnotation annotation, @Nonnull LanguageLevel level, @Nonnull PsiFile file) { + public static HighlightInfo.Builder checkApplicability( + @Nonnull PsiAnnotation annotation, + @Nonnull LanguageLevel level, + @Nonnull PsiFile file + ) { if (ANY_ANNOTATION_ALLOWED.accepts(annotation)) { return null; } @@ -433,9 +436,9 @@ public static HighlightInfo checkApplicability(@Nonnull PsiAnnotation annotation } if (!(owner instanceof PsiModifierList)) { - HighlightInfo info = HighlightUtil.checkFeature(annotation, JavaFeature.TYPE_ANNOTATIONS, level, file); - if (info != null) { - return info; + HighlightInfo.Builder hlBuilder = HighlightUtil.checkFeature(annotation, JavaFeature.TYPE_ANNOTATIONS, level, file); + if (hlBuilder != null) { + return hlBuilder; } } @@ -445,15 +448,18 @@ public static HighlightInfo checkApplicability(@Nonnull PsiAnnotation annotation } if (applicable == null) { - return annotationError(annotation, JavaErrorLocalize.annotationNotApplicable(nameRef.getText(), targets[0].getPresentableText())); + return annotationError( + annotation, + JavaErrorLocalize.annotationNotApplicable(nameRef.getText(), targets[0].getPresentableText()) + ); } if (applicable == PsiAnnotation.TargetType.TYPE_USE) { if (owner instanceof PsiClassReferenceType classRefType) { PsiJavaCodeReferenceElement ref = classRefType.getReference(); - HighlightInfo info = checkReferenceTarget(annotation, ref); - if (info != null) { - return info; + HighlightInfo.Builder hlBuilder = checkReferenceTarget(annotation, ref); + if (hlBuilder != null) { + return hlBuilder; } } else if (owner instanceof PsiModifierList modifierList) { @@ -467,9 +473,9 @@ else if (owner instanceof PsiModifierList modifierList) { } if (!(type instanceof PsiPrimitiveType)) { PsiJavaCodeReferenceElement ref = getOutermostReferenceElement(typeElement.getInnermostComponentReferenceElement()); - HighlightInfo info = checkReferenceTarget(annotation, ref); - if (info != null) { - return info; + HighlightInfo.Builder hlBuilder = checkReferenceTarget(annotation, ref); + if (hlBuilder != null) { + return hlBuilder; } } } @@ -486,17 +492,16 @@ else if (owner instanceof PsiTypeElement) { } @RequiredReadAction - private static HighlightInfo annotationError(PsiAnnotation annotation, LocalizeValue message) { + private static HighlightInfo.Builder annotationError(PsiAnnotation annotation, LocalizeValue message) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(annotation) .descriptionAndTooltip(message) - .registerFix(new DeleteAnnotationAction(annotation)) - .create(); + .registerFix(new DeleteAnnotationAction(annotation)); } @Nullable @RequiredReadAction - private static HighlightInfo checkReferenceTarget(PsiAnnotation annotation, @Nullable PsiJavaCodeReferenceElement ref) { + private static HighlightInfo.Builder checkReferenceTarget(PsiAnnotation annotation, @Nullable PsiJavaCodeReferenceElement ref) { if (ref == null) { return null; } 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 d2c77438b..bf5314b1a 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 @@ -34,7 +34,7 @@ import consulo.java.language.impl.localize.JavaErrorLocalize; import consulo.java.language.module.util.JavaClassNames; import consulo.language.content.FileIndexFacade; -import consulo.language.editor.intention.QuickFixAction; +import consulo.language.editor.intention.IntentionAction; import consulo.language.editor.intention.QuickFixActionRegistrar; import consulo.language.editor.rawHighlight.HighlightInfo; import consulo.language.editor.rawHighlight.HighlightInfoHolder; @@ -69,7 +69,7 @@ private GenericsHighlightUtil() { @Nullable @RequiredReadAction - public static HighlightInfo checkInferredTypeArguments( + public static HighlightInfo.Builder checkInferredTypeArguments( PsiTypeParameterListOwner listOwner, PsiElement call, PsiSubstitutor substitutor @@ -79,7 +79,7 @@ public static HighlightInfo checkInferredTypeArguments( @Nullable @RequiredReadAction - private static HighlightInfo checkInferredTypeArguments( + private static HighlightInfo.Builder checkInferredTypeArguments( PsiTypeParameter[] typeParameters, PsiElement call, PsiSubstitutor substitutor @@ -99,8 +99,7 @@ private static HighlightInfo checkInferredTypeArguments( : JavaErrorLocalize.genericsInferredTypeForTypeParameterIsNotWithinItsBoundImplement(c, t1, t2); return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(call) - .descriptionAndTooltip(description) - .create(); + .descriptionAndTooltip(description); } return null; @@ -108,7 +107,7 @@ private static HighlightInfo checkInferredTypeArguments( @Nullable @RequiredReadAction - public static HighlightInfo checkParameterizedReferenceTypeArguments( + public static HighlightInfo.Builder checkParameterizedReferenceTypeArguments( PsiElement resolved, PsiJavaCodeReferenceElement referenceElement, PsiSubstitutor substitutor, @@ -128,7 +127,7 @@ public static HighlightInfo checkParameterizedReferenceTypeArguments( @Nullable @RequiredReadAction - public static HighlightInfo checkReferenceTypeArgumentList( + public static HighlightInfo.Builder checkReferenceTypeArgumentList( PsiTypeParameterListOwner typeParameterListOwner, PsiReferenceParameterList referenceParameterList, PsiSubstitutor substitutor, @@ -143,8 +142,7 @@ public static HighlightInfo checkReferenceTypeArgumentList( if (!typeParameterListOwner.hasTypeParameters()) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(referenceParameterList) - .descriptionAndTooltip(JavaErrorLocalize.genericsDiamondNotApplicable()) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.genericsDiamondNotApplicable()); } inferenceResult = diamondType.resolveInferredTypes(); String errorMessage = inferenceResult.getErrorMessage(); @@ -154,14 +152,13 @@ && detectExpectedType(referenceParameterList) instanceof PsiClassType expectedCl && expectedClassType.isRaw())) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(referenceParameterList) - .descriptionAndTooltip(errorMessage) - .create(); + .descriptionAndTooltip(errorMessage); } } } if (registerIntentions) { - HighlightInfo wrongParamNumberHighlightInfo = + HighlightInfo.Builder wrongParamNumberHighlightInfo = checkForWrongNumberOfTypeParameters(typeParameterListOwner, referenceParameterList, javaSdkVersion); if (wrongParamNumberHighlightInfo != null) { return wrongParamNumberHighlightInfo; @@ -177,30 +174,30 @@ && detectExpectedType(referenceParameterList) instanceof PsiClassType expectedCl PsiType[] types = inferenceResult.getTypes(); for (int i = 0; i < typeParameters.length; i++) { PsiType type = types[i]; - HighlightInfo highlightInfo = checkTypeParameterWithinItsBound( + HighlightInfo.Builder hlBuilder = checkTypeParameterWithinItsBound( typeParameters[i], substitutor, type, referenceElements[0], referenceParameterList ); - if (highlightInfo != null) { - return highlightInfo; + if (hlBuilder != null) { + return hlBuilder; } } } else { for (int i = 0; i < typeParameters.length; i++) { PsiTypeElement typeElement = referenceElements[i]; - HighlightInfo highlightInfo = checkTypeParameterWithinItsBound( + HighlightInfo.Builder hlBuilder = checkTypeParameterWithinItsBound( typeParameters[i], substitutor, typeElement.getType(), typeElement, referenceParameterList ); - if (highlightInfo != null) { - return highlightInfo; + if (hlBuilder != null) { + return hlBuilder; } } } @@ -211,7 +208,7 @@ && detectExpectedType(referenceParameterList) instanceof PsiClassType expectedCl @Nullable @RequiredReadAction - private static HighlightInfo checkForWrongNumberOfTypeParameters( + private static HighlightInfo.Builder checkForWrongNumberOfTypeParameters( PsiTypeParameterListOwner typeParameterListOwner, PsiReferenceParameterList referenceParameterList, @Nonnull JavaSdkVersion javaSdkVersion @@ -241,28 +238,21 @@ private static HighlightInfo checkForWrongNumberOfTypeParameters( description = JavaErrorLocalize.genericsWrongNumberOfTypeArguments(refParametersNum, targetParametersNum); } - HighlightInfo highlightInfo = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) + HighlightInfo.Builder hlBuilder = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(referenceParameterList) - .descriptionAndTooltip(description) - .create(); + .descriptionAndTooltip(description); if (typeParameterListOwner instanceof PsiClass psiClass) { - QuickFixAction.registerQuickFixAction( - highlightInfo, - QuickFixFactory.getInstance().createChangeClassSignatureFromUsageFix(psiClass, referenceParameterList) - ); + hlBuilder.registerFix(QuickFixFactory.getInstance().createChangeClassSignatureFromUsageFix(psiClass, referenceParameterList)); } if (referenceParameterList.getParent().getParent() instanceof PsiTypeElement typeElem && typeElem.getParent() instanceof PsiVariable variable) { if (targetParametersNum == 0) { - QuickFixAction.registerQuickFixAction( - highlightInfo, - QuickFixFactory.getInstance().createRemoveTypeArgumentsFix(variable) - ); + hlBuilder.registerFix(QuickFixFactory.getInstance().createRemoveTypeArgumentsFix(variable)); } - registerVariableParameterizedTypeFixes(highlightInfo, variable, referenceParameterList, javaSdkVersion); + registerVariableParameterizedTypeFixes(hlBuilder, variable, referenceParameterList, javaSdkVersion); } - return highlightInfo; + return hlBuilder; } private static boolean hasSuperMethodsWithTypeParams(PsiMethod method) { @@ -310,7 +300,7 @@ else if (parent instanceof PsiExpressionList) { @Nullable @RequiredReadAction - private static HighlightInfo checkTypeParameterWithinItsBound( + private static HighlightInfo.Builder checkTypeParameterWithinItsBound( PsiTypeParameter classParameter, PsiSubstitutor substitutor, PsiType type, @@ -323,8 +313,7 @@ private static HighlightInfo checkTypeParameterWithinItsBound( && GenericsUtil.checkNotInBounds(type, psiType, referenceParameterList)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(typeElement2Highlight) - .descriptionAndTooltip(JavaErrorLocalize.actualTypeArgumentContradictInferredType()) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.actualTypeArgumentContradictInferredType()); } PsiClassType[] bounds = classParameter.getSuperTypes(); @@ -341,17 +330,13 @@ private static HighlightInfo checkTypeParameterWithinItsBound( ? JavaErrorLocalize.genericsTypeParameterIsNotWithinItsBoundExtend(c, t) : JavaErrorLocalize.genericsTypeParameterIsNotWithinItsBoundImplement(c, t); - HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) + HighlightInfo.Builder hlBuilder = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(typeElement2Highlight) - .descriptionAndTooltip(description) - .create(); - if (bound instanceof PsiClassType boundClassType && referenceClass != null && info != null) { - QuickFixAction.registerQuickFixAction( - info, - QuickFixFactory.getInstance().createExtendsListFix(referenceClass, boundClassType, true), null - ); + .descriptionAndTooltip(description); + if (bound instanceof PsiClassType boundClassType && referenceClass != null) { + hlBuilder.registerFix(QuickFixFactory.getInstance().createExtendsListFix(referenceClass, boundClassType, true)); } - return info; + return hlBuilder; } } return null; @@ -381,7 +366,7 @@ private static LocalizeValue typeParameterListOwnerCategoryDescription(PsiTypePa @Nullable @RequiredReadAction - public static HighlightInfo checkElementInTypeParameterExtendsList( + public static HighlightInfo.Builder checkElementInTypeParameterExtendsList( @Nonnull PsiReferenceList referenceList, @Nonnull PsiClass aClass, @Nonnull JavaResolveResult resolveResult, @@ -398,8 +383,7 @@ public static HighlightInfo checkElementInTypeParameterExtendsList( return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(element) .descriptionAndTooltip(JavaErrorLocalize.interfaceExpected()) - .registerFix(QuickFixFactory.getInstance().createMoveBoundClassToFrontFix(aClass, type)) - .create(); + .registerFix(QuickFixFactory.getInstance().createMoveBoundClassToFrontFix(aClass, type)); } else if (referenceElements.length != 0 && element != referenceElements[0] && referenceElements[0].resolve() instanceof PsiTypeParameter) { @@ -408,8 +392,7 @@ else if (referenceElements.length != 0 && element != referenceElements[0] return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(element) .descriptionAndTooltip(JavaErrorLocalize.typeParameterCannotBeFollowedByOtherBounds()) - .registerFix(QuickFixFactory.getInstance().createExtendsListFix(aClass, type, false)) - .create(); + .registerFix(QuickFixFactory.getInstance().createExtendsListFix(aClass, type, false)); } return null; } @@ -614,11 +597,11 @@ public static HighlightInfo checkUnrelatedDefaultMethods(@Nonnull PsiClass aClas LocalizeValue description = unrelatedDefaults != null ? JavaErrorLocalize.textClassInheritsUnrelatedDefaults(c, m, unrelatedDefaults) : JavaErrorLocalize.textClassInheritsAbstractAndDefault( - c, - m, - HighlightUtil.formatClass(defaultMethodContainingClass), - HighlightUtil.formatClass(unrelatedMethodContainingClass) - ); + c, + m, + HighlightUtil.formatClass(defaultMethodContainingClass), + HighlightUtil.formatClass(unrelatedMethodContainingClass) + ); return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(classIdentifier) @@ -687,7 +670,8 @@ public static HighlightInfo checkUnrelatedConcrete(@Nonnull PsiClass psiClass, @ if (containingClass == null) { continue; } - PsiSubstitutor containingClassSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(containingClass, psiClass, PsiSubstitutor.EMPTY); + PsiSubstitutor containingClassSubstitutor = + TypeConversionUtil.getSuperClassSubstitutor(containingClass, psiClass, PsiSubstitutor.EMPTY); PsiSubstitutor finalSubstitutor = PsiSuperMethodUtil.obtainFinalSubstitutor(containingClass, containingClassSubstitutor, hms.getSubstitutor(), false); MethodSignatureBackedByPsiMethod signature = MethodSignatureBackedByPsiMethod.create(method, finalSubstitutor, false); @@ -938,7 +922,7 @@ else if (refParent instanceof PsiReferenceList refList) { } @RequiredReadAction - public static HighlightInfo checkReferenceTypeUsedAsTypeArgument(PsiTypeElement typeElement, LanguageLevel level) { + public static HighlightInfo.Builder checkReferenceTypeUsedAsTypeArgument(PsiTypeElement typeElement, LanguageLevel level) { PsiType type = typeElement.getType(); if (type != PsiType.NULL && type instanceof PsiPrimitiveType || type instanceof PsiWildcardType wildcardType && wildcardType.getBound() instanceof PsiPrimitiveType) { @@ -954,10 +938,9 @@ public static HighlightInfo checkReferenceTypeUsedAsTypeArgument(PsiTypeElement return null; } - HighlightInfo highlightInfo = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) + HighlightInfo.Builder hlBuilder = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(typeElement) - .descriptionAndTooltip(JavaErrorLocalize.genericsTypeArgumentCannotBeOfPrimitiveType()) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.genericsTypeArgumentCannotBeOfPrimitiveType()); PsiType toConvert = type; if (type instanceof PsiWildcardType wildcardType) { @@ -966,40 +949,40 @@ public static HighlightInfo checkReferenceTypeUsedAsTypeArgument(PsiTypeElement if (toConvert instanceof PsiPrimitiveType primitiveType) { PsiClassType boxedType = primitiveType.getBoxedType(typeElement); if (boxedType != null) { - QuickFixAction.registerQuickFixAction( - highlightInfo, - QuickFixFactory.getInstance().createReplacePrimitiveWithBoxedTypeAction( - typeElement, - toConvert.getPresentableText(), - primitiveType.getBoxedTypeName() - ) - ); + hlBuilder.registerFix(QuickFixFactory.getInstance().createReplacePrimitiveWithBoxedTypeAction( + typeElement, + toConvert.getPresentableText(), + primitiveType.getBoxedTypeName() + )); } } - return highlightInfo; + return hlBuilder; } return null; } @RequiredReadAction - public static HighlightInfo checkForeachExpressionTypeIsIterable(PsiExpression expression) { + public static HighlightInfo.Builder checkForeachExpressionTypeIsIterable(PsiExpression expression) { if (expression == null || expression.getType() == null) { return null; } PsiType itemType = JavaGenericsUtil.getCollectionItemType(expression); if (itemType == null) { - return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) + HighlightInfo.Builder hlBuilder = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.foreachNotApplicable(JavaHighlightUtil.formatType(expression.getType()))) - .registerFix(QuickFixFactory.getInstance().createNotIterableForEachLoopFix(expression)) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.foreachNotApplicable(JavaHighlightUtil.formatType(expression.getType()))); + IntentionAction fix = QuickFixFactory.getInstance().createNotIterableForEachLoopFix(expression); + if (fix != null) { + hlBuilder.registerFix(fix); + } + return hlBuilder; } return null; } @RequiredReadAction - public static HighlightInfo checkForEachParameterType(@Nonnull PsiForeachStatement statement, @Nonnull PsiParameter parameter) { + public static HighlightInfo.Builder checkForEachParameterType(@Nonnull PsiForeachStatement statement, @Nonnull PsiParameter parameter) { PsiExpression expression = statement.getIteratedValue(); PsiType itemType = expression == null ? null : JavaGenericsUtil.getCollectionItemType(expression); if (itemType == null) { @@ -1010,10 +993,10 @@ public static HighlightInfo checkForEachParameterType(@Nonnull PsiForeachStateme if (TypeConversionUtil.isAssignable(parameterType, itemType)) { return null; } - HighlightInfo highlightInfo = + HighlightInfo.Builder hlBuilder = HighlightUtil.createIncompatibleTypeHighlightInfo(itemType, parameterType, parameter.getTextRange(), 0); - HighlightUtil.registerChangeVariableTypeFixes(parameter, itemType, expression, highlightInfo); - return highlightInfo; + HighlightUtil.registerChangeVariableTypeFixes(parameter, itemType, expression, hlBuilder); + return hlBuilder; } //http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.9.2 @@ -1367,11 +1350,11 @@ public static void checkEnumConstantForConstructorProblems( ) { PsiClass containingClass = enumConstant.getContainingClass(); if (enumConstant.getInitializingClass() == null) { - HighlightInfo highlightInfo = + HighlightInfo.Builder highlightInfo = HighlightClassUtil.checkInstantiationOfAbstractClass(containingClass, enumConstant.getNameIdentifier()); if (highlightInfo != null) { - QuickFixAction.registerQuickFixAction(highlightInfo, QuickFixFactory.getInstance().createImplementMethodsFix(enumConstant)); - holder.add(highlightInfo); + highlightInfo.registerFix(QuickFixFactory.getInstance().createImplementMethodsFix(enumConstant)); + holder.add(highlightInfo.create()); return; } highlightInfo = HighlightClassUtil.checkClassWithAbstractMethods( @@ -1380,7 +1363,7 @@ public static void checkEnumConstantForConstructorProblems( enumConstant.getNameIdentifier().getTextRange() ); if (highlightInfo != null) { - holder.add(highlightInfo); + holder.add(highlightInfo.create()); return; } } @@ -1639,12 +1622,11 @@ public static HighlightInfo checkSelectStaticClassFromParameterizedType(PsiEleme } @RequiredReadAction - public static HighlightInfo checkCannotInheritFromTypeParameter(PsiClass superClass, PsiJavaCodeReferenceElement toHighlight) { + public static HighlightInfo.Builder checkCannotInheritFromTypeParameter(PsiClass superClass, PsiJavaCodeReferenceElement toHighlight) { if (superClass instanceof PsiTypeParameter) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(toHighlight) - .descriptionAndTooltip(JavaErrorLocalize.classCannotInheritFromItsTypeParameter()) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.classCannotInheritFromItsTypeParameter()); } return null; } @@ -1731,7 +1713,7 @@ private static boolean unqualifiedNestedClassReferenceAccessedViaContainingClass @RequiredReadAction private static void registerVariableParameterizedTypeFixes( - @Nullable HighlightInfo highlightInfo, + @Nullable HighlightInfo.Builder highlightInfo, @Nonnull PsiVariable variable, @Nonnull PsiReferenceParameterList parameterList, @Nonnull JavaSdkVersion version @@ -1766,7 +1748,7 @@ private static void registerVariableParameterizedTypeFixes( } @RequiredReadAction - public static HighlightInfo checkInferredIntersections(PsiSubstitutor substitutor, TextRange ref) { + public static HighlightInfo.Builder checkInferredIntersections(PsiSubstitutor substitutor, TextRange ref) { for (Map.Entry typeEntry : substitutor.getSubstitutionMap().entrySet()) { String parameterName = typeEntry.getKey().getName(); if (typeEntry.getValue() instanceof PsiIntersectionType intersectionType) { @@ -1776,8 +1758,7 @@ public static HighlightInfo checkInferredIntersections(PsiSubstitutor substituto .descriptionAndTooltip( JavaErrorLocalize.typeParameterHasIncompatibleUpperBounds(parameterName, conflictingConjunctsMessage) ) - .range(ref) - .create(); + .range(ref); } } } 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 9cd07e61e..53bed5dcc 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 @@ -36,7 +36,6 @@ import consulo.document.util.TextRange; import consulo.java.language.impl.localize.JavaErrorLocalize; import consulo.java.language.module.util.JavaClassNames; -import consulo.language.editor.intention.QuickFixAction; import consulo.language.editor.rawHighlight.HighlightInfo; import consulo.language.editor.rawHighlight.HighlightInfoType; import consulo.language.psi.*; @@ -61,7 +60,7 @@ public class HighlightClassUtil { */ @Nullable @RequiredReadAction - public static HighlightInfo checkAbstractInstantiation(@Nonnull PsiJavaCodeReferenceElement ref) { + public static HighlightInfo.Builder checkAbstractInstantiation(@Nonnull PsiJavaCodeReferenceElement ref) { if (ref.getParent() instanceof PsiAnonymousClass anonymousClass && anonymousClass.getParent() instanceof PsiNewExpression newExpr && !PsiUtilCore.hasErrorElementChild(newExpr)) { @@ -72,17 +71,13 @@ public static HighlightInfo checkAbstractInstantiation(@Nonnull PsiJavaCodeRefer @Nullable @RequiredReadAction - private static HighlightInfo checkClassWithAbstractMethods(PsiClass aClass, TextRange range) { + private static HighlightInfo.Builder checkClassWithAbstractMethods(PsiClass aClass, TextRange range) { return checkClassWithAbstractMethods(aClass, aClass, range); } @Nullable @RequiredReadAction - public static HighlightInfo checkClassWithAbstractMethods( - PsiClass aClass, - PsiElement implementsFixElement, - TextRange range - ) { + public static HighlightInfo.Builder checkClassWithAbstractMethods(PsiClass aClass, PsiElement implementsFixElement, TextRange range) { PsiMethod abstractMethod = ClassUtil.getAnyAbstractMethod(aClass); if (abstractMethod == null) { @@ -97,45 +92,34 @@ public static HighlightInfo checkClassWithAbstractMethods( String baseClassName = HighlightUtil.formatClass(aClass, false); String methodName = JavaHighlightUtil.formatMethod(abstractMethod); String c = HighlightUtil.formatClass(superClass, false); - LocalizeValue message = aClass instanceof PsiEnumConstantInitializer || implementsFixElement instanceof PsiEnumConstant + LocalizeValue description = aClass instanceof PsiEnumConstantInitializer || implementsFixElement instanceof PsiEnumConstant ? JavaErrorLocalize.enumConstantShouldImplementMethod(baseClassName, methodName, c) : JavaErrorLocalize.classMustBeAbstract(baseClassName, methodName, c); - HighlightInfo errorResult = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range) - .descriptionAndTooltip(message).create(); + HighlightInfo.Builder hlBuilder = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) + .range(range) + .descriptionAndTooltip(description); PsiMethod anyMethodToImplement = ClassUtil.getAnyMethodToImplement(aClass); if (anyMethodToImplement != null) { if (!anyMethodToImplement.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) || JavaPsiFacade.getInstance(aClass.getProject()).arePackagesTheSame(aClass, superClass)) { - QuickFixAction.registerQuickFixAction( - errorResult, - QuickFixFactory.getInstance().createImplementMethodsFix(implementsFixElement) - ); + hlBuilder.registerFix(QuickFixFactory.getInstance().createImplementMethodsFix(implementsFixElement)); } else { - QuickFixAction.registerQuickFixAction( - errorResult, - QuickFixFactory.getInstance().createModifierListFix(anyMethodToImplement, PsiModifier.PROTECTED, true, true) - ); - QuickFixAction.registerQuickFixAction( - errorResult, - QuickFixFactory.getInstance().createModifierListFix(anyMethodToImplement, PsiModifier.PUBLIC, true, true) - ); + hlBuilder.registerFix(QuickFixFactory.getInstance().createModifierListFix(anyMethodToImplement, PsiModifier.PROTECTED, true, true)); + hlBuilder.registerFix(QuickFixFactory.getInstance().createModifierListFix(anyMethodToImplement, PsiModifier.PUBLIC, true, true)); } } if (!(aClass instanceof PsiAnonymousClass) && HighlightUtil.getIncompatibleModifier(PsiModifier.ABSTRACT, aClass.getModifierList()) == null) { - QuickFixAction.registerQuickFixAction( - errorResult, - QuickFixFactory.getInstance().createAddModifierFix(aClass, PsiModifier.ABSTRACT) - ); + hlBuilder.registerFix(QuickFixFactory.getInstance().createAddModifierFix(aClass, PsiModifier.ABSTRACT)); } - return errorResult; + return hlBuilder; } @Nullable @RequiredReadAction - public static HighlightInfo checkClassMustBeAbstract(PsiClass aClass, TextRange textRange) { + public static HighlightInfo.Builder checkClassMustBeAbstract(PsiClass aClass, TextRange textRange) { if (aClass.isAbstract() || aClass.getRBrace() == null || aClass.isEnum() && hasEnumConstants(aClass)) { return null; } @@ -144,21 +128,21 @@ public static HighlightInfo checkClassMustBeAbstract(PsiClass aClass, TextRange @Nullable @RequiredReadAction - public static HighlightInfo checkInstantiationOfAbstractClass(PsiClass aClass, @Nonnull PsiElement highlightElement) { + public static HighlightInfo.Builder checkInstantiationOfAbstractClass(PsiClass aClass, @Nonnull PsiElement highlightElement) { if (aClass != null && aClass.isAbstract() && !(highlightElement instanceof PsiNewExpression newExpr && newExpr.getType() instanceof PsiArrayType)) { - HighlightInfo.Builder errorResult = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) + HighlightInfo.Builder hlBuilder = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(highlightElement) .descriptionAndTooltip(JavaErrorLocalize.abstractCannotBeInstantiated(aClass.getName())); PsiMethod anyAbstractMethod = ClassUtil.getAnyAbstractMethod(aClass); if (!aClass.isInterface() && anyAbstractMethod == null) { // suggest to make not abstract only if possible - errorResult.registerFix(QuickFixFactory.getInstance().createRemoveModifierFix(aClass, PsiModifier.ABSTRACT)); + hlBuilder.registerFix(QuickFixFactory.getInstance().createRemoveModifierFix(aClass, PsiModifier.ABSTRACT)); } if (anyAbstractMethod != null && highlightElement instanceof PsiNewExpression newExpr && newExpr.getClassReference() != null) { - errorResult.registerFix(QuickFixFactory.getInstance().createImplementAbstractClassMethodsFix(highlightElement)); + hlBuilder.registerFix(QuickFixFactory.getInstance().createImplementAbstractClassMethodsFix(highlightElement)); } - return errorResult.create(); + return hlBuilder; } return null; } @@ -521,7 +505,7 @@ public static HighlightInfo checkImplementsAllowed(PsiReferenceList list) { @Nullable @RequiredReadAction - public static HighlightInfo checkExtendsClassAndImplementsInterface( + public static HighlightInfo.Builder checkExtendsClassAndImplementsInterface( PsiReferenceList referenceList, JavaResolveResult resolveResult, PsiJavaCodeReferenceElement ref @@ -542,28 +526,26 @@ public static HighlightInfo checkExtendsClassAndImplementsInterface( return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(ref) .descriptionAndTooltip(message) - .registerFix(QuickFixFactory.getInstance().createChangeExtendsToImplementsFix(aClass, type)) - .create(); + .registerFix(QuickFixFactory.getInstance().createChangeExtendsToImplementsFix(aClass, type)); } return null; } @Nullable @RequiredReadAction - public static HighlightInfo checkCannotInheritFromFinal(PsiClass superClass, PsiElement elementToHighlight) { + public static HighlightInfo.Builder checkCannotInheritFromFinal(PsiClass superClass, PsiElement elementToHighlight) { if (superClass.isFinal() || superClass.isEnum()) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(elementToHighlight) .descriptionAndTooltip(JavaErrorLocalize.inheritanceFromFinalClass(superClass.getQualifiedName())) - .registerFix(QuickFixFactory.getInstance().createRemoveModifierFix(superClass, PsiModifier.FINAL)) - .create(); + .registerFix(QuickFixFactory.getInstance().createRemoveModifierFix(superClass, PsiModifier.FINAL)); } return null; } @Nullable @RequiredReadAction - public static HighlightInfo checkAnonymousInheritFinal(PsiNewExpression expression) { + public static HighlightInfo.Builder checkAnonymousInheritFinal(PsiNewExpression expression) { PsiAnonymousClass aClass = PsiTreeUtil.getChildOfType(expression, PsiAnonymousClass.class); if (aClass == null) { return null; @@ -597,7 +579,7 @@ private static LocalizeValue checkDefaultConstructorThrowsException( @Nullable @RequiredReadAction - public static HighlightInfo checkClassDoesNotCallSuperConstructorOrHandleExceptions( + public static HighlightInfo.Builder checkClassDoesNotCallSuperConstructorOrHandleExceptions( @Nonnull PsiClass aClass, RefCountHolder refCountHolder, @Nonnull PsiResolveHelper resolveHelper @@ -614,8 +596,9 @@ public static HighlightInfo checkClassDoesNotCallSuperConstructorOrHandleExcepti return checkBaseClassDefaultConstructorProblem(aClass, refCountHolder, resolveHelper, textRange, PsiClassType.EMPTY_ARRAY); } + @Nullable @RequiredReadAction - public static HighlightInfo checkBaseClassDefaultConstructorProblem( + public static HighlightInfo.Builder checkBaseClassDefaultConstructorProblem( @Nonnull PsiClass aClass, RefCountHolder refCountHolder, @Nonnull PsiResolveHelper resolveHelper, @@ -644,8 +627,7 @@ public static HighlightInfo checkBaseClassDefaultConstructorProblem( return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(range) .descriptionAndTooltip(description) - .registerFix(QuickFixFactory.getInstance().createCreateConstructorMatchingSuperFix(aClass)) - .create(); + .registerFix(QuickFixFactory.getInstance().createCreateConstructorMatchingSuperFix(aClass)); } if (refCountHolder != null) { refCountHolder.registerLocallyReferenced(constructor); @@ -658,8 +640,7 @@ public static HighlightInfo checkBaseClassDefaultConstructorProblem( return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(range) .descriptionAndTooltip(JavaErrorLocalize.noDefaultConstructorAvailable(HighlightUtil.formatClass(baseClass))) - .registerFix(QuickFixFactory.getInstance().createCreateConstructorMatchingSuperFix(aClass)) - .create(); + .registerFix(QuickFixFactory.getInstance().createCreateConstructorMatchingSuperFix(aClass)); } @Nullable @@ -1053,7 +1034,7 @@ public static HighlightInfo checkCreateInnerClassFromStaticContext( @Nullable @RequiredReadAction - public static HighlightInfo checkSuperQualifierType(@Nonnull Project project, @Nonnull PsiMethodCallExpression superCall) { + public static HighlightInfo.Builder checkSuperQualifierType(@Nonnull Project project, @Nonnull PsiMethodCallExpression superCall) { if (!RefactoringChangeUtil.isSuperMethodCall(superCall)) { return null; } @@ -1082,8 +1063,7 @@ public static HighlightInfo checkSuperQualifierType(@Nonnull Project project, @N String description = "'" + HighlightUtil.formatClass(targetClass) + "' is not an inner class"; return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(qualifier) - .descriptionAndTooltip(description) - .create(); + .descriptionAndTooltip(description); } } return 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 e7360444c..d23be25f7 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 @@ -31,7 +31,6 @@ import consulo.java.analysis.impl.JavaQuickFixBundle; import consulo.java.language.impl.localize.JavaErrorLocalize; import consulo.language.ast.IElementType; -import consulo.language.editor.intention.QuickFixAction; import consulo.language.editor.rawHighlight.HighlightInfo; import consulo.language.editor.rawHighlight.HighlightInfoType; import consulo.language.psi.PsiElement; @@ -283,17 +282,11 @@ public static HighlightInfo checkFinalFieldInitialized(@Nonnull PsiField field) .descriptionAndTooltip(JavaErrorLocalize.variableNotInitialized(field.getName())) .registerFix( QuickFixFactory.getInstance().createCreateConstructorParameterFromFieldFix(field), - null, - null, - HighlightMethodUtil.getFixRange(field), - null + HighlightMethodUtil.getFixRange(field) ) .registerFix( QuickFixFactory.getInstance().createInitializeFinalFieldInConstructorFix(field), - null, - null, - HighlightMethodUtil.getFixRange(field), - null + HighlightMethodUtil.getFixRange(field) ); PsiClass containingClass = field.getContainingClass(); if (containingClass != null && !containingClass.isInterface()) { @@ -831,7 +824,7 @@ private static boolean isSameField( @Nullable @RequiredReadAction - public static HighlightInfo checkVariableMustBeFinal( + public static HighlightInfo.Builder checkVariableMustBeFinal( @Nonnull PsiVariable variable, @Nonnull PsiJavaCodeReferenceElement context, @Nonnull LanguageLevel languageLevel @@ -857,14 +850,14 @@ && notAccessedForWriting(variable, new LocalSearchScope(param.getDeclarationScop return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(context) .descriptionAndTooltip(description) - .registerFix(QuickFixFactory.getInstance().createVariableAccessFromInnerClassFix(variable, innerClass)) - .create(); + .registerFix(QuickFixFactory.getInstance().createVariableAccessFromInnerClassFix(variable, innerClass)); } return checkWriteToFinalInsideLambda(variable, context); } + @Nullable @RequiredReadAction - private static HighlightInfo checkWriteToFinalInsideLambda( + private static HighlightInfo.Builder checkWriteToFinalInsideLambda( @Nonnull PsiVariable variable, @Nonnull PsiJavaCodeReferenceElement context ) { @@ -878,8 +871,7 @@ private static HighlightInfo checkWriteToFinalInsideLambda( return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(context) .descriptionAndTooltip(JavaErrorLocalize.lambdaVariableMustBeFinal()) - .registerFix(QuickFixFactory.getInstance().createVariableAccessFromInnerClassFix(variable, lambdaExpression)) - .create(); + .registerFix(QuickFixFactory.getInstance().createVariableAccessFromInnerClassFix(variable, lambdaExpression)); } } return null; 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 5e68de8bd..c20743169 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 @@ -85,16 +85,17 @@ public static String createClashMethodMessage(PsiMethod method1, PsiMethod metho String m2 = JavaHighlightUtil.formatMethod(method2); return showContainingClasses ? JavaErrorLocalize.clashMethodsMessageShowClasses( - m1, - m2, - HighlightUtil.formatClass(method1.getContainingClass()), - HighlightUtil.formatClass(method2.getContainingClass()) - ).get() + m1, + m2, + HighlightUtil.formatClass(method1.getContainingClass()), + HighlightUtil.formatClass(method2.getContainingClass()) + ).get() : JavaErrorLocalize.clashMethodsMessage(m1, m2).get(); } + @Nullable @RequiredReadAction - public static HighlightInfo checkMethodWeakerPrivileges( + public static HighlightInfo.Builder checkMethodWeakerPrivileges( @Nonnull MethodSignatureBackedByPsiMethod methodSignature, @Nonnull List superMethodSignatures, boolean includeRealPositionInfo, @@ -118,16 +119,18 @@ public static HighlightInfo checkMethodWeakerPrivileges( if (!includeRealPositionInfo && MethodSignatureUtil.isSuperMethod(superMethod, method)) { continue; } - HighlightInfo info = isWeaker(method, modifierList, accessModifier, accessLevel, superMethod, includeRealPositionInfo); - if (info != null) { - return info; + HighlightInfo.Builder hlBuilder = + isWeaker(method, modifierList, accessModifier, accessLevel, superMethod, includeRealPositionInfo); + if (hlBuilder != null) { + return hlBuilder; } } return null; } + @Nullable @RequiredReadAction - private static HighlightInfo isWeaker( + private static HighlightInfo.Builder isWeaker( PsiMethod method, PsiModifierList modifierList, String accessModifier, @@ -158,8 +161,7 @@ private static HighlightInfo isWeaker( VisibilityUtil.toPresentableText(accessModifier), PsiUtil.getAccessModifier(superAccessLevel) )) - .registerFix(QuickFixFactory.getInstance().createAddModifierFix(method, PsiUtil.getAccessModifier(superAccessLevel))) - .create(); + .registerFix(QuickFixFactory.getInstance().createAddModifierFix(method, PsiUtil.getAccessModifier(superAccessLevel))); } return null; } @@ -277,36 +279,39 @@ private static HighlightInfo createIncompatibleReturnTypeMessage( ) { String description = MessageFormat.format("{0}; {1}", createClashMethodMessage(method, superMethod, true), detailMessage); QuickFixFactory factory = QuickFixFactory.getInstance(); - HighlightInfo.Builder builder = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) + HighlightInfo.Builder hlBuilder = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(textRange) .descriptionAndTooltip(description) .registerFix(factory.createMethodReturnFix(method, substitutedSuperReturnType, false)) .registerFix(factory.createSuperMethodReturnFix(superMethod, returnType)); PsiClass returnClass = PsiUtil.resolveClassInClassTypeOnly(returnType); if (returnClass != null && substitutedSuperReturnType instanceof PsiClassType classType) { - builder.registerFix(factory.createChangeParameterClassFix(returnClass, classType)); + hlBuilder.registerFix(factory.createChangeParameterClassFix(returnClass, classType)); } - return builder.create(); + return hlBuilder.create(); } - public static HighlightInfo checkMethodOverridesFinal( + @Nullable + @RequiredReadAction + public static HighlightInfo.Builder checkMethodOverridesFinal( MethodSignatureBackedByPsiMethod methodSignature, List superMethodSignatures ) { PsiMethod method = methodSignature.getMethod(); for (MethodSignatureBackedByPsiMethod superMethodSignature : superMethodSignatures) { PsiMethod superMethod = superMethodSignature.getMethod(); - HighlightInfo info = checkSuperMethodIsFinal(method, superMethod); - if (info != null) { - return info; + HighlightInfo.Builder hlBuilder = checkSuperMethodIsFinal(method, superMethod); + if (hlBuilder != null) { + return hlBuilder; } } return null; } + @Nullable @RequiredReadAction - private static HighlightInfo checkSuperMethodIsFinal(PsiMethod method, PsiMethod superMethod) { + private static HighlightInfo.Builder checkSuperMethodIsFinal(PsiMethod method, PsiMethod superMethod) { // strange things happen when super method is from Object and method from interface if (superMethod.isFinal()) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) @@ -321,8 +326,7 @@ private static HighlightInfo checkSuperMethodIsFinal(PsiMethod method, PsiMethod PsiModifier.FINAL, false, true - )) - .create(); + )); } return null; } @@ -455,7 +459,7 @@ private static boolean isMethodThrows( @Nullable @RequiredReadAction - public static HighlightInfo checkMethodCall( + public static HighlightInfo.Builder checkMethodCall( @Nonnull PsiMethodCallExpression methodCall, @Nonnull PsiResolveHelper resolveHelper, @Nonnull LanguageLevel languageLevel, @@ -472,55 +476,53 @@ public static HighlightInfo checkMethodCall( if (isDummy) { return null; } - HighlightInfo highlightInfo; + HighlightInfo.Builder hlBuilder; PsiSubstitutor substitutor = resolveResult.getSubstitutor(); if (resolved instanceof PsiMethod method && resolveResult.isValidResult()) { TextRange fixRange = getFixRange(methodCall); - highlightInfo = HighlightUtil.checkUnhandledExceptions(methodCall, fixRange); + hlBuilder = HighlightUtil.checkUnhandledExceptions(methodCall, fixRange); - if (highlightInfo == null && method.isStatic()) { + if (hlBuilder == null && method.isStatic()) { PsiClass containingClass = method.getContainingClass(); if (containingClass != null && containingClass.isInterface()) { PsiReferenceExpression methodRef = methodCall.getMethodExpression(); PsiElement element = ObjectUtil.notNull(methodRef.getReferenceNameElement(), methodRef); - highlightInfo = HighlightUtil.checkFeature(element, JavaFeature.STATIC_INTERFACE_CALLS, languageLevel, file); - if (highlightInfo == null) { + hlBuilder = HighlightUtil.checkFeature(element, JavaFeature.STATIC_INTERFACE_CALLS, languageLevel, file); + if (hlBuilder == null) { LocalizeValue message = checkStaticInterfaceMethodCallQualifier(methodRef, resolveResult.getCurrentFileResolveScope(), containingClass); if (message != null) { - highlightInfo = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) + hlBuilder = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .descriptionAndTooltip(message) - .range(fixRange) - .create(); + .range(fixRange); } } } } - if (highlightInfo == null) { - highlightInfo = GenericsHighlightUtil.checkInferredIntersections(substitutor, fixRange); + if (hlBuilder == null) { + hlBuilder = GenericsHighlightUtil.checkInferredIntersections(substitutor, fixRange); } - if (highlightInfo == null) { - highlightInfo = checkVarargParameterErasureToBeAccessible((MethodCandidateInfo)resolveResult, methodCall); + if (hlBuilder == null) { + hlBuilder = checkVarargParameterErasureToBeAccessible((MethodCandidateInfo)resolveResult, methodCall); } - if (highlightInfo == null) { + if (hlBuilder == null) { String errorMessage = ((MethodCandidateInfo)resolveResult).getInferenceErrorMessage(); if (errorMessage != null) { - highlightInfo = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) + hlBuilder = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .descriptionAndTooltip(errorMessage) - .range(fixRange) - .create(); - if (highlightInfo != null) { - registerMethodCallIntentions(highlightInfo, methodCall, list, resolveHelper); - registerMethodReturnFixAction(highlightInfo, (MethodCandidateInfo)resolveResult, methodCall); + .range(fixRange); + if (hlBuilder != null) { + registerMethodCallIntentions(hlBuilder, methodCall, list, resolveHelper); + registerMethodReturnFixAction(hlBuilder, (MethodCandidateInfo)resolveResult, methodCall); registerTargetTypeFixesBasedOnApplicabilityInference( methodCall, (MethodCandidateInfo)resolveResult, (PsiMethod)resolved, - highlightInfo + hlBuilder ); } } @@ -535,7 +537,7 @@ public static HighlightInfo checkMethodCall( } if (!resolveResult.isAccessible() || !resolveResult.isStaticsScopeCorrect()) { - highlightInfo = null; + hlBuilder = null; } else if (candidateInfo != null && !candidateInfo.isApplicable()) { if (candidateInfo.isTypeArgumentsApplicable()) { @@ -559,16 +561,15 @@ else if (candidateInfo != null && !candidateInfo.isApplicable()) { PsiElement element = elementToHighlight.get(); int navigationShift = element instanceof PsiExpressionList ? +1 : 0; // argument list starts with paren which there is no need to highlight - highlightInfo = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) + hlBuilder = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(element) .description(description) .escapedToolTip(toolTip) - .navigationShift(navigationShift) - .create(); - if (highlightInfo != null) { - registerMethodCallIntentions(highlightInfo, methodCall, list, resolveHelper); - registerMethodReturnFixAction(highlightInfo, candidateInfo, methodCall); - registerTargetTypeFixesBasedOnApplicabilityInference(methodCall, candidateInfo, resolvedMethod, highlightInfo); + .navigationShift(navigationShift); + if (hlBuilder != null) { + registerMethodCallIntentions(hlBuilder, methodCall, list, resolveHelper); + registerMethodReturnFixAction(hlBuilder, candidateInfo, methodCall); + registerTargetTypeFixesBasedOnApplicabilityInference(methodCall, candidateInfo, resolvedMethod, hlBuilder); } } else { @@ -576,11 +577,11 @@ else if (candidateInfo != null && !candidateInfo.isApplicable()) { PsiReferenceParameterList typeArgumentList = methodCall.getTypeArgumentList(); PsiSubstitutor applicabilitySubstitutor = candidateInfo.getSubstitutor(false); if (typeArgumentList.getTypeArguments().length == 0 && resolvedMethod.hasTypeParameters()) { - highlightInfo = + hlBuilder = GenericsHighlightUtil.checkInferredTypeArguments(resolvedMethod, methodCall, applicabilitySubstitutor); } else { - highlightInfo = GenericsHighlightUtil.checkParameterizedReferenceTypeArguments( + hlBuilder = GenericsHighlightUtil.checkParameterizedReferenceTypeArguments( resolved, methodExpression, applicabilitySubstitutor, @@ -590,56 +591,32 @@ else if (candidateInfo != null && !candidateInfo.isApplicable()) { } } else { - highlightInfo = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) + hlBuilder = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(methodCall) - .descriptionAndTooltip(JavaErrorLocalize.methodCallExpected()) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.methodCallExpected()); if (resolved instanceof PsiClass psiClass) { - QuickFixAction.registerQuickFixAction( - highlightInfo, - QuickFixFactory.getInstance().createInsertNewFix(methodCall, psiClass) - ); + hlBuilder.registerFix(QuickFixFactory.getInstance().createInsertNewFix(methodCall, psiClass)); } else { TextRange range = getFixRange(methodCall); - QuickFixAction.registerQuickFixAction( - highlightInfo, - range, - QuickFixFactory.getInstance().createCreateMethodFromUsageFix(methodCall) - ); - QuickFixAction.registerQuickFixAction( - highlightInfo, - range, - QuickFixFactory.getInstance().createCreateAbstractMethodFromUsageFix(methodCall) - ); - QuickFixAction.registerQuickFixAction( - highlightInfo, - range, - QuickFixFactory.getInstance().createCreatePropertyFromUsageFix(methodCall) - ); - QuickFixAction.registerQuickFixAction( - highlightInfo, - range, - QuickFixFactory.getInstance().createStaticImportMethodFix(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); if (resolved instanceof PsiVariable variable && languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) { PsiMethod method = LambdaUtil.getFunctionalInterfaceMethod(variable.getType()); if (method != null) { - QuickFixAction.registerQuickFixAction( - highlightInfo, - range, - QuickFixFactory.getInstance().createInsertMethodCallFix(methodCall, method) - ); + hlBuilder.registerFix(QuickFixFactory.getInstance().createInsertMethodCallFix(methodCall, method), range); } } } } } - if (highlightInfo == null) { - highlightInfo = + if (hlBuilder == null) { + hlBuilder = GenericsHighlightUtil.checkParameterizedReferenceTypeArguments(resolved, referenceToMethod, substitutor, javaSdkVersion); } - return highlightInfo; + return hlBuilder; } @RequiredReadAction @@ -647,7 +624,7 @@ private static void registerTargetTypeFixesBasedOnApplicabilityInference( @Nonnull PsiMethodCallExpression methodCall, MethodCandidateInfo resolveResult, PsiMethod resolved, - HighlightInfo highlightInfo + HighlightInfo.Builder hlBuilder ) { PsiElement parent = PsiUtil.skipParenthesizedExprUp(methodCall.getParent()); PsiVariable variable = null; @@ -669,7 +646,7 @@ else if (parent instanceof PsiAssignmentExpression assignment variable, expectedTypeByApplicabilityConstraints, methodCall, - highlightInfo + hlBuilder ); } } @@ -715,7 +692,11 @@ private static LocalizeValue checkStaticInterfaceMethodCallQualifier( } @RequiredReadAction - private static void registerMethodReturnFixAction(HighlightInfo highlightInfo, MethodCandidateInfo candidate, PsiCall methodCall) { + private static void registerMethodReturnFixAction( + HighlightInfo.Builder highlightInfo, + MethodCandidateInfo candidate, + PsiCall methodCall + ) { if (methodCall.getParent() instanceof PsiReturnStatement) { PsiMethod containerMethod = PsiTreeUtil.getParentOfType(methodCall, PsiMethod.class, true, PsiLambdaExpression.class); if (containerMethod != null) { @@ -728,14 +709,13 @@ private static void registerMethodReturnFixAction(HighlightInfo highlightInfo, M .createRawSubstitutor(method) .substitute(methodCallTypeByArgs); if (methodCallTypeByArgs != null) { - QuickFixAction.registerQuickFixAction( - highlightInfo, - getFixRange(methodCall), + highlightInfo.registerFix( QuickFixFactory.getInstance().createMethodReturnFix( containerMethod, methodCallTypeByArgs, true - ) + ), + getFixRange(methodCall) ); } } @@ -819,7 +799,7 @@ public static boolean isDummyConstructorCall( @Nullable @RequiredReadAction - public static HighlightInfo checkAmbiguousMethodCallIdentifier( + public static HighlightInfo.Builder checkAmbiguousMethodCallIdentifier( @Nonnull PsiReferenceExpression referenceToMethod, @Nonnull JavaResolveResult[] resolveResults, @Nonnull PsiExpressionList list, @@ -861,10 +841,10 @@ else if (element != null && !resolveResult.isStaticsScopeCorrect()) { if (element instanceof PsiMethod method && method.isStatic()) { PsiClass containingClass = method.getContainingClass(); if (containingClass != null && containingClass.isInterface()) { - HighlightInfo info = + HighlightInfo.Builder hlBuilder = HighlightUtil.checkFeature(elementToHighlight, JavaFeature.STATIC_INTERFACE_CALLS, languageLevel, file); - if (info != null) { - return info; + if (hlBuilder != null) { + return hlBuilder; } description = checkStaticInterfaceMethodCallQualifier( referenceToMethod, @@ -874,10 +854,9 @@ else if (element != null && !resolveResult.isStaticsScopeCorrect()) { if (description != null) { return HighlightInfo.newHighlightInfo(highlightInfoType) .range(elementToHighlight) - .description(description.get()) + .description(description) .escapedToolTip(XmlStringUtil.escapeString(description.get())) - .registerFix(QuickFixFactory.getInstance().createAccessStaticViaInstanceFix(referenceToMethod, resolveResult)) - .create(); + .registerFix(QuickFixFactory.getInstance().createAccessStaticViaInstanceFix(referenceToMethod, resolveResult)); } } } @@ -896,37 +875,36 @@ else if (element != null && !resolveResult.isStaticsScopeCorrect()) { } String toolTip = XmlStringUtil.escapeString(description.get()); - HighlightInfo info = HighlightInfo.newHighlightInfo(highlightInfoType) + HighlightInfo.Builder hlBuilder = HighlightInfo.newHighlightInfo(highlightInfoType) .range(elementToHighlight) - .description(description.get()) - .escapedToolTip(toolTip) - .create(); - registerMethodCallIntentions(info, methodCall, list, resolveHelper); + .description(description) + .escapedToolTip(toolTip); + registerMethodCallIntentions(hlBuilder, methodCall, list, resolveHelper); if (element != null && !resolveResult.isStaticsScopeCorrect()) { - HighlightUtil.registerStaticProblemQuickFixAction(element, info, referenceToMethod); + HighlightUtil.registerStaticProblemQuickFixAction(element, hlBuilder, referenceToMethod); } TextRange fixRange = getFixRange(elementToHighlight); - CastMethodArgumentFix.REGISTRAR.registerCastActions(candidates, methodCall, info, fixRange); - WrapArrayToArraysAsListFix.REGISTAR.registerCastActions(candidates, methodCall, info, fixRange); - WrapLongWithMathToIntExactFix.REGISTAR.registerCastActions(candidates, methodCall, info, fixRange); - WrapObjectWithOptionalOfNullableFix.REGISTAR.registerCastActions(candidates, methodCall, info, fixRange); - WrapLongWithMathToIntExactFix.REGISTAR.registerCastActions(candidates, methodCall, info, fixRange); - PermuteArgumentsFix.registerFix(info, methodCall, candidates, fixRange); - WrapExpressionFix.registerWrapAction(candidates, list.getExpressions(), info); - registerChangeParameterClassFix(methodCall, list, info); - if (candidates.length == 0 && info != null) { + CastMethodArgumentFix.REGISTRAR.registerCastActions(candidates, methodCall, hlBuilder, fixRange); + WrapArrayToArraysAsListFix.REGISTAR.registerCastActions(candidates, methodCall, hlBuilder, fixRange); + WrapLongWithMathToIntExactFix.REGISTAR.registerCastActions(candidates, methodCall, hlBuilder, fixRange); + WrapObjectWithOptionalOfNullableFix.REGISTAR.registerCastActions(candidates, methodCall, hlBuilder, fixRange); + WrapLongWithMathToIntExactFix.REGISTAR.registerCastActions(candidates, methodCall, hlBuilder, fixRange); + PermuteArgumentsFix.registerFix(hlBuilder, methodCall, candidates, fixRange); + WrapExpressionFix.registerWrapAction(candidates, list.getExpressions(), hlBuilder); + registerChangeParameterClassFix(methodCall, list, hlBuilder); + if (candidates.length == 0 && hlBuilder != null) { UnresolvedReferenceQuickFixProvider.registerReferenceFixes( methodCall.getMethodExpression(), - QuickFixActionRegistrar.create(info) + QuickFixActionRegistrar.create(hlBuilder) ); } - return info; + return hlBuilder; } @Nullable @RequiredReadAction - public static HighlightInfo checkAmbiguousMethodCallArguments( + public static HighlightInfo.Builder checkAmbiguousMethodCallArguments( @Nonnull PsiReferenceExpression referenceToMethod, @Nonnull JavaResolveResult[] resolveResults, @Nonnull PsiExpressionList list, @@ -1002,36 +980,36 @@ public static HighlightInfo checkAmbiguousMethodCallArguments( } toolTip = XmlStringUtil.escapeString(description); } - HighlightInfo info = HighlightInfo.newHighlightInfo(highlightInfoType) + HighlightInfo.Builder hlBuilder = HighlightInfo.newHighlightInfo(highlightInfoType) .range(elementToHighlight) .description(description) - .escapedToolTip(toolTip) - .create(); + .escapedToolTip(toolTip); if (methodCandidate2 == null) { - registerMethodCallIntentions(info, methodCall, list, resolveHelper); + registerMethodCallIntentions(hlBuilder, methodCall, list, resolveHelper); } if (!resolveResult.isAccessible() && resolveResult.isStaticsScopeCorrect() && methodCandidate2 != null) { HighlightUtil.registerAccessQuickFixAction( (PsiMember)element, referenceToMethod, - info, + hlBuilder, + elementToHighlight.getTextRange(), resolveResult.getCurrentFileResolveScope() ); } if (element != null && !resolveResult.isStaticsScopeCorrect()) { - HighlightUtil.registerStaticProblemQuickFixAction(element, info, referenceToMethod); + HighlightUtil.registerStaticProblemQuickFixAction(element, hlBuilder, referenceToMethod); } TextRange fixRange = getFixRange(elementToHighlight); - CastMethodArgumentFix.REGISTRAR.registerCastActions(candidates, methodCall, info, fixRange); - WrapArrayToArraysAsListFix.REGISTAR.registerCastActions(candidates, methodCall, info, fixRange); - WrapLongWithMathToIntExactFix.REGISTAR.registerCastActions(candidates, methodCall, info, fixRange); - WrapObjectWithOptionalOfNullableFix.REGISTAR.registerCastActions(candidates, methodCall, info, fixRange); - WrapStringWithFileFix.REGISTAR.registerCastActions(candidates, methodCall, info, fixRange); - PermuteArgumentsFix.registerFix(info, methodCall, candidates, fixRange); - WrapExpressionFix.registerWrapAction(candidates, list.getExpressions(), info); - registerChangeParameterClassFix(methodCall, list, info); - return info; + CastMethodArgumentFix.REGISTRAR.registerCastActions(candidates, methodCall, hlBuilder, fixRange); + WrapArrayToArraysAsListFix.REGISTAR.registerCastActions(candidates, methodCall, hlBuilder, fixRange); + WrapLongWithMathToIntExactFix.REGISTAR.registerCastActions(candidates, methodCall, hlBuilder, fixRange); + WrapObjectWithOptionalOfNullableFix.REGISTAR.registerCastActions(candidates, methodCall, hlBuilder, fixRange); + WrapStringWithFileFix.REGISTAR.registerCastActions(candidates, methodCall, hlBuilder, fixRange); + PermuteArgumentsFix.registerFix(hlBuilder, methodCall, candidates, fixRange); + WrapExpressionFix.registerWrapAction(candidates, list.getExpressions(), hlBuilder); + registerChangeParameterClassFix(methodCall, list, hlBuilder); + return hlBuilder; } @Nonnull @@ -1048,89 +1026,55 @@ private static MethodCandidateInfo[] toMethodCandidates(@Nonnull JavaResolveResu @RequiredReadAction private static void registerMethodCallIntentions( - @Nullable HighlightInfo highlightInfo, + @Nullable HighlightInfo.Builder hlBuilder, PsiMethodCallExpression methodCall, PsiExpressionList list, PsiResolveHelper resolveHelper ) { + if (hlBuilder == null) { + return; + } TextRange fixRange = getFixRange(methodCall); + QuickFixFactory factory = QuickFixFactory.getInstance(); if (methodCall.getMethodExpression().getQualifierExpression() instanceof PsiReferenceExpression qualifierExpr && qualifierExpr.resolve() instanceof PsiClass psiClass && psiClass.getContainingClass() != null && !psiClass.isStatic()) { - QuickFixAction.registerQuickFixAction( - highlightInfo, - QuickFixFactory.getInstance().createAddModifierFix(psiClass, PsiModifier.STATIC) - ); + hlBuilder.registerFix(factory.createAddModifierFix(psiClass, PsiModifier.STATIC)); } - QuickFixAction.registerQuickFixAction( - highlightInfo, - fixRange, - QuickFixFactory.getInstance().createCreateMethodFromUsageFix(methodCall) - ); - QuickFixAction.registerQuickFixAction( - highlightInfo, - fixRange, - QuickFixFactory.getInstance().createCreateAbstractMethodFromUsageFix(methodCall) - ); - QuickFixAction.registerQuickFixAction( - highlightInfo, - fixRange, - QuickFixFactory.getInstance().createCreateConstructorFromSuperFix(methodCall) - ); - QuickFixAction.registerQuickFixAction( - highlightInfo, - fixRange, - QuickFixFactory.getInstance().createCreateConstructorFromThisFix(methodCall) - ); - QuickFixAction.registerQuickFixAction( - highlightInfo, - fixRange, - QuickFixFactory.getInstance().createCreatePropertyFromUsageFix(methodCall) - ); - QuickFixAction.registerQuickFixAction( - highlightInfo, - fixRange, - QuickFixFactory.getInstance().createCreateGetterSetterPropertyFromUsageFix(methodCall) - ); + 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); + CandidateInfo[] methodCandidates = resolveHelper.getReferencedMethodCandidates(methodCall, false); - CastMethodArgumentFix.REGISTRAR.registerCastActions(methodCandidates, methodCall, highlightInfo, fixRange); - PermuteArgumentsFix.registerFix(highlightInfo, methodCall, methodCandidates, fixRange); - AddTypeArgumentsFix.REGISTRAR.registerCastActions(methodCandidates, methodCall, highlightInfo, fixRange); - WrapArrayToArraysAsListFix.REGISTAR.registerCastActions(methodCandidates, methodCall, highlightInfo, fixRange); - WrapLongWithMathToIntExactFix.REGISTAR.registerCastActions(methodCandidates, methodCall, highlightInfo, fixRange); - WrapObjectWithOptionalOfNullableFix.REGISTAR.registerCastActions(methodCandidates, methodCall, highlightInfo, fixRange); - WrapStringWithFileFix.REGISTAR.registerCastActions(methodCandidates, methodCall, highlightInfo, fixRange); - registerMethodAccessLevelIntentions(methodCandidates, methodCall, list, highlightInfo); - registerChangeMethodSignatureFromUsageIntentions(methodCandidates, list, highlightInfo, fixRange); - RemoveRedundantArgumentsFix.registerIntentions(methodCandidates, list, highlightInfo, fixRange); - ConvertDoubleToFloatFix.registerIntentions(methodCandidates, list, highlightInfo, fixRange); - WrapExpressionFix.registerWrapAction(methodCandidates, list.getExpressions(), highlightInfo); - registerChangeParameterClassFix(methodCall, list, highlightInfo); + CastMethodArgumentFix.REGISTRAR.registerCastActions(methodCandidates, methodCall, hlBuilder, fixRange); + PermuteArgumentsFix.registerFix(hlBuilder, methodCall, methodCandidates, fixRange); + AddTypeArgumentsFix.REGISTRAR.registerCastActions(methodCandidates, methodCall, hlBuilder, fixRange); + WrapArrayToArraysAsListFix.REGISTAR.registerCastActions(methodCandidates, methodCall, hlBuilder, fixRange); + WrapLongWithMathToIntExactFix.REGISTAR.registerCastActions(methodCandidates, methodCall, hlBuilder, fixRange); + WrapObjectWithOptionalOfNullableFix.REGISTAR.registerCastActions(methodCandidates, methodCall, hlBuilder, fixRange); + WrapStringWithFileFix.REGISTAR.registerCastActions(methodCandidates, methodCall, hlBuilder, fixRange); + registerMethodAccessLevelIntentions(methodCandidates, methodCall, list, hlBuilder, fixRange); + registerChangeMethodSignatureFromUsageIntentions(methodCandidates, list, hlBuilder, fixRange); + RemoveRedundantArgumentsFix.registerIntentions(methodCandidates, list, hlBuilder, fixRange); + ConvertDoubleToFloatFix.registerIntentions(methodCandidates, list, hlBuilder, fixRange); + WrapExpressionFix.registerWrapAction(methodCandidates, list.getExpressions(), hlBuilder); + registerChangeParameterClassFix(methodCall, list, hlBuilder); if (methodCandidates.length == 0) { - QuickFixAction.registerQuickFixAction( - highlightInfo, - fixRange, - QuickFixFactory.getInstance().createStaticImportMethodFix(methodCall) - ); - QuickFixAction.registerQuickFixAction(highlightInfo, fixRange, QuickFixFactory.getInstance().addMethodQualifierFix(methodCall)); + hlBuilder.registerFix(factory.createStaticImportMethodFix(methodCall), fixRange); + hlBuilder.registerFix(factory.addMethodQualifierFix(methodCall), fixRange); } - for (IntentionAction action : QuickFixFactory.getInstance().getVariableTypeFromCallFixes(methodCall, list)) { - QuickFixAction.registerQuickFixAction(highlightInfo, fixRange, action); + for (IntentionAction action : factory.getVariableTypeFromCallFixes(methodCall, list)) { + hlBuilder.registerFix(action, fixRange); } - QuickFixAction.registerQuickFixAction( - highlightInfo, - fixRange, - QuickFixFactory.getInstance().createReplaceAddAllArrayToCollectionFix(methodCall) - ); - QuickFixAction.registerQuickFixAction( - highlightInfo, - fixRange, - QuickFixFactory.getInstance().createSurroundWithArrayFix(methodCall, null) - ); - QualifyThisArgumentFix.registerQuickFixAction(methodCandidates, methodCall, highlightInfo, fixRange); + hlBuilder.registerFix(factory.createReplaceAddAllArrayToCollectionFix(methodCall), fixRange); + hlBuilder.registerFix(factory.createSurroundWithArrayFix(methodCall, null), fixRange); + QualifyThisArgumentFix.registerQuickFixAction(methodCandidates, methodCall, hlBuilder, fixRange); CandidateInfo[] candidates = resolveHelper.getReferencedMethodCandidates(methodCall, true); - ChangeStringLiteralToCharInMethodCallFix.registerFixes(candidates, methodCall, highlightInfo); + ChangeStringLiteralToCharInMethodCallFix.registerFixes(candidates, methodCall, hlBuilder); } @RequiredReadAction @@ -1138,7 +1082,8 @@ private static void registerMethodAccessLevelIntentions( CandidateInfo[] methodCandidates, PsiMethodCallExpression methodCall, PsiExpressionList exprList, - HighlightInfo highlightInfo + @Nonnull HighlightInfo.Builder highlightInfo, + @Nonnull TextRange fixRange ) { for (CandidateInfo methodCandidate : methodCandidates) { PsiMethod method = (PsiMethod)methodCandidate.getElement(); @@ -1147,6 +1092,7 @@ private static void registerMethodAccessLevelIntentions( method, methodCall.getMethodExpression(), highlightInfo, + fixRange, methodCandidate.getCurrentFileResolveScope() ); } @@ -1613,7 +1559,9 @@ public static HighlightInfo checkSuperAbstractMethodDirectCall(@Nonnull PsiMetho return null; } - public static HighlightInfo checkConstructorCallsBaseClassConstructor( + @Nullable + @RequiredReadAction + public static HighlightInfo.Builder checkConstructorCallsBaseClassConstructor( PsiMethod constructor, RefCountHolder refCountHolder, PsiResolveHelper resolveHelper @@ -1634,10 +1582,10 @@ public static HighlightInfo checkConstructorCallsBaseClassConstructor( } // check whether constructor call super(...) or this(...) - PsiElement element = new PsiMatcherImpl(body).firstChild(PsiMatchers.hasClass(PsiExpressionStatement.class)) + PsiElement element = new PsiMatcherImpl(body) + .firstChild(PsiMatchers.hasClass(PsiExpressionStatement.class)) .firstChild(PsiMatchers.hasClass(PsiMethodCallExpression.class)) - .firstChild - (PsiMatchers.hasClass(PsiReferenceExpression.class)) + .firstChild(PsiMatchers.hasClass(PsiReferenceExpression.class)) .firstChild(PsiMatchers.hasClass(PsiKeyword.class)) .getElement(); if (element != null) { @@ -1645,24 +1593,22 @@ public static HighlightInfo checkConstructorCallsBaseClassConstructor( } TextRange textRange = HighlightNamesUtil.getMethodDeclarationTextRange(constructor); PsiClassType[] handledExceptions = constructor.getThrowsList().getReferencedTypes(); - HighlightInfo info = + HighlightInfo.Builder hlBuilder = HighlightClassUtil.checkBaseClassDefaultConstructorProblem(aClass, refCountHolder, resolveHelper, textRange, handledExceptions); - if (info != null) { - QuickFixAction.registerQuickFixAction(info, QuickFixFactory.getInstance().createInsertSuperFix(constructor)); - QuickFixAction.registerQuickFixAction( - info, - QuickFixFactory.getInstance().createAddDefaultConstructorFix(aClass.getSuperClass()) - ); + if (hlBuilder != null) { + hlBuilder.registerFix(QuickFixFactory.getInstance().createInsertSuperFix(constructor)); + hlBuilder.registerFix(QuickFixFactory.getInstance().createAddDefaultConstructorFix(aClass.getSuperClass())); } - return info; + return hlBuilder; } /** * @return error if static method overrides instance method or * instance method overrides static. see JLS 8.4.6.1, 8.4.6.2 */ + @Nullable @RequiredReadAction - public static HighlightInfo checkStaticMethodOverride(@Nonnull PsiMethod method, @Nonnull PsiFile containingFile) { + public static HighlightInfo.Builder checkStaticMethodOverride(@Nonnull PsiMethod method, @Nonnull PsiFile containingFile) { // constructors are not members and therefor don't override class methods if (method.isConstructor()) { return null; @@ -1685,17 +1631,18 @@ public static HighlightInfo checkStaticMethodOverride(@Nonnull PsiMethod method, if (superClass == null) { continue; } - HighlightInfo highlightInfo = + HighlightInfo.Builder hlBuilder = checkStaticMethodOverride(aClass, method, isStatic, superClass, superMethod, containingFile); - if (highlightInfo != null) { - return highlightInfo; + if (hlBuilder != null) { + return hlBuilder; } } return null; } + @Nullable @RequiredReadAction - private static HighlightInfo checkStaticMethodOverride( + private static HighlightInfo.Builder checkStaticMethodOverride( PsiClass aClass, PsiMethod method, boolean isMethodStatic, @@ -1726,34 +1673,27 @@ private static HighlightInfo checkStaticMethodOverride( ? JavaErrorLocalize.staticMethodCannotOverrideInstanceMethod(m1, c1, m2, c2) : JavaErrorLocalize.instanceMethodCannotOverrideStaticMethod(m1, c1, m2, c2); - HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) + HighlightInfo.Builder hlBuilder = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(HighlightNamesUtil.getMethodDeclarationTextRange(method)) - .descriptionAndTooltip(description) - .create(); + .descriptionAndTooltip(description); if (!isSuperMethodStatic || HighlightUtil.getIncompatibleModifier(PsiModifier.STATIC, modifierList) == null) { - QuickFixAction.registerQuickFixAction( - info, - QuickFixFactory.getInstance().createModifierListFix( - method, - PsiModifier.STATIC, - isSuperMethodStatic, - false - ) - ); + hlBuilder.registerFix(QuickFixFactory.getInstance().createModifierListFix( + method, + PsiModifier.STATIC, + isSuperMethodStatic, + false + )); } if (manager.isInProject(superMethod) && (!isMethodStatic || HighlightUtil.getIncompatibleModifier(PsiModifier.STATIC, superModifierList) == null)) { - QuickFixAction.registerQuickFixAction( - info, - QuickFixFactory.getInstance().createModifierListFix( - superMethod, - PsiModifier.STATIC, - isMethodStatic, - true - ) - ); + hlBuilder.registerFix(QuickFixFactory.getInstance().createModifierListFix( + superMethod, + PsiModifier.STATIC, + isMethodStatic, + true + )); } - return info; + return hlBuilder; } if (isMethodStatic) { @@ -1762,7 +1702,7 @@ private static HighlightInfo checkStaticMethodOverride( } int accessLevel = PsiUtil.getAccessLevel(modifierList); String accessModifier = PsiUtil.getAccessModifier(accessLevel); - HighlightInfo info = isWeaker(method, modifierList, accessModifier, accessLevel, superMethod, true); + HighlightInfo.Builder info = isWeaker(method, modifierList, accessModifier, accessLevel, superMethod, true); if (info != null) { return info; } @@ -1880,7 +1820,8 @@ public static HighlightInfo checkOverrideEquivalentInheritedMethods( for (HierarchicalMethodSignature superSignature : superSignatures) { PsiMethod superMethod = superSignature.getMethod(); if (!superMethod.isStatic()) { - description = JavaErrorLocalize.staticMethodCannotOverrideInstanceMethod(JavaHighlightUtil.formatMethod(method), + description = JavaErrorLocalize.staticMethodCannotOverrideInstanceMethod( + JavaHighlightUtil.formatMethod(method), HighlightUtil.formatClass(containingClass), JavaHighlightUtil.formatMethod(superMethod), HighlightUtil.formatClass(superMethod.getContainingClass()) @@ -1900,7 +1841,8 @@ public static HighlightInfo checkOverrideEquivalentInheritedMethods( } if (description == null) { - highlightInfo = checkMethodWeakerPrivileges(signature, superSignatures, false, containingFile); + HighlightInfo.Builder hlBuilder = checkMethodWeakerPrivileges(signature, superSignatures, false, containingFile); + highlightInfo = hlBuilder == null ? null : hlBuilder.create(); if (highlightInfo != null) { description = highlightInfo.getDescription(); } @@ -2039,12 +1981,12 @@ public static void checkConstructorCall( } } if (classReference != null && !resolveHelper.isAccessible(aClass, constructorCall, accessObjectClass)) { - HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) - .range(classReference.getReferenceNameElement()) - .descriptionAndTooltip(HighlightUtil.buildProblemWithAccessDescription(classReference, typeResolveResult)) - .create(); - HighlightUtil.registerAccessQuickFixAction(aClass, classReference, info, null); - holder.add(info); + PsiElement refName = classReference.getReferenceNameElement(); + HighlightInfo.Builder hlBuilder = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) + .range(refName) + .descriptionAndTooltip(HighlightUtil.buildProblemWithAccessDescription(classReference, typeResolveResult)); + HighlightUtil.registerAccessQuickFixAction(aClass, classReference, hlBuilder, refName.getTextRange(), null); + holder.add(hlBuilder.create()); return; } PsiMethod[] constructors = aClass.getConstructors(); @@ -2061,21 +2003,19 @@ public static void checkConstructorCall( PsiSubstitutor.EMPTY, aClass ); - HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) + HighlightInfo.Builder hlBuilder = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(list) - .description(JavaErrorLocalize.wrongConstructorArguments(constructorName + "()", argTypes).get()) + .description(JavaErrorLocalize.wrongConstructorArguments(constructorName + "()", argTypes)) .escapedToolTip(tooltip) - .navigationShift(+1) - .create(); - QuickFixAction.registerQuickFixAction( - info, - constructorCall.getTextRange(), - QuickFixFactory.getInstance().createCreateConstructorFromCallFix(constructorCall) + .navigationShift(+1); + hlBuilder.registerFix( + QuickFixFactory.getInstance().createCreateConstructorFromCallFix(constructorCall), + constructorCall.getTextRange() ); if (classReference != null) { - ConstructorParametersFixer.registerFixActions(classReference, constructorCall, info, getFixRange(list)); + ConstructorParametersFixer.registerFixActions(classReference, constructorCall, hlBuilder, getFixRange(list)); } - holder.add(info); + holder.add(hlBuilder.create()); return; } if (classReference != null && aClass.isProtected() @@ -2126,25 +2066,22 @@ else if (aClass.isInterface() && constructorCall instanceof PsiNewExpression new if (constructor == null) { String name = aClass.getName(); name += buildArgTypesList(list); - HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) + HighlightInfo.Builder info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(list) .descriptionAndTooltip(JavaErrorLocalize.cannotResolveConstructor(name)) - .navigationShift(+1) - .create(); - if (info != null) { - WrapExpressionFix.registerWrapAction(results, list.getExpressions(), info); - registerFixesOnInvalidConstructorCall( - constructorCall, - classReference, - list, - aClass, - constructors, - results, - infoElement, - info - ); - holder.add(info); - } + .navigationShift(+1); + WrapExpressionFix.registerWrapAction(results, list.getExpressions(), info); + registerFixesOnInvalidConstructorCall( + constructorCall, + classReference, + list, + aClass, + constructors, + results, + infoElement, + info + ); + holder.add(info.create()); } else if (classReference != null && (!result.isAccessible() || constructor.isProtected() && callingProtectedConstructorFromDerivedClass(constructorCall, aClass))) { @@ -2156,46 +2093,46 @@ else if (!applicable) { String argTypes = buildArgTypesList(list); String toolTip = createMismatchedArgumentsHtmlTooltip(result, list); - HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) + HighlightInfo.Builder hlBuilder = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(infoElement) - .description(JavaErrorLocalize.wrongMethodArguments(constructorName, containerName, argTypes).get()) + .description(JavaErrorLocalize.wrongMethodArguments(constructorName, containerName, argTypes)) .escapedToolTip(toolTip) - .navigationShift(+1) - .create(); - if (info != null) { - JavaResolveResult[] methodCandidates = results; - if (constructorCall instanceof PsiNewExpression newExpr) { - methodCandidates = resolveHelper.getReferencedMethodCandidates(newExpr, true); - } - registerFixesOnInvalidConstructorCall( - constructorCall, - classReference, - list, - aClass, - constructors, - methodCandidates, - infoElement, - info - ); - registerMethodReturnFixAction(info, result, constructorCall); - holder.add(info); + .navigationShift(+1); + JavaResolveResult[] methodCandidates = results; + if (constructorCall instanceof PsiNewExpression newExpr) { + methodCandidates = resolveHelper.getReferencedMethodCandidates(newExpr, true); } + registerFixesOnInvalidConstructorCall( + constructorCall, + classReference, + list, + aClass, + constructors, + methodCandidates, + infoElement, + hlBuilder + ); + registerMethodReturnFixAction(hlBuilder, result, constructorCall); + holder.add(hlBuilder.create()); } else if (constructorCall instanceof PsiNewExpression newExpr) { - HighlightInfo info = GenericsHighlightUtil.checkReferenceTypeArgumentList( + HighlightInfo.Builder hlBuilder = GenericsHighlightUtil.checkReferenceTypeArgumentList( constructor, newExpr.getTypeArgumentList(), result.getSubstitutor(), false, javaSdkVersion ); - if (info != null) { - holder.add(info); + if (hlBuilder != null) { + holder.add(hlBuilder.create()); } } if (result != null && !holder.hasErrorResults()) { - holder.add(checkVarargParameterErasureToBeAccessible(result, constructorCall)); + HighlightInfo.Builder hlBuilder = checkVarargParameterErasureToBeAccessible(result, constructorCall); + if (hlBuilder != null) { + holder.add(hlBuilder.create()); + } } } } @@ -2206,7 +2143,7 @@ else if (constructorCall instanceof PsiNewExpression newExpr) { * it is a compile-time error if the type which is the erasure of Fn is not accessible at the point of invocation. */ @RequiredReadAction - private static HighlightInfo checkVarargParameterErasureToBeAccessible(MethodCandidateInfo info, PsiCall place) { + private static HighlightInfo.Builder checkVarargParameterErasureToBeAccessible(MethodCandidateInfo info, PsiCall place) { PsiMethod method = info.getElement(); if (info.isVarargs() || method.isVarArgs() && !PsiUtil.isLanguageLevel8OrHigher(place)) { PsiParameter[] parameters = method.getParameterList().getParameters(); @@ -2220,8 +2157,7 @@ private static HighlightInfo checkVarargParameterErasureToBeAccessible(MethodCan "Formal varargs element type " + PsiFormatUtil.formatClass(targetClass, PsiFormatUtilBase.SHOW_FQ_NAME) + " is inaccessible here" )) - .range(argumentList != null ? argumentList : place) - .create(); + .range(argumentList != null ? argumentList : place); } } return null; @@ -2236,27 +2172,22 @@ private static void registerFixesOnInvalidConstructorCall( PsiMethod[] constructors, JavaResolveResult[] results, PsiElement infoElement, - @Nonnull HighlightInfo info + @Nonnull HighlightInfo.Builder hlBuilder ) { - QuickFixAction.registerQuickFixAction( - info, - constructorCall.getTextRange(), - QuickFixFactory.getInstance().createCreateConstructorFromCallFix(constructorCall) + hlBuilder.registerFix( + QuickFixFactory.getInstance().createCreateConstructorFromCallFix(constructorCall), + constructorCall.getTextRange() ); if (classReference != null) { - ConstructorParametersFixer.registerFixActions(classReference, constructorCall, info, getFixRange(infoElement)); - ChangeTypeArgumentsFix.registerIntentions(results, list, info, aClass); - ConvertDoubleToFloatFix.registerIntentions(results, list, info, null); - } - registerChangeMethodSignatureFromUsageIntentions(results, list, info, null); - PermuteArgumentsFix.registerFix(info, constructorCall, toMethodCandidates(results), getFixRange(list)); - registerChangeParameterClassFix(constructorCall, list, info); - QuickFixAction.registerQuickFixAction( - info, - getFixRange(list), - QuickFixFactory.getInstance().createSurroundWithArrayFix(constructorCall, null) - ); - ChangeStringLiteralToCharInMethodCallFix.registerFixes(constructors, constructorCall, info); + ConstructorParametersFixer.registerFixActions(classReference, constructorCall, hlBuilder, getFixRange(infoElement)); + ChangeTypeArgumentsFix.registerIntentions(results, list, hlBuilder, aClass); + ConvertDoubleToFloatFix.registerIntentions(results, list, hlBuilder, null); + } + 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)); + ChangeStringLiteralToCharInMethodCallFix.registerFixes(constructors, constructorCall, hlBuilder); } @RequiredReadAction @@ -2265,15 +2196,20 @@ private static HighlightInfo buildAccessProblem( JavaResolveResult result, PsiMember elementToFix ) { - HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) + HighlightInfo.Builder hlBuilder = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(classReference) .descriptionAndTooltip(HighlightUtil.buildProblemWithAccessDescription(classReference, result)) - .navigationShift(+1) - .create(); + .navigationShift(+1); if (result.isStaticsScopeCorrect()) { - HighlightUtil.registerAccessQuickFixAction(elementToFix, classReference, info, result.getCurrentFileResolveScope()); + HighlightUtil.registerAccessQuickFixAction( + elementToFix, + classReference, + hlBuilder, + classReference.getTextRange(), + result.getCurrentFileResolveScope() + ); } - return info; + return hlBuilder.create(); } private static boolean callingProtectedConstructorFromDerivedClass(PsiConstructorCall place, PsiClass constructorClass) { @@ -2318,7 +2254,7 @@ private static String buildArgTypesList(PsiExpressionList list) { private static void registerChangeParameterClassFix( @Nonnull PsiCall methodCall, @Nonnull PsiExpressionList list, - HighlightInfo highlightInfo + HighlightInfo.Builder hlBuilder ) { JavaResolveResult result = methodCall.resolveMethodGenerics(); PsiMethod method = (PsiMethod)result.getElement(); @@ -2358,17 +2294,15 @@ private static void registerChangeParameterClassFix( || parameterClass.isInheritor(expressionClass, true)) { continue; } - QuickFixAction.registerQuickFixAction( - highlightInfo, - QuickFixFactory.getInstance().createChangeParameterClassFix(expressionClass, (PsiClassType)parameterType) - ); + hlBuilder.registerFix(QuickFixFactory.getInstance() + .createChangeParameterClassFix(expressionClass, (PsiClassType)parameterType)); } } private static void registerChangeMethodSignatureFromUsageIntentions( @Nonnull JavaResolveResult[] candidates, @Nonnull PsiExpressionList list, - @Nullable HighlightInfo highlightInfo, + @Nullable HighlightInfo.Builder highlightInfo, TextRange fixRange ) { if (candidates.length == 0) { @@ -2382,29 +2316,40 @@ private static void registerChangeMethodSignatureFromUsageIntentions( private static void registerChangeMethodSignatureFromUsageIntention( @Nonnull PsiExpression[] expressions, - @Nullable HighlightInfo highlightInfo, + @Nullable HighlightInfo.Builder highlightInfo, TextRange fixRange, @Nonnull JavaResolveResult candidate, @Nonnull PsiElement context ) { - if (!candidate.isStaticsScopeCorrect()) { + if (highlightInfo == null || !candidate.isStaticsScopeCorrect()) { return; } PsiMethod method = (PsiMethod)candidate.getElement(); PsiSubstitutor substitutor = candidate.getSubstitutor(); if (method != null && context.getManager().isInProject(method)) { - IntentionAction fix = QuickFixFactory.getInstance() - .createChangeMethodSignatureFromUsageFix(method, expressions, substitutor, context, false, 2); - QuickFixAction.registerQuickFixAction(highlightInfo, fixRange, fix); - IntentionAction f2 = QuickFixFactory.getInstance().createChangeMethodSignatureFromUsageReverseOrderFix( - method, - expressions, - substitutor, - context, - false, - 2 + QuickFixFactory factory = QuickFixFactory.getInstance(); + highlightInfo.registerFix( + factory.createChangeMethodSignatureFromUsageFix( + method, + expressions, + substitutor, + context, + false, + 2 + ), + fixRange + ); + highlightInfo.registerFix( + factory.createChangeMethodSignatureFromUsageReverseOrderFix( + method, + expressions, + substitutor, + context, + false, + 2 + ), + fixRange ); - QuickFixAction.registerQuickFixAction(highlightInfo, fixRange, f2); } } } 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 80187491b..ab308eea4 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 @@ -51,10 +51,7 @@ import consulo.language.editor.highlight.HighlightUsagesDescriptionLocation; import consulo.language.editor.inspection.LocalQuickFixOnPsiElementAsIntentionAdapter; import consulo.language.editor.inspection.PriorityActionWrapper; -import consulo.language.editor.intention.IntentionAction; -import consulo.language.editor.intention.QuickFixAction; -import consulo.language.editor.intention.QuickFixActionRegistrar; -import consulo.language.editor.intention.UnresolvedReferenceQuickFixProvider; +import consulo.language.editor.intention.*; import consulo.language.editor.rawHighlight.HighlightInfo; import consulo.language.editor.rawHighlight.HighlightInfoType; import consulo.language.findUsage.FindUsagesProvider; @@ -92,7 +89,7 @@ /** * @author cdr - * @since Jul 30, 2002 + * @since 2002-07-30 */ public class HighlightUtil extends HighlightUtilBase { private static final Logger LOG = Logger.getInstance(HighlightUtil.class); @@ -290,10 +287,11 @@ private static String getIncompatibleModifier( public static void registerAccessQuickFixAction( @Nonnull PsiMember refElement, @Nonnull PsiJavaCodeReferenceElement place, - @Nullable HighlightInfo errorResult, + @Nullable HighlightInfo.Builder hlBuilder, + @Nullable TextRange hlRange, PsiElement fileResolveScope ) { - if (errorResult == null) { + if (hlBuilder == null) { return; } PsiClass accessObjectClass = null; @@ -301,7 +299,7 @@ public static void registerAccessQuickFixAction( if (qualifier instanceof PsiExpression qExpr) { accessObjectClass = (PsiClass)PsiUtil.getAccessObjectClass(qExpr).getElement(); } - registerReplaceInaccessibleFieldWithGetterSetterFix(refElement, place, accessObjectClass, errorResult); + registerReplaceInaccessibleFieldWithGetterSetterFix(refElement, place, accessObjectClass, hlBuilder); if (refElement instanceof PsiCompiledElement) { return; @@ -315,7 +313,7 @@ public static void registerAccessQuickFixAction( if (packageLocalClassInTheMiddle != null) { IntentionAction fix = QuickFixFactory.getInstance() .createModifierListFix(packageLocalClassInTheMiddle, PsiModifier.PUBLIC, true, true); - QuickFixAction.registerQuickFixAction(errorResult, fix); + hlBuilder.registerFix(fix); return; } @@ -346,12 +344,12 @@ public static void registerAccessQuickFixAction( modifierListCopy.setModifierProperty(modifier, true); if (facade.getResolveHelper().isAccessible(refElement, modifierListCopy, place, accessObjectClass, fileResolveScope)) { IntentionAction fix = QuickFixFactory.getInstance().createModifierListFix(refElement, modifier, true, true); - TextRange fixRange = new TextRange(errorResult.getStartOffset(), errorResult.getEndOffset()); + TextRange fixRange = hlRange; PsiElement ref = place.getReferenceNameElement(); if (ref != null) { fixRange = fixRange.union(ref.getTextRange()); } - QuickFixAction.registerQuickFixAction(errorResult, fixRange, fix); + hlBuilder.registerFix(fix, fixRange); } } } @@ -421,16 +419,16 @@ public static HighlightInfo checkInstanceOfApplicable(@Nonnull PsiInstanceOfExpr */ @Nullable @RequiredReadAction - public static HighlightInfo checkIntersectionInTypeCast( + public static HighlightInfo.Builder checkIntersectionInTypeCast( @Nonnull PsiTypeCastExpression expression, @Nonnull LanguageLevel languageLevel, @Nonnull PsiFile file ) { PsiTypeElement castTypeElement = expression.getCastType(); if (castTypeElement != null && isIntersection(castTypeElement, castTypeElement.getType())) { - HighlightInfo info = checkFeature(expression, JavaFeature.INTERSECTION_CASTS, languageLevel, file); - if (info != null) { - return info; + HighlightInfo.Builder hlBuilder = checkFeature(expression, JavaFeature.INTERSECTION_CASTS, languageLevel, file); + if (hlBuilder != null) { + return hlBuilder; } PsiTypeElement[] conjuncts = PsiTreeUtil.getChildrenOfType(castTypeElement, PsiTypeElement.class); @@ -447,22 +445,19 @@ public static HighlightInfo checkIntersectionInTypeCast( return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(conjunct) .descriptionAndTooltip(JavaErrorLocalize.interfaceExpected()) - .registerFix(new FlipIntersectionSidesFix(aClass.getName(), conjList, conjunct, castTypeElement)) - .create(); + .registerFix(new FlipIntersectionSidesFix(aClass.getName(), conjList, conjunct, castTypeElement)); } } else { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(conjunct) - .descriptionAndTooltip(JavaErrorLocalize.unexpectedTypeClassExpected()) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.unexpectedTypeClassExpected()); } if (!erasures.add(TypeConversionUtil.erasure(conjType))) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(conjunct) .descriptionAndTooltip(JavaErrorLocalize.repeatedInterface()) - .registerFix(new DeleteRepeatedInterfaceFix(conjunct, conjList)) - .create(); + .registerFix(new DeleteRepeatedInterfaceFix(conjunct, conjList)); } } @@ -484,8 +479,7 @@ public static HighlightInfo checkIntersectionInTypeCast( .descriptionAndTooltip(JavaErrorLocalize.classCannotBeInheritedWithDifferentArguments( formatClass(sameGenericParameterization), differentArgumentsMessage.get() - )) - .create(); + )); } } } @@ -592,7 +586,7 @@ public static HighlightInfo checkAssignmentOperatorApplicable(@Nonnull PsiAssign @Nullable @RequiredReadAction - public static HighlightInfo checkAssignmentCompatibleTypes(@Nonnull PsiAssignmentExpression assignment) { + public static HighlightInfo.Builder checkAssignmentCompatibleTypes(@Nonnull PsiAssignmentExpression assignment) { PsiExpression lExpr = assignment.getLExpression(); PsiExpression rExpr = assignment.getRExpression(); if (rExpr == null) { @@ -605,9 +599,9 @@ public static HighlightInfo checkAssignmentCompatibleTypes(@Nonnull PsiAssignmen } IElementType sign = assignment.getOperationTokenType(); - HighlightInfo highlightInfo; + HighlightInfo.Builder hlBuilder; if (JavaTokenType.EQ.equals(sign)) { - highlightInfo = checkAssignability(lType, rType, rExpr, assignment); + hlBuilder = checkAssignability(lType, rType, rExpr, assignment); } else { // 15.26.2. Compound Assignment Operators @@ -616,20 +610,17 @@ public static HighlightInfo checkAssignmentCompatibleTypes(@Nonnull PsiAssignmen if (type == null || lType == null || TypeConversionUtil.areTypesConvertible(type, lType)) { return null; } - highlightInfo = createIncompatibleTypeHighlightInfo(lType, type, assignment.getTextRange(), 0); - QuickFixAction.registerQuickFixAction( - highlightInfo, - QuickFixFactory.getInstance().createChangeToAppendFix(sign, lType, assignment) - ); + hlBuilder = createIncompatibleTypeHighlightInfo(lType, type, assignment.getTextRange(), 0); + hlBuilder.registerFix(QuickFixFactory.getInstance().createChangeToAppendFix(sign, lType, assignment)); } - if (highlightInfo == null) { + if (hlBuilder == null) { return null; } - registerChangeVariableTypeFixes(lExpr, rType, rExpr, highlightInfo); + registerChangeVariableTypeFixes(lExpr, rType, rExpr, hlBuilder); if (lType != null) { - registerChangeVariableTypeFixes(rExpr, lType, lExpr, highlightInfo); + registerChangeVariableTypeFixes(rExpr, lType, lExpr, hlBuilder); } - return highlightInfo; + return hlBuilder; } @RequiredReadAction @@ -637,7 +628,7 @@ private static void registerChangeVariableTypeFixes( @Nonnull PsiExpression expression, @Nonnull PsiType type, @Nullable PsiExpression lExpr, - @Nullable HighlightInfo highlightInfo + @Nullable HighlightInfo.Builder highlightInfo ) { if (highlightInfo == null || !(expression instanceof PsiReferenceExpression refExpr) || !(refExpr.resolve() instanceof PsiVariable variable)) { @@ -651,13 +642,7 @@ private static void registerChangeVariableTypeFixes( && assignment.getParent() instanceof PsiStatement) { PsiMethod method = methodCall.resolveMethod(); if (method != null && PsiType.VOID.equals(method.getReturnType())) { - highlightInfo.registerFix( - new ReplaceAssignmentFromVoidWithStatementIntentionAction(assignment, lExpr), - null, - null, - null, - null - ); + highlightInfo.registerFix(new ReplaceAssignmentFromVoidWithStatementIntentionAction(assignment, lExpr)); } } } @@ -681,7 +666,7 @@ private static boolean isCastIntentionApplicable(@Nonnull PsiExpression expressi @Nullable @RequiredReadAction - public static HighlightInfo checkVariableInitializerType(@Nonnull PsiVariable variable) { + public static HighlightInfo.Builder checkVariableInitializerType(@Nonnull PsiVariable variable) { PsiExpression initializer = variable.getInitializer(); // array initializer checked in checkArrayInitializerApplicable if (initializer == null || initializer instanceof PsiArrayInitializerExpression) { @@ -692,17 +677,17 @@ public static HighlightInfo checkVariableInitializerType(@Nonnull PsiVariable va PsiTypeElement typeElement = variable.getTypeElement(); int start = typeElement != null ? typeElement.getTextRange().getStartOffset() : variable.getTextRange().getStartOffset(); int end = variable.getTextRange().getEndOffset(); - HighlightInfo highlightInfo = checkAssignability(lType, rType, initializer, new TextRange(start, end), 0); - if (highlightInfo != null) { - registerChangeVariableTypeFixes(variable, rType, variable.getInitializer(), highlightInfo); - registerChangeVariableTypeFixes(initializer, lType, null, highlightInfo); + HighlightInfo.Builder hlBuilder = checkAssignability(lType, rType, initializer, new TextRange(start, end), 0); + if (hlBuilder != null) { + registerChangeVariableTypeFixes(variable, rType, variable.getInitializer(), hlBuilder); + registerChangeVariableTypeFixes(initializer, lType, null, hlBuilder); } - return highlightInfo; + return hlBuilder; } @Nullable @RequiredReadAction - public static HighlightInfo checkAssignability( + public static HighlightInfo.Builder checkAssignability( @Nullable PsiType lType, @Nullable PsiType rType, @Nullable PsiExpression expression, @@ -713,7 +698,8 @@ public static HighlightInfo checkAssignability( } @Nullable - private static HighlightInfo checkAssignability( + @RequiredReadAction + private static HighlightInfo.Builder checkAssignability( @Nullable PsiType lType, @Nullable PsiType rType, @Nullable PsiExpression expression, @@ -734,31 +720,26 @@ else if (TypeConversionUtil.areTypesAssignmentCompatible(lType, expression)) { if (rType == null) { rType = expression.getType(); } - HighlightInfo highlightInfo = createIncompatibleTypeHighlightInfo(lType, rType, textRange, navigationShift); + HighlightInfo.Builder hlBuilder = createIncompatibleTypeHighlightInfo(lType, rType, textRange, navigationShift); + QuickFixFactory factory = QuickFixFactory.getInstance(); if (rType != null && expression != null && isCastIntentionApplicable(expression, lType)) { - QuickFixAction.registerQuickFixAction(highlightInfo, QuickFixFactory.getInstance().createAddTypeCastFix(lType, expression)); + hlBuilder.registerFix(factory.createAddTypeCastFix(lType, expression)); } if (expression != null) { - QuickFixAction.registerQuickFixAction(highlightInfo, QuickFixFactory.getInstance().createWrapWithAdapterFix(lType, expression)); - QuickFixAction.registerQuickFixAction( - highlightInfo, - QuickFixFactory.getInstance().createWrapWithOptionalFix(lType, expression) - ); - QuickFixAction.registerQuickFixAction(highlightInfo, QuickFixFactory.getInstance().createWrapExpressionFix(lType, expression)); - QuickFixAction.registerQuickFixAction( - highlightInfo, - QuickFixFactory.getInstance().createWrapStringWithFileFix(lType, expression) - ); - AddTypeArgumentsConditionalFix.register(highlightInfo, expression, lType); - registerCollectionToArrayFixAction(highlightInfo, rType, lType, expression); + hlBuilder.registerFix(factory.createWrapWithAdapterFix(lType, expression)) + .registerFix(factory.createWrapWithOptionalFix(lType, expression)) + .registerFix(factory.createWrapExpressionFix(lType, expression)) + .registerFix(factory.createWrapStringWithFileFix(lType, expression)); + AddTypeArgumentsConditionalFix.register(hlBuilder, expression, lType); + registerCollectionToArrayFixAction(hlBuilder, rType, lType, expression); } - ChangeNewOperatorTypeFix.register(highlightInfo, expression, lType); - return highlightInfo; + ChangeNewOperatorTypeFix.register(hlBuilder, expression, lType); + return hlBuilder; } @Nullable @RequiredReadAction - public static HighlightInfo checkReturnStatementType(@Nonnull PsiReturnStatement statement) { + public static HighlightInfo.Builder checkReturnStatementType(@Nonnull PsiReturnStatement statement) { PsiMethod method = null; PsiLambdaExpression lambda = null; PsiElement parent = statement.getParent(); @@ -788,8 +769,7 @@ public static HighlightInfo checkReturnStatementType(@Nonnull PsiReturnStatement else if (method == null && !(parent instanceof ServerPageFile)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(statement) - .descriptionAndTooltip(JavaErrorLocalize.returnOutsideMethod()) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.returnOutsideMethod()); } else { PsiType returnType = method != null ? method.getReturnType() : null/*JSP page returns void*/; @@ -804,32 +784,26 @@ else if (method == null && !(parent instanceof ServerPageFile)) { if (valueType != null) { errorResult.registerFix(QuickFixFactory.getInstance().createMethodReturnFix(method, valueType, true)); } - return errorResult.create(); + return errorResult; } else { TextRange textRange = statement.getTextRange(); - HighlightInfo errorResult = + HighlightInfo.Builder hlBuilder = checkAssignability(returnType, valueType, returnValue, textRange, returnValue.getStartOffsetInParent()); - if (errorResult != null && valueType != null) { + if (hlBuilder != null && valueType != null) { if (!PsiType.VOID.equals(valueType)) { - QuickFixAction.registerQuickFixAction( - errorResult, - QuickFixFactory.getInstance().createMethodReturnFix(method, valueType, true) - ); + hlBuilder.registerFix(QuickFixFactory.getInstance().createMethodReturnFix(method, valueType, true)); } - registerChangeParameterClassFix(returnType, valueType, errorResult); + registerChangeParameterClassFix(returnType, valueType, hlBuilder); if (returnType instanceof PsiArrayType arrayType) { PsiType erasedValueType = TypeConversionUtil.erasure(valueType); if (erasedValueType != null && TypeConversionUtil.isAssignable(arrayType.getComponentType(), erasedValueType)) { - QuickFixAction.registerQuickFixAction( - errorResult, - QuickFixFactory.getInstance().createSurroundWithArrayFix(null, returnValue) - ); + hlBuilder.registerFix(QuickFixFactory.getInstance().createSurroundWithArrayFix(null, returnValue)); } } - registerCollectionToArrayFixAction(errorResult, valueType, returnType, returnValue); - return errorResult; + registerCollectionToArrayFixAction(hlBuilder, valueType, returnType, returnValue); + return hlBuilder; } } } @@ -838,30 +812,26 @@ else if (!isMethodVoid) { .range(statement) .descriptionAndTooltip(JavaErrorLocalize.missingReturnValue()) .navigationShift(PsiKeyword.RETURN.length()) - .registerFix(QuickFixFactory.getInstance().createMethodReturnFix(method, PsiType.VOID, true)) - .create(); + .registerFix(QuickFixFactory.getInstance().createMethodReturnFix(method, PsiType.VOID, true)); } } return null; } private static void registerCollectionToArrayFixAction( - @Nullable HighlightInfo info, + @Nullable HighlightInfo.Builder hlBuilder, @Nullable PsiType fromType, @Nullable PsiType toType, @Nonnull PsiExpression expression ) { - if (toType instanceof PsiArrayType arrayType) { + if (hlBuilder != null && toType instanceof PsiArrayType arrayType) { PsiType arrayComponentType = arrayType.getComponentType(); if (!(arrayComponentType instanceof PsiPrimitiveType) && !(PsiUtil.resolveClassInType(arrayComponentType) instanceof PsiTypeParameter) && InheritanceUtil.isInheritor(fromType, JavaClassNames.JAVA_UTIL_COLLECTION)) { PsiType collectionItemType = JavaGenericsUtil.getCollectionItemType(fromType, expression.getResolveScope()); if (collectionItemType != null && arrayComponentType.isAssignableFrom(collectionItemType)) { - QuickFixAction.registerQuickFixAction( - info, - QuickFixFactory.getInstance().createCollectionToArrayFix(expression, arrayType) - ); + hlBuilder.registerFix(QuickFixFactory.getInstance().createCollectionToArrayFix(expression, arrayType)); } } } @@ -951,7 +921,7 @@ private static String formatField(@Nonnull PsiField field) { @Nullable @RequiredReadAction - public static HighlightInfo checkUnhandledExceptions(@Nonnull PsiElement element, @Nullable TextRange textRange) { + public static HighlightInfo.Builder checkUnhandledExceptions(@Nonnull PsiElement element, @Nullable TextRange textRange) { List unhandledExceptions = ExceptionUtil.getUnhandledExceptions(element); if (unhandledExceptions.isEmpty()) { return null; @@ -965,10 +935,10 @@ public static HighlightInfo checkUnhandledExceptions(@Nonnull PsiElement element if (textRange == null) { textRange = element.getTextRange(); } - HighlightInfo.Builder errorResult = HighlightInfo.newHighlightInfo(highlightType) + HighlightInfo.Builder hlBuilder = HighlightInfo.newHighlightInfo(highlightType) .range(textRange) .descriptionAndTooltip(getUnhandledExceptionsDescriptor(unhandledExceptions)); - return registerUnhandledExceptionFixes(element, errorResult, unhandledExceptions).create(); + return registerUnhandledExceptionFixes(element, hlBuilder, unhandledExceptions); } @Nullable @@ -992,18 +962,18 @@ public static HighlightInfo checkUnhandledCloserExceptions(@Nonnull PsiResourceL private static HighlightInfo.Builder registerUnhandledExceptionFixes( PsiElement element, - HighlightInfo.Builder errorResult, + HighlightInfo.Builder hlBuilder, List unhandled ) { QuickFixFactory factory = QuickFixFactory.getInstance(); - errorResult.registerFix(factory.createAddExceptionToCatchFix()) + hlBuilder.registerFix(factory.createAddExceptionToCatchFix()) .registerFix(factory.createAddExceptionToThrowsFix(element)) .registerFix(factory.createAddExceptionFromFieldInitializerToConstructorThrowsFix(element)) .registerFix(factory.createSurroundWithTryCatchFix(element)); if (unhandled.size() == 1) { - errorResult.registerFix(factory.createGeneralizeCatchFix(element, unhandled.get(0))); + hlBuilder.registerFix(factory.createGeneralizeCatchFix(element, unhandled.get(0))); } - return errorResult; + return hlBuilder; } @Nullable @@ -1228,7 +1198,7 @@ else if (modifierOwner instanceof PsiReceiverParameter) { @Nullable @RequiredReadAction - public static HighlightInfo checkLiteralExpressionParsingError( + public static HighlightInfo.Builder checkLiteralExpressionParsingError( @Nonnull PsiLiteralExpression expression, LanguageLevel level, PsiFile file @@ -1248,30 +1218,27 @@ public static HighlightInfo checkLiteralExpressionParsingError( if (file != null) { if (isFP) { if (text.startsWith(PsiLiteralUtil.HEX_PREFIX)) { - HighlightInfo info = checkFeature(expression, JavaFeature.HEX_FP_LITERALS, level, file); - if (info != null) { - return info; + HighlightInfo.Builder hlBuilder = checkFeature(expression, JavaFeature.HEX_FP_LITERALS, level, file); + if (hlBuilder != null) { + return hlBuilder; } } } if (isInt) { if (text.startsWith(PsiLiteralUtil.BIN_PREFIX)) { - HighlightInfo info = checkFeature(expression, JavaFeature.BIN_LITERALS, level, file); - if (info != null) { - return info; + HighlightInfo.Builder hlBuilder = checkFeature(expression, JavaFeature.BIN_LITERALS, level, file); + if (hlBuilder != null) { + return hlBuilder; } } } - if (isInt || isFP) { - if (text.contains("_")) { - HighlightInfo info = checkFeature(expression, JavaFeature.UNDERSCORES, level, file); - if (info != null) { - return info; - } - info = checkUnderscores(expression, text, isInt); - if (info != null) { - return info; - } + if ((isInt || isFP) && text.contains("_")) { + HighlightInfo.Builder hlBuilder = checkFeature(expression, JavaFeature.UNDERSCORES, level, file); + if (hlBuilder == null) { + hlBuilder = checkUnderscores(expression, text, isInt); + } + if (hlBuilder != null) { + return hlBuilder; } } } @@ -1285,20 +1252,17 @@ public static HighlightInfo checkLiteralExpressionParsingError( if (cleanText.equals(PsiLiteralUtil.HEX_PREFIX)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.hexadecimalNumbersMustContainAtLeastOneHexadecimalDigit()) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.hexadecimalNumbersMustContainAtLeastOneHexadecimalDigit()); } if (cleanText.equals(PsiLiteralUtil.BIN_PREFIX)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.binaryNumbersMustContainAtLeastOneHexadecimalDigit()) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.binaryNumbersMustContainAtLeastOneHexadecimalDigit()); } if (value == null || cleanText.equals(PsiLiteralUtil._2_IN_31)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.integerNumberTooLarge()) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.integerNumberTooLarge()); } } } @@ -1311,20 +1275,17 @@ else if (type == JavaTokenType.LONG_LITERAL) { if (cleanText.equals(PsiLiteralUtil.HEX_PREFIX)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.hexadecimalNumbersMustContainAtLeastOneHexadecimalDigit()) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.hexadecimalNumbersMustContainAtLeastOneHexadecimalDigit()); } if (cleanText.equals(PsiLiteralUtil.BIN_PREFIX)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.binaryNumbersMustContainAtLeastOneHexadecimalDigit()) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.binaryNumbersMustContainAtLeastOneHexadecimalDigit()); } if (value == null || cleanText.equals(PsiLiteralUtil._2_IN_63)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.longNumberTooLarge()) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.longNumberTooLarge()); } } } @@ -1332,8 +1293,7 @@ else if (isFP) { if (value == null) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.malformedFloatingPointLiteral().get()) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.malformedFloatingPointLiteral().get()); } } else if (type == JavaTokenType.CHARACTER_LITERAL) { @@ -1344,8 +1304,7 @@ else if (type == JavaTokenType.CHARACTER_LITERAL) { if (!StringUtil.endsWithChar(text, '\'') || text.length() == 1) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.unclosedCharLiteral()) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.unclosedCharLiteral()); } text = text.substring(1, text.length() - 1); @@ -1353,22 +1312,19 @@ else if (type == JavaTokenType.CHARACTER_LITERAL) { if (chars == null) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.illegalEscapeCharacterInCharacterLiteral()) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.illegalEscapeCharacterInCharacterLiteral()); } int length = chars.length(); if (length > 1) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) .descriptionAndTooltip(JavaErrorLocalize.tooManyCharactersInCharacterLiteral()) - .registerFix(QuickFixFactory.getInstance().createConvertToStringLiteralAction()) - .create(); + .registerFix(QuickFixFactory.getInstance().createConvertToStringLiteralAction()); } else if (length == 0) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.emptyCharacterLiteral()) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.emptyCharacterLiteral()); } } } @@ -1388,23 +1344,20 @@ else if (type == JavaTokenType.STRING_LITERAL || type == JavaTokenType.TEXT_BLOC if (text.length() == 1) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.illegalLineEndInStringLiteral()) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.illegalLineEndInStringLiteral()); } text = text.substring(1, text.length() - 1); } else { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.illegalLineEndInStringLiteral()) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.illegalLineEndInStringLiteral()); } if (CodeInsightUtilCore.parseStringCharacters(text, null) == null) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.illegalEscapeCharacterInStringLiteral()) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.illegalEscapeCharacterInStringLiteral()); } } } @@ -1414,8 +1367,7 @@ else if (value == null) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(p, p) .endOfLine() - .descriptionAndTooltip(JavaErrorLocalize.textBlockUnclosed()) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.textBlockUnclosed()); } else { StringBuilder chars = new StringBuilder(text.length()); @@ -1427,29 +1379,27 @@ else if (value == null) { : expression.getTextRange(); return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression, textRange) - .descriptionAndTooltip(JavaErrorLocalize.illegalEscapeCharacterInStringLiteral()) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.illegalEscapeCharacterInStringLiteral()); } else { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.textBlockNewLine()) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.textBlockNewLine()); } } } else { if (file != null && containsUnescaped(text, "\\\n")) { - HighlightInfo info = checkFeature(expression, JavaFeature.TEXT_BLOCK_ESCAPES, level, file); - if (info != null) { - return info; + HighlightInfo.Builder hlBuilder = checkFeature(expression, JavaFeature.TEXT_BLOCK_ESCAPES, level, file); + if (hlBuilder != null) { + return hlBuilder; } } } if (file != null && containsUnescaped(text, "\\s")) { - HighlightInfo info = checkFeature(expression, JavaFeature.TEXT_BLOCK_ESCAPES, level, file); - if (info != null) { - return info; + HighlightInfo.Builder hlBuilder = checkFeature(expression, JavaFeature.TEXT_BLOCK_ESCAPES, level, file); + if (hlBuilder != null) { + return hlBuilder; } } } @@ -1458,28 +1408,24 @@ else if (value == null) { if (number.isInfinite()) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.floatingPointNumberTooLarge()) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.floatingPointNumberTooLarge()); } if (number == 0 && !TypeConversionUtil.isFPZero(text)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.floatingPointNumberTooSmall()) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.floatingPointNumberTooSmall()); } } else if (value instanceof Double number) { if (number.isInfinite()) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.floatingPointNumberTooLarge()) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.floatingPointNumberTooLarge()); } if (number == 0 && !TypeConversionUtil.isFPZero(text)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.floatingPointNumberTooSmall()) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.floatingPointNumberTooSmall()); } } @@ -1514,7 +1460,7 @@ private static boolean containsUnescaped(@Nonnull String text, @Nonnull String s } @RequiredReadAction - private static HighlightInfo checkUnderscores(@Nonnull PsiElement expression, @Nonnull String text, boolean isInt) { + private static HighlightInfo.Builder checkUnderscores(@Nonnull PsiElement expression, @Nonnull String text, boolean isInt) { String[] parts = ArrayUtil.EMPTY_STRING_ARRAY; if (isInt) { @@ -1542,8 +1488,7 @@ private static HighlightInfo checkUnderscores(@Nonnull PsiElement expression, @N if (part != null && (StringUtil.startsWithChar(part, '_') || StringUtil.endsWithChar(part, '_'))) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.illegalUnderscore()) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.illegalUnderscore()); } } @@ -1552,7 +1497,7 @@ private static HighlightInfo checkUnderscores(@Nonnull PsiElement expression, @N @Nullable @RequiredReadAction - public static HighlightInfo checkMustBeBoolean(@Nonnull PsiExpression expr, PsiType type) { + public static HighlightInfo.Builder checkMustBeBoolean(@Nonnull PsiExpression expr, PsiType type) { PsiElement parent = expr.getParent(); if (parent instanceof PsiIfStatement || parent instanceof PsiWhileStatement || parent instanceof PsiForStatement forStmt && expr.equals(forStmt.getCondition()) @@ -1562,23 +1507,17 @@ public static HighlightInfo checkMustBeBoolean(@Nonnull PsiExpression expr, PsiT } if (!TypeConversionUtil.isBooleanType(type)) { - HighlightInfo info = createIncompatibleTypeHighlightInfo(PsiType.BOOLEAN, type, expr.getTextRange(), 0); + HighlightInfo.Builder hlBuilder = createIncompatibleTypeHighlightInfo(PsiType.BOOLEAN, type, expr.getTextRange(), 0); if (expr instanceof PsiMethodCallExpression methodCall) { PsiMethod method = methodCall.resolveMethod(); if (method != null && PsiType.VOID.equals(method.getReturnType())) { - QuickFixAction.registerQuickFixAction( - info, - QuickFixFactory.getInstance().createMethodReturnFix(method, PsiType.BOOLEAN, true) - ); + hlBuilder.registerFix(QuickFixFactory.getInstance().createMethodReturnFix(method, PsiType.BOOLEAN, true)); } } else if (expr instanceof PsiAssignmentExpression assignment && assignment.getOperationTokenType() == JavaTokenType.EQ) { - QuickFixAction.registerQuickFixAction( - info, - QuickFixFactory.getInstance().createAssignmentToComparisonFix(assignment) - ); + hlBuilder.registerFix(QuickFixFactory.getInstance().createAssignmentToComparisonFix(assignment)); } - return info; + return hlBuilder; } } return null; @@ -1778,7 +1717,7 @@ public static HighlightInfo checkNotAStatement(@Nonnull PsiStatement statement) @Nullable @RequiredReadAction - public static HighlightInfo checkSwitchBlockStatements( + public static HighlightInfo.Builder checkSwitchBlockStatements( @Nonnull PsiSwitchBlock switchBlock, @Nonnull LanguageLevel languageLevel, @Nonnull PsiFile file @@ -1789,8 +1728,7 @@ public static HighlightInfo checkSwitchBlockStatements( if (first != null && !(first instanceof PsiSwitchLabelStatementBase) && !PsiUtil.isJavaToken(first, JavaTokenType.RBRACE)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(first) - .descriptionAndTooltip(JavaErrorLocalize.statementMustBePrependedWithCaseLabel()) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.statementMustBePrependedWithCaseLabel()); } PsiElement element = first; @@ -1801,9 +1739,9 @@ public static HighlightInfo checkSwitchBlockStatements( while (element != null && !PsiUtil.isJavaToken(element, JavaTokenType.RBRACE)) { if (element instanceof PsiSwitchLabeledRuleStatement) { if (!levelChecked) { - HighlightInfo info = checkFeature(element, JavaFeature.ENHANCED_SWITCH, languageLevel, file); - if (info != null) { - return info; + HighlightInfo.Builder hlBuilder = checkFeature(element, JavaFeature.ENHANCED_SWITCH, languageLevel, file); + if (hlBuilder != null) { + return hlBuilder; } levelChecked = true; } @@ -1824,9 +1762,9 @@ else if (element instanceof PsiStatement statement) { if (!levelChecked && element instanceof PsiSwitchLabelStatementBase switchLabelStatementBase) { PsiExpressionList values = switchLabelStatementBase.getCaseValues(); if (values != null && values.getExpressionCount() > 1) { - HighlightInfo info = checkFeature(values, JavaFeature.ENHANCED_SWITCH, languageLevel, file); - if (info != null) { - return info; + HighlightInfo.Builder hlBuilder = checkFeature(values, JavaFeature.ENHANCED_SWITCH, languageLevel, file); + if (hlBuilder != null) { + return hlBuilder; } levelChecked = true; } @@ -1838,18 +1776,17 @@ else if (element instanceof PsiStatement statement) { if (enhancedLabels && !(alien instanceof PsiSwitchLabelStatementBase)) { PsiSwitchLabeledRuleStatement previousRule = PsiTreeUtil.getPrevSiblingOfType(alien, PsiSwitchLabeledRuleStatement.class); - HighlightInfo.Builder info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) + HighlightInfo.Builder hlBuilder = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(alien) .descriptionAndTooltip(JavaErrorLocalize.statementMustBePrependedWithCaseLabel()); if (previousRule != null) { - info.registerFix(QuickFixFactory.getInstance().createWrapSwitchRuleStatementsIntoBlockFix(previousRule)); + hlBuilder.registerFix(QuickFixFactory.getInstance().createWrapSwitchRuleStatementsIntoBlockFix(previousRule)); } - return info.create(); + return hlBuilder; } return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(alien) - .descriptionAndTooltip(JavaErrorLocalize.differentCaseKindsInSwitch()) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.differentCaseKindsInSwitch()); } } @@ -2183,29 +2120,20 @@ public static LocalizeValue buildProblemWithStaticDescription(@Nonnull PsiElemen @RequiredReadAction public static void registerStaticProblemQuickFixAction( @Nonnull PsiElement refElement, - HighlightInfo errorResult, + @Nonnull HighlightInfo.Builder hlBuilder, @Nonnull PsiJavaCodeReferenceElement place ) { QuickFixFactory factory = QuickFixFactory.getInstance(); if (refElement instanceof PsiModifierListOwner modifierListOwner) { - QuickFixAction.registerQuickFixAction( - errorResult, - factory.createAddModifierFix(modifierListOwner, PsiModifier.STATIC) - ); + hlBuilder.registerFix(factory.createAddModifierFix(modifierListOwner, PsiModifier.STATIC)); } // make context non static PsiModifierListOwner staticParent = PsiUtil.getEnclosingStaticElement(place, null); if (staticParent != null && isInstanceReference(place)) { - QuickFixAction.registerQuickFixAction( - errorResult, - factory.createRemoveModifierFix(staticParent, PsiModifier.STATIC) - ); + hlBuilder.registerFix(factory.createRemoveModifierFix(staticParent, PsiModifier.STATIC)); } if (place instanceof PsiReferenceExpression placeRefExpr && refElement instanceof PsiField) { - QuickFixAction.registerQuickFixAction( - errorResult, - factory.createCreateFieldFromUsageFix(placeRefExpr) - ); + hlBuilder.registerFix(factory.createCreateFieldFromUsageFix(placeRefExpr)); } } @@ -2288,7 +2216,7 @@ private static LocalizeValue getContainerName(PsiModifierListOwner refElement, P @Nullable @RequiredReadAction - public static HighlightInfo checkValidArrayAccessExpression(@Nonnull PsiArrayAccessExpression arrayAccessExpression) { + public static HighlightInfo.Builder checkValidArrayAccessExpression(@Nonnull PsiArrayAccessExpression arrayAccessExpression) { PsiExpression arrayExpression = arrayAccessExpression.getArrayExpression(); PsiType arrayExpressionType = arrayExpression.getType(); @@ -2296,8 +2224,7 @@ public static HighlightInfo checkValidArrayAccessExpression(@Nonnull PsiArrayAcc return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(arrayExpression) .descriptionAndTooltip(JavaErrorLocalize.arrayTypeExpected(JavaHighlightUtil.formatType(arrayExpressionType))) - .registerFix(QuickFixFactory.getInstance().createReplaceWithListAccessFix(arrayAccessExpression)) - .create(); + .registerFix(QuickFixFactory.getInstance().createReplaceWithListAccessFix(arrayAccessExpression)); } PsiExpression indexExpression = arrayAccessExpression.getIndexExpression(); @@ -2309,7 +2236,7 @@ public static HighlightInfo checkValidArrayAccessExpression(@Nonnull PsiArrayAcc @Nullable @RequiredReadAction - public static HighlightInfo checkCatchParameterIsThrowable(@Nonnull PsiParameter parameter) { + public static HighlightInfo.Builder checkCatchParameterIsThrowable(@Nonnull PsiParameter parameter) { if (parameter.getDeclarationScope() instanceof PsiCatchSection) { PsiType type = parameter.getType(); return checkMustBeThrowable(type, parameter, true); @@ -2319,7 +2246,7 @@ public static HighlightInfo checkCatchParameterIsThrowable(@Nonnull PsiParameter @Nullable @RequiredReadAction - public static HighlightInfo checkTryResourceIsAutoCloseable(@Nonnull PsiResourceListElement resource) { + public static HighlightInfo.Builder checkTryResourceIsAutoCloseable(@Nonnull PsiResourceListElement resource) { PsiType type = resource.getType(); if (type == null) { return null; @@ -2391,18 +2318,17 @@ public static Collection checkArrayInitializer(PsiExpression init Collection result = new ArrayList<>(); PsiExpression[] initializers = arrayInitializer.getInitializers(); for (PsiExpression expression : initializers) { - HighlightInfo info = checkArrayInitializerCompatibleTypes(expression, componentType); - if (info != null) { - result.add(info); - + HighlightInfo.Builder hlBuilder = checkArrayInitializerCompatibleTypes(expression, componentType); + if (hlBuilder != null) { if (!arrayTypeFixChecked) { PsiType checkResult = JavaHighlightUtil.sameType(initializers); fix = checkResult != null ? VariableArrayTypeFix.createFix(arrayInitializer, checkResult) : null; arrayTypeFixChecked = true; } if (fix != null) { - QuickFixAction.registerQuickFixAction(info, new LocalQuickFixOnPsiElementAsIntentionAdapter(fix)); + hlBuilder.registerFix(new LocalQuickFixOnPsiElementAsIntentionAdapter(fix)); } + result.add(hlBuilder.create()); } } return result; @@ -2410,13 +2336,12 @@ public static Collection checkArrayInitializer(PsiExpression init @Nullable @RequiredReadAction - private static HighlightInfo checkArrayInitializerCompatibleTypes(@Nonnull PsiExpression initializer, PsiType componentType) { + private static HighlightInfo.Builder checkArrayInitializerCompatibleTypes(@Nonnull PsiExpression initializer, PsiType componentType) { PsiType initializerType = initializer.getType(); if (initializerType == null) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(initializer) - .descriptionAndTooltip(JavaErrorLocalize.illegalInitializer(JavaHighlightUtil.formatType(componentType))) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.illegalInitializer(JavaHighlightUtil.formatType(componentType))); } PsiExpression expression = initializer instanceof PsiArrayInitializerExpression ? null : initializer; return checkAssignability(componentType, initializerType, expression, initializer); @@ -2521,9 +2446,9 @@ public static Collection checkSwitchLabelValues(@Nonnull PsiSwitc if (expressionList != null) { for (PsiExpression expr : expressionList.getExpressions()) { if (selectorExpression != null) { - HighlightInfo result = checkAssignability(selectorType, expr.getType(), expr, expr); + HighlightInfo.Builder result = checkAssignability(selectorType, expr.getType(), expr, expr); if (result != null) { - results.add(result); + results.add(result.create()); continue; } } @@ -2791,7 +2716,7 @@ else if (typeOwner instanceof JavaCodeFragment) { @Nullable @RequiredReadAction - public static HighlightInfo checkMemberReferencedBeforeConstructorCalled( + public static HighlightInfo.Builder checkMemberReferencedBeforeConstructorCalled( @Nonnull PsiElement expression, PsiElement resolved, @Nonnull PsiFile containingFile @@ -2916,7 +2841,7 @@ else if (expression instanceof PsiThisExpression thisExpr) { @Nullable @RequiredReadAction - private static HighlightInfo checkReferenceToOurInstanceInsideThisOrSuper( + private static HighlightInfo.Builder checkReferenceToOurInstanceInsideThisOrSuper( @Nonnull PsiElement expression, @Nonnull PsiClass referencedClass, String resolvedName, @@ -2966,18 +2891,18 @@ private static HighlightInfo checkReferenceToOurInstanceInsideThisOrSuper( return null; } - HighlightInfo highlightInfo = createMemberReferencedError(resolvedName, expression.getTextRange()); + HighlightInfo.Builder hlBuilder = createMemberReferencedError(resolvedName, expression.getTextRange()); if (expression instanceof PsiReferenceExpression refExpr && PsiUtil.isInnerClass(aClass)) { String referenceName = refExpr.getReferenceName(); PsiClass containingClass = aClass.getContainingClass(); LOG.assertTrue(containingClass != null); PsiField fieldInContainingClass = containingClass.findFieldByName(referenceName, true); if (fieldInContainingClass != null && refExpr.getQualifierExpression() == null) { - QuickFixAction.registerQuickFixAction(highlightInfo, new QualifyWithThisFix(containingClass, refExpr)); + hlBuilder.registerFix(new QualifyWithThisFix(containingClass, refExpr)); } } - return highlightInfo; + return hlBuilder; } if (element instanceof PsiReferenceExpression refExpr) { @@ -3009,16 +2934,16 @@ private static HighlightInfo checkReferenceToOurInstanceInsideThisOrSuper( return null; } - private static HighlightInfo createMemberReferencedError(String resolvedName, @Nonnull TextRange textRange) { + @Nonnull + private static HighlightInfo.Builder createMemberReferencedError(String resolvedName, @Nonnull TextRange textRange) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(textRange) - .descriptionAndTooltip(JavaErrorLocalize.memberReferencedBeforeConstructorCalled(resolvedName)) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.memberReferencedBeforeConstructorCalled(resolvedName)); } @Nullable @RequiredReadAction - public static HighlightInfo 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; } @@ -3250,7 +3175,7 @@ private static boolean checkSingleType(PsiClass catchClass, PsiType upperCatchTy @Nullable @RequiredReadAction - public static HighlightInfo checkTernaryOperatorConditionIsBoolean(@Nonnull PsiExpression expression, PsiType type) { + public static HighlightInfo.Builder checkTernaryOperatorConditionIsBoolean(@Nonnull PsiExpression expression, PsiType type) { if (expression.getParent() instanceof PsiConditionalExpression condExpr && condExpr.getCondition() == expression && !TypeConversionUtil.isBooleanType(type)) { return createIncompatibleTypeHighlightInfo(PsiType.BOOLEAN, type, expression.getTextRange(), 0); @@ -3277,7 +3202,7 @@ public static HighlightInfo checkStatementPrependedWithCaseInsideSwitch(@Nonnull @Nullable @RequiredReadAction - public static HighlightInfo checkAssertOperatorTypes(@Nonnull PsiExpression expression, @Nullable PsiType type) { + public static HighlightInfo.Builder checkAssertOperatorTypes(@Nonnull PsiExpression expression, @Nullable PsiType type) { if (type == null) { return null; } @@ -3286,27 +3211,24 @@ public static HighlightInfo checkAssertOperatorTypes(@Nonnull PsiExpression expr } if (expression == assertStatement.getAssertCondition() && !TypeConversionUtil.isBooleanType(type)) { // addTypeCast quickfix is not applicable here since no type can be cast to boolean - HighlightInfo highlightInfo = createIncompatibleTypeHighlightInfo(PsiType.BOOLEAN, type, expression.getTextRange(), 0); + HighlightInfo.Builder hlBuilder = + createIncompatibleTypeHighlightInfo(PsiType.BOOLEAN, type, expression.getTextRange(), 0); if (expression instanceof PsiAssignmentExpression assignment && assignment.getOperationTokenType() == JavaTokenType.EQ) { - QuickFixAction.registerQuickFixAction( - highlightInfo, - QuickFixFactory.getInstance().createAssignmentToComparisonFix(assignment) - ); + hlBuilder.registerFix(QuickFixFactory.getInstance().createAssignmentToComparisonFix(assignment)); } - return highlightInfo; + return hlBuilder; } if (expression == assertStatement.getAssertDescription() && TypeConversionUtil.isVoidType(type)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(JavaErrorLocalize.voidTypeIsNotAllowed()) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.voidTypeIsNotAllowed()); } return null; } @Nullable @RequiredReadAction - public static HighlightInfo checkSynchronizedExpressionType( + public static HighlightInfo.Builder checkSynchronizedExpressionType( @Nonnull PsiExpression expression, @Nullable PsiType type, @Nonnull PsiFile containingFile @@ -3324,7 +3246,7 @@ public static HighlightInfo checkSynchronizedExpressionType( @Nullable @RequiredReadAction - public static HighlightInfo checkConditionalExpressionBranchTypesMatch(@Nonnull PsiExpression expression, PsiType type) { + public static HighlightInfo.Builder checkConditionalExpressionBranchTypesMatch(@Nonnull PsiExpression expression, PsiType type) { PsiElement parent = expression.getParent(); if (!(parent instanceof PsiConditionalExpression conditionalExpr)) { return null; @@ -3350,8 +3272,9 @@ public static HighlightInfo checkConditionalExpressionBranchTypesMatch(@Nonnull return null; } + @Nonnull @SuppressWarnings("StringContatenationInLoop") - public static HighlightInfo createIncompatibleTypeHighlightInfo( + public static HighlightInfo.Builder createIncompatibleTypeHighlightInfo( PsiType lType, PsiType rType, @Nonnull TextRange textRange, @@ -3419,16 +3342,14 @@ public static HighlightInfo createIncompatibleTypeHighlightInfo( return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(textRange) - .description(JavaErrorLocalize.incompatibleTypes(JavaHighlightUtil.formatType(lType1), JavaHighlightUtil.formatType(rType1)) - .get()) - .escapedToolTip(toolTip.get()) - .navigationShift(navigationShift) - .create(); + .description(JavaErrorLocalize.incompatibleTypes(JavaHighlightUtil.formatType(lType1), JavaHighlightUtil.formatType(rType1))) + .escapedToolTip(toolTip) + .navigationShift(navigationShift); } @Nullable @RequiredReadAction - public static HighlightInfo checkSingleImportClassConflict( + public static HighlightInfo.Builder checkSingleImportClassConflict( @Nonnull PsiImportStatement statement, @Nonnull Map> importedClasses, @Nonnull PsiFile containingFile @@ -3444,8 +3365,7 @@ public static HighlightInfo checkSingleImportClassConflict( if (importedClass != null && !containingFile.getManager().areElementsEquivalent(importedClass, element)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(statement) - .descriptionAndTooltip(JavaErrorLocalize.singleImportClassConflict(formatClass(importedClass)).get()) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.singleImportClassConflict(formatClass(importedClass))); } importedClasses.put(name, Pair.create(null, (PsiClass)element)); } @@ -3469,37 +3389,35 @@ private static String getFQName(@Nullable PsiType type, boolean longName) { @Nullable @RequiredReadAction - public static HighlightInfo checkMustBeThrowable(@Nullable PsiType type, @Nonnull PsiElement context, boolean addCastIntention) { + public static HighlightInfo.Builder checkMustBeThrowable( + @Nullable PsiType type, + @Nonnull PsiElement context, + boolean addCastIntention + ) { if (type == null) { return null; } PsiElementFactory factory = JavaPsiFacade.getInstance(context.getProject()).getElementFactory(); PsiClassType throwable = factory.createTypeByFQClassName("java.lang.Throwable", context.getResolveScope()); if (!TypeConversionUtil.isAssignable(throwable, type)) { - HighlightInfo highlightInfo = createIncompatibleTypeHighlightInfo(throwable, type, context.getTextRange(), 0); + HighlightInfo.Builder hlBuilder = createIncompatibleTypeHighlightInfo(throwable, type, context.getTextRange(), 0); if (addCastIntention && TypeConversionUtil.areTypesConvertible(type, throwable) && context instanceof PsiExpression contextErpr) { - QuickFixAction.registerQuickFixAction( - highlightInfo, - QuickFixFactory.getInstance().createAddTypeCastFix(throwable, contextErpr) - ); + hlBuilder.registerFix(QuickFixFactory.getInstance().createAddTypeCastFix(throwable, contextErpr)); } PsiClass aClass = PsiUtil.resolveClassInClassTypeOnly(type); if (aClass != null) { - QuickFixAction.registerQuickFixAction( - highlightInfo, - QuickFixFactory.getInstance().createExtendsListFix(aClass, throwable, true) - ); + hlBuilder.registerFix(QuickFixFactory.getInstance().createExtendsListFix(aClass, throwable, true)); } - return highlightInfo; + return hlBuilder; } return null; } @Nullable @RequiredReadAction - private static HighlightInfo checkMustBeThrowable(@Nullable PsiClass aClass, @Nonnull PsiElement context) { + private static HighlightInfo.Builder checkMustBeThrowable(@Nullable PsiClass aClass, @Nonnull PsiElement context) { if (aClass == null) { return null; } @@ -3528,7 +3446,7 @@ public static HighlightInfo checkLabelDefined(@Nullable PsiIdentifier labelIdent @Nullable @RequiredReadAction - public static HighlightInfo checkReference( + public static HighlightInfo.Builder checkReference( @Nonnull PsiJavaCodeReferenceElement ref, @Nonnull JavaResolveResult result, @Nonnull PsiFile containingFile, @@ -3540,9 +3458,11 @@ public static HighlightInfo checkReference( } PsiElement resolved = result.getElement(); - HighlightInfo highlightInfo = checkMemberReferencedBeforeConstructorCalled(ref, resolved, containingFile); - if (highlightInfo != null) { - return highlightInfo; + { + HighlightInfo.Builder hlBuilder = checkMemberReferencedBeforeConstructorCalled(ref, resolved, containingFile); + if (hlBuilder != null) { + return hlBuilder; + } } PsiElement refParent = ref.getParent(); @@ -3552,8 +3472,7 @@ public static HighlightInfo checkReference( if (qualifierExpression == ref && resolved != null && !(resolved instanceof PsiClass) && !(resolved instanceof PsiVariable)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF) .range(qualifierExpression) - .descriptionAndTooltip(JavaErrorLocalize.qualifierMustBeExpression()) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.qualifierMustBeExpression()); } } else if (refParent instanceof PsiMethodCallExpression) { @@ -3581,48 +3500,43 @@ else if (refParent instanceof PsiMethodCallExpression) { description = JavaErrorLocalize.cannotResolveSymbol(refName.getText()); } - HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF) + HighlightInfo.Builder hlBuilder = HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF) .range(refName) - .descriptionAndTooltip(description) - .createUnconditionally(); - UnresolvedReferenceQuickFixProvider.registerReferenceFixes(ref, QuickFixActionRegistrar.create(info)); - return info; + .descriptionAndTooltip(description); + UnresolvedReferenceQuickFixUpdater.getInstance(containingFile.getProject()).registerQuickFixesLater(ref, hlBuilder); + return hlBuilder; } if (!result.isValidResult() && !PsiUtil.isInsideJavadocComment(ref)) { if (!result.isAccessible()) { - HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF) + HighlightInfo.Builder hlBuilder = HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF) .range(refName) - .descriptionAndTooltip(buildProblemWithAccessDescription(ref, result, resolved)) - .create(); + .descriptionAndTooltip(buildProblemWithAccessDescription(ref, result, resolved)); if (result.isStaticsScopeCorrect()) { - registerAccessQuickFixAction((PsiMember)resolved, ref, info, result.getCurrentFileResolveScope()); + registerAccessQuickFixAction( + (PsiMember)resolved, + ref, + hlBuilder, + refName.getTextRange(), + result.getCurrentFileResolveScope() + ); if (ref instanceof PsiReferenceExpression refExpr) { - QuickFixAction.registerQuickFixAction( - info, - QuickFixFactory.getInstance().createRenameWrongRefFix(refExpr) - ); + hlBuilder.registerFix(QuickFixFactory.getInstance().createRenameWrongRefFix(refExpr)); } } - if (info != null) { - UnresolvedReferenceQuickFixProvider.registerReferenceFixes(ref, QuickFixActionRegistrar.create(info)); - } - return info; + UnresolvedReferenceQuickFixUpdater.getInstance(containingFile.getProject()).registerQuickFixesLater(ref, hlBuilder); + return hlBuilder; } if (!result.isStaticsScopeCorrect()) { - HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF) + HighlightInfo.Builder hlBuilder = HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF) .range(refName) - .descriptionAndTooltip(buildProblemWithStaticDescription(resolved)) - .create(); - registerStaticProblemQuickFixAction(resolved, info, ref); + .descriptionAndTooltip(buildProblemWithStaticDescription(resolved)); + registerStaticProblemQuickFixAction(resolved, hlBuilder, ref); if (ref instanceof PsiReferenceExpression refExpr) { - QuickFixAction.registerQuickFixAction( - info, - QuickFixFactory.getInstance().createRenameWrongRefFix(refExpr) - ); + hlBuilder.registerFix(QuickFixFactory.getInstance().createRenameWrongRefFix(refExpr)); } - return info; + return hlBuilder; } } @@ -3634,8 +3548,7 @@ else if (refParent instanceof PsiMethodCallExpression) { && PsiUtil.isFromDefaultPackage(resolvedClass)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF) .range(refName) - .descriptionAndTooltip(JavaErrorLocalize.cannotResolveSymbol(refName.getText())) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.cannotResolveSymbol(refName.getText())); } return null; @@ -3688,48 +3601,46 @@ public static HighlightInfo checkPackageAndClassConflict(@Nonnull PsiJavaCodeRef @Nullable @RequiredReadAction - public static HighlightInfo checkElementInReferenceList( + public static HighlightInfo.Builder checkElementInReferenceList( @Nonnull PsiJavaCodeReferenceElement ref, @Nonnull PsiReferenceList referenceList, @Nonnull JavaResolveResult resolveResult ) { PsiElement resolved = resolveResult.getElement(); - HighlightInfo highlightInfo = null; PsiElement refGrandParent = referenceList.getParent(); if (resolved instanceof PsiClass aClass) { if (refGrandParent instanceof PsiClass parentClass) { if (refGrandParent instanceof PsiTypeParameter typeParameter) { - highlightInfo = - GenericsHighlightUtil.checkElementInTypeParameterExtendsList(referenceList, typeParameter, resolveResult, ref); + return GenericsHighlightUtil.checkElementInTypeParameterExtendsList(referenceList, typeParameter, resolveResult, ref); } else if (referenceList.equals(parentClass.getImplementsList()) || referenceList.equals(parentClass.getExtendsList())) { - highlightInfo = HighlightClassUtil.checkExtendsClassAndImplementsInterface(referenceList, resolveResult, ref); - if (highlightInfo == null) { - highlightInfo = HighlightClassUtil.checkCannotInheritFromFinal(aClass, ref); + HighlightInfo.Builder hlBuilder = + HighlightClassUtil.checkExtendsClassAndImplementsInterface(referenceList, resolveResult, ref); + if (hlBuilder == null) { + hlBuilder = HighlightClassUtil.checkCannotInheritFromFinal(aClass, ref); } - if (highlightInfo == null) { + if (hlBuilder == null) { // TODO highlightInfo = HighlightClassUtil.checkExtendsProhibitedClass(aClass, parentClass, ref); } - if (highlightInfo == null) { - highlightInfo = GenericsHighlightUtil.checkCannotInheritFromTypeParameter(aClass, ref); + if (hlBuilder == null) { + hlBuilder = GenericsHighlightUtil.checkCannotInheritFromTypeParameter(aClass, ref); } - if (highlightInfo == null) { + if (hlBuilder == null) { // TODO highlightInfo = HighlightClassUtil.checkExtendsSealedClass(parentClass, aClass, ref); } } } else if (refGrandParent instanceof PsiMethod method && method.getThrowsList() == referenceList) { - highlightInfo = checkMustBeThrowable(aClass, ref); + return checkMustBeThrowable(aClass, ref); } } else if (refGrandParent instanceof PsiMethod method && referenceList == method.getThrowsList()) { - highlightInfo = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) + return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(ref) - .descriptionAndTooltip(JavaErrorLocalize.classNameExpected()) - .create(); + .descriptionAndTooltip(JavaErrorLocalize.classNameExpected()); } - return highlightInfo; + return null; } public static boolean isSerializationImplicitlyUsedField(@Nonnull PsiField field) { @@ -3771,25 +3682,22 @@ public static void registerChangeVariableTypeFixes( @Nonnull PsiVariable parameter, PsiType itemType, @Nullable PsiExpression expr, - @Nonnull HighlightInfo highlightInfo + @Nonnull HighlightInfo.Builder highlightInfo ) { for (IntentionAction action : getChangeVariableTypeFixes(parameter, itemType)) { - QuickFixAction.registerQuickFixAction(highlightInfo, action); + highlightInfo.registerFix(action); } if (expr instanceof PsiMethodCallExpression methodCall) { PsiMethod method = methodCall.resolveMethod(); if (method != null) { - QuickFixAction.registerQuickFixAction( - highlightInfo, - PriorityActionWrapper.lowPriority( + highlightInfo.registerFix(PriorityActionWrapper.lowPriority( + method, + QuickFixFactory.getInstance().createMethodReturnFix( method, - QuickFixFactory.getInstance().createMethodReturnFix( - method, - parameter.getType(), - true - ) + parameter.getType(), + true ) - ); + )); } } } @@ -3844,8 +3752,11 @@ public static HighlightInfo checkForStatement(@Nonnull PsiForStatement statement .create(); } - private static void registerChangeParameterClassFix(PsiType lType, PsiType rType, HighlightInfo info) { - QuickFixAction.registerQuickFixAction(info, getChangeParameterClassFix(lType, rType)); + private static void registerChangeParameterClassFix(PsiType lType, PsiType rType, HighlightInfo.Builder hlBuilder) { + IntentionAction fix = getChangeParameterClassFix(lType, rType); + if (fix != null) { + hlBuilder.registerFix(fix); + } } @Nullable @@ -3876,7 +3787,7 @@ private static void registerReplaceInaccessibleFieldWithGetterSetterFix( PsiMember refElement, PsiJavaCodeReferenceElement place, PsiClass accessObjectClass, - HighlightInfo error + HighlightInfo.Builder hlBuilder ) { if (refElement instanceof PsiField field && place instanceof PsiReferenceExpression placeRefExpr) { PsiClass containingClass = field.getContainingClass(); @@ -3887,14 +3798,11 @@ private static void registerReplaceInaccessibleFieldWithGetterSetterFix( if (setter != null && PsiUtil.isAccessible(setter, placeRefExpr, accessObjectClass)) { PsiElement element = PsiTreeUtil.skipParentsOfType(placeRefExpr, PsiParenthesizedExpression.class); if (element instanceof PsiAssignmentExpression assignment && assignment.getOperationTokenType() == JavaTokenType.EQ) { - QuickFixAction.registerQuickFixAction( - error, - QuickFixFactory.getInstance().createReplaceInaccessibleFieldWithGetterSetterFix( - placeRefExpr, - setter, - true - ) - ); + hlBuilder.registerFix(QuickFixFactory.getInstance().createReplaceInaccessibleFieldWithGetterSetterFix( + placeRefExpr, + setter, + true + )); } } } @@ -3902,8 +3810,7 @@ else if (PsiUtil.isAccessedForReading(placeRefExpr)) { PsiMethod getterPrototype = PropertyUtil.generateGetterPrototype(field); PsiMethod getter = containingClass.findMethodBySignature(getterPrototype, true); if (getter != null && PsiUtil.isAccessible(getter, placeRefExpr, accessObjectClass)) { - QuickFixAction.registerQuickFixAction( - error, + hlBuilder.registerFix( QuickFixFactory.getInstance().createReplaceInaccessibleFieldWithGetterSetterFix(placeRefExpr, getter, false) ); } @@ -3914,7 +3821,7 @@ else if (PsiUtil.isAccessedForReading(placeRefExpr)) { @Nullable @RequiredReadAction - public static HighlightInfo checkFeature( + public static HighlightInfo.Builder checkFeature( @Nonnull PsiElement element, @Nonnull JavaFeature feature, @Nonnull LanguageLevel level, @@ -3925,8 +3832,7 @@ public static HighlightInfo checkFeature( .range(element) .descriptionAndTooltip(getUnsupportedFeatureMessage(element, feature, level, file)) .registerFix(QuickFixFactory.getInstance().createIncreaseLanguageLevelFix(feature.getMinimumLevel())) - .registerFix(QuickFixFactory.getInstance().createShowModulePropertiesFix(element)) - .create(); + .registerFix(QuickFixFactory.getInstance().createShowModulePropertiesFix(element)); } return 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 e76e85c09..5f2d7c252 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 @@ -20,7 +20,6 @@ import com.intellij.java.analysis.impl.codeInsight.daemon.impl.JavaHighlightInfoTypes; import com.intellij.java.language.JavaFeature; import com.intellij.java.language.LanguageLevel; -import com.intellij.java.language.impl.codeInsight.daemon.JavaErrorBundle; import com.intellij.java.language.impl.psi.controlFlow.ControlFlowUtil; import com.intellij.java.language.impl.psi.impl.source.javadoc.PsiDocMethodOrFieldRef; import com.intellij.java.language.impl.psi.impl.source.resolve.JavaResolveUtil; @@ -226,9 +225,8 @@ public void visitElement(PsiElement element) { // in JSP, XmlAttributeValue may contain java references try { for (PsiReference reference : element.getReferences()) { - if (reference instanceof PsiJavaReference) { - PsiJavaReference psiJavaReference = (PsiJavaReference)reference; - myRefCountHolder.registerReference(psiJavaReference, psiJavaReference.advancedResolve(false)); + if (reference instanceof PsiJavaReference javaRef) { + myRefCountHolder.registerReference(javaRef, javaRef.advancedResolve(false)); } } } @@ -250,8 +248,8 @@ public static JavaResolveResult resolveJavaReference(@Nonnull PsiReference refer if (reference instanceof PsiPolyVariantReference polyVariantReference && reference instanceof ResolvingHint hint && hint.canResolveTo(PsiClass.class)) { ResolveResult[] resolve = polyVariantReference.multiResolve(false); - if (resolve.length == 1 && resolve[0] instanceof JavaResolveResult) { - return (JavaResolveResult)resolve[0]; + if (resolve.length == 1 && resolve[0] instanceof JavaResolveResult resolveResult) { + return resolveResult; } } return null; @@ -262,10 +260,10 @@ public static JavaResolveResult resolveJavaReference(@Nonnull PsiReference refer public void visitAnnotation(@Nonnull PsiAnnotation annotation) { super.visitAnnotation(annotation); if (!myHolder.hasErrorResults()) { - myHolder.add(checkFeature(annotation, JavaFeature.ANNOTATIONS)); + add(checkFeature(annotation, JavaFeature.ANNOTATIONS)); } if (!myHolder.hasErrorResults()) { - myHolder.add(AnnotationsHighlightUtil.checkApplicability(annotation, myLanguageLevel, myFile)); + add(AnnotationsHighlightUtil.checkApplicability(annotation, myLanguageLevel, myFile)); } if (!myHolder.hasErrorResults()) { myHolder.add(AnnotationsHighlightUtil.checkAnnotationType(annotation)); @@ -277,7 +275,7 @@ public void visitAnnotation(@Nonnull PsiAnnotation annotation) { myHolder.add(AnnotationsHighlightUtil.checkTargetAnnotationDuplicates(annotation)); } if (!myHolder.hasErrorResults()) { - myHolder.add(AnnotationsHighlightUtil.checkDuplicateAnnotations(annotation, myLanguageLevel)); + add(AnnotationsHighlightUtil.checkDuplicateAnnotations(annotation, myLanguageLevel)); } if (!myHolder.hasErrorResults()) { myHolder.add(AnnotationsHighlightUtil.checkFunctionalInterface(annotation, myLanguageLevel)); @@ -359,7 +357,7 @@ public void visitArrayInitializerExpression(@Nonnull PsiArrayInitializerExpressi @RequiredReadAction public void visitAssignmentExpression(@Nonnull PsiAssignmentExpression assignment) { if (!myHolder.hasErrorResults()) { - myHolder.add(HighlightUtil.checkAssignmentCompatibleTypes(assignment)); + add(HighlightUtil.checkAssignmentCompatibleTypes(assignment)); } if (!myHolder.hasErrorResults()) { myHolder.add(HighlightUtil.checkAssignmentOperatorApplicable(assignment)); @@ -381,7 +379,7 @@ public void visitPolyadicExpression(@Nonnull PsiPolyadicExpression expression) { @Override @RequiredReadAction public void visitLambdaExpression(@Nonnull PsiLambdaExpression expression) { - myHolder.add(checkFeature(expression, JavaFeature.LAMBDA_EXPRESSIONS)); + add(checkFeature(expression, JavaFeature.LAMBDA_EXPRESSIONS)); PsiElement parent = PsiUtil.skipParenthesizedExprUp(expression.getParent()); if (parent instanceof PsiExpressionStatement) { return; @@ -455,11 +453,8 @@ else if (returnErrors != null) { } } - if (!myHolder.hasErrorResults()) { - PsiElement body = expression.getBody(); - if (body instanceof PsiCodeBlock) { - myHolder.add(HighlightControlFlowUtil.checkUnreachableStatement((PsiCodeBlock)body)); - } + if (!myHolder.hasErrorResults() && expression.getBody() instanceof PsiCodeBlock bodyCodeBlock) { + myHolder.add(HighlightControlFlowUtil.checkUnreachableStatement(bodyCodeBlock)); } } @@ -498,7 +493,7 @@ public void visitClass(@Nonnull PsiClass aClass) { myHolder.add(GenericsHighlightUtil.checkEnumWithoutConstantsCantHaveAbstractMethods(aClass)); } if (!myHolder.hasErrorResults()) { - myHolder.add(HighlightUtil.checkImplicitThisReferenceBeforeSuper(aClass, myJavaSdkVersion)); + add(HighlightUtil.checkImplicitThisReferenceBeforeSuper(aClass, myJavaSdkVersion)); } if (!myHolder.hasErrorResults()) { myHolder.add(HighlightClassUtil.checkClassAndPackageConflict(aClass)); @@ -616,6 +611,7 @@ else if (element instanceof PsiParameter parameter) { } @Override + @RequiredReadAction public void visitEnumConstant(@Nonnull PsiEnumConstant enumConstant) { super.visitEnumConstant(enumConstant); if (!myHolder.hasErrorResults()) { @@ -625,16 +621,17 @@ public void visitEnumConstant(@Nonnull PsiEnumConstant enumConstant) { registerConstructorCall(enumConstant); } if (!myHolder.hasErrorResults()) { - myHolder.add(HighlightUtil.checkUnhandledExceptions(enumConstant, null)); + add(HighlightUtil.checkUnhandledExceptions(enumConstant, null)); } } @Override - public void visitEnumConstantInitializer(PsiEnumConstantInitializer enumConstantInitializer) { + @RequiredReadAction + public void visitEnumConstantInitializer(@Nonnull PsiEnumConstantInitializer enumConstantInitializer) { super.visitEnumConstantInitializer(enumConstantInitializer); if (!myHolder.hasErrorResults()) { TextRange textRange = HighlightNamesUtil.getClassDeclarationTextRange(enumConstantInitializer); - myHolder.add(HighlightClassUtil.checkClassMustBeAbstract(enumConstantInitializer, textRange)); + add(HighlightClassUtil.checkClassMustBeAbstract(enumConstantInitializer, textRange)); } } @@ -645,12 +642,12 @@ public void visitExpression(@Nonnull PsiExpression expression) { super.visitExpression(expression); PsiType type = expression.getType(); - if (myHolder.add(HighlightUtil.checkMustBeBoolean(expression, type))) { + if (add(HighlightUtil.checkMustBeBoolean(expression, type))) { return; } - if (expression instanceof PsiArrayAccessExpression) { - myHolder.add(HighlightUtil.checkValidArrayAccessExpression((PsiArrayAccessExpression)expression)); + if (expression instanceof PsiArrayAccessExpression arrayAccess) { + add(HighlightUtil.checkValidArrayAccessExpression(arrayAccess)); } PsiElement parent = expression.getParent(); @@ -658,7 +655,7 @@ public void visitExpression(@Nonnull PsiExpression expression) { && newExpr.getQualifier() != expression && newExpr.getArrayInitializer() != expression) { // like in 'new String["s"]' - myHolder.add(HighlightUtil.checkAssignability(PsiType.INT, expression.getType(), expression, expression)); + add(HighlightUtil.checkAssignability(PsiType.INT, expression.getType(), expression, expression)); } if (!myHolder.hasErrorResults()) { myHolder.add(HighlightControlFlowUtil.checkCannotWriteToFinal(expression, myFile)); @@ -670,35 +667,33 @@ public void visitExpression(@Nonnull PsiExpression expression) { myHolder.addAll(HighlightUtil.checkArrayInitializer(expression, type)); } if (!myHolder.hasErrorResults()) { - myHolder.add(HighlightUtil.checkTernaryOperatorConditionIsBoolean(expression, type)); + add(HighlightUtil.checkTernaryOperatorConditionIsBoolean(expression, type)); } if (!myHolder.hasErrorResults()) { - myHolder.add(HighlightUtil.checkAssertOperatorTypes(expression, type)); + add(HighlightUtil.checkAssertOperatorTypes(expression, type)); } if (!myHolder.hasErrorResults()) { - myHolder.add(HighlightUtil.checkSynchronizedExpressionType(expression, type, myFile)); + add(HighlightUtil.checkSynchronizedExpressionType(expression, type, myFile)); } if (!myHolder.hasErrorResults()) { - myHolder.add(HighlightUtil.checkConditionalExpressionBranchTypesMatch(expression, type)); + add(HighlightUtil.checkConditionalExpressionBranchTypesMatch(expression, type)); } if (!myHolder.hasErrorResults() && parent instanceof PsiThrowStatement throwStmt && throwStmt.getException() == expression) { - myHolder.add(HighlightUtil.checkMustBeThrowable(type, expression, true)); + add(HighlightUtil.checkMustBeThrowable(type, expression, true)); } - if (!myHolder.hasErrorResults()) { - myHolder.add(AnnotationsHighlightUtil.checkConstantExpression(expression)); + add(AnnotationsHighlightUtil.checkConstantExpression(expression)); } if (!myHolder.hasErrorResults() && parent instanceof PsiForeachStatement forEach && forEach.getIteratedValue() == expression) { - myHolder.add(GenericsHighlightUtil.checkForeachExpressionTypeIsIterable(expression)); + add(GenericsHighlightUtil.checkForeachExpressionTypeIsIterable(expression)); } } @Override - public void visitExpressionList(PsiExpressionList list) { + @RequiredReadAction + public void visitExpressionList(@Nonnull PsiExpressionList list) { super.visitExpressionList(list); - PsiElement parent = list.getParent(); - if (parent instanceof PsiMethodCallExpression) { - PsiMethodCallExpression expression = (PsiMethodCallExpression)parent; + if (list.getParent() instanceof PsiMethodCallExpression expression) { if (expression.getArgumentList() == list) { PsiReferenceExpression referenceExpression = expression.getMethodExpression(); JavaResolveResult[] results = resolveOptimised(referenceExpression); @@ -714,7 +709,7 @@ public void visitExpressionList(PsiExpressionList list) { && referenceExpression.getParent() == expression) { try { if (PsiTreeUtil.findChildrenOfType(expression.getArgumentList(), PsiLambdaExpression.class).isEmpty()) { - myHolder.add(HighlightMethodUtil.checkAmbiguousMethodCallArguments( + add(HighlightMethodUtil.checkAmbiguousMethodCallArguments( referenceExpression, results, list, @@ -734,7 +729,8 @@ public void visitExpressionList(PsiExpressionList list) { } @Override - public void visitField(PsiField field) { + @RequiredReadAction + public void visitField(@Nonnull PsiField field) { super.visitField(field); if (!myHolder.hasErrorResults()) { myHolder.add(HighlightControlFlowUtil.checkFinalFieldInitialized(field)); @@ -742,19 +738,21 @@ public void visitField(PsiField field) { } @Override - public void visitForStatement(PsiForStatement statement) { + @RequiredReadAction + public void visitForStatement(@Nonnull PsiForStatement statement) { myHolder.add(HighlightUtil.checkForStatement(statement)); } @Override - public void visitForeachStatement(PsiForeachStatement statement) { - myHolder.add(checkFeature(statement, JavaFeature.FOR_EACH)); + @RequiredReadAction + public void visitForeachStatement(@Nonnull PsiForeachStatement statement) { + add(checkFeature(statement, JavaFeature.FOR_EACH)); } @Override @RequiredReadAction public void visitImportStaticStatement(@Nonnull PsiImportStaticStatement statement) { - myHolder.add(checkFeature(statement, JavaFeature.STATIC_IMPORTS)); + add(checkFeature(statement, JavaFeature.STATIC_IMPORTS)); if (!myHolder.hasErrorResults()) { myHolder.add(ImportsHighlightUtil.checkStaticOnDemandImportResolvesToClass(statement)); } @@ -766,8 +764,7 @@ public void visitIdentifier(PsiIdentifier identifier) { TextAttributesScheme colorsScheme = myHolder.getColorsScheme(); PsiElement parent = identifier.getParent(); - if (parent instanceof PsiVariable) { - PsiVariable variable = (PsiVariable)parent; + if (parent instanceof PsiVariable variable) { myHolder.add(HighlightUtil.checkVariableAlreadyDefined(variable)); if (variable.getInitializer() == null) { @@ -777,8 +774,8 @@ public void visitIdentifier(PsiIdentifier identifier) { } } - boolean isMethodParameter = - variable instanceof PsiParameter && ((PsiParameter)variable).getDeclarationScope() instanceof PsiMethod; + boolean isMethodParameter = variable instanceof PsiParameter parameter + && parameter.getDeclarationScope() instanceof PsiMethod; if (isMethodParameter) { myReassignedParameters.putInt((PsiParameter)variable, 1); // mark param as present in current file } @@ -792,7 +789,7 @@ else if (HighlightControlFlowUtil.isReassigned(variable, myFinalVarProblems)) { } else if (parent instanceof PsiClass aClass) { if (aClass.isAnnotationType()) { - myHolder.add(checkFeature(identifier, JavaFeature.ANNOTATIONS)); + add(checkFeature(identifier, JavaFeature.ANNOTATIONS)); } myHolder.add(HighlightClassUtil.checkClassAlreadyImported(aClass, identifier)); @@ -832,7 +829,7 @@ else if (parent instanceof PsiMethod method) { @RequiredReadAction public void visitImportStatement(@Nonnull PsiImportStatement statement) { if (!myHolder.hasErrorResults()) { - myHolder.add(HighlightUtil.checkSingleImportClassConflict(statement, mySingleImportedClasses, myFile)); + add(HighlightUtil.checkSingleImportClassConflict(statement, mySingleImportedClasses, myFile)); } } @@ -857,38 +854,39 @@ public void visitImportStaticReferenceElement(@Nonnull PsiImportStaticReferenceE PsiManager manager = ref.getManager(); for (JavaResolveResult result : results) { PsiElement element = result.getElement(); - - String description = null; - if (element instanceof PsiClass) { + if (element instanceof PsiClass psiClass) { Pair imported = mySingleImportedClasses.get(refName); - PsiClass aClass = imported == null ? null : imported.getSecond(); - if (aClass != null && !manager.areElementsEquivalent(aClass, element)) { - //noinspection ConditionalExpressionWithIdenticalBranches - description = imported.first == null - ? JavaErrorLocalize.singleImportClassConflict(refName).get() + PsiClass importedClass = imported == null ? null : imported.getSecond(); + if (importedClass != null && !manager.areElementsEquivalent(importedClass, psiClass)) { + LocalizeValue description = imported.first == null + ? JavaErrorLocalize.singleImportClassConflict(refName) : imported.first.equals(ref) - ? JavaErrorLocalize.classIsAmbiguousInSingleStaticImport(refName).get() - : JavaErrorLocalize.classIsAlreadyDefinedInSingleStaticImport(refName).get(); + ? JavaErrorLocalize.classIsAmbiguousInSingleStaticImport(refName) + : JavaErrorLocalize.classIsAlreadyDefinedInSingleStaticImport(refName); + myHolder.add( + HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) + .range(ref) + .descriptionAndTooltip(description) + .create() + ); } - mySingleImportedClasses.put(refName, Pair.create(ref, (PsiClass)element)); + mySingleImportedClasses.put(refName, Pair.create(ref, psiClass)); } - else if (element instanceof PsiField) { + else if (element instanceof PsiField field) { Pair imported = mySingleImportedFields.get(refName); - PsiField field = imported == null ? null : imported.getSecond(); - if (field != null && !manager.areElementsEquivalent(field, element)) { - //noinspection ConditionalExpressionWithIdenticalBranches - description = imported.first.equals(ref) - ? JavaErrorLocalize.fieldIsAmbiguousInSingleStaticImport(refName).get() - : JavaErrorLocalize.fieldIsAlreadyDefinedInSingleStaticImport(refName).get(); + 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); + myHolder.add( + HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) + .range(ref) + .descriptionAndTooltip(description) + .create() + ); } - mySingleImportedFields.put(refName, Pair.create(ref, (PsiField)element)); - } - - if (description != null) { - myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) - .range(ref) - .descriptionAndTooltip(description) - .create()); + mySingleImportedFields.put(refName, Pair.create(ref, field)); } } } @@ -905,7 +903,7 @@ else if (element instanceof PsiField) { } } } - final TextAttributesScheme colorsScheme = myHolder.getColorsScheme(); + TextAttributesScheme colorsScheme = myHolder.getColorsScheme(); if (resolved instanceof PsiClass psiClass) { myHolder.add(HighlightNamesUtil.highlightClassName(psiClass, ref, colorsScheme)); } @@ -941,23 +939,22 @@ public void visitKeyword(@Nonnull PsiKeyword keyword) { super.visitKeyword(keyword); PsiElement parent = keyword.getParent(); String text = keyword.getText(); - if (parent instanceof PsiModifierList) { - PsiModifierList psiModifierList = (PsiModifierList)parent; + if (parent instanceof PsiModifierList modifierList) { if (!myHolder.hasErrorResults()) { - myHolder.add(HighlightUtil.checkNotAllowedModifier(keyword, psiModifierList)); + myHolder.add(HighlightUtil.checkNotAllowedModifier(keyword, modifierList)); } if (!myHolder.hasErrorResults()) { - myHolder.add(HighlightUtil.checkIllegalModifierCombination(keyword, psiModifierList)); + myHolder.add(HighlightUtil.checkIllegalModifierCombination(keyword, modifierList)); } - if (PsiModifier.ABSTRACT.equals(text) && psiModifierList.getParent() instanceof PsiMethod) { + if (PsiModifier.ABSTRACT.equals(text) && modifierList.getParent() instanceof PsiMethod method) { if (!myHolder.hasErrorResults()) { - myHolder.add(HighlightMethodUtil.checkAbstractMethodInConcreteClass((PsiMethod)psiModifierList.getParent(), keyword)); + myHolder.add(HighlightMethodUtil.checkAbstractMethodInConcreteClass(method, keyword)); } } } - else if (PsiKeyword.INTERFACE.equals(text) && parent instanceof PsiClass) { + else if (PsiKeyword.INTERFACE.equals(text) && parent instanceof PsiClass psiClass) { if (!myHolder.hasErrorResults()) { - myHolder.add(HighlightClassUtil.checkInterfaceCannotBeLocal((PsiClass)parent)); + myHolder.add(HighlightClassUtil.checkInterfaceCannotBeLocal(psiClass)); } } if (!myHolder.hasErrorResults()) { @@ -987,7 +984,7 @@ public void visitLiteralExpression(@Nonnull PsiLiteralExpression expression) { if (myHolder.hasErrorResults()) { return; } - myHolder.add(HighlightUtil.checkLiteralExpressionParsingError(expression, myLanguageLevel, myFile)); + add(HighlightUtil.checkLiteralExpressionParsingError(expression, myLanguageLevel, myFile)); if (myRefCountHolder != null && !myHolder.hasErrorResults()) { registerReferencesFromInjectedFragments(expression); } @@ -1002,7 +999,8 @@ public void visitLiteralExpression(@Nonnull PsiLiteralExpression expression) { } @Override - public void visitMethod(PsiMethod method) { + @RequiredReadAction + public void visitMethod(@Nonnull PsiMethod method) { super.visitMethod(method); if (!myHolder.hasErrorResults()) { myHolder.add(HighlightControlFlowUtil.checkUnreachableStatement(method.getBody())); @@ -1022,10 +1020,10 @@ public void visitMethod(PsiMethod method) { myHolder.add(HighlightClassUtil.checkThingNotAllowedInInterface(method, aClass)); } if (!myHolder.hasErrorResults() && method.hasModifierProperty(PsiModifier.DEFAULT)) { - myHolder.add(checkFeature(method, JavaFeature.EXTENSION_METHODS)); + add(checkFeature(method, JavaFeature.EXTENSION_METHODS)); } - if (!myHolder.hasErrorResults() && aClass != null && aClass.isInterface() && method.hasModifierProperty(PsiModifier.STATIC)) { - myHolder.add(checkFeature(method, JavaFeature.EXTENSION_METHODS)); + if (!myHolder.hasErrorResults() && aClass != null && aClass.isInterface() && method.isStatic()) { + add(checkFeature(method, JavaFeature.EXTENSION_METHODS)); } if (!myHolder.hasErrorResults() && aClass != null) { myHolder.add(HighlightMethodUtil.checkDuplicateMethod(aClass, method, getDuplicateMethods(aClass))); @@ -1033,7 +1031,7 @@ public void visitMethod(PsiMethod method) { // method params are highlighted in visitMethod since we should make sure the method body was visited before PsiParameter[] parameters = method.getParameterList().getParameters(); - final TextAttributesScheme colorsScheme = myHolder.getColorsScheme(); + TextAttributesScheme colorsScheme = myHolder.getColorsScheme(); for (PsiParameter parameter : parameters) { int info = myReassignedParameters.getInt(parameter); @@ -1053,23 +1051,24 @@ public void visitMethod(PsiMethod method) { } } + @RequiredReadAction private void highlightReferencedMethodOrClassName(@Nonnull PsiJavaCodeReferenceElement element, PsiElement resolved) { PsiElement parent = element.getParent(); - final TextAttributesScheme colorsScheme = myHolder.getColorsScheme(); - if (parent instanceof PsiMethodCallExpression) { - PsiMethod method = ((PsiMethodCallExpression)parent).resolveMethod(); + TextAttributesScheme colorsScheme = myHolder.getColorsScheme(); + if (parent instanceof PsiMethodCallExpression methodCall) { + PsiMethod method = methodCall.resolveMethod(); PsiElement methodNameElement = element.getReferenceNameElement(); if (method != null && methodNameElement != null && !(methodNameElement instanceof PsiKeyword)) { myHolder.add(HighlightNamesUtil.highlightMethodName(method, methodNameElement, false, colorsScheme)); myHolder.add(HighlightNamesUtil.highlightClassNameInQualifier(element, colorsScheme)); } } - else if (parent instanceof PsiConstructorCall) { + else if (parent instanceof PsiConstructorCall constructorCall) { try { - PsiMethod method = ((PsiConstructorCall)parent).resolveConstructor(); - PsiMember methodOrClass = method != null ? method : resolved instanceof PsiClass ? (PsiClass)resolved : null; + PsiMethod method = constructorCall.resolveConstructor(); + PsiMember methodOrClass = method != null ? method : resolved instanceof PsiClass psiClass ? psiClass : null; if (methodOrClass != null) { - final PsiElement referenceNameElement = element.getReferenceNameElement(); + PsiElement referenceNameElement = element.getReferenceNameElement(); if (referenceNameElement != null) { // exclude type parameters from the highlighted text range TextRange range = referenceNameElement.getTextRange(); @@ -1090,23 +1089,24 @@ else if (resolved instanceof PsiPackage) { // highlight package (and following dot) as a class myHolder.add(HighlightNamesUtil.highlightPackage(resolved, element, colorsScheme)); } - else if (resolved instanceof PsiClass) { - myHolder.add(HighlightNamesUtil.highlightClassName((PsiClass)resolved, element, colorsScheme)); + else if (resolved instanceof PsiClass psiClass) { + myHolder.add(HighlightNamesUtil.highlightClassName(psiClass, element, colorsScheme)); } } @Override - public void visitMethodCallExpression(PsiMethodCallExpression expression) { + @RequiredReadAction + public void visitMethodCallExpression(@Nonnull PsiMethodCallExpression expression) { if (!myHolder.hasErrorResults()) { myHolder.add(GenericsHighlightUtil.checkEnumSuperConstructorCall(expression)); } if (!myHolder.hasErrorResults()) { - myHolder.add(HighlightClassUtil.checkSuperQualifierType(myFile.getProject(), expression)); + add(HighlightClassUtil.checkSuperQualifierType(myFile.getProject(), expression)); } // in case of JSP synthetic method call, do not check if (myFile.isPhysical() && !myHolder.hasErrorResults()) { try { - myHolder.add(HighlightMethodUtil.checkMethodCall(expression, myResolveHelper, myLanguageLevel, myJavaSdkVersion, myFile)); + add(HighlightMethodUtil.checkMethodCall(expression, myResolveHelper, myLanguageLevel, myJavaSdkVersion, myFile)); } catch (IndexNotReadyException ignored) { } @@ -1125,11 +1125,11 @@ public void visitMethodCallExpression(PsiMethodCallExpression expression) { } @Override - public void visitModifierList(PsiModifierList list) { + @RequiredReadAction + public void visitModifierList(@Nonnull PsiModifierList list) { super.visitModifierList(list); PsiElement parent = list.getParent(); - if (parent instanceof PsiMethod) { - PsiMethod method = (PsiMethod)parent; + if (parent instanceof PsiMethod method) { if (!myHolder.hasErrorResults()) { myHolder.add(HighlightMethodUtil.checkMethodCanHaveBody(method, myLanguageLevel)); } @@ -1153,9 +1153,9 @@ public void visitModifierList(PsiModifierList list) { method.getContainingClass() )); } - if (!method.hasModifierProperty(PsiModifier.STATIC)) { + if (!method.isStatic()) { if (!myHolder.hasErrorResults()) { - myHolder.add(HighlightMethodUtil.checkMethodWeakerPrivileges( + add(HighlightMethodUtil.checkMethodWeakerPrivileges( methodSignature, superMethodSignatures, true, @@ -1163,7 +1163,7 @@ public void visitModifierList(PsiModifierList list) { )); } if (!myHolder.hasErrorResults()) { - myHolder.add(HighlightMethodUtil.checkMethodOverridesFinal(methodSignature, superMethodSignatures)); + add(HighlightMethodUtil.checkMethodOverridesFinal(methodSignature, superMethodSignatures)); } } } @@ -1176,27 +1176,26 @@ public void visitModifierList(PsiModifierList list) { myHolder.add(HighlightMethodUtil.checkMethodMustHaveBody(method, aClass)); } if (!myHolder.hasErrorResults()) { - myHolder.add(HighlightMethodUtil.checkConstructorCallsBaseClassConstructor(method, myRefCountHolder, myResolveHelper)); + add(HighlightMethodUtil.checkConstructorCallsBaseClassConstructor(method, myRefCountHolder, myResolveHelper)); } if (!myHolder.hasErrorResults()) { - myHolder.add(HighlightMethodUtil.checkStaticMethodOverride(method, myFile)); + add(HighlightMethodUtil.checkStaticMethodOverride(method, myFile)); } if (!myHolder.hasErrorResults() && aClass != null && myOverrideEquivalentMethodsVisitedClasses.add(aClass)) { myHolder.addAll(GenericsHighlightUtil.checkOverrideEquivalentMethods(aClass)); } } - else if (parent instanceof PsiClass) { - PsiClass aClass = (PsiClass)parent; + else if (parent instanceof PsiClass aClass) { try { if (!myHolder.hasErrorResults()) { myHolder.add(HighlightClassUtil.checkDuplicateNestedClass(aClass)); } if (!myHolder.hasErrorResults()) { TextRange textRange = HighlightNamesUtil.getClassDeclarationTextRange(aClass); - myHolder.add(HighlightClassUtil.checkClassMustBeAbstract(aClass, textRange)); + add(HighlightClassUtil.checkClassMustBeAbstract(aClass, textRange)); } if (!myHolder.hasErrorResults()) { - myHolder.add(HighlightClassUtil.checkClassDoesNotCallSuperConstructorOrHandleExceptions( + add(HighlightClassUtil.checkClassDoesNotCallSuperConstructorOrHandleExceptions( aClass, myRefCountHolder, myResolveHelper @@ -1239,11 +1238,11 @@ public void visitNameValuePair(@Nonnull PsiNameValuePair pair) { @Override @RequiredReadAction public void visitNewExpression(PsiNewExpression expression) { - final PsiType type = expression.getType(); - final PsiClass aClass = PsiUtil.resolveClassInType(type); - myHolder.add(HighlightUtil.checkUnhandledExceptions(expression, null)); + PsiType type = expression.getType(); + PsiClass aClass = PsiUtil.resolveClassInType(type); + add(HighlightUtil.checkUnhandledExceptions(expression, null)); if (!myHolder.hasErrorResults()) { - myHolder.add(HighlightClassUtil.checkAnonymousInheritFinal(expression)); + add(HighlightClassUtil.checkAnonymousInheritFinal(expression)); } if (!myHolder.hasErrorResults()) { myHolder.add(HighlightClassUtil.checkQualifiedNew(expression, type, aClass)); @@ -1255,7 +1254,7 @@ public void visitNewExpression(PsiNewExpression expression) { myHolder.add(GenericsHighlightUtil.checkTypeParameterInstantiation(expression)); } if (!myHolder.hasErrorResults()) { - myHolder.add(HighlightClassUtil.checkInstantiationOfAbstractClass(aClass, expression)); + add(HighlightClassUtil.checkInstantiationOfAbstractClass(aClass, expression)); } try { if (!myHolder.hasErrorResults()) { @@ -1299,7 +1298,7 @@ public void visitParameter(@Nonnull PsiParameter parameter) { PsiElement parent = parameter.getParent(); if (parent instanceof PsiParameterList && parameter.isVarArgs()) { if (!myHolder.hasErrorResults()) { - myHolder.add(checkFeature(parameter, JavaFeature.VARARGS)); + add(checkFeature(parameter, JavaFeature.VARARGS)); } if (!myHolder.hasErrorResults()) { myHolder.add(GenericsHighlightUtil.checkVarArgParameterIsLast(parameter)); @@ -1307,10 +1306,10 @@ public void visitParameter(@Nonnull PsiParameter parameter) { } else if (parent instanceof PsiCatchSection) { if (!myHolder.hasErrorResults() && parameter.getType() instanceof PsiDisjunctionType) { - myHolder.add(checkFeature(parameter, JavaFeature.MULTI_CATCH)); + add(checkFeature(parameter, JavaFeature.MULTI_CATCH)); } if (!myHolder.hasErrorResults()) { - myHolder.add(HighlightUtil.checkCatchParameterIsThrowable(parameter)); + add(HighlightUtil.checkCatchParameterIsThrowable(parameter)); } if (!myHolder.hasErrorResults()) { myHolder.addAll(GenericsHighlightUtil.checkCatchParameterIsClass(parameter)); @@ -1319,9 +1318,9 @@ else if (parent instanceof PsiCatchSection) { myHolder.addAll(HighlightUtil.checkCatchTypeIsDisjoint(parameter)); } } - else if (parent instanceof PsiForeachStatement) { + else if (parent instanceof PsiForeachStatement forEach) { if (!myHolder.hasErrorResults()) { - myHolder.add(GenericsHighlightUtil.checkForEachParameterType((PsiForeachStatement)parent, parameter)); + add(GenericsHighlightUtil.checkForEachParameterType(forEach, parameter)); } } } @@ -1391,7 +1390,7 @@ private JavaResolveResult doVisitReferenceElement(@Nonnull PsiJavaCodeReferenceE myRefCountHolder.registerReference(ref, result); } - myHolder.add(HighlightUtil.checkReference(ref, result, myFile, myLanguageLevel)); + add(HighlightUtil.checkReference(ref, result, myFile, myLanguageLevel)); if (parent instanceof PsiJavaCodeReferenceElement || ref.isQualified()) { if (!myHolder.hasErrorResults() && resolved instanceof PsiTypeParameter) { @@ -1415,7 +1414,7 @@ private JavaResolveResult doVisitReferenceElement(@Nonnull PsiJavaCodeReferenceE } if (!myHolder.hasErrorResults()) { - myHolder.add(HighlightClassUtil.checkAbstractInstantiation(ref)); + add(HighlightClassUtil.checkAbstractInstantiation(ref)); } if (!myHolder.hasErrorResults()) { myHolder.add(HighlightClassUtil.checkExtendsDuplicate(ref, resolved, myFile)); @@ -1427,7 +1426,7 @@ private JavaResolveResult doVisitReferenceElement(@Nonnull PsiJavaCodeReferenceE myHolder.add(GenericsHighlightUtil.checkSelectStaticClassFromParameterizedType(resolved, ref)); } if (!myHolder.hasErrorResults()) { - myHolder.add(GenericsHighlightUtil.checkParameterizedReferenceTypeArguments( + add(GenericsHighlightUtil.checkParameterizedReferenceTypeArguments( resolved, ref, result.getSubstitutor(), @@ -1439,7 +1438,7 @@ private JavaResolveResult doVisitReferenceElement(@Nonnull PsiJavaCodeReferenceE } if (resolved != null && parent instanceof PsiReferenceList referenceList && !myHolder.hasErrorResults()) { - myHolder.add(HighlightUtil.checkElementInReferenceList(ref, referenceList, result)); + add(HighlightUtil.checkElementInReferenceList(ref, referenceList, result)); } if (parent instanceof PsiAnonymousClass anonymousClass @@ -1458,8 +1457,8 @@ private JavaResolveResult doVisitReferenceElement(@Nonnull PsiJavaCodeReferenceE } if (variable instanceof PsiParameter parameter - && ref instanceof PsiExpression - && PsiUtil.isAccessedForWriting((PsiExpression)ref)) { + && ref instanceof PsiExpression expr + && PsiUtil.isAccessedForWriting(expr)) { myReassignedParameters.putInt(parameter, 2); } @@ -1611,7 +1610,7 @@ public void visitReferenceExpression(@Nonnull PsiReferenceExpression expression) PsiExpressionList list = methodCall.getArgumentList(); if (!HighlightMethodUtil.isDummyConstructorCall(methodCall, myResolveHelper, list, expression)) { try { - myHolder.add(HighlightMethodUtil.checkAmbiguousMethodCallIdentifier( + add(HighlightMethodUtil.checkAmbiguousMethodCallIdentifier( expression, results, list, @@ -1626,7 +1625,7 @@ public void visitReferenceExpression(@Nonnull PsiReferenceExpression expression) if (!PsiTreeUtil.findChildrenOfType(methodCall.getArgumentList(), PsiLambdaExpression.class).isEmpty()) { PsiElement nameElement = expression.getReferenceNameElement(); if (nameElement != null) { - myHolder.add(HighlightMethodUtil.checkAmbiguousMethodCallArguments( + add(HighlightMethodUtil.checkAmbiguousMethodCallArguments( expression, results, list, @@ -1682,7 +1681,7 @@ public void visitReferenceExpression(@Nonnull PsiReferenceExpression expression) @Override @RequiredReadAction public void visitMethodReferenceExpression(@Nonnull PsiMethodReferenceExpression expression) { - myHolder.add(checkFeature(expression, JavaFeature.METHOD_REFERENCES)); + add(checkFeature(expression, JavaFeature.METHOD_REFERENCES)); PsiElement parent = PsiUtil.skipParenthesizedExprUp(expression.getParent()); if (parent instanceof PsiExpressionStatement) { return; @@ -1702,12 +1701,17 @@ public void visitMethodReferenceExpression(@Nonnull PsiMethodReferenceExpression } PsiElement method = result.getElement(); if (method != null && !result.isAccessible()) { - HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) + HighlightInfo.Builder hlBuilder = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(expression) - .descriptionAndTooltip(HighlightUtil.buildProblemWithAccessDescription(expression, result)) - .create(); - HighlightUtil.registerAccessQuickFixAction((PsiMember)method, expression, info, result.getCurrentFileResolveScope()); - myHolder.add(info); + .descriptionAndTooltip(HighlightUtil.buildProblemWithAccessDescription(expression, result)); + HighlightUtil.registerAccessQuickFixAction( + (PsiMember)method, + expression, + hlBuilder, + expression.getTextRange(), + result.getCurrentFileResolveScope() + ); + myHolder.add(hlBuilder.create()); } else { TextAttributesScheme colorsScheme = myHolder.getColorsScheme(); @@ -1798,7 +1802,7 @@ public void visitMethodReferenceExpression(@Nonnull PsiMethodReferenceExpression } if (!myHolder.hasErrorResults()) { - myHolder.add(HighlightUtil.checkUnhandledExceptions(expression, expression.getTextRange())); + add(HighlightUtil.checkUnhandledExceptions(expression, expression.getTextRange())); } if (!myHolder.hasErrorResults()) { @@ -1822,7 +1826,7 @@ public void visitMethodReferenceExpression(@Nonnull PsiMethodReferenceExpression PsiClass containingClass = PsiMethodReferenceUtil.getQualifierResolveResult(expression).getContainingClass(); if (containingClass != null - && !myHolder.add(HighlightClassUtil.checkInstantiationOfAbstractClass(containingClass, expression)) + && !add(HighlightClassUtil.checkInstantiationOfAbstractClass(containingClass, expression)) && !myHolder.add(GenericsHighlightUtil.checkEnumInstantiation(expression, containingClass)) && containingClass.isPhysical() && description == null) { description = JavaErrorLocalize.cannotResolveConstructor(containingClass.getName()).get(); @@ -1906,7 +1910,7 @@ public void visitReferenceParameterList(PsiReferenceParameterList list) { return; } - myHolder.add(checkFeature(list, JavaFeature.GENERICS)); + add(checkFeature(list, JavaFeature.GENERICS)); if (!myHolder.hasErrorResults()) { myHolder.add(GenericsHighlightUtil.checkParametersAllowed(list)); } @@ -1916,7 +1920,7 @@ public void visitReferenceParameterList(PsiReferenceParameterList list) { if (!myHolder.hasErrorResults()) { for (PsiTypeElement typeElement : list.getTypeParameterElements()) { if (typeElement.getType() instanceof PsiDiamondType) { - myHolder.add(checkFeature(list, JavaFeature.DIAMOND_TYPES)); + add(checkFeature(list, JavaFeature.DIAMOND_TYPES)); } } } @@ -1926,7 +1930,7 @@ public void visitReferenceParameterList(PsiReferenceParameterList list) { @RequiredReadAction public void visitReturnStatement(@Nonnull PsiReturnStatement statement) { try { - myHolder.add(HighlightUtil.checkReturnStatementType(statement)); + add(HighlightUtil.checkReturnStatementType(statement)); } catch (IndexNotReadyException ignore) { } @@ -1979,7 +1983,7 @@ public void visitSwitchStatement(@Nonnull PsiSwitchStatement statement) { @RequiredReadAction private void checkSwitchBlock(PsiSwitchBlock switchBlock) { if (!myHolder.hasErrorResults()) { - myHolder.add(HighlightUtil.checkSwitchBlockStatements(switchBlock, myLanguageLevel, myFile)); + add(HighlightUtil.checkSwitchBlockStatements(switchBlock, myLanguageLevel, myFile)); } if (!myHolder.hasErrorResults()) { myHolder.add(HighlightUtil.checkSwitchSelectorType(switchBlock, myLanguageLevel)); @@ -1995,7 +1999,7 @@ public void visitThisExpression(PsiThisExpression expr) { if (!(expr.getParent() instanceof PsiReceiverParameter)) { myHolder.add(HighlightUtil.checkThisOrSuperExpressionInIllegalContext(expr, expr.getQualifier(), myLanguageLevel)); if (!myHolder.hasErrorResults()) { - myHolder.add(HighlightUtil.checkMemberReferencedBeforeConstructorCalled(expr, null, myFile)); + add(HighlightUtil.checkMemberReferencedBeforeConstructorCalled(expr, null, myFile)); } if (!myHolder.hasErrorResults()) { visitExpression(expr); @@ -2006,7 +2010,7 @@ public void visitThisExpression(PsiThisExpression expr) { @Override @RequiredReadAction public void visitThrowStatement(@Nonnull PsiThrowStatement statement) { - myHolder.add(HighlightUtil.checkUnhandledExceptions(statement, null)); + add(HighlightUtil.checkUnhandledExceptions(statement, null)); if (!myHolder.hasErrorResults()) { visitStatement(statement); } @@ -2035,7 +2039,7 @@ public void visitTryStatement(@Nonnull PsiTryStatement statement) { public void visitResourceList(@Nonnull PsiResourceList resourceList) { super.visitResourceList(resourceList); if (!myHolder.hasErrorResults()) { - myHolder.add(checkFeature(resourceList, JavaFeature.TRY_WITH_RESOURCES)); + add(checkFeature(resourceList, JavaFeature.TRY_WITH_RESOURCES)); } } @@ -2044,7 +2048,7 @@ public void visitResourceList(@Nonnull PsiResourceList resourceList) { public void visitResourceVariable(@Nonnull PsiResourceVariable resource) { super.visitResourceVariable(resource); if (!myHolder.hasErrorResults()) { - myHolder.add(HighlightUtil.checkTryResourceIsAutoCloseable(resource)); + add(HighlightUtil.checkTryResourceIsAutoCloseable(resource)); } if (!myHolder.hasErrorResults()) { myHolder.add(HighlightUtil.checkUnhandledCloserExceptions(resource)); @@ -2056,13 +2060,13 @@ public void visitResourceVariable(@Nonnull PsiResourceVariable resource) { public void visitResourceExpression(@Nonnull PsiResourceExpression resource) { super.visitResourceExpression(resource); if (!myHolder.hasErrorResults()) { - myHolder.add(checkFeature(resource, JavaFeature.REFS_AS_RESOURCE)); + add(checkFeature(resource, JavaFeature.REFS_AS_RESOURCE)); } if (!myHolder.hasErrorResults()) { myHolder.add(HighlightUtil.checkResourceVariableIsFinal(resource)); } if (!myHolder.hasErrorResults()) { - myHolder.add(HighlightUtil.checkTryResourceIsAutoCloseable(resource)); + add(HighlightUtil.checkTryResourceIsAutoCloseable(resource)); } if (!myHolder.hasErrorResults()) { myHolder.add(HighlightUtil.checkUnhandledCloserExceptions(resource)); @@ -2076,7 +2080,7 @@ public void visitTypeElement(@Nonnull PsiTypeElement type) { myHolder.add(HighlightUtil.checkIllegalType(type)); } if (!myHolder.hasErrorResults()) { - myHolder.add(GenericsHighlightUtil.checkReferenceTypeUsedAsTypeArgument(type, myLanguageLevel)); + add(GenericsHighlightUtil.checkReferenceTypeUsedAsTypeArgument(type, myLanguageLevel)); } if (!myHolder.hasErrorResults()) { myHolder.add(GenericsHighlightUtil.checkWildcardUsage(type)); @@ -2089,7 +2093,7 @@ public void visitTypeCastExpression(@Nonnull PsiTypeCastExpression typeCast) { super.visitTypeCastExpression(typeCast); try { if (!myHolder.hasErrorResults()) { - myHolder.add(HighlightUtil.checkIntersectionInTypeCast(typeCast, myLanguageLevel, myFile)); + add(HighlightUtil.checkIntersectionInTypeCast(typeCast, myLanguageLevel, myFile)); } if (!myHolder.hasErrorResults()) { myHolder.add(HighlightUtil.checkInconvertibleTypeCast(typeCast)); @@ -2104,7 +2108,7 @@ public void visitTypeCastExpression(@Nonnull PsiTypeCastExpression typeCast) { public void visitTypeParameterList(PsiTypeParameterList list) { PsiTypeParameter[] typeParameters = list.getTypeParameters(); if (typeParameters.length > 0) { - myHolder.add(checkFeature(list, JavaFeature.GENERICS)); + add(checkFeature(list, JavaFeature.GENERICS)); if (!myHolder.hasErrorResults()) { myHolder.add(GenericsHighlightUtil.checkTypeParametersList(list, typeParameters, myLanguageLevel)); } @@ -2117,7 +2121,7 @@ public void visitVariable(@Nonnull PsiVariable variable) { super.visitVariable(variable); try { if (!myHolder.hasErrorResults()) { - myHolder.add(HighlightUtil.checkVariableInitializerType(variable)); + add(HighlightUtil.checkVariableInitializerType(variable)); } } catch (IndexNotReadyException ignored) { @@ -2158,7 +2162,7 @@ public void visitConditionalExpression(@Nonnull PsiConditionalExpression express for (PsiExpression side : sides) { PsiType sideType = side.getType(); if (sideType != null && !TypeConversionUtil.isAssignable(conditionalType, sideType)) { - myHolder.add(HighlightUtil.checkAssignability(conditionalType, sideType, side, side)); + add(HighlightUtil.checkAssignability(conditionalType, sideType, side, side)); } } } @@ -2171,7 +2175,7 @@ public void visitConditionalExpression(@Nonnull PsiConditionalExpression express public void visitReceiverParameter(@Nonnull PsiReceiverParameter parameter) { super.visitReceiverParameter(parameter); if (!myHolder.hasErrorResults()) { - myHolder.add(checkFeature(parameter, JavaFeature.RECEIVERS)); + add(checkFeature(parameter, JavaFeature.RECEIVERS)); } if (!myHolder.hasErrorResults()) { myHolder.add(AnnotationsHighlightUtil.checkReceiverPlacement(parameter)); @@ -2186,7 +2190,7 @@ public void visitReceiverParameter(@Nonnull PsiReceiverParameter parameter) { public void visitModule(@Nonnull PsiJavaModule module) { super.visitModule(module); if (!myHolder.hasErrorResults()) { - myHolder.add(checkFeature(module, JavaFeature.MODULES)); + add(checkFeature(module, JavaFeature.MODULES)); } if (!myHolder.hasErrorResults()) { myHolder.add(ModuleHighlightUtil.checkFileName(module, myFile)); @@ -2262,7 +2266,11 @@ public void visitProvidesStatement(@Nonnull PsiProvidesStatement statement) { @Nullable @RequiredReadAction - private HighlightInfo checkFeature(@Nonnull PsiElement element, @Nonnull JavaFeature feature) { + private HighlightInfo.Builder checkFeature(@Nonnull PsiElement element, @Nonnull JavaFeature feature) { return HighlightUtil.checkFeature(element, feature, myLanguageLevel, myFile); } + + private boolean add(HighlightInfo.Builder hlInfoBuilder) { + return hlInfoBuilder != null && myHolder.add(hlInfoBuilder.create()); + } } \ No newline at end of file diff --git a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/RefCountHolder.java b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/RefCountHolder.java index 80195c5f7..857a6e9c2 100644 --- a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/RefCountHolder.java +++ b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/analysis/RefCountHolder.java @@ -60,11 +60,11 @@ static RefCountHolder get(@Nonnull PsiFile file, @Nonnull TextRange dirtyScope) } return storedHolder == null || wholeFile ? new RefCountHolder( - file, - MultiMap.createConcurrentSet(), - Sets.newConcurrentHashSet(HashingStrategy.canonical()), - new ConcurrentHashMap<>() - ) + file, + MultiMap.createConcurrentSet(), + Sets.newConcurrentHashSet(HashingStrategy.canonical()), + new ConcurrentHashMap<>() + ) : storedHolder.removeInvalidRefs(); } 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 82138982f..021f54b24 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 @@ -19,8 +19,8 @@ import com.intellij.java.language.psi.impl.source.resolve.DefaultParameterTypeInferencePolicy; import com.intellij.java.language.psi.util.PsiUtil; import com.intellij.java.language.psi.util.TypeConversionUtil; +import consulo.annotation.access.RequiredReadAction; import consulo.codeEditor.Editor; -import consulo.language.editor.intention.QuickFixAction; import consulo.language.editor.intention.SyntheticIntentionAction; import consulo.language.editor.rawHighlight.HighlightInfo; import consulo.language.psi.PsiElement; @@ -28,125 +28,137 @@ import consulo.language.util.IncorrectOperationException; import consulo.logging.Logger; import consulo.project.Project; +import consulo.ui.annotation.RequiredUIAccess; import consulo.util.lang.StringUtil; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; /** - * User: anna - * Date: 2/17/12 + * @author anna + * @since 2012-02-17 */ public class AddTypeArgumentsConditionalFix implements SyntheticIntentionAction { - private static final Logger LOG = Logger.getInstance(AddTypeArgumentsConditionalFix.class); + private static final Logger LOG = Logger.getInstance(AddTypeArgumentsConditionalFix.class); - private final PsiSubstitutor mySubstitutor; - private final PsiMethodCallExpression myExpression; - private final PsiMethod myMethod; + private final PsiSubstitutor mySubstitutor; + private final PsiMethodCallExpression myExpression; + private final PsiMethod myMethod; - public AddTypeArgumentsConditionalFix(PsiSubstitutor substitutor, - PsiMethodCallExpression expression, - PsiMethod method) { - mySubstitutor = substitutor; - myExpression = expression; - myMethod = method; - } + public AddTypeArgumentsConditionalFix( + PsiSubstitutor substitutor, + PsiMethodCallExpression expression, + PsiMethod method + ) { + mySubstitutor = substitutor; + myExpression = expression; + myMethod = method; + } - @Nonnull - @Override - public String getText() { - return "Add explicit type arguments"; - } + @Nonnull + @Override + public String getText() { + return "Add explicit type arguments"; + } - @Override - public boolean isAvailable(@Nonnull Project project, Editor editor, PsiFile file) { - if (mySubstitutor.isValid() && myExpression.isValid() && myMethod.isValid()) { - return true; + @Override + public boolean isAvailable(@Nonnull Project project, Editor editor, PsiFile file) { + return mySubstitutor.isValid() && myExpression.isValid() && myMethod.isValid(); } - return false; - } - @Override - public void invoke(@Nonnull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { - final PsiTypeParameter[] typeParameters = myMethod.getTypeParameters(); - final String typeArguments = "<" + StringUtil.join(typeParameters, parameter -> { - final PsiType substituteTypeParam = mySubstitutor.substitute(parameter); - LOG.assertTrue(substituteTypeParam != null); - return GenericsUtil.eliminateWildcards(substituteTypeParam).getCanonicalText(); - }, ", ") + ">"; - final PsiExpression expression = myExpression.getMethodExpression().getQualifierExpression(); - String withTypeArgsText; - if (expression != null) { - withTypeArgsText = expression.getText(); - } else { - if (isInStaticContext(myExpression, null) || myMethod.hasModifierProperty(PsiModifier.STATIC)) { - final PsiClass aClass = myMethod.getContainingClass(); - LOG.assertTrue(aClass != null); - withTypeArgsText = aClass.getQualifiedName(); - } else { - withTypeArgsText = "this"; - } + @Override + @RequiredUIAccess + public void invoke(@Nonnull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { + PsiTypeParameter[] typeParameters = myMethod.getTypeParameters(); + String typeArguments = "<" + StringUtil.join( + typeParameters, + parameter -> { + PsiType substituteTypeParam = mySubstitutor.substitute(parameter); + LOG.assertTrue(substituteTypeParam != null); + return GenericsUtil.eliminateWildcards(substituteTypeParam).getCanonicalText(); + }, + ", " + ) + ">"; + final PsiExpression expression = myExpression.getMethodExpression().getQualifierExpression(); + String withTypeArgsText; + if (expression != null) { + withTypeArgsText = expression.getText(); + } + else if (isInStaticContext(myExpression, null) || myMethod.isStatic()) { + final PsiClass aClass = myMethod.getContainingClass(); + LOG.assertTrue(aClass != null); + withTypeArgsText = aClass.getQualifiedName(); + } + else { + withTypeArgsText = "this"; + } + withTypeArgsText += "." + typeArguments + myExpression.getMethodExpression().getReferenceName(); + final PsiExpression withTypeArgs = JavaPsiFacade.getElementFactory(project) + .createExpressionFromText(withTypeArgsText + myExpression.getArgumentList().getText(), myExpression); + myExpression.replace(withTypeArgs); } - withTypeArgsText += "." + typeArguments + myExpression.getMethodExpression().getReferenceName(); - final PsiExpression withTypeArgs = JavaPsiFacade.getElementFactory(project).createExpressionFromText - (withTypeArgsText + myExpression.getArgumentList().getText(), myExpression); - myExpression.replace(withTypeArgs); - } - public static boolean isInStaticContext(PsiElement element, @Nullable final PsiClass aClass) { - return PsiUtil.getEnclosingStaticElement(element, aClass) != null; - } + public static boolean isInStaticContext(PsiElement element, @Nullable final PsiClass aClass) { + return PsiUtil.getEnclosingStaticElement(element, aClass) != null; + } - @Override - public boolean startInWriteAction() { - return true; - } + @Override + public boolean startInWriteAction() { + return true; + } - public static void register(HighlightInfo highlightInfo, PsiExpression expression, @Nonnull PsiType lType) { - if (lType != PsiType.NULL && expression instanceof PsiConditionalExpression) { - final PsiExpression thenExpression = ((PsiConditionalExpression) expression).getThenExpression(); - final PsiExpression elseExpression = ((PsiConditionalExpression) expression).getElseExpression(); - if (thenExpression != null && elseExpression != null) { - final PsiType thenType = thenExpression.getType(); - final PsiType elseType = elseExpression.getType(); - if (thenType != null && elseType != null) { - final boolean thenAssignable = TypeConversionUtil.isAssignable(lType, thenType); - final boolean elseAssignable = TypeConversionUtil.isAssignable(lType, elseType); - if (!thenAssignable && thenExpression instanceof PsiMethodCallExpression) { - inferTypeArgs(highlightInfo, lType, thenExpression); - } - if (!elseAssignable && elseExpression instanceof PsiMethodCallExpression) { - inferTypeArgs(highlightInfo, lType, elseExpression); - } + @RequiredReadAction + public static void register(@Nonnull HighlightInfo.Builder hlBuilder, PsiExpression expression, @Nonnull PsiType lType) { + if (lType != PsiType.NULL && expression instanceof PsiConditionalExpression condExpr) { + PsiExpression thenExpression = condExpr.getThenExpression(); + PsiExpression elseExpression = condExpr.getElseExpression(); + if (thenExpression != null && elseExpression != null) { + PsiType thenType = thenExpression.getType(); + PsiType elseType = elseExpression.getType(); + if (thenType != null && elseType != null) { + boolean thenAssignable = TypeConversionUtil.isAssignable(lType, thenType); + boolean elseAssignable = TypeConversionUtil.isAssignable(lType, elseType); + if (!thenAssignable && thenExpression instanceof PsiMethodCallExpression) { + inferTypeArgs(hlBuilder, lType, thenExpression); + } + if (!elseAssignable && elseExpression instanceof PsiMethodCallExpression) { + inferTypeArgs(hlBuilder, lType, elseExpression); + } + } + } } - } } - } - private static void inferTypeArgs(HighlightInfo highlightInfo, PsiType lType, PsiExpression thenExpression) { - final JavaResolveResult result = ((PsiMethodCallExpression) thenExpression).resolveMethodGenerics(); - final PsiMethod method = (PsiMethod) result.getElement(); - if (method != null) { - final PsiType returnType = method.getReturnType(); - final PsiClass aClass = method.getContainingClass(); - if (returnType != null && aClass != null && aClass.getQualifiedName() != null) { - final JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(method.getProject()); - final PsiDeclarationStatement variableDeclarationStatement = javaPsiFacade.getElementFactory() - .createVariableDeclarationStatement("xxx", lType, thenExpression); - final PsiExpression initializer = ((PsiLocalVariable) variableDeclarationStatement.getDeclaredElements - ()[0]).getInitializer(); - LOG.assertTrue(initializer != null); + @RequiredReadAction + private static void inferTypeArgs(@Nonnull HighlightInfo.Builder highlightInfo, PsiType lType, PsiExpression thenExpression) { + PsiMethodCallExpression thenMethodCall = (PsiMethodCallExpression)thenExpression; + JavaResolveResult result = thenMethodCall.resolveMethodGenerics(); + PsiMethod method = (PsiMethod)result.getElement(); + if (method != null) { + PsiType returnType = method.getReturnType(); + PsiClass aClass = method.getContainingClass(); + if (returnType != null && aClass != null && aClass.getQualifiedName() != null) { + JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(method.getProject()); + PsiDeclarationStatement variableDeclarationStatement = javaPsiFacade.getElementFactory() + .createVariableDeclarationStatement("xxx", lType, thenExpression); + PsiExpression initializer = ((PsiLocalVariable)variableDeclarationStatement.getDeclaredElements()[0]).getInitializer(); + LOG.assertTrue(initializer != null); - final PsiSubstitutor substitutor = javaPsiFacade.getResolveHelper().inferTypeArguments(method - .getTypeParameters(), method.getParameterList().getParameters(), - ((PsiMethodCallExpression) thenExpression).getArgumentList().getExpressions(), - PsiSubstitutor.EMPTY, initializer, DefaultParameterTypeInferencePolicy.INSTANCE); - PsiType substitutedType = substitutor.substitute(returnType); - if (substitutedType != null && TypeConversionUtil.isAssignable(lType, substitutedType)) { - QuickFixAction.registerQuickFixAction(highlightInfo, thenExpression.getTextRange(), - new AddTypeArgumentsConditionalFix(substitutor, (PsiMethodCallExpression) thenExpression, - method)); + PsiSubstitutor substitutor = javaPsiFacade.getResolveHelper().inferTypeArguments( + method.getTypeParameters(), + method.getParameterList().getParameters(), + thenMethodCall.getArgumentList().getExpressions(), + PsiSubstitutor.EMPTY, + initializer, + DefaultParameterTypeInferencePolicy.INSTANCE + ); + PsiType substitutedType = substitutor.substitute(returnType); + if (substitutedType != null && TypeConversionUtil.isAssignable(lType, substitutedType)) { + highlightInfo.registerFix( + new AddTypeArgumentsConditionalFix(substitutor, thenMethodCall, method), + thenExpression.getTextRange() + ); + } + } } - } } - } } 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 542e5f66e..887945152 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 @@ -32,82 +32,98 @@ * @author ven */ public abstract class ArgumentFixerActionFactory { - private static final Logger LOG = Logger.getInstance(ArgumentFixerActionFactory.class); + private static final Logger LOG = Logger.getInstance(ArgumentFixerActionFactory.class); - @Nullable - protected abstract PsiExpression getModifiedArgument(PsiExpression expression, final PsiType toType) throws IncorrectOperationException; + @Nullable + protected abstract PsiExpression getModifiedArgument(PsiExpression expression, PsiType toType) throws IncorrectOperationException; - public void registerCastActions(CandidateInfo[] candidates, PsiCall call, HighlightInfo highlightInfo, final TextRange fixRange) { - if (candidates.length == 0) return; - List methodCandidates = new ArrayList(Arrays.asList(candidates)); - PsiExpressionList list = call.getArgumentList(); - PsiExpression[] expressions = list.getExpressions(); - if (expressions.length == 0) return; - // filter out not castable candidates - nextMethod: - for (int i = methodCandidates.size() - 1; i >= 0; i--) { - 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); - continue; - } - for (int j = 0; j < parameters.length; j++) { - PsiParameter parameter = parameters[j]; - PsiExpression expression = expressions[j]; - // check if we can cast to this method - PsiType exprType = expression.getType(); - PsiType parameterType = substitutor.substitute(parameter.getType()); - if (exprType == null - || parameterType == null - || !areTypesConvertible(exprType, parameterType, call)) { - methodCandidates.remove(i); - continue nextMethod; + public void registerCastActions(CandidateInfo[] candidates, PsiCall call, HighlightInfo.Builder hlBuilder, TextRange fixRange) { + if (candidates.length == 0) { + return; + } + List methodCandidates = new ArrayList<>(Arrays.asList(candidates)); + PsiExpressionList list = call.getArgumentList(); + PsiExpression[] expressions = list.getExpressions(); + if (expressions.length == 0) { + return; + } + // filter out not castable candidates + nextMethod: + for (int i = methodCandidates.size() - 1; i >= 0; i--) { + 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); + continue; + } + for (int j = 0; j < parameters.length; j++) { + PsiParameter parameter = parameters[j]; + PsiExpression expression = expressions[j]; + // check if we can cast to this method + PsiType exprType = expression.getType(); + PsiType parameterType = substitutor.substitute(parameter.getType()); + if (exprType == null + || parameterType == null + || !areTypesConvertible(exprType, parameterType, call)) { + methodCandidates.remove(i); + continue nextMethod; + } + } } - } - } - if (methodCandidates.isEmpty()) return; + if (methodCandidates.isEmpty()) { + return; + } - try { - for (int i = 0; i < expressions.length; i++) { - PsiExpression expression = expressions[i]; - PsiType exprType = expression.getType(); - Set suggestedCasts = new HashSet(); - // find to which type we can cast this param to get valid method call - 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); - if (parameterType instanceof PsiWildcardType) continue; - if (!GenericsUtil.isFromExternalTypeLanguage(parameterType)) continue; - if (suggestedCasts.contains(parameterType.getCanonicalText())) continue; - // strict compare since even widening cast may help - if (Comparing.equal(exprType, parameterType)) continue; - PsiCall newCall = (PsiCall) call.copy(); - PsiExpression modifiedExpression = getModifiedArgument(expression, parameterType); - if (modifiedExpression == null) continue; - newCall.getArgumentList().getExpressions()[i].replace(modifiedExpression); - JavaResolveResult resolveResult = newCall.resolveMethodGenerics(); - if (resolveResult.getElement() != null && resolveResult.isValidResult()) { - suggestedCasts.add(parameterType.getCanonicalText()); - QuickFixAction.registerQuickFixAction(highlightInfo, fixRange, createFix(list, i, parameterType)); - } + try { + for (int i = 0; i < expressions.length; i++) { + PsiExpression expression = expressions[i]; + PsiType exprType = expression.getType(); + Set suggestedCasts = new HashSet<>(); + // find to which type we can cast this param to get valid method call + 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); + if (parameterType instanceof PsiWildcardType) { + continue; + } + if (!GenericsUtil.isFromExternalTypeLanguage(parameterType)) { + continue; + } + if (suggestedCasts.contains(parameterType.getCanonicalText())) { + continue; + } + // strict compare since even widening cast may help + if (Comparing.equal(exprType, parameterType)) { + continue; + } + PsiCall newCall = (PsiCall)call.copy(); + PsiExpression modifiedExpression = getModifiedArgument(expression, parameterType); + if (modifiedExpression == null) { + continue; + } + newCall.getArgumentList().getExpressions()[i].replace(modifiedExpression); + JavaResolveResult resolveResult = newCall.resolveMethodGenerics(); + if (resolveResult.getElement() != null && resolveResult.isValidResult()) { + suggestedCasts.add(parameterType.getCanonicalText()); + hlBuilder.registerFix(createFix(list, i, parameterType), fixRange); + } + } + } + } + catch (IncorrectOperationException e) { + LOG.error(e); } - } - } catch (IncorrectOperationException e) { - LOG.error(e); } - } - - public abstract boolean areTypesConvertible(final PsiType exprType, final PsiType parameterType, final PsiElement context); - public abstract MethodArgumentFix createFix(final PsiExpressionList list, final int i, final PsiType parameterType); + public abstract boolean areTypesConvertible(PsiType exprType, PsiType parameterType, PsiElement context); + public abstract MethodArgumentFix createFix(PsiExpressionList list, int i, PsiType parameterType); } diff --git a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/ChangeNewOperatorTypeFix.java b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/ChangeNewOperatorTypeFix.java index 30a56ed83..79c2aaee1 100644 --- a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/ChangeNewOperatorTypeFix.java +++ b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/ChangeNewOperatorTypeFix.java @@ -20,13 +20,13 @@ import com.intellij.java.language.psi.util.PsiExpressionTrimRenderer; import com.intellij.java.language.psi.util.PsiUtil; import com.intellij.java.language.psi.util.TypeConversionUtil; +import consulo.annotation.access.RequiredReadAction; import consulo.codeEditor.Editor; import consulo.codeEditor.ScrollType; import consulo.document.util.TextRange; import consulo.document.util.UnfairTextRange; -import consulo.java.analysis.impl.JavaQuickFixBundle; +import consulo.java.analysis.impl.localize.JavaQuickFixLocalize; import consulo.language.editor.FileModificationService; -import consulo.language.editor.intention.QuickFixAction; import consulo.language.editor.intention.SyntheticIntentionAction; import consulo.language.editor.rawHighlight.HighlightInfo; import consulo.language.psi.PsiElement; @@ -34,167 +34,199 @@ import consulo.language.psi.util.PsiTreeUtil; import consulo.language.util.IncorrectOperationException; import consulo.project.Project; -import jakarta.annotation.Nullable; -import org.jetbrains.annotations.NonNls; - +import consulo.ui.annotation.RequiredUIAccess; import jakarta.annotation.Nonnull; +import jakarta.annotation.Nullable; public class ChangeNewOperatorTypeFix implements SyntheticIntentionAction { - private final PsiType myType; - private final PsiNewExpression myExpression; + private final PsiType myType; + private final PsiNewExpression myExpression; - private ChangeNewOperatorTypeFix(PsiType type, PsiNewExpression expression) { - myType = type; - myExpression = expression; - } - - @Override - @Nonnull - public String getText() { - return JavaQuickFixBundle.message("change.new.operator.type.text", new PsiExpressionTrimRenderer.RenderFunction().apply(myExpression), myType.getPresentableText(), myType instanceof PsiArrayType ? "" : "()"); - } + private ChangeNewOperatorTypeFix(PsiType type, PsiNewExpression expression) { + myType = type; + myExpression = expression; + } - @Override - public boolean isAvailable(@Nonnull Project project, Editor editor, PsiFile file) { - return myType.isValid() - && myExpression.isValid() - && myExpression.getManager().isInProject(myExpression) - && !TypeConversionUtil.isPrimitiveAndNotNull(myType) - && (myType instanceof PsiArrayType || myExpression.getArgumentList() != null) - ; - } + @Nonnull + @Override + public String getText() { + return JavaQuickFixLocalize.changeNewOperatorTypeText( + new PsiExpressionTrimRenderer.RenderFunction().apply(myExpression), + myType.getPresentableText(), + myType instanceof PsiArrayType ? "" : "()" + ).get(); + } - @Override - public void invoke(@Nonnull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { - if (!FileModificationService.getInstance().prepareFileForWrite(file)) return; - changeNewOperatorType(myExpression, myType, editor); - } + @Override + public boolean isAvailable(@Nonnull Project project, Editor editor, PsiFile file) { + return myType.isValid() + && myExpression.isValid() + && myExpression.getManager().isInProject(myExpression) + && !TypeConversionUtil.isPrimitiveAndNotNull(myType) + && (myType instanceof PsiArrayType || myExpression.getArgumentList() != null); + } - private static void changeNewOperatorType(PsiNewExpression originalExpression, PsiType toType, final Editor editor) throws IncorrectOperationException { - PsiNewExpression newExpression; - PsiElementFactory factory = JavaPsiFacade.getInstance(originalExpression.getProject()).getElementFactory(); - int caretOffset; - TextRange selection; - if (toType instanceof PsiArrayType) { - final PsiExpression[] originalExpressionArrayDimensions = originalExpression.getArrayDimensions(); - caretOffset = 0; - @NonNls String text = "new " + toType.getDeepComponentType().getCanonicalText() + "["; - if (originalExpressionArrayDimensions.length > 0) { - text += originalExpressionArrayDimensions[0].getText(); - } else { - text += "0"; - caretOffset = -2; - } - text += "]"; - for (int i = 1; i < toType.getArrayDimensions(); i++) { - text += "["; - String arrayDimension = ""; - if (originalExpressionArrayDimensions.length > i) { - arrayDimension = originalExpressionArrayDimensions[i].getText(); - text += arrayDimension; + @Override + @RequiredUIAccess + public void invoke(@Nonnull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { + if (!FileModificationService.getInstance().prepareFileForWrite(file)) { + return; } - text += "]"; - if (caretOffset < 0) { - caretOffset -= arrayDimension.length() + 2; - } - } + changeNewOperatorType(myExpression, myType, editor); + } - newExpression = (PsiNewExpression) factory.createExpressionFromText(text, originalExpression); - if (caretOffset < 0) { - selection = new UnfairTextRange(caretOffset, caretOffset + 1); - } else { - selection = null; - } - } else { - final PsiAnonymousClass anonymousClass = originalExpression.getAnonymousClass(); - newExpression = (PsiNewExpression) factory.createExpressionFromText("new " + toType.getCanonicalText() + "()" + (anonymousClass != null ? "{}" : ""), originalExpression); - PsiExpressionList argumentList = originalExpression.getArgumentList(); - if (argumentList == null) return; - newExpression.getArgumentList().replace(argumentList); - if (anonymousClass == null) { //just to prevent useless inference - if (PsiDiamondTypeUtil.canCollapseToDiamond(newExpression, originalExpression, toType)) { - final PsiElement paramList = PsiDiamondTypeUtil.replaceExplicitWithDiamond(newExpression.getClassOrAnonymousClassReference().getParameterList()); - newExpression = PsiTreeUtil.getParentOfType(paramList, PsiNewExpression.class); + @RequiredUIAccess + private static void changeNewOperatorType(PsiNewExpression originalExpression, PsiType toType, Editor editor) + throws IncorrectOperationException { + PsiNewExpression newExpression; + PsiElementFactory factory = JavaPsiFacade.getInstance(originalExpression.getProject()).getElementFactory(); + int caretOffset; + TextRange selection; + if (toType instanceof PsiArrayType) { + final PsiExpression[] originalExpressionArrayDimensions = originalExpression.getArrayDimensions(); + caretOffset = 0; + String text = "new " + toType.getDeepComponentType().getCanonicalText() + "["; + if (originalExpressionArrayDimensions.length > 0) { + text += originalExpressionArrayDimensions[0].getText(); + } + else { + text += "0"; + caretOffset = -2; + } + text += "]"; + for (int i = 1; i < toType.getArrayDimensions(); i++) { + text += "["; + String arrayDimension = ""; + if (originalExpressionArrayDimensions.length > i) { + arrayDimension = originalExpressionArrayDimensions[i].getText(); + text += arrayDimension; + } + text += "]"; + if (caretOffset < 0) { + caretOffset -= arrayDimension.length() + 2; + } + } + + newExpression = (PsiNewExpression)factory.createExpressionFromText(text, originalExpression); + if (caretOffset < 0) { + selection = new UnfairTextRange(caretOffset, caretOffset + 1); + } + else { + selection = null; + } } - } + else { + PsiAnonymousClass anonymousClass = originalExpression.getAnonymousClass(); + newExpression = (PsiNewExpression)factory.createExpressionFromText( + "new " + toType.getCanonicalText() + "()" + (anonymousClass != null ? "{}" : ""), + originalExpression + ); + PsiExpressionList argumentList = originalExpression.getArgumentList(); + if (argumentList == null) { + return; + } + newExpression.getArgumentList().replace(argumentList); + if (anonymousClass == null) { //just to prevent useless inference + if (PsiDiamondTypeUtil.canCollapseToDiamond(newExpression, originalExpression, toType)) { + PsiElement paramList = + PsiDiamondTypeUtil.replaceExplicitWithDiamond(newExpression.getClassOrAnonymousClassReference().getParameterList()); + newExpression = PsiTreeUtil.getParentOfType(paramList, PsiNewExpression.class); + } + } - if (anonymousClass != null) { - PsiAnonymousClass newAnonymousClass = newExpression.getAnonymousClass(); - final PsiElement childInside = anonymousClass.getLBrace().getNextSibling(); - if (childInside != null) { - newAnonymousClass.addRange(childInside, anonymousClass.getRBrace().getPrevSibling()); + if (anonymousClass != null) { + PsiAnonymousClass newAnonymousClass = newExpression.getAnonymousClass(); + PsiElement childInside = anonymousClass.getLBrace().getNextSibling(); + if (childInside != null) { + newAnonymousClass.addRange(childInside, anonymousClass.getRBrace().getPrevSibling()); + } + } + selection = null; + caretOffset = -1; + } + PsiElement element = originalExpression.replace(newExpression); + editor.getCaretModel().moveToOffset(element.getTextRange().getEndOffset() + caretOffset); + editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + if (selection != null) { + selection = selection.shiftRight(element.getTextRange().getEndOffset()); + editor.getSelectionModel().setSelection(selection.getStartOffset(), selection.getEndOffset()); } - } - selection = null; - caretOffset = -1; - } - PsiElement element = originalExpression.replace(newExpression); - editor.getCaretModel().moveToOffset(element.getTextRange().getEndOffset() + caretOffset); - editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); - if (selection != null) { - selection = selection.shiftRight(element.getTextRange().getEndOffset()); - editor.getSelectionModel().setSelection(selection.getStartOffset(), selection.getEndOffset()); } - } - @Override - public boolean startInWriteAction() { - return true; - } + @Override + public boolean startInWriteAction() { + return true; + } - public static void register(final HighlightInfo highlightInfo, PsiExpression expression, final PsiType lType) { - expression = PsiUtil.deparenthesizeExpression(expression); - if (!(expression instanceof PsiNewExpression)) return; - final PsiType rType = expression.getType(); - PsiType newType = lType; - if (rType instanceof PsiClassType && newType instanceof PsiClassType) { - final PsiClassType.ClassResolveResult rResolveResult = ((PsiClassType) rType).resolveGenerics(); - PsiClass rClass = rResolveResult.getElement(); - if (rClass instanceof PsiAnonymousClass) { - rClass = ((PsiAnonymousClass) rClass).getBaseClassType().resolve(); - } - if (rClass != null) { - final PsiClassType.ClassResolveResult lResolveResult = ((PsiClassType) newType).resolveGenerics(); - final PsiClass lClass = lResolveResult.getElement(); - if (lClass != null) { - PsiSubstitutor substitutor = getInheritorSubstitutorForNewExpression(lClass, rClass, lResolveResult.getSubstitutor(), expression); - if (substitutor != null) { - newType = JavaPsiFacade.getInstance(lClass.getProject()).getElementFactory().createType(rClass, substitutor); - } + @RequiredReadAction + public static void register(@Nonnull HighlightInfo.Builder highlightInfo, PsiExpression expression, PsiType lType) { + if (!(PsiUtil.deparenthesizeExpression(expression) instanceof PsiNewExpression newExpr)) { + return; } - } + PsiType newType = lType; + if (newExpr.getType() instanceof PsiClassType rClassType && newType instanceof PsiClassType lClassType) { + PsiClassType.ClassResolveResult rResolveResult = rClassType.resolveGenerics(); + PsiClass rClass = rResolveResult.getElement(); + if (rClass instanceof PsiAnonymousClass anonymousClass) { + rClass = anonymousClass.getBaseClassType().resolve(); + } + if (rClass != null) { + PsiClassType.ClassResolveResult lResolveResult = lClassType.resolveGenerics(); + PsiClass lClass = lResolveResult.getElement(); + if (lClass != null) { + PsiSubstitutor substitutor = + getInheritorSubstitutorForNewExpression(lClass, rClass, lResolveResult.getSubstitutor(), newExpr); + if (substitutor != null) { + newType = JavaPsiFacade.getInstance(lClass.getProject()).getElementFactory().createType(rClass, substitutor); + } + } + } + } + highlightInfo.registerFix(new ChangeNewOperatorTypeFix(newType, newExpr)); } - PsiNewExpression newExpression = (PsiNewExpression) expression; - QuickFixAction.registerQuickFixAction(highlightInfo, new ChangeNewOperatorTypeFix(newType, newExpression)); - } - /* Guesswork - */ - @Nullable - private static PsiSubstitutor getInheritorSubstitutorForNewExpression(final PsiClass baseClass, final PsiClass inheritor, - final PsiSubstitutor baseSubstitutor, final PsiElement context) { - final Project project = baseClass.getProject(); - JavaPsiFacade facade = JavaPsiFacade.getInstance(project); - final PsiResolveHelper resolveHelper = facade.getResolveHelper(); - PsiSubstitutor superSubstitutor = TypeConversionUtil.getClassSubstitutor(baseClass, inheritor, PsiSubstitutor.EMPTY); - if (superSubstitutor == null) return null; - PsiSubstitutor inheritorSubstitutor = PsiSubstitutor.EMPTY; - for (PsiTypeParameter inheritorParameter : PsiUtil.typeParametersIterable(inheritor)) { - for (PsiTypeParameter baseParameter : PsiUtil.typeParametersIterable(baseClass)) { - final PsiType substituted = superSubstitutor.substitute(baseParameter); - PsiType arg = baseSubstitutor.substitute(baseParameter); - if (arg instanceof PsiWildcardType) arg = ((PsiWildcardType) arg).getBound(); - PsiType substitution = - resolveHelper.getSubstitutionForTypeParameter(inheritorParameter, substituted, arg, true, PsiUtil.getLanguageLevel(context)); - if (PsiType.NULL.equals(substitution)) continue; - if (substitution == null) { - return facade.getElementFactory().createRawSubstitutor(inheritor); + /* Guesswork */ + @Nullable + @RequiredReadAction + private static PsiSubstitutor getInheritorSubstitutorForNewExpression( + PsiClass baseClass, + PsiClass inheritor, + PsiSubstitutor baseSubstitutor, + PsiElement context + ) { + Project project = baseClass.getProject(); + JavaPsiFacade facade = JavaPsiFacade.getInstance(project); + PsiResolveHelper resolveHelper = facade.getResolveHelper(); + PsiSubstitutor superSubstitutor = TypeConversionUtil.getClassSubstitutor(baseClass, inheritor, PsiSubstitutor.EMPTY); + if (superSubstitutor == null) { + return null; + } + PsiSubstitutor inheritorSubstitutor = PsiSubstitutor.EMPTY; + for (PsiTypeParameter inheritorParameter : PsiUtil.typeParametersIterable(inheritor)) { + for (PsiTypeParameter baseParameter : PsiUtil.typeParametersIterable(baseClass)) { + PsiType substituted = superSubstitutor.substitute(baseParameter); + PsiType arg = baseSubstitutor.substitute(baseParameter); + if (arg instanceof PsiWildcardType wildcardType) { + arg = wildcardType.getBound(); + } + PsiType substitution = resolveHelper.getSubstitutionForTypeParameter( + inheritorParameter, + substituted, + arg, + true, + PsiUtil.getLanguageLevel(context) + ); + if (PsiType.NULL.equals(substitution)) { + continue; + } + if (substitution == null) { + return facade.getElementFactory().createRawSubstitutor(inheritor); + } + inheritorSubstitutor = inheritorSubstitutor.put(inheritorParameter, substitution); + break; + } } - inheritorSubstitutor = inheritorSubstitutor.put(inheritorParameter, substitution); - break; - } - } - return inheritorSubstitutor; - } + return inheritorSubstitutor; + } } diff --git a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/ChangeStringLiteralToCharInMethodCallFix.java b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/ChangeStringLiteralToCharInMethodCallFix.java index 6ffaa99fd..c4ecbcccb 100644 --- a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/ChangeStringLiteralToCharInMethodCallFix.java +++ b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/ChangeStringLiteralToCharInMethodCallFix.java @@ -18,10 +18,11 @@ import com.intellij.java.language.psi.*; import com.intellij.java.language.psi.infos.CandidateInfo; import com.intellij.java.language.psi.infos.MethodCandidateInfo; +import consulo.annotation.access.RequiredReadAction; import consulo.codeEditor.Editor; -import consulo.java.analysis.impl.JavaQuickFixBundle; +import consulo.java.analysis.impl.localize.JavaQuickFixLocalize; +import consulo.java.language.module.util.JavaClassNames; import consulo.language.editor.FileModificationService; -import consulo.language.editor.intention.QuickFixAction; import consulo.language.editor.intention.SyntheticIntentionAction; import consulo.language.editor.rawHighlight.HighlightInfo; import consulo.language.psi.PsiFile; @@ -29,7 +30,6 @@ import consulo.project.Project; import consulo.util.lang.Comparing; import consulo.util.lang.StringUtil; - import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; @@ -37,137 +37,156 @@ import java.util.Set; public class ChangeStringLiteralToCharInMethodCallFix implements SyntheticIntentionAction { - private final PsiLiteralExpression myLiteral; - private final PsiCall myCall; - - public ChangeStringLiteralToCharInMethodCallFix(final PsiLiteralExpression literal, final PsiCall methodCall) { - myLiteral = literal; - myCall = methodCall; - } - - @Override - @Nonnull - public String getText() { - final String convertedValue = convertedValue(); - final boolean isString = isString(myLiteral.getType()); - return JavaQuickFixBundle.message("fix.single.character.string.to.char.literal.text", myLiteral.getText(), - quote(convertedValue, !isString), isString ? PsiType.CHAR.getCanonicalText() : "String"); - } - - @Override - public boolean isAvailable(@Nonnull final Project project, final Editor editor, final PsiFile file) { - return myCall.isValid() && myLiteral.isValid() && myCall.getManager().isInProject(myCall); - } - - @Override - public void invoke(@Nonnull final Project project, final Editor editor, final PsiFile file) throws IncorrectOperationException { - if (!FileModificationService.getInstance().prepareFileForWrite(file)) return; - - final Object value = myLiteral.getValue(); - if (value != null && value.toString().length() == 1) { - final PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory(); - - final PsiExpression newExpression = factory.createExpressionFromText(quote(convertedValue(), !isString(myLiteral.getType())), - myLiteral.getParent()); - myLiteral.replace(newExpression); + private final PsiLiteralExpression myLiteral; + private final PsiCall myCall; + + public ChangeStringLiteralToCharInMethodCallFix(PsiLiteralExpression literal, final PsiCall methodCall) { + myLiteral = literal; + myCall = methodCall; + } + + @Nonnull + @Override + @RequiredReadAction + public String getText() { + String convertedValue = convertedValue(); + boolean isString = isString(myLiteral.getType()); + return JavaQuickFixLocalize.fixSingleCharacterStringToCharLiteralText( + myLiteral.getText(), + quote(convertedValue, !isString), + isString ? PsiType.CHAR.getCanonicalText() : "String" + ).get(); } - } - - @Override - public boolean startInWriteAction() { - return true; - } - - private static String quote(final String value, final boolean doubleQuotes) { - final char quote = doubleQuotes ? '"' : '\''; - return quote + value + quote; - } - - private String convertedValue() { - String value = String.valueOf(myLiteral.getValue()); - final StringBuilder builder = new StringBuilder(); - StringUtil.escapeStringCharacters(value.length(), value, "\"'", builder); - return builder.toString(); - } - - public static void registerFixes(@Nonnull final PsiMethod[] candidates, @Nonnull final PsiConstructorCall call, - @Nonnull final HighlightInfo out) { - final Set literals = new HashSet(); - if (call.getArgumentList() == null) { - return; + + @Override + public boolean isAvailable(@Nonnull final Project project, final Editor editor, final PsiFile file) { + return myCall.isValid() && myLiteral.isValid() && myCall.getManager().isInProject(myCall); + } + + @Override + public void invoke(@Nonnull final Project project, final Editor editor, final PsiFile file) throws IncorrectOperationException { + if (!FileModificationService.getInstance().prepareFileForWrite(file)) { + return; + } + + final Object value = myLiteral.getValue(); + if (value != null && value.toString().length() == 1) { + final PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory(); + + final PsiExpression newExpression = factory.createExpressionFromText( + quote(convertedValue(), !isString(myLiteral.getType())), + myLiteral.getParent() + ); + myLiteral.replace(newExpression); + } } - boolean exactMatch = false; - for (PsiMethod method : candidates) { - exactMatch |= findMatchingExpressions(call.getArgumentList().getExpressions(), method, literals); + + @Override + public boolean startInWriteAction() { + return true; } - if (!exactMatch) { - processLiterals(literals, call, out); + + private static String quote(final String value, final boolean doubleQuotes) { + final char quote = doubleQuotes ? '"' : '\''; + return quote + value + quote; } - } - - public static void registerFixes(@Nonnull final CandidateInfo[] candidates, - @Nonnull final PsiMethodCallExpression methodCall, - @Nullable final HighlightInfo info) { - if (info == null) return; - final Set literals = new HashSet(); - boolean exactMatch = false; - for (CandidateInfo candidate : candidates) { - if (candidate instanceof MethodCandidateInfo) { - final PsiMethod method = ((MethodCandidateInfo) candidate).getElement(); - exactMatch |= findMatchingExpressions(methodCall.getArgumentList().getExpressions(), method, literals); - } + + private String convertedValue() { + String value = String.valueOf(myLiteral.getValue()); + final StringBuilder builder = new StringBuilder(); + StringUtil.escapeStringCharacters(value.length(), value, "\"'", builder); + return builder.toString(); } - if (!exactMatch) { - processLiterals(literals, methodCall, info); + + public static void registerFixes( + @Nonnull PsiMethod[] candidates, + @Nonnull PsiConstructorCall call, + @Nonnull HighlightInfo.Builder hlBuilder + ) { + Set literals = new HashSet<>(); + if (call.getArgumentList() == null) { + return; + } + boolean exactMatch = false; + for (PsiMethod method : candidates) { + exactMatch |= findMatchingExpressions(call.getArgumentList().getExpressions(), method, literals); + } + if (!exactMatch) { + processLiterals(literals, call, hlBuilder); + } } - } - - private static void processLiterals(@Nonnull final Set literals, - @Nonnull final PsiCall call, - @Nonnull final HighlightInfo info) { - for (PsiLiteralExpression literal : literals) { - final ChangeStringLiteralToCharInMethodCallFix fix = new ChangeStringLiteralToCharInMethodCallFix(literal, call); - QuickFixAction.registerQuickFixAction(info, fix); + + public static void registerFixes( + @Nonnull CandidateInfo[] candidates, + @Nonnull PsiMethodCallExpression methodCall, + @Nullable HighlightInfo.Builder hlBuilder + ) { + if (hlBuilder == null) { + return; + } + Set literals = new HashSet<>(); + boolean exactMatch = false; + for (CandidateInfo candidate : candidates) { + if (candidate instanceof MethodCandidateInfo methodCandidateInfo) { + PsiMethod method = methodCandidateInfo.getElement(); + exactMatch |= findMatchingExpressions(methodCall.getArgumentList().getExpressions(), method, literals); + } + } + if (!exactMatch) { + processLiterals(literals, methodCall, hlBuilder); + } } - } - - /** - * @return true if exact TYPEs match - */ - private static boolean findMatchingExpressions(final PsiExpression[] arguments, final PsiMethod existingMethod, - final Set result) { - final PsiParameterList parameterList = existingMethod.getParameterList(); - final PsiParameter[] parameters = parameterList.getParameters(); - - if (arguments.length != parameters.length) { - return false; + + private static void processLiterals( + @Nonnull Set literals, + @Nonnull PsiCall call, + @Nonnull HighlightInfo.Builder hlBuilder + ) { + for (PsiLiteralExpression literal : literals) { + hlBuilder.registerFix(new ChangeStringLiteralToCharInMethodCallFix(literal, call)); + } } - boolean typeMatch = true; - for (int i = 0; i < parameters.length && i < arguments.length; i++) { - final PsiParameter parameter = parameters[i]; - final PsiType parameterType = parameter.getType(); - final PsiType argumentType = arguments[i].getType(); + /** + * @return true if exact TYPEs match + */ + private static boolean findMatchingExpressions( + PsiExpression[] arguments, + PsiMethod existingMethod, + Set result + ) { + PsiParameterList parameterList = existingMethod.getParameterList(); + PsiParameter[] parameters = parameterList.getParameters(); + + if (arguments.length != parameters.length) { + return false; + } - typeMatch &= Comparing.equal(parameterType, argumentType); + boolean typeMatch = true; + for (int i = 0; i < parameters.length && i < arguments.length; i++) { + PsiParameter parameter = parameters[i]; + PsiType parameterType = parameter.getType(); + PsiType argumentType = arguments[i].getType(); - if (arguments[i] instanceof PsiLiteralExpression && !result.contains(arguments[i]) && - (charToString(parameterType, argumentType) || charToString(argumentType, parameterType))) { + typeMatch &= Comparing.equal(parameterType, argumentType); - final String value = String.valueOf(((PsiLiteralExpression) arguments[i]).getValue()); - if (value != null && value.length() == 1) { - result.add((PsiLiteralExpression) arguments[i]); + if (arguments[i] instanceof PsiLiteralExpression && !result.contains(arguments[i]) + && (charToString(parameterType, argumentType) || charToString(argumentType, parameterType))) { + + String value = String.valueOf(((PsiLiteralExpression)arguments[i]).getValue()); + if (value != null && value.length() == 1) { + result.add((PsiLiteralExpression)arguments[i]); + } + } } - } + return typeMatch; } - return typeMatch; - } - private static boolean charToString(final PsiType firstType, final PsiType secondType) { - return Comparing.equal(PsiType.CHAR, firstType) && isString(secondType); - } + private static boolean charToString(PsiType firstType, PsiType secondType) { + return Comparing.equal(PsiType.CHAR, firstType) && isString(secondType); + } - private static boolean isString(final PsiType type) { - return type != null && "java.lang.String".equals(type.getCanonicalText()); - } + private static boolean isString(PsiType type) { + return type != null && JavaClassNames.JAVA_LANG_STRING.equals(type.getCanonicalText()); + } } diff --git a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/ChangeTypeArgumentsFix.java b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/ChangeTypeArgumentsFix.java index 4a44be913..bd107b541 100644 --- a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/ChangeTypeArgumentsFix.java +++ b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/ChangeTypeArgumentsFix.java @@ -38,127 +38,150 @@ import consulo.language.psi.util.PsiTreeUtil; import consulo.logging.Logger; import consulo.project.Project; +import consulo.ui.annotation.RequiredUIAccess; import consulo.util.lang.StringUtil; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; public class ChangeTypeArgumentsFix implements SyntheticIntentionAction, HighPriorityAction { - private final PsiMethod myTargetMethod; - private final PsiClass myPsiClass; - private final PsiExpression[] myExpressions; - private static final Logger LOG = Logger.getInstance(ChangeTypeArgumentsFix.class); - private final PsiNewExpression myNewExpression; + private final PsiMethod myTargetMethod; + private final PsiClass myPsiClass; + private final PsiExpression[] myExpressions; + private static final Logger LOG = Logger.getInstance(ChangeTypeArgumentsFix.class); + private final PsiNewExpression myNewExpression; - ChangeTypeArgumentsFix(@Nonnull PsiMethod targetMethod, - PsiClass psiClass, - @Nonnull PsiExpression[] expressions, - @Nonnull PsiElement context) { - myTargetMethod = targetMethod; - myPsiClass = psiClass; - myExpressions = expressions; - myNewExpression = PsiTreeUtil.getParentOfType(context, PsiNewExpression.class); - } + ChangeTypeArgumentsFix( + @Nonnull PsiMethod targetMethod, + PsiClass psiClass, + @Nonnull PsiExpression[] expressions, + @Nonnull PsiElement context + ) { + myTargetMethod = targetMethod; + myPsiClass = psiClass; + myExpressions = expressions; + myNewExpression = PsiTreeUtil.getParentOfType(context, PsiNewExpression.class); + } - @Override - @Nonnull - public String getText() { - final PsiSubstitutor substitutor = inferTypeArguments(); - return "Change type arguments to <" + StringUtil.join(myPsiClass.getTypeParameters(), typeParameter -> { - final PsiType substituted = substitutor.substitute(typeParameter); - return substituted != null ? substituted.getPresentableText() : JavaClassNames.JAVA_LANG_OBJECT; - }, ", ") + ">"; - } + @Nonnull + @Override + public String getText() { + PsiSubstitutor substitutor = inferTypeArguments(); + return "Change type arguments to <" + StringUtil.join( + myPsiClass.getTypeParameters(), + typeParameter -> { + PsiType substituted = substitutor.substitute(typeParameter); + return substituted != null ? substituted.getPresentableText() : JavaClassNames.JAVA_LANG_OBJECT; + }, + ", " + ) + ">"; + } - @Override - public boolean isAvailable(@Nonnull Project project, Editor editor, PsiFile file) { - final PsiTypeParameter[] typeParameters = myPsiClass.getTypeParameters(); - if (typeParameters.length > 0) { - if (myNewExpression != null && myNewExpression.isValid() && myNewExpression.getArgumentList() != null) { - final PsiJavaCodeReferenceElement reference = myNewExpression.getClassOrAnonymousClassReference(); - if (reference != null) { - final PsiReferenceParameterList parameterList = reference.getParameterList(); - if (parameterList != null) { - final PsiSubstitutor substitutor = inferTypeArguments(); - final PsiParameter[] parameters = myTargetMethod.getParameterList().getParameters(); - if (parameters.length != myExpressions.length) return false; - for (int i = 0, length = parameters.length; i < length; i++) { - PsiParameter parameter = parameters[i]; - final PsiType expectedType = substitutor.substitute(parameter.getType()); - if (!myExpressions[i].isValid()) return false; - final PsiType actualType = myExpressions[i].getType(); - if (expectedType == null || actualType == null || !TypeConversionUtil.isAssignable(expectedType, actualType)) - return false; - } - for (PsiTypeParameter parameter : typeParameters) { - if (substitutor.substitute(parameter) == null) return false; + @Override + public boolean isAvailable(@Nonnull Project project, Editor editor, PsiFile file) { + PsiTypeParameter[] typeParameters = myPsiClass.getTypeParameters(); + if (typeParameters.length > 0 + && myNewExpression != null && myNewExpression.isValid() && myNewExpression.getArgumentList() != null) { + PsiJavaCodeReferenceElement reference = myNewExpression.getClassOrAnonymousClassReference(); + if (reference != null) { + PsiReferenceParameterList parameterList = reference.getParameterList(); + if (parameterList != null) { + PsiSubstitutor substitutor = inferTypeArguments(); + PsiParameter[] parameters = myTargetMethod.getParameterList().getParameters(); + if (parameters.length != myExpressions.length) { + return false; + } + for (int i = 0, length = parameters.length; i < length; i++) { + PsiParameter parameter = parameters[i]; + PsiType expectedType = substitutor.substitute(parameter.getType()); + if (!myExpressions[i].isValid()) { + return false; + } + PsiType actualType = myExpressions[i].getType(); + if (expectedType == null || actualType == null || !TypeConversionUtil.isAssignable(expectedType, actualType)) { + return false; + } + } + for (PsiTypeParameter parameter : typeParameters) { + if (substitutor.substitute(parameter) == null) { + return false; + } + } + return true; + } } - return true; - } } - } + return false; } - return false; - } - @Override - public void invoke(@Nonnull final Project project, Editor editor, final PsiFile file) { - if (!FileModificationService.getInstance().prepareFileForWrite(file)) return; + @Override + @RequiredUIAccess + public void invoke(@Nonnull Project project, Editor editor, PsiFile file) { + if (!FileModificationService.getInstance().prepareFileForWrite(file)) { + return; + } - final PsiTypeParameter[] typeParameters = myPsiClass.getTypeParameters(); - final PsiSubstitutor psiSubstitutor = inferTypeArguments(); - final PsiJavaCodeReferenceElement reference = myNewExpression.getClassOrAnonymousClassReference(); - LOG.assertTrue(reference != null, myNewExpression); - final PsiReferenceParameterList parameterList = reference.getParameterList(); - LOG.assertTrue(parameterList != null, myNewExpression); - PsiTypeElement[] elements = parameterList.getTypeParameterElements(); - for (int i = elements.length - 1; i >= 0; i--) { - PsiTypeElement typeElement = elements[i]; - final PsiType typeArg = psiSubstitutor.substitute(typeParameters[i]); - typeElement.replace(JavaPsiFacade.getElementFactory(project).createTypeElement(typeArg)); + PsiTypeParameter[] typeParameters = myPsiClass.getTypeParameters(); + PsiSubstitutor psiSubstitutor = inferTypeArguments(); + PsiJavaCodeReferenceElement reference = myNewExpression.getClassOrAnonymousClassReference(); + LOG.assertTrue(reference != null, myNewExpression); + PsiReferenceParameterList parameterList = reference.getParameterList(); + LOG.assertTrue(parameterList != null, myNewExpression); + PsiTypeElement[] elements = parameterList.getTypeParameterElements(); + for (int i = elements.length - 1; i >= 0; i--) { + PsiTypeElement typeElement = elements[i]; + PsiType typeArg = psiSubstitutor.substitute(typeParameters[i]); + typeElement.replace(JavaPsiFacade.getElementFactory(project).createTypeElement(typeArg)); + } } - } - - private PsiSubstitutor inferTypeArguments() { - final JavaPsiFacade facade = JavaPsiFacade.getInstance(myNewExpression.getProject()); - final PsiResolveHelper resolveHelper = facade.getResolveHelper(); - final PsiParameter[] parameters = myTargetMethod.getParameterList().getParameters(); - final PsiExpressionList argumentList = myNewExpression.getArgumentList(); - LOG.assertTrue(argumentList != null); - final PsiExpression[] expressions = argumentList.getExpressions(); - return resolveHelper.inferTypeArguments(myPsiClass.getTypeParameters(), parameters, expressions, - PsiSubstitutor.EMPTY, - myNewExpression.getParent(), - DefaultParameterTypeInferencePolicy.INSTANCE); - } + private PsiSubstitutor inferTypeArguments() { + JavaPsiFacade facade = JavaPsiFacade.getInstance(myNewExpression.getProject()); + PsiResolveHelper resolveHelper = facade.getResolveHelper(); + PsiParameter[] parameters = myTargetMethod.getParameterList().getParameters(); + PsiExpressionList argumentList = myNewExpression.getArgumentList(); + LOG.assertTrue(argumentList != null); + PsiExpression[] expressions = argumentList.getExpressions(); + return resolveHelper.inferTypeArguments(myPsiClass.getTypeParameters(), parameters, expressions, + PsiSubstitutor.EMPTY, + myNewExpression.getParent(), + DefaultParameterTypeInferencePolicy.INSTANCE + ); + } - public static void registerIntentions(@Nonnull JavaResolveResult[] candidates, - @Nonnull PsiExpressionList list, - @Nullable HighlightInfo highlightInfo, - PsiClass psiClass) { - if (candidates.length == 0) return; - PsiExpression[] expressions = list.getExpressions(); - for (JavaResolveResult candidate : candidates) { - registerIntention(expressions, highlightInfo, psiClass, candidate, list); + public static void registerIntentions( + @Nonnull JavaResolveResult[] candidates, + @Nonnull PsiExpressionList list, + @Nullable HighlightInfo.Builder highlightInfo, + PsiClass psiClass + ) { + if (highlightInfo == null || candidates.length == 0) { + return; + } + PsiExpression[] expressions = list.getExpressions(); + for (JavaResolveResult candidate : candidates) { + registerIntention(expressions, highlightInfo, psiClass, candidate, list); + } } - } - private static void registerIntention(@Nonnull PsiExpression[] expressions, - @Nullable HighlightInfo highlightInfo, - PsiClass psiClass, - @Nonnull JavaResolveResult candidate, - @Nonnull PsiElement context) { - if (!candidate.isStaticsScopeCorrect()) return; - PsiMethod method = (PsiMethod) candidate.getElement(); - if (method != null && context.getManager().isInProject(method)) { - final ChangeTypeArgumentsFix fix = new ChangeTypeArgumentsFix(method, psiClass, expressions, context); - QuickFixAction.registerQuickFixAction(highlightInfo, null, fix); + private static void registerIntention( + @Nonnull PsiExpression[] expressions, + @Nonnull HighlightInfo.Builder highlightInfo, + PsiClass psiClass, + @Nonnull JavaResolveResult candidate, + @Nonnull PsiElement context + ) { + if (!candidate.isStaticsScopeCorrect()) { + return; + } + PsiMethod method = (PsiMethod)candidate.getElement(); + if (method != null && context.getManager().isInProject(method)) { + highlightInfo.registerFix(new ChangeTypeArgumentsFix(method, psiClass, expressions, context)); + } } - } - @Override - public boolean startInWriteAction() { - return true; - } + @Override + public boolean startInWriteAction() { + return true; + } } diff --git a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/ConstructorParametersFixer.java b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/ConstructorParametersFixer.java index 7b679134d..80bd1cf9e 100644 --- a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/ConstructorParametersFixer.java +++ b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/ConstructorParametersFixer.java @@ -13,15 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -/** - * Propose to cast one argument to corresponding type - * in the constructor invocation - * E.g. - * - * User: cdr - * Date: Nov 13, 2002 - */ package com.intellij.java.analysis.impl.codeInsight.daemon.impl.quickfix; import consulo.language.editor.rawHighlight.HighlightInfo; @@ -30,18 +21,32 @@ import consulo.document.util.TextRange; import jakarta.annotation.Nonnull; +/** + * Propose to cast one argument to corresponding type + * in the constructor invocation + * E.g. + * + * @author cdr + * @since 2002-11-13 + */ public class ConstructorParametersFixer { - public static void registerFixActions(@Nonnull PsiJavaCodeReferenceElement ctrRef, PsiConstructorCall constructorCall, HighlightInfo highlightInfo, - final TextRange fixRange) { - JavaResolveResult resolved = ctrRef.advancedResolve(false); - PsiClass aClass = (PsiClass) resolved.getElement(); - if (aClass == null) return; - PsiMethod[] methods = aClass.getConstructors(); - CandidateInfo[] candidates = new CandidateInfo[methods.length]; - for (int i = 0; i < candidates.length; i++) { - candidates[i] = new CandidateInfo(methods[i], resolved.getSubstitutor()); + public static void registerFixActions( + @Nonnull PsiJavaCodeReferenceElement ctrRef, + PsiConstructorCall constructorCall, + @Nonnull HighlightInfo.Builder highlightInfo, + TextRange fixRange + ) { + JavaResolveResult resolved = ctrRef.advancedResolve(false); + PsiClass aClass = (PsiClass)resolved.getElement(); + if (aClass == null) { + return; + } + PsiMethod[] methods = aClass.getConstructors(); + CandidateInfo[] candidates = new CandidateInfo[methods.length]; + for (int i = 0; i < candidates.length; i++) { + candidates[i] = new CandidateInfo(methods[i], resolved.getSubstitutor()); + } + CastMethodArgumentFix.REGISTRAR.registerCastActions(candidates, constructorCall, highlightInfo, fixRange); + AddTypeArgumentsFix.REGISTRAR.registerCastActions(candidates, constructorCall, highlightInfo, fixRange); } - CastMethodArgumentFix.REGISTRAR.registerCastActions(candidates, constructorCall, highlightInfo, fixRange); - AddTypeArgumentsFix.REGISTRAR.registerCastActions(candidates, constructorCall, highlightInfo, fixRange); - } } 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 ef502173a..7a09da960 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 @@ -17,9 +17,10 @@ import com.intellij.java.language.psi.*; 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; -import consulo.language.editor.intention.QuickFixAction; import consulo.language.editor.intention.SyntheticIntentionAction; import consulo.language.editor.rawHighlight.HighlightInfo; import consulo.language.psi.PsiElement; @@ -31,82 +32,100 @@ import jakarta.annotation.Nullable; /** - * User: anna - * Date: 2/10/12 + * @author anna + * @since 2012-02-10 */ public class ConvertDoubleToFloatFix implements SyntheticIntentionAction { - private final PsiExpression myExpression; + private final PsiExpression myExpression; - public ConvertDoubleToFloatFix(PsiExpression expression) { - myExpression = expression; - } + public ConvertDoubleToFloatFix(PsiExpression expression) { + myExpression = expression; + } - @Nonnull - @Override - public String getText() { - return "Convert '" + myExpression.getText() + "' to float"; - } + @Nonnull + @Override + @RequiredReadAction + public String getText() { + return "Convert '" + myExpression.getText() + "' to float"; + } - @Override - public boolean isAvailable(@Nonnull Project project, Editor editor, PsiFile file) { - if (myExpression.isValid()) { - if (!StringUtil.endsWithIgnoreCase(myExpression.getText(), "f")) { - final PsiLiteralExpression expression = (PsiLiteralExpression) createFloatingPointExpression(project); - final Object value = expression.getValue(); - return value instanceof Float && !((Float) value).isInfinite() && !(((Float) value).floatValue() == 0 && !TypeConversionUtil.isFPZero(expression.getText())); - } + @Override + @RequiredReadAction + 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 + && !floatValue.isInfinite() + && !(floatValue == 0 && !TypeConversionUtil.isFPZero(expression.getText())); + } + } + return false; } - return false; - } - @Override - public void invoke(@Nonnull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { - myExpression.replace(createFloatingPointExpression(project)); - } + @Override + @RequiredWriteAction + public void invoke(@Nonnull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { + myExpression.replace(createFloatingPointExpression(project)); + } - private PsiExpression createFloatingPointExpression(Project project) { - final String text = myExpression.getText(); - if (StringUtil.endsWithIgnoreCase(text, "d")) { - return JavaPsiFacade.getElementFactory(project).createExpressionFromText(text.substring(0, text.length() - 1) + "f", myExpression); - } else { - return JavaPsiFacade.getElementFactory(project).createExpressionFromText(text + "f", myExpression); + @RequiredReadAction + private PsiExpression createFloatingPointExpression(Project project) { + final String text = myExpression.getText(); + if (StringUtil.endsWithIgnoreCase(text, "d")) { + return JavaPsiFacade.getElementFactory(project) + .createExpressionFromText(text.substring(0, text.length() - 1) + "f", myExpression); + } + else { + return JavaPsiFacade.getElementFactory(project).createExpressionFromText(text + "f", myExpression); + } } - } - @Override - public boolean startInWriteAction() { - return true; - } + @Override + public boolean startInWriteAction() { + return true; + } - public static void registerIntentions(@Nonnull JavaResolveResult[] candidates, - @Nonnull PsiExpressionList list, - @Nullable HighlightInfo highlightInfo, - TextRange fixRange) { - if (candidates.length == 0) return; - PsiExpression[] expressions = list.getExpressions(); - for (JavaResolveResult candidate : candidates) { - registerIntention(expressions, highlightInfo, fixRange, candidate, list); + public static void registerIntentions( + @Nonnull JavaResolveResult[] candidates, + @Nonnull PsiExpressionList list, + @Nullable HighlightInfo.Builder hlBuilder, + TextRange fixRange + ) { + if (hlBuilder == null || candidates.length == 0) { + return; + } + PsiExpression[] expressions = list.getExpressions(); + for (JavaResolveResult candidate : candidates) { + registerIntention(expressions, hlBuilder, fixRange, candidate, list); + } } - } - private static void registerIntention(@Nonnull PsiExpression[] expressions, - @Nullable HighlightInfo highlightInfo, - TextRange fixRange, - @Nonnull JavaResolveResult candidate, - @Nonnull PsiElement context) { - if (!candidate.isStaticsScopeCorrect()) return; - PsiMethod method = (PsiMethod) candidate.getElement(); - if (method != null && context.getManager().isInProject(method)) { - final PsiParameter[] parameters = method.getParameterList().getParameters(); - if (parameters.length == expressions.length) { - for (int i = 0, length = parameters.length; i < length; i++) { - PsiParameter parameter = parameters[i]; - final PsiExpression expression = expressions[i]; - if (expression instanceof PsiLiteralExpression && PsiType.FLOAT.equals(parameter.getType()) && PsiType.DOUBLE.equals(expression.getType())) { - QuickFixAction.registerQuickFixAction(highlightInfo, fixRange, new ConvertDoubleToFloatFix(expression)); - } + private static void registerIntention( + @Nonnull PsiExpression[] expressions, + @Nonnull HighlightInfo.Builder hlBuilder, + TextRange fixRange, + @Nonnull JavaResolveResult candidate, + @Nonnull PsiElement context + ) { + if (!candidate.isStaticsScopeCorrect()) { + return; + } + PsiMethod method = (PsiMethod)candidate.getElement(); + if (method != null && context.getManager().isInProject(method)) { + PsiParameter[] parameters = method.getParameterList().getParameters(); + 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 + && PsiType.FLOAT.equals(parameter.getType()) + && PsiType.DOUBLE.equals(expression.getType())) { + hlBuilder.registerFix(new ConvertDoubleToFloatFix(expression), fixRange); + } + } + } } - } } - } } 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 4eab7fee4..bb1031734 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 @@ -20,6 +20,7 @@ import com.intellij.java.language.psi.infos.MethodCandidateInfo; import com.intellij.java.language.psi.util.PsiUtil; import com.intellij.java.language.psi.util.TypeConversionUtil; +import consulo.annotation.access.RequiredReadAction; import consulo.codeEditor.Editor; import consulo.document.util.TextRange; import consulo.java.analysis.impl.JavaQuickFixBundle; @@ -31,9 +32,11 @@ import consulo.language.util.IncorrectOperationException; import consulo.logging.Logger; import consulo.project.Project; +import consulo.ui.annotation.RequiredUIAccess; import consulo.util.collection.ArrayUtil; import jakarta.annotation.Nonnull; + import java.util.ArrayList; import java.util.List; @@ -41,147 +44,195 @@ * @author cdr */ public class PermuteArgumentsFix implements SyntheticIntentionAction { - private static final Logger LOG = Logger.getInstance(PermuteArgumentsFix.class); - private final PsiCall myCall; - private final PsiCall myPermutation; - - private PermuteArgumentsFix(@Nonnull PsiCall call, @Nonnull PsiCall permutation) { - myCall = call; - myPermutation = permutation; - } - - @Override - public boolean startInWriteAction() { - return true; - } - - - @Override - @Nonnull - public String getText() { - return JavaQuickFixBundle.message("permute.arguments"); - } - - @Override - public boolean isAvailable(@Nonnull Project project, Editor editor, PsiFile file) { - return !project.isDisposed() && myCall.isValid() && myCall.getManager().isInProject(myCall); - } - - @Override - public void invoke(@Nonnull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { - if (!FileModificationService.getInstance().prepareFileForWrite(file)) return; - myCall.getArgumentList().replace(myPermutation.getArgumentList()); - } - - public static void registerFix(HighlightInfo info, PsiCall callExpression, final CandidateInfo[] candidates, final TextRange fixRange) { - PsiExpression[] expressions = callExpression.getArgumentList().getExpressions(); - if (expressions.length < 2) return; - List permutations = new ArrayList(); - - for (CandidateInfo candidate : candidates) { - if (candidate instanceof MethodCandidateInfo) { - MethodCandidateInfo methodCandidate = (MethodCandidateInfo) candidate; - PsiMethod method = methodCandidate.getElement(); - PsiSubstitutor substitutor = methodCandidate.getSubstitutor(); + private static final Logger LOG = Logger.getInstance(PermuteArgumentsFix.class); + private final PsiCall myCall; + private final PsiCall myPermutation; - PsiParameter[] parameters = method.getParameterList().getParameters(); - if (expressions.length != parameters.length || parameters.length == 0) continue; - int minIncompatibleIndex = parameters.length; - int maxIncompatibleIndex = 0; - int incompatibilitiesCount = 0; - for (int i = 0; i < parameters.length; i++) { - PsiParameter parameter = parameters[i]; - PsiType type = substitutor.substitute(parameter.getType()); - if (TypeConversionUtil.areTypesAssignmentCompatible(type, expressions[i])) continue; - if (minIncompatibleIndex == parameters.length) minIncompatibleIndex = i; - maxIncompatibleIndex = i; - incompatibilitiesCount++; - } + private PermuteArgumentsFix(@Nonnull PsiCall call, @Nonnull PsiCall permutation) { + myCall = call; + myPermutation = permutation; + } - try { - registerSwapFixes(expressions, callExpression, permutations, methodCandidate, incompatibilitiesCount, minIncompatibleIndex, maxIncompatibleIndex); - registerShiftFixes(expressions, callExpression, permutations, methodCandidate, minIncompatibleIndex, maxIncompatibleIndex); - } catch (IncorrectOperationException e) { - LOG.error(e); - } - } + @Override + public boolean startInWriteAction() { + return true; } - if (permutations.size() == 1) { - PermuteArgumentsFix fix = new PermuteArgumentsFix(callExpression, permutations.get(0)); - QuickFixAction.registerQuickFixAction(info, fixRange, fix); + + @Override + @Nonnull + public String getText() { + return JavaQuickFixBundle.message("permute.arguments"); } - } - - private static void registerShiftFixes(final PsiExpression[] expressions, final PsiCall callExpression, final List permutations, - final MethodCandidateInfo methodCandidate, final int minIncompatibleIndex, final int maxIncompatibleIndex) - throws IncorrectOperationException { - PsiMethod method = methodCandidate.getElement(); - PsiSubstitutor substitutor = methodCandidate.getSubstitutor(); - // shift range should include both incompatible indexes - for (int i = 0; i <= minIncompatibleIndex; i++) { - for (int j = Math.max(i + 2, maxIncompatibleIndex); j < expressions.length; j++) { // if j=i+1 the shift is equal to swap - { - ArrayUtil.rotateLeft(expressions, i, j); - if (PsiUtil.isApplicable(method, substitutor, expressions)) { - PsiCall copy = (PsiCall) callExpression.copy(); - PsiExpression[] copyExpressions = copy.getArgumentList().getExpressions(); - for (int k = i; k < copyExpressions.length; k++) { - copyExpressions[k].replace(expressions[k]); - } - JavaResolveResult result = copy.resolveMethodGenerics(); - if (result.getElement() != null && result.isValidResult()) { - permutations.add(copy); - if (permutations.size() > 1) return; - } - } - ArrayUtil.rotateRight(expressions, i, j); + @Override + public boolean isAvailable(@Nonnull Project project, Editor editor, PsiFile file) { + return !project.isDisposed() && myCall.isValid() && myCall.getManager().isInProject(myCall); + } + + @Override + @RequiredUIAccess + public void invoke(@Nonnull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { + if (!FileModificationService.getInstance().prepareFileForWrite(file)) { + return; } + myCall.getArgumentList().replace(myPermutation.getArgumentList()); + } - { - ArrayUtil.rotateRight(expressions, i, j); - if (PsiUtil.isApplicable(method, substitutor, expressions)) { - PsiCall copy = (PsiCall) callExpression.copy(); - PsiExpression[] copyExpressions = copy.getArgumentList().getExpressions(); - for (int k = i; k < copyExpressions.length; k++) { - copyExpressions[k].replace(expressions[k]); + @RequiredReadAction + public static void registerFix(HighlightInfo.Builder hlBuilder, PsiCall callExpression, CandidateInfo[] candidates, TextRange fixRange) { + PsiExpression[] expressions = callExpression.getArgumentList().getExpressions(); + if (hlBuilder == null || expressions.length < 2) { + return; + } + List permutations = new ArrayList<>(); + + for (CandidateInfo candidate : candidates) { + if (candidate instanceof MethodCandidateInfo) { + MethodCandidateInfo methodCandidate = (MethodCandidateInfo)candidate; + PsiMethod method = methodCandidate.getElement(); + PsiSubstitutor substitutor = methodCandidate.getSubstitutor(); + + PsiParameter[] parameters = method.getParameterList().getParameters(); + if (expressions.length != parameters.length || parameters.length == 0) { + continue; + } + int minIncompatibleIndex = parameters.length; + int maxIncompatibleIndex = 0; + int incompatibilitiesCount = 0; + for (int i = 0; i < parameters.length; i++) { + PsiParameter parameter = parameters[i]; + PsiType type = substitutor.substitute(parameter.getType()); + if (TypeConversionUtil.areTypesAssignmentCompatible(type, expressions[i])) { + continue; + } + if (minIncompatibleIndex == parameters.length) { + minIncompatibleIndex = i; + } + maxIncompatibleIndex = i; + incompatibilitiesCount++; + } + + try { + registerSwapFixes( + expressions, + callExpression, + permutations, + methodCandidate, + incompatibilitiesCount, + minIncompatibleIndex, + maxIncompatibleIndex + ); + registerShiftFixes( + expressions, + callExpression, + permutations, + methodCandidate, + minIncompatibleIndex, + maxIncompatibleIndex + ); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } } + } + if (permutations.size() == 1) { + hlBuilder.registerFix(new PermuteArgumentsFix(callExpression, permutations.get(0)), fixRange); + } + } - JavaResolveResult result = copy.resolveMethodGenerics(); - if (result.getElement() != null && result.isValidResult()) { - permutations.add(copy); - if (permutations.size() > 1) return; + @RequiredReadAction + private static void registerShiftFixes( + PsiExpression[] expressions, + PsiCall callExpression, + List permutations, + MethodCandidateInfo methodCandidate, + int minIncompatibleIndex, + int maxIncompatibleIndex + ) + throws IncorrectOperationException { + PsiMethod method = methodCandidate.getElement(); + PsiSubstitutor substitutor = methodCandidate.getSubstitutor(); + // shift range should include both incompatible indexes + for (int i = 0; i <= minIncompatibleIndex; i++) { + for (int j = Math.max(i + 2, maxIncompatibleIndex); j < expressions.length; j++) { // if j=i+1 the shift is equal to swap + { + ArrayUtil.rotateLeft(expressions, i, j); + if (PsiUtil.isApplicable(method, substitutor, expressions)) { + PsiCall copy = (PsiCall)callExpression.copy(); + PsiExpression[] copyExpressions = copy.getArgumentList().getExpressions(); + for (int k = i; k < copyExpressions.length; k++) { + copyExpressions[k].replace(expressions[k]); + } + + JavaResolveResult result = copy.resolveMethodGenerics(); + if (result.getElement() != null && result.isValidResult()) { + permutations.add(copy); + if (permutations.size() > 1) { + return; + } + } + } + ArrayUtil.rotateRight(expressions, i, j); + } + + { + ArrayUtil.rotateRight(expressions, i, j); + if (PsiUtil.isApplicable(method, substitutor, expressions)) { + PsiCall copy = (PsiCall)callExpression.copy(); + PsiExpression[] copyExpressions = copy.getArgumentList().getExpressions(); + for (int k = i; k < copyExpressions.length; k++) { + copyExpressions[k].replace(expressions[k]); + } + + JavaResolveResult result = copy.resolveMethodGenerics(); + if (result.getElement() != null && result.isValidResult()) { + permutations.add(copy); + if (permutations.size() > 1) { + return; + } + } + } + ArrayUtil.rotateLeft(expressions, i, j); + } } - } - ArrayUtil.rotateLeft(expressions, i, j); } - } } - } - - private static void registerSwapFixes(final PsiExpression[] expressions, final PsiCall callExpression, final List permutations, - MethodCandidateInfo candidate, final int incompatibilitiesCount, final int minIncompatibleIndex, - final int maxIncompatibleIndex) throws IncorrectOperationException { - PsiMethod method = candidate.getElement(); - PsiSubstitutor substitutor = candidate.getSubstitutor(); - if (incompatibilitiesCount >= 3) return; // no way we can fix it by swapping - - for (int i = minIncompatibleIndex; i < maxIncompatibleIndex; i++) { - for (int j = i + 1; j <= maxIncompatibleIndex; j++) { - ArrayUtil.swap(expressions, i, j); - if (PsiUtil.isApplicable(method, substitutor, expressions)) { - PsiCall copy = (PsiCall) callExpression.copy(); - PsiExpression[] copyExpressions = copy.getArgumentList().getExpressions(); - copyExpressions[i].replace(expressions[i]); - copyExpressions[j].replace(expressions[j]); - JavaResolveResult result = copy.resolveMethodGenerics(); - if (result.getElement() != null && result.isValidResult()) { - permutations.add(copy); - if (permutations.size() > 1) return; - } + + @RequiredReadAction + private static void registerSwapFixes( + PsiExpression[] expressions, + PsiCall callExpression, + List permutations, + MethodCandidateInfo candidate, + int incompatibilitiesCount, + int minIncompatibleIndex, + int maxIncompatibleIndex + ) throws IncorrectOperationException { + PsiMethod method = candidate.getElement(); + PsiSubstitutor substitutor = candidate.getSubstitutor(); + if (incompatibilitiesCount >= 3) { + return; // no way we can fix it by swapping + } + + for (int i = minIncompatibleIndex; i < maxIncompatibleIndex; i++) { + for (int j = i + 1; j <= maxIncompatibleIndex; j++) { + ArrayUtil.swap(expressions, i, j); + if (PsiUtil.isApplicable(method, substitutor, expressions)) { + PsiCall copy = (PsiCall)callExpression.copy(); + PsiExpression[] copyExpressions = copy.getArgumentList().getExpressions(); + copyExpressions[i].replace(expressions[i]); + copyExpressions[j].replace(expressions[j]); + JavaResolveResult result = copy.resolveMethodGenerics(); + if (result.getElement() != null && result.isValidResult()) { + permutations.add(copy); + if (permutations.size() > 1) { + return; + } + } + } + ArrayUtil.swap(expressions, i, j); + } } - ArrayUtil.swap(expressions, i, j); - } } - } } 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 0370ccc2c..5d8d33ea3 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,10 +28,10 @@ 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.RequiredWriteAction; import consulo.codeEditor.Editor; import consulo.document.util.TextRange; import consulo.language.editor.intention.PsiElementBaseIntentionAction; -import consulo.language.editor.intention.QuickFixAction; import consulo.language.editor.rawHighlight.HighlightInfo; import consulo.language.psi.PsiElement; import consulo.language.psi.PsiManager; @@ -44,75 +44,91 @@ import java.util.Set; public class QualifyThisArgumentFix extends PsiElementBaseIntentionAction { - private final PsiThisExpression myExpression; - private final PsiClass myPsiClass; + private final PsiThisExpression myExpression; + private final PsiClass myPsiClass; + public QualifyThisArgumentFix(@Nonnull PsiThisExpression expression, @Nonnull PsiClass psiClass) { + myExpression = expression; + myPsiClass = psiClass; + } - public QualifyThisArgumentFix(@Nonnull PsiThisExpression expression, @Nonnull PsiClass psiClass) { - myExpression = expression; - myPsiClass = psiClass; - } - - - @Override - public boolean isAvailable(@Nonnull Project project, Editor editor, @Nonnull PsiElement element) { - if (!myExpression.isValid()) return false; - if (!myPsiClass.isValid()) return false; - setText("Qualify this expression with \'" + myPsiClass.getQualifiedName() + "\'"); - return true; - } - - @Override - public void invoke(@Nonnull Project project, Editor editor, @Nonnull PsiElement element) throws IncorrectOperationException { - myExpression.replace(RefactoringChangeUtil.createThisExpression(PsiManager.getInstance(project), myPsiClass)); - } - - public static void registerQuickFixAction(CandidateInfo[] candidates, PsiCall call, HighlightInfo highlightInfo, final TextRange fixRange) { - if (candidates.length == 0) return; - - final Set containingClasses = new HashSet(); - PsiClass parentClass = PsiTreeUtil.getParentOfType(call, PsiClass.class); - while (parentClass != null) { - if (parentClass.hasModifierProperty(PsiModifier.STATIC)) break; - if (!(parentClass instanceof PsiAnonymousClass)) { - containingClasses.add(parentClass); - } - parentClass = PsiTreeUtil.getParentOfType(parentClass, PsiClass.class, true); + @Override + public boolean isAvailable(@Nonnull Project project, Editor editor, @Nonnull PsiElement element) { + if (!myExpression.isValid()) { + return false; + } + if (!myPsiClass.isValid()) { + return false; + } + setText("Qualify this expression with \'" + myPsiClass.getQualifiedName() + "\'"); + return true; } - if (containingClasses.isEmpty()) return; - final PsiExpressionList list = call.getArgumentList(); - final PsiExpression[] expressions = list.getExpressions(); - if (expressions.length == 0) return; + @Override + @RequiredWriteAction + public void invoke(@Nonnull Project project, Editor editor, @Nonnull PsiElement element) throws IncorrectOperationException { + myExpression.replace(RefactoringChangeUtil.createThisExpression(PsiManager.getInstance(project), myPsiClass)); + } - for (int i1 = 0, expressionsLength = expressions.length; i1 < expressionsLength; i1++) { - final PsiExpression expression = expressions[i1]; - if (expression instanceof PsiThisExpression) { - final PsiType exprType = expression.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; - } + public static void registerQuickFixAction( + CandidateInfo[] candidates, + PsiCall call, + HighlightInfo.Builder highlightInfo, + final TextRange fixRange + ) { + if (candidates.length == 0) { + return; + } - PsiParameter parameter = parameters[i1]; + final Set containingClasses = new HashSet<>(); + PsiClass parentClass = PsiTreeUtil.getParentOfType(call, PsiClass.class); + while (parentClass != null) { + if (parentClass.isStatic()) { + break; + } + if (!(parentClass instanceof PsiAnonymousClass)) { + containingClasses.add(parentClass); + } + parentClass = PsiTreeUtil.getParentOfType(parentClass, PsiClass.class, true); + } + if (containingClasses.isEmpty()) { + return; + } - PsiType parameterType = substitutor.substitute(parameter.getType()); - if (exprType == null || parameterType == null) { - continue; - } + final PsiExpressionList list = call.getArgumentList(); + final PsiExpression[] expressions = list.getExpressions(); + if (expressions.length == 0) { + return; + } - if (!TypeConversionUtil.isAssignable(parameterType, exprType)) { - final PsiClass psiClass = PsiUtil.resolveClassInClassTypeOnly(parameterType); - if (psiClass != null && containingClasses.contains(psiClass)) { - QuickFixAction.registerQuickFixAction(highlightInfo, fixRange, new QualifyThisArgumentFix((PsiThisExpression) expression, psiClass)); + for (int i1 = 0, expressionsLength = expressions.length; i1 < expressionsLength; i1++) { + final PsiExpression expression = expressions[i1]; + if (expression instanceof PsiThisExpression) { + final PsiType exprType = expression.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; + } + + PsiParameter parameter = parameters[i1]; + + PsiType parameterType = substitutor.substitute(parameter.getType()); + if (exprType == null || parameterType == null) { + continue; + } + + if (!TypeConversionUtil.isAssignable(parameterType, exprType)) { + final PsiClass psiClass = PsiUtil.resolveClassInClassTypeOnly(parameterType); + if (psiClass != null && containingClasses.contains(psiClass)) { + highlightInfo.registerFix(new QualifyThisArgumentFix((PsiThisExpression)expression, psiClass), fixRange); + } + } + } } - } } - } } - } } 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 ac25617d2..e9d1a6d60 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 @@ -20,16 +20,14 @@ import com.intellij.java.language.psi.util.TypeConversionUtil; import consulo.codeEditor.Editor; import consulo.document.util.TextRange; -import consulo.java.analysis.impl.JavaQuickFixBundle; +import consulo.java.analysis.impl.localize.JavaQuickFixLocalize; import consulo.language.editor.FileModificationService; -import consulo.language.editor.intention.QuickFixAction; import consulo.language.editor.intention.SyntheticIntentionAction; import consulo.language.editor.rawHighlight.HighlightInfo; import consulo.language.psi.PsiElement; import consulo.language.psi.PsiFile; import consulo.language.util.IncorrectOperationException; import consulo.project.Project; - import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; @@ -39,92 +37,119 @@ * @author Danila Ponomarenko */ public class RemoveRedundantArgumentsFix implements SyntheticIntentionAction { - private final PsiMethod myTargetMethod; - private final PsiExpression[] myArguments; - private final PsiSubstitutor mySubstitutor; - - private RemoveRedundantArgumentsFix(@Nonnull PsiMethod targetMethod, - @Nonnull PsiExpression[] arguments, - @Nonnull PsiSubstitutor substitutor) { - myTargetMethod = targetMethod; - myArguments = arguments; - mySubstitutor = substitutor; - } - - @Nonnull - @Override - public String getText() { - return JavaQuickFixBundle.message("remove.redundant.arguments.text", JavaHighlightUtil.formatMethod(myTargetMethod)); - } - - @Override - public boolean isAvailable(@Nonnull Project project, Editor editor, PsiFile file) { - if (!myTargetMethod.isValid() || myTargetMethod.getContainingClass() == null) return false; - for (PsiExpression expression : myArguments) { - if (!expression.isValid()) return false; + private final PsiMethod myTargetMethod; + private final PsiExpression[] myArguments; + private final PsiSubstitutor mySubstitutor; + + private RemoveRedundantArgumentsFix( + @Nonnull PsiMethod targetMethod, + @Nonnull PsiExpression[] arguments, + @Nonnull PsiSubstitutor substitutor + ) { + myTargetMethod = targetMethod; + myArguments = arguments; + mySubstitutor = substitutor; } - if (!mySubstitutor.isValid()) return false; - - return findRedundantArgument(myArguments, myTargetMethod.getParameterList().getParameters(), mySubstitutor) != null; - } - @Nullable - private static PsiExpression[] findRedundantArgument(@Nonnull PsiExpression[] arguments, - @Nonnull PsiParameter[] parameters, - @Nonnull PsiSubstitutor substitutor) { - if (arguments.length <= parameters.length) return null; + @Nonnull + @Override + public String getText() { + return JavaQuickFixLocalize.removeRedundantArgumentsText(JavaHighlightUtil.formatMethod(myTargetMethod)).get(); + } - for (int i = 0; i < parameters.length; i++) { - final PsiExpression argument = arguments[i]; - final PsiParameter parameter = parameters[i]; + @Override + public boolean isAvailable(@Nonnull Project project, Editor editor, PsiFile file) { + if (!myTargetMethod.isValid() || myTargetMethod.getContainingClass() == null) { + return false; + } + for (PsiExpression expression : myArguments) { + if (!expression.isValid()) { + return false; + } + } + //noinspection SimplifiableIfStatement + if (!mySubstitutor.isValid()) { + return false; + } + + return findRedundantArgument(myArguments, myTargetMethod.getParameterList().getParameters(), mySubstitutor) != null; + } - final PsiType argumentType = argument.getType(); - if (argumentType == null) return null; - final PsiType parameterType = substitutor.substitute(parameter.getType()); + @Nullable + private static PsiExpression[] findRedundantArgument( + @Nonnull PsiExpression[] arguments, + @Nonnull PsiParameter[] parameters, + @Nonnull PsiSubstitutor substitutor + ) { + if (arguments.length <= parameters.length) { + return null; + } + + for (int i = 0; i < parameters.length; i++) { + final PsiExpression argument = arguments[i]; + final PsiParameter parameter = parameters[i]; + + final PsiType argumentType = argument.getType(); + if (argumentType == null) { + return null; + } + final PsiType parameterType = substitutor.substitute(parameter.getType()); + + if (!TypeConversionUtil.isAssignable(parameterType, argumentType)) { + return null; + } + } + + return Arrays.copyOfRange(arguments, parameters.length, arguments.length); + } - if (!TypeConversionUtil.isAssignable(parameterType, argumentType)) { - return null; - } + @Override + public void invoke(@Nonnull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { + if (!FileModificationService.getInstance().prepareFileForWrite(file)) { + return; + } + final PsiExpression[] redundantArguments = + findRedundantArgument(myArguments, myTargetMethod.getParameterList().getParameters(), mySubstitutor); + if (redundantArguments != null) { + for (PsiExpression argument : redundantArguments) { + argument.delete(); + } + } } - return Arrays.copyOfRange(arguments, parameters.length, arguments.length); - } - - @Override - public void invoke(@Nonnull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { - if (!FileModificationService.getInstance().prepareFileForWrite(file)) return; - final PsiExpression[] redundantArguments = findRedundantArgument(myArguments, myTargetMethod.getParameterList().getParameters(), mySubstitutor); - if (redundantArguments != null) { - for (PsiExpression argument : redundantArguments) { - argument.delete(); - } + @Override + public boolean startInWriteAction() { + return true; } - } - - @Override - public boolean startInWriteAction() { - return true; - } - - public static void registerIntentions(@Nonnull JavaResolveResult[] candidates, - @Nonnull PsiExpressionList arguments, - @Nullable HighlightInfo highlightInfo, - TextRange fixRange) { - for (JavaResolveResult candidate : candidates) { - registerIntention(arguments, highlightInfo, fixRange, candidate, arguments); + + public static void registerIntentions( + @Nonnull JavaResolveResult[] candidates, + @Nonnull PsiExpressionList arguments, + @Nullable HighlightInfo.Builder hlBuilder, + TextRange fixRange + ) { + if (hlBuilder == null) { + return; + } + for (JavaResolveResult candidate : candidates) { + registerIntention(arguments, hlBuilder, fixRange, candidate, arguments); + } } - } - - private static void registerIntention(@Nonnull PsiExpressionList arguments, - @Nullable HighlightInfo highlightInfo, - TextRange fixRange, - @Nonnull JavaResolveResult candidate, - @Nonnull PsiElement context) { - if (!candidate.isStaticsScopeCorrect()) return; - PsiMethod method = (PsiMethod) candidate.getElement(); - PsiSubstitutor substitutor = candidate.getSubstitutor(); - if (method != null && context.getManager().isInProject(method)) { - QuickFixAction.registerQuickFixAction(highlightInfo, fixRange, new RemoveRedundantArgumentsFix(method, arguments.getExpressions(), substitutor)); + + private static void registerIntention( + @Nonnull PsiExpressionList arguments, + @Nonnull HighlightInfo.Builder hlBuilder, + TextRange fixRange, + @Nonnull JavaResolveResult candidate, + @Nonnull PsiElement context + ) { + if (!candidate.isStaticsScopeCorrect()) { + return; + } + 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); + } } - } } 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 558eb9fbe..a7b26e913 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 @@ -16,10 +16,11 @@ package com.intellij.java.analysis.impl.codeInsight.daemon.impl.quickfix; import com.intellij.java.language.psi.*; +import consulo.annotation.access.RequiredReadAction; +import consulo.annotation.access.RequiredWriteAction; import consulo.codeEditor.Editor; -import consulo.java.analysis.impl.JavaQuickFixBundle; +import consulo.java.analysis.impl.localize.JavaQuickFixLocalize; import consulo.language.editor.FileModificationService; -import consulo.language.editor.intention.QuickFixAction; import consulo.language.editor.intention.SyntheticIntentionAction; import consulo.language.editor.rawHighlight.HighlightInfo; import consulo.language.psi.PsiElement; @@ -27,10 +28,9 @@ import consulo.language.psi.scope.GlobalSearchScope; import consulo.language.util.IncorrectOperationException; import consulo.project.Project; -import org.jetbrains.annotations.NonNls; - import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; + import java.util.LinkedHashSet; import java.util.Set; @@ -38,133 +38,156 @@ * @author ven */ public class WrapExpressionFix implements SyntheticIntentionAction { + private final PsiExpression myExpression; + private final PsiClassType myExpectedType; + private final boolean myPrimitiveExpected; - private final PsiExpression myExpression; - private final PsiClassType myExpectedType; - private final boolean myPrimitiveExpected; - - public WrapExpressionFix(PsiType expectedType, PsiExpression expression) { - myExpression = expression; - myExpectedType = getClassType(expectedType, expression); - myPrimitiveExpected = expectedType instanceof PsiPrimitiveType; - } + public WrapExpressionFix(PsiType expectedType, PsiExpression expression) { + myExpression = expression; + myExpectedType = getClassType(expectedType, expression); + myPrimitiveExpected = expectedType instanceof PsiPrimitiveType; + } - @Nullable - private static PsiClassType getClassType(PsiType type, PsiElement place) { - if (type instanceof PsiClassType) { - return (PsiClassType) type; - } else if (type instanceof PsiPrimitiveType) { - return ((PsiPrimitiveType) type).getBoxedType(place.getManager(), GlobalSearchScope.allScope(place.getProject())); + @Nullable + private static PsiClassType getClassType(PsiType type, PsiElement place) { + if (type instanceof PsiClassType classType) { + return classType; + } + else if (type instanceof PsiPrimitiveType primitiveType) { + return primitiveType.getBoxedType(place.getManager(), GlobalSearchScope.allScope(place.getProject())); + } + return null; } - return null; - } - @Override - @Nonnull - public String getText() { - final PsiMethod wrapper = myExpression.isValid() && myExpectedType != null ? findWrapper(myExpression.getType(), myExpectedType, myPrimitiveExpected) : null; - final String methodPresentation = wrapper != null ? wrapper.getContainingClass().getName() + "." + wrapper.getName() : ""; - return JavaQuickFixBundle.message("wrap.expression.using.static.accessor.text", methodPresentation); - } + @Nonnull + @Override + @RequiredReadAction + public String getText() { + PsiMethod wrapper = myExpression.isValid() && myExpectedType != null + ? findWrapper(myExpression.getType(), myExpectedType, myPrimitiveExpected) + : null; + String methodPresentation = wrapper != null ? wrapper.getContainingClass().getName() + "." + wrapper.getName() : ""; + return JavaQuickFixLocalize.wrapExpressionUsingStaticAccessorText(methodPresentation).get(); + } - @Nullable - private static PsiMethod findWrapper(PsiType type, @Nonnull PsiClassType expectedType, boolean primitiveExpected) { - PsiClass aClass = expectedType.resolve(); - if (aClass != null) { - PsiType expectedReturnType = expectedType; - if (primitiveExpected) { - expectedReturnType = PsiPrimitiveType.getUnboxedType(expectedType); - } - if (expectedReturnType == null) return null; - PsiMethod[] methods = aClass.getMethods(); - final Set wrapperMethods = new LinkedHashSet(); - for (PsiMethod method : methods) { - if (method.hasModifierProperty(PsiModifier.STATIC) - && method.getParameterList().getParametersCount() == 1 - && method.getParameterList().getParameters()[0].getType().isAssignableFrom(type) - && method.getReturnType() != null - && expectedReturnType.equals(method.getReturnType())) { - final String methodName = method.getName(); - if (methodName.startsWith("parse") || methodName.equals("valueOf")) { - return method; - } - wrapperMethods.add(method); + @Nullable + private static PsiMethod findWrapper(PsiType type, @Nonnull PsiClassType expectedType, boolean primitiveExpected) { + PsiClass aClass = expectedType.resolve(); + if (aClass != null) { + PsiType expectedReturnType = expectedType; + if (primitiveExpected) { + expectedReturnType = PsiPrimitiveType.getUnboxedType(expectedType); + } + if (expectedReturnType == null) { + return null; + } + PsiMethod[] methods = aClass.getMethods(); + Set wrapperMethods = new LinkedHashSet<>(); + for (PsiMethod method : methods) { + if (method.isStatic() + && method.getParameterList().getParametersCount() == 1 + && method.getParameterList().getParameters()[0].getType().isAssignableFrom(type) + && method.getReturnType() != null + && expectedReturnType.equals(method.getReturnType())) { + String methodName = method.getName(); + if (methodName.startsWith("parse") || methodName.equals("valueOf")) { + return method; + } + wrapperMethods.add(method); + } + } + if (!wrapperMethods.isEmpty()) { + return wrapperMethods.iterator().next(); + } } - } - if (!wrapperMethods.isEmpty()) return wrapperMethods.iterator().next(); - } - return null; - } + return null; + } - @Override - public boolean isAvailable(@Nonnull Project project, Editor editor, PsiFile file) { - return myExpression.isValid() - && myExpression.getManager().isInProject(myExpression) - && myExpectedType != null - && myExpectedType.isValid() - && myExpression.getType() != null - && findWrapper(myExpression.getType(), myExpectedType, myPrimitiveExpected) != null; - } + @Override + public boolean isAvailable(@Nonnull Project project, Editor editor, PsiFile file) { + return myExpression.isValid() + && myExpression.getManager().isInProject(myExpression) + && myExpectedType != null + && myExpectedType.isValid() + && myExpression.getType() != null + && findWrapper(myExpression.getType(), myExpectedType, myPrimitiveExpected) != null; + } - @Override - public void invoke(@Nonnull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { - if (!FileModificationService.getInstance().prepareFileForWrite(file)) return; - PsiMethod wrapper = findWrapper(myExpression.getType(), myExpectedType, myPrimitiveExpected); - assert wrapper != null; - PsiElementFactory factory = JavaPsiFacade.getInstance(file.getProject()).getElementFactory(); - @NonNls String methodCallText = "Foo." + wrapper.getName() + "()"; - PsiMethodCallExpression call = (PsiMethodCallExpression) factory.createExpressionFromText(methodCallText, - null); - call.getArgumentList().add(myExpression); - ((PsiReferenceExpression) call.getMethodExpression().getQualifierExpression()).bindToElement( - wrapper.getContainingClass()); - myExpression.replace(call); - } + @Override + @RequiredWriteAction + public void invoke(@Nonnull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { + if (!FileModificationService.getInstance().prepareFileForWrite(file)) { + return; + } + PsiMethod wrapper = findWrapper(myExpression.getType(), myExpectedType, myPrimitiveExpected); + assert wrapper != null; + PsiElementFactory factory = JavaPsiFacade.getInstance(file.getProject()).getElementFactory(); + String methodCallText = "Foo." + wrapper.getName() + "()"; + PsiMethodCallExpression call = (PsiMethodCallExpression)factory.createExpressionFromText(methodCallText, null); + call.getArgumentList().add(myExpression); + ((PsiReferenceExpression)call.getMethodExpression().getQualifierExpression()) + .bindToElement(wrapper.getContainingClass()); + myExpression.replace(call); + } - @Override - public boolean startInWriteAction() { - return true; - } + @Override + public boolean startInWriteAction() { + return true; + } - public static void registerWrapAction(JavaResolveResult[] candidates, PsiExpression[] expressions, HighlightInfo highlightInfo) { - PsiType expectedType = null; - PsiExpression expr = null; + @RequiredReadAction + public static void registerWrapAction( + JavaResolveResult[] candidates, + PsiExpression[] expressions, + @Nullable HighlightInfo.Builder hlBuilder + ) { + if (hlBuilder == null) { + return; + } + PsiType expectedType = null; + PsiExpression expr = null; - nextMethod: - for (int i = 0; i < candidates.length && expectedType == null; i++) { - final JavaResolveResult candidate = candidates[i]; - final PsiSubstitutor substitutor = candidate.getSubstitutor(); - final PsiElement element = candidate.getElement(); - assert element != null; - final PsiMethod method = (PsiMethod) element; - final PsiParameter[] parameters = method.getParameterList().getParameters(); - if (!method.isVarArgs() && parameters.length != expressions.length) continue; - for (int j = 0; j < expressions.length; j++) { - PsiExpression expression = expressions[j]; - final PsiType exprType = expression.getType(); - if (exprType != null) { - PsiType paramType = parameters[Math.min(j, parameters.length - 1)].getType(); - if (paramType instanceof PsiEllipsisType) { - paramType = ((PsiEllipsisType) paramType).getComponentType(); - } - paramType = substitutor != null ? substitutor.substitute(paramType) : paramType; - if (paramType.isAssignableFrom(exprType)) continue; - final PsiClassType classType = getClassType(paramType, expression); - if (expectedType == null && classType != null && findWrapper(exprType, classType, paramType instanceof PsiPrimitiveType) != null) { - expectedType = paramType; - expr = expression; - } else { - expectedType = null; - expr = null; - continue nextMethod; - } + nextMethod: + for (int i = 0; i < candidates.length && expectedType == null; i++) { + JavaResolveResult candidate = candidates[i]; + PsiSubstitutor substitutor = candidate.getSubstitutor(); + PsiElement element = candidate.getElement(); + assert element != null; + PsiMethod method = (PsiMethod)element; + PsiParameter[] parameters = method.getParameterList().getParameters(); + if (!method.isVarArgs() && parameters.length != expressions.length) { + continue; + } + for (int j = 0; j < expressions.length; j++) { + PsiExpression expression = expressions[j]; + PsiType exprType = expression.getType(); + if (exprType != null) { + PsiType paramType = parameters[Math.min(j, parameters.length - 1)].getType(); + if (paramType instanceof PsiEllipsisType ellipsisType) { + paramType = ellipsisType.getComponentType(); + } + paramType = substitutor != null ? substitutor.substitute(paramType) : paramType; + if (paramType.isAssignableFrom(exprType)) { + continue; + } + PsiClassType classType = getClassType(paramType, expression); + if (expectedType == null && classType != null + && findWrapper(exprType, classType, paramType instanceof PsiPrimitiveType) != null) { + expectedType = paramType; + expr = expression; + } + else { + expectedType = null; + expr = null; + continue nextMethod; + } + } + } } - } - } - if (expectedType != null) { - QuickFixAction.registerQuickFixAction(highlightInfo, expr.getTextRange(), new WrapExpressionFix(expectedType, expr)); + if (expectedType != null) { + hlBuilder.registerFix(new WrapExpressionFix(expectedType, expr), expr.getTextRange()); + } } - } } diff --git a/java-debugger-impl/src/main/java/com/intellij/java/debugger/impl/engine/evaluation/expression/EvaluatorBuilderImpl.java b/java-debugger-impl/src/main/java/com/intellij/java/debugger/impl/engine/evaluation/expression/EvaluatorBuilderImpl.java index 52b2a71de..0cd2812c8 100644 --- a/java-debugger-impl/src/main/java/com/intellij/java/debugger/impl/engine/evaluation/expression/EvaluatorBuilderImpl.java +++ b/java-debugger-impl/src/main/java/com/intellij/java/debugger/impl/engine/evaluation/expression/EvaluatorBuilderImpl.java @@ -1326,11 +1326,14 @@ else if(qualifier != null) @Override public void visitLiteralExpression(PsiLiteralExpression expression) { - final HighlightInfo parsingError = HighlightUtil.checkLiteralExpressionParsingError(expression, null, null); + final HighlightInfo.Builder parsingError = HighlightUtil.checkLiteralExpressionParsingError(expression, null, null); if(parsingError != null) { - throwEvaluateException(parsingError.getDescription()); - return; + HighlightInfo hlInfo = parsingError.create(); + if (hlInfo != null) { + throwEvaluateException(hlInfo.getDescription()); + return; + } } final PsiType type = expression.getType();