From 6a2a667f6bea21e8e82fba628ddc1a7b8b119852 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 23 Nov 2021 11:33:31 +0100 Subject: [PATCH] [java] show mismatch arg count error and highlight only additional arg (IDEA-282207) fix ranges should be extended for the whole argList, otherwise only the first highlighting become fixes. It's possible to attach separated fixes though it may be more useful to have single fix over whole range, let's see GitOrigin-RevId: a568d2633824abd7207fb3c54687b64588a43e62 --- .../impl/analysis/HighlightFixUtil.java | 16 ++-- .../impl/analysis/HighlightMethodUtil.java | 84 +++++++++---------- .../daemon/impl/analysis/HighlightUtil.java | 2 +- .../impl/analysis/HighlightVisitorImpl.java | 2 +- ...ngeStringLiteralToCharInMethodCallFix.java | 30 ++----- .../impl/quickfix/ChangeTypeArgumentsFix.java | 12 +-- .../impl/quickfix/MoveParenthesisFix.java | 7 +- .../quickfix/CreateMethodFromUsageFix.java | 19 +---- .../CreateMethodFromJavaUsageRequest.kt | 6 +- .../changeTypeArgs/afterManyArgs.java | 11 +++ .../changeTypeArgs/beforeManyArgs.java | 11 +++ .../moveParenthesis/beforeShiftLeft.java | 2 +- 12 files changed, 102 insertions(+), 100 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/afterManyArgs.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/beforeManyArgs.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightFixUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightFixUtil.java index e7a345661d90..fcab7565d9b3 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightFixUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightFixUtil.java @@ -1,4 +1,4 @@ -// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.codeInsight.daemon.impl.analysis; import com.intellij.codeInsight.daemon.QuickFixBundle; @@ -77,14 +77,15 @@ public final class HighlightFixUtil { static void registerAccessQuickFixAction(@NotNull PsiJvmMember refElement, @NotNull PsiJavaCodeReferenceElement place, @Nullable HighlightInfo errorResult, - PsiElement fileResolveScope) { + PsiElement fileResolveScope, + TextRange parentFixRange) { if (errorResult == null) return; PsiClass accessObjectClass = null; PsiElement qualifier = place.getQualifier(); if (qualifier instanceof PsiExpression) { accessObjectClass = (PsiClass)PsiUtil.getAccessObjectClass((PsiExpression)qualifier).getElement(); } - registerReplaceInaccessibleFieldWithGetterSetterFix(refElement, place, accessObjectClass, errorResult); + registerReplaceInaccessibleFieldWithGetterSetterFix(refElement, place, accessObjectClass, errorResult, parentFixRange); if (refElement instanceof PsiCompiledElement) return; PsiModifierList modifierList = refElement.getModifierList(); @@ -94,7 +95,7 @@ public final class HighlightFixUtil { if (packageLocalClassInTheMiddle != null) { List fixes = JvmElementActionFactories.createModifierActions(packageLocalClassInTheMiddle, MemberRequestsKt.modifierRequest(JvmModifier.PUBLIC, true)); - QuickFixAction.registerQuickFixActions(errorResult, null, fixes); + QuickFixAction.registerQuickFixActions(errorResult, parentFixRange, fixes); return; } @@ -291,7 +292,8 @@ public final class HighlightFixUtil { private static void registerReplaceInaccessibleFieldWithGetterSetterFix(PsiMember refElement, PsiJavaCodeReferenceElement place, PsiClass accessObjectClass, - HighlightInfo error) { + HighlightInfo error, + TextRange parentFixRange) { if (refElement instanceof PsiField && place instanceof PsiReferenceExpression) { PsiField psiField = (PsiField)refElement; PsiClass containingClass = psiField.getContainingClass(); @@ -302,7 +304,7 @@ public final class HighlightFixUtil { if (setter != null && PsiUtil.isAccessible(setter, place, accessObjectClass)) { PsiElement element = PsiTreeUtil.skipParentsOfType(place, PsiParenthesizedExpression.class); if (element instanceof PsiAssignmentExpression && ((PsiAssignmentExpression)element).getOperationTokenType() == JavaTokenType.EQ) { - QuickFixAction.registerQuickFixAction(error, QUICK_FIX_FACTORY.createReplaceInaccessibleFieldWithGetterSetterFix(place, setter, true)); + QuickFixAction.registerQuickFixAction(error, parentFixRange, QUICK_FIX_FACTORY.createReplaceInaccessibleFieldWithGetterSetterFix(place, setter, true)); } } } @@ -310,7 +312,7 @@ public final class HighlightFixUtil { PsiMethod getterPrototype = PropertyUtilBase.generateGetterPrototype(psiField); PsiMethod getter = containingClass.findMethodBySignature(getterPrototype, true); if (getter != null && PsiUtil.isAccessible(getter, place, accessObjectClass)) { - QuickFixAction.registerQuickFixAction(error, QUICK_FIX_FACTORY.createReplaceInaccessibleFieldWithGetterSetterFix(place, getter, false)); + QuickFixAction.registerQuickFixAction(error, parentFixRange, QUICK_FIX_FACTORY.createReplaceInaccessibleFieldWithGetterSetterFix(place, getter, false)); } } } diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java index ea38ea63755f..a695a2e188e5 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java @@ -24,7 +24,6 @@ import com.intellij.openapi.projectRoots.JavaSdkVersion; import com.intellij.openapi.util.*; import com.intellij.openapi.util.text.HtmlBuilder; import com.intellij.openapi.util.text.HtmlChunk; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; @@ -417,12 +416,8 @@ public final class HighlightMethodUtil { } } else { - PsiMethod resolvedMethod = null; - MethodCandidateInfo candidateInfo = null; - if (resolveResult instanceof MethodCandidateInfo) { - candidateInfo = (MethodCandidateInfo)resolveResult; - resolvedMethod = candidateInfo.getElement(); - } + MethodCandidateInfo candidateInfo = resolveResult instanceof MethodCandidateInfo ? (MethodCandidateInfo)resolveResult : null; + PsiMethod resolvedMethod = candidateInfo != null ? candidateInfo.getElement() : null; if (!resolveResult.isAccessible() || !resolveResult.isStaticsScopeCorrect()) { highlightInfo = null; @@ -506,9 +501,6 @@ public final class HighlightMethodUtil { if (mismatchedExpressions.size() == 1) { toolTip = createOneArgMismatchTooltip(candidateInfo, mismatchedExpressions, expressions, parameters); } - else if (mismatchedExpressions.isEmpty()) { - toolTip = StringUtil.escapeXmlEntities(description); - } if (toolTip == null) { toolTip = createMismatchedArgumentsHtmlTooltip(candidateInfo, list); } @@ -551,6 +543,9 @@ public final class HighlightMethodUtil { final PsiExpression wrongArg = mismatchedExpressions.get(0); final PsiType argType = wrongArg.getType(); if (argType != null) { + if ((parameters.length == 0 || !parameters[parameters.length - 1].isVarArgs()) && parameters.length != expressions.length) { + return createMismatchedArgumentCountTooltip(parameters, expressions); + } boolean varargs = candidateInfo.getApplicabilityLevel() == MethodCandidateInfo.ApplicabilityLevel.VARARGS; int idx = ArrayUtil.find(expressions, wrongArg); PsiType paramType = candidateInfo.getSubstitutor().substitute(PsiTypesUtil.getParameterType(parameters, idx, varargs)); @@ -719,13 +714,13 @@ public final class HighlightMethodUtil { PsiSubstitutor substitutor, PsiParameter @NotNull [] parameters, boolean varargs) { - if ((parameters.length == 0 || !parameters[parameters.length - 1].isVarArgs()) && parameters.length != expressions.length) { + if ((parameters.length == 0 || !parameters[parameters.length - 1].isVarArgs()) && parameters.length > expressions.length) { return Collections.emptyList(); } List result = new ArrayList<>(); for (int i = 0; i < Math.max(parameters.length, expressions.length); i++) { - if (!assignmentCompatible(i, parameters, expressions, substitutor, varargs)) { + if (parameters.length == 0 || !assignmentCompatible(i, parameters, expressions, substitutor, varargs)) { result.add(i < expressions.length ? expressions[i] : null); } } @@ -811,7 +806,7 @@ public final class HighlightMethodUtil { WrapObjectWithOptionalOfNullableFix.REGISTAR.registerCastActions(candidates, methodCall, info, fixRange); WrapExpressionFix.registerWrapAction(candidates, list.getExpressions(), info, fixRange); PermuteArgumentsFix.registerFix(info, methodCall, candidates, fixRange); - registerChangeParameterClassFix(methodCall, list, info); + registerChangeParameterClassFix(methodCall, list, info, fixRange); if (candidates.length == 0 && info != null) { UnresolvedReferenceQuickFixProvider.registerReferenceFixes(methodCall.getMethodExpression(), new QuickFixActionRegistrarImpl(info)); } @@ -870,10 +865,11 @@ public final class HighlightMethodUtil { } toolTip = XmlStringUtil.escapeString(description); } + TextRange fixRange = getFixRange(elementToHighlight); HighlightInfo info = HighlightInfo.newHighlightInfo(highlightInfoType).range(elementToHighlight).description(description).escapedToolTip(toolTip).create(); if (!resolveResult.isAccessible() && resolveResult.isStaticsScopeCorrect() && methodCandidate2 != null) { - HighlightFixUtil.registerAccessQuickFixAction((PsiJvmMember)element, referenceToMethod, info, resolveResult.getCurrentFileResolveScope()); + HighlightFixUtil.registerAccessQuickFixAction((PsiJvmMember)element, referenceToMethod, info, resolveResult.getCurrentFileResolveScope(), fixRange); } if (methodCandidate2 == null) { registerMethodCallIntentions(info, methodCall, list, resolveHelper); @@ -881,14 +877,12 @@ public final class HighlightMethodUtil { if (element != null && !resolveResult.isStaticsScopeCorrect()) { HighlightFixUtil.registerStaticProblemQuickFixAction(element, info, referenceToMethod); } - - TextRange fixRange = getFixRange(elementToHighlight); CastMethodArgumentFix.REGISTRAR.registerCastActions(candidates, methodCall, info, fixRange); WrapWithAdapterMethodCallFix.registerCastActions(candidates, methodCall, info, fixRange); WrapObjectWithOptionalOfNullableFix.REGISTAR.registerCastActions(candidates, methodCall, info, fixRange); WrapExpressionFix.registerWrapAction(candidates, list.getExpressions(), info, fixRange); PermuteArgumentsFix.registerFix(info, methodCall, candidates, fixRange); - registerChangeParameterClassFix(methodCall, list, info); + registerChangeParameterClassFix(methodCall, list, info, fixRange); return info; } @@ -933,7 +927,7 @@ public final class HighlightMethodUtil { if (resolve instanceof PsiClass && ((PsiClass)resolve).getContainingClass() != null && !((PsiClass)resolve).hasModifierProperty(PsiModifier.STATIC)) { - QuickFixAction.registerQuickFixActions(highlightInfo, null, JvmElementActionFactories.createModifierActions((PsiClass)resolve, MemberRequestsKt.modifierRequest(JvmModifier.STATIC, true))); + QuickFixAction.registerQuickFixActions(highlightInfo, fixRange, JvmElementActionFactories.createModifierActions((PsiClass)resolve, MemberRequestsKt.modifierRequest(JvmModifier.STATIC, true))); } } else if (qualifierExpression instanceof PsiSuperExpression && ((PsiSuperExpression)qualifierExpression).getQualifier() == null) { @@ -958,7 +952,7 @@ public final class HighlightMethodUtil { AddTypeArgumentsFix.REGISTRAR.registerCastActions(methodCandidates, methodCall, highlightInfo, fixRange); CandidateInfo[] candidates = resolveHelper.getReferencedMethodCandidates(methodCall, true); - ChangeStringLiteralToCharInMethodCallFix.registerFixes(candidates, methodCall, highlightInfo); + ChangeStringLiteralToCharInMethodCallFix.registerFixes(candidates, methodCall, highlightInfo, fixRange); WrapWithAdapterMethodCallFix.registerCastActions(methodCandidates, methodCall, highlightInfo, fixRange); QuickFixAction.registerQuickFixAction(highlightInfo, fixRange, QUICK_FIX_FACTORY.createReplaceAddAllArrayToCollectionFix(methodCall)); @@ -966,10 +960,10 @@ public final class HighlightMethodUtil { MethodReturnFixFactory.INSTANCE.registerCastActions(methodCandidates, methodCall, highlightInfo, fixRange); WrapExpressionFix.registerWrapAction(methodCandidates, list.getExpressions(), highlightInfo, fixRange); QualifyThisArgumentFix.registerQuickFixAction(methodCandidates, methodCall, highlightInfo, fixRange); - registerMethodAccessLevelIntentions(methodCandidates, methodCall, list, highlightInfo); + registerMethodAccessLevelIntentions(methodCandidates, methodCall, list, highlightInfo, fixRange); if (!PermuteArgumentsFix.registerFix(highlightInfo, methodCall, methodCandidates, fixRange) && - !MoveParenthesisFix.registerFix(highlightInfo, methodCall, methodCandidates)) { + !MoveParenthesisFix.registerFix(highlightInfo, methodCall, methodCandidates, fixRange)) { registerChangeMethodSignatureFromUsageIntentions(methodCandidates, list, highlightInfo, fixRange); } @@ -985,17 +979,19 @@ public final class HighlightMethodUtil { registerUsageFixes(methodCall, highlightInfo, fixRange); RemoveRedundantArgumentsFix.registerIntentions(methodCandidates, list, highlightInfo, fixRange); - registerChangeParameterClassFix(methodCall, list, highlightInfo); + registerChangeParameterClassFix(methodCall, list, highlightInfo, fixRange); } private static void registerMethodAccessLevelIntentions(CandidateInfo @NotNull [] methodCandidates, @NotNull PsiMethodCallExpression methodCall, @NotNull PsiExpressionList exprList, - @Nullable HighlightInfo highlightInfo) { + @Nullable HighlightInfo highlightInfo, + TextRange fixRange) { for (CandidateInfo methodCandidate : methodCandidates) { PsiMethod method = (PsiMethod)methodCandidate.getElement(); if (!methodCandidate.isAccessible() && PsiUtil.isApplicable(method, methodCandidate.getSubstitutor(), exprList)) { - HighlightFixUtil.registerAccessQuickFixAction(method, methodCall.getMethodExpression(), highlightInfo, methodCandidate.getCurrentFileResolveScope()); + HighlightFixUtil.registerAccessQuickFixAction(method, methodCall.getMethodExpression(), highlightInfo, methodCandidate.getCurrentFileResolveScope(), + fixRange); } } } @@ -1053,8 +1049,7 @@ public final class HighlightMethodUtil { PsiExpression[] expressions = list.getExpressions(); if ((parameters.length == 0 || !parameters[parameters.length - 1].isVarArgs()) && parameters.length != expressions.length) { - return HtmlChunk.text(JavaAnalysisBundle.message("arguments.count.mismatch", parameters.length, expressions.length)) - .wrapWith("html").toString(); + return createMismatchedArgumentCountTooltip(parameters, expressions); } HtmlBuilder message = new HtmlBuilder(); @@ -1065,6 +1060,12 @@ public final class HighlightMethodUtil { return message.wrapWithHtmlBody().toString(); } + @NotNull + private static @NlsContexts.Tooltip String createMismatchedArgumentCountTooltip(PsiParameter @NotNull [] parameters, PsiExpression[] expressions) { + return HtmlChunk.text(JavaAnalysisBundle.message("arguments.count.mismatch", parameters.length, expressions.length)) + .wrapWith("html").toString(); + } + @NotNull private static HtmlChunk getTypeMismatchErrorHtml(@Nls String errorMessage) { if (errorMessage == null) { @@ -1682,7 +1683,7 @@ public final class HighlightMethodUtil { String description = HighlightUtil.accessProblemDescription(classReference, aClass, typeResolveResult); PsiElement element = ObjectUtils.notNull(classReference.getReferenceNameElement(), classReference); HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(element).descriptionAndTooltip(description).create(); - HighlightFixUtil.registerAccessQuickFixAction(aClass, classReference, info, null); + HighlightFixUtil.registerAccessQuickFixAction(aClass, classReference, info, null, null); holder.add(info); return; } @@ -1749,7 +1750,6 @@ public final class HighlightMethodUtil { catch (IndexNotReadyException ignored) { } - PsiElement infoElement = list.getTextLength() > 0 ? list : constructorCall; if (constructor == null) { String name = aClass.getName(); name += buildArgTypesList(list); @@ -1757,7 +1757,7 @@ public final class HighlightMethodUtil { HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(list).descriptionAndTooltip(description).navigationShift(+1).create(); if (info != null) { WrapExpressionFix.registerWrapAction(results, list.getExpressions(), info, getFixRange(list)); - registerFixesOnInvalidConstructorCall(constructorCall, classReference, list, aClass, constructors, results, infoElement, info); + registerFixesOnInvalidConstructorCall(constructorCall, classReference, list, aClass, constructors, results, info); holder.add(info); } } @@ -1773,7 +1773,7 @@ public final class HighlightMethodUtil { if (constructorCall instanceof PsiNewExpression) { methodCandidates = resolveHelper.getReferencedMethodCandidates((PsiCallExpression)constructorCall, true); } - registerFixesOnInvalidConstructorCall(constructorCall, classReference, list, aClass, constructors, methodCandidates, infoElement, info); + registerFixesOnInvalidConstructorCall(constructorCall, classReference, list, aClass, constructors, methodCandidates, info); registerMethodReturnFixAction(info, result, constructorCall); holder.add(info); } @@ -1822,22 +1822,22 @@ public final class HighlightMethodUtil { @NotNull PsiClass aClass, PsiMethod @NotNull [] constructors, JavaResolveResult @NotNull [] results, - @NotNull PsiElement infoElement, @NotNull final HighlightInfo info) { + TextRange fixRange = getFixRange(list); if (classReference != null) { - ConstructorParametersFixer.registerFixActions(classReference, constructorCall, info, getFixRange(infoElement)); - ChangeTypeArgumentsFix.registerIntentions(results, list, info, aClass); - ConvertDoubleToFloatFix.registerIntentions(results, list, info, null); + ConstructorParametersFixer.registerFixActions(classReference, constructorCall, info, fixRange); + ChangeTypeArgumentsFix.registerIntentions(results, list, info, aClass, fixRange); + ConvertDoubleToFloatFix.registerIntentions(results, list, info, fixRange); } - ChangeStringLiteralToCharInMethodCallFix.registerFixes(constructors, constructorCall, info); - QuickFixAction.registerQuickFixAction(info, getFixRange(list), QUICK_FIX_FACTORY.createSurroundWithArrayFix(constructorCall,null)); - if (!PermuteArgumentsFix.registerFix(info, constructorCall, toMethodCandidates(results), getFixRange(list))) { - registerChangeMethodSignatureFromUsageIntentions(results, list, info, null); + ChangeStringLiteralToCharInMethodCallFix.registerFixes(constructors, constructorCall, info, fixRange); + QuickFixAction.registerQuickFixAction(info, fixRange, QUICK_FIX_FACTORY.createSurroundWithArrayFix(constructorCall, null)); + if (!PermuteArgumentsFix.registerFix(info, constructorCall, toMethodCandidates(results), fixRange)) { + registerChangeMethodSignatureFromUsageIntentions(results, list, info, fixRange); } QuickFixAction.registerQuickFixActions( info, constructorCall.getTextRange(), QUICK_FIX_FACTORY.createCreateConstructorFromUsageFixes(constructorCall) ); - registerChangeParameterClassFix(constructorCall, list, info); + registerChangeParameterClassFix(constructorCall, list, info, fixRange); } private static HighlightInfo buildAccessProblem(@NotNull PsiJavaCodeReferenceElement ref, @@ -1846,7 +1846,7 @@ public final class HighlightMethodUtil { String description = HighlightUtil.accessProblemDescription(ref, resolved, result); HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(ref).descriptionAndTooltip(description).navigationShift(+1).create(); if (result.isStaticsScopeCorrect()) { - HighlightFixUtil.registerAccessQuickFixAction(resolved, ref, info, result.getCurrentFileResolveScope()); + HighlightFixUtil.registerAccessQuickFixAction(resolved, ref, info, result.getCurrentFileResolveScope(), null); } return info; } @@ -1883,7 +1883,7 @@ public final class HighlightMethodUtil { private static void registerChangeParameterClassFix(@NotNull PsiCall methodCall, @NotNull PsiExpressionList list, - @Nullable HighlightInfo highlightInfo) { + @Nullable HighlightInfo highlightInfo, TextRange fixRange) { final JavaResolveResult result = methodCall.resolveMethodGenerics(); PsiMethod method = (PsiMethod)result.getElement(); final PsiSubstitutor substitutor = result.getSubstitutor(); @@ -1904,7 +1904,7 @@ public final class HighlightMethodUtil { if (parameterClass == null || expressionClass == null) continue; if (expressionClass instanceof PsiAnonymousClass) continue; if (expressionClass.isInheritor(parameterClass, true)) continue; - QuickFixAction.registerQuickFixAction(highlightInfo, QUICK_FIX_FACTORY.createChangeParameterClassFix(expressionClass, (PsiClassType)parameterType)); + QuickFixAction.registerQuickFixAction(highlightInfo, fixRange, QUICK_FIX_FACTORY.createChangeParameterClassFix(expressionClass, (PsiClassType)parameterType)); } } diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java index 16448b6df6a4..22330ada6452 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java @@ -3065,7 +3065,7 @@ public final class HighlightUtil { problem.second.forEach(fix -> QuickFixAction.registerQuickFixAction(info, fix)); } else if (result.isStaticsScopeCorrect() && resolved instanceof PsiJvmMember) { - HighlightFixUtil.registerAccessQuickFixAction((PsiJvmMember)resolved, ref, info, result.getCurrentFileResolveScope()); + HighlightFixUtil.registerAccessQuickFixAction((PsiJvmMember)resolved, ref, info, result.getCurrentFileResolveScope(), null); if (ref instanceof PsiReferenceExpression) { QuickFixAction.registerQuickFixAction(info, getFixFactory().createRenameWrongRefFix((PsiReferenceExpression)ref)); } diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java index b6793286eca8..70a16bac21be 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java @@ -1527,7 +1527,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh if (method instanceof PsiJvmMember && !result.isAccessible()) { String accessProblem = HighlightUtil.accessProblemDescription(expression, method, result); HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(accessProblem).create(); - HighlightFixUtil.registerAccessQuickFixAction((PsiJvmMember)method, expression, info, result.getCurrentFileResolveScope()); + HighlightFixUtil.registerAccessQuickFixAction((PsiJvmMember)method, expression, info, result.getCurrentFileResolveScope(), null); myHolder.add(info); } else { diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeStringLiteralToCharInMethodCallFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeStringLiteralToCharInMethodCallFix.java index 6ac588558460..8b83e5aa2699 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeStringLiteralToCharInMethodCallFix.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeStringLiteralToCharInMethodCallFix.java @@ -1,18 +1,4 @@ -/* - * Copyright 2000-2014 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.codeInsight.daemon.impl.quickfix; import com.intellij.codeInsight.daemon.QuickFixBundle; @@ -24,6 +10,7 @@ import com.intellij.codeInsight.intention.impl.BaseIntentionAction; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.infos.CandidateInfo; @@ -105,7 +92,7 @@ public final class ChangeStringLiteralToCharInMethodCallFix implements Intention } public static void registerFixes(final PsiMethod @NotNull [] candidates, @NotNull final PsiConstructorCall call, - @NotNull final HighlightInfo out) { + @NotNull final HighlightInfo out, TextRange fixRange) { final Set literals = new HashSet<>(); if (call.getArgumentList() == null) { return; @@ -115,13 +102,14 @@ public final class ChangeStringLiteralToCharInMethodCallFix implements Intention exactMatch |= findMatchingExpressions(call.getArgumentList().getExpressions(), method, literals); } if (! exactMatch) { - processLiterals(literals, call, out); + processLiterals(literals, call, out, fixRange); } } public static void registerFixes(final CandidateInfo @NotNull [] candidates, @NotNull final PsiMethodCallExpression methodCall, - @Nullable final HighlightInfo info) { + @Nullable final HighlightInfo info, + @Nullable TextRange fixRange) { if (info == null) return; final Set literals = new HashSet<>(); boolean exactMatch = false; @@ -132,16 +120,16 @@ public final class ChangeStringLiteralToCharInMethodCallFix implements Intention } } if (!exactMatch) { - processLiterals(literals, methodCall, info); + processLiterals(literals, methodCall, info, fixRange); } } private static void processLiterals(@NotNull final Set literals, @NotNull final PsiCall call, - @NotNull final HighlightInfo info) { + @NotNull final HighlightInfo info, TextRange fixRange) { for (PsiLiteralExpression literal : literals) { final ChangeStringLiteralToCharInMethodCallFix fix = new ChangeStringLiteralToCharInMethodCallFix(literal, call); - QuickFixAction.registerQuickFixAction(info, fix); + QuickFixAction.registerQuickFixAction(info, fixRange, fix); } } diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeTypeArgumentsFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeTypeArgumentsFix.java index 86ecc9d4e4ff..def864914838 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeTypeArgumentsFix.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeTypeArgumentsFix.java @@ -1,4 +1,4 @@ -// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.codeInsight.daemon.impl.quickfix; import com.intellij.codeInsight.daemon.impl.HighlightInfo; @@ -9,6 +9,7 @@ import com.intellij.java.analysis.JavaAnalysisBundle; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.codeStyle.JavaCodeStyleManager; @@ -120,11 +121,11 @@ public class ChangeTypeArgumentsFix implements IntentionAction, HighPriorityActi public static void registerIntentions(JavaResolveResult @NotNull [] candidates, @NotNull PsiExpressionList list, @Nullable HighlightInfo highlightInfo, - PsiClass psiClass) { + PsiClass psiClass, TextRange fixRange) { if (candidates.length == 0) return; PsiExpression[] expressions = list.getExpressions(); for (JavaResolveResult candidate : candidates) { - registerIntention(expressions, highlightInfo, psiClass, candidate, list); + registerIntention(expressions, highlightInfo, psiClass, candidate, list, fixRange); } } @@ -132,12 +133,13 @@ public class ChangeTypeArgumentsFix implements IntentionAction, HighPriorityActi @Nullable HighlightInfo highlightInfo, PsiClass psiClass, @NotNull JavaResolveResult candidate, - @NotNull PsiElement context) { + @NotNull PsiElement context, + TextRange fixRange) { if (!candidate.isStaticsScopeCorrect()) return; PsiMethod method = (PsiMethod)candidate.getElement(); if (method != null && BaseIntentionAction.canModify(method)) { final ChangeTypeArgumentsFix fix = new ChangeTypeArgumentsFix(method, psiClass, expressions, context); - QuickFixAction.registerQuickFixAction(highlightInfo, null, fix); + QuickFixAction.registerQuickFixAction(highlightInfo, fixRange, fix); } } diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MoveParenthesisFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MoveParenthesisFix.java index 419dba36848e..329ab1a9f305 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MoveParenthesisFix.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MoveParenthesisFix.java @@ -1,4 +1,4 @@ -// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.codeInsight.daemon.impl.quickfix; import com.intellij.codeInsight.daemon.QuickFixBundle; @@ -11,6 +11,7 @@ import com.intellij.codeInspection.util.IntentionFamilyName; import com.intellij.codeInspection.util.IntentionName; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; import com.intellij.psi.infos.CandidateInfo; import com.intellij.psi.util.PsiTreeUtil; @@ -97,7 +98,7 @@ public final class MoveParenthesisFix implements IntentionAction, HighPriorityAc return parentCopy; } - public static boolean registerFix(HighlightInfo info, PsiCallExpression callExpression, final CandidateInfo[] candidates) { + public static boolean registerFix(HighlightInfo info, PsiCallExpression callExpression, final CandidateInfo[] candidates, TextRange fixRange) { PsiExpressionList parent = ObjectUtils.tryCast(callExpression.getParent(), PsiExpressionList.class); if (parent == null) return false; PsiCallExpression parentCall = ObjectUtils.tryCast(parent.getParent(), PsiCallExpression.class); @@ -131,7 +132,7 @@ public final class MoveParenthesisFix implements IntentionAction, HighPriorityAc fix = new MoveParenthesisFix(parentCall, pos, shift); } if (fix == null) return false; - QuickFixAction.registerQuickFixAction(info, null, fix); + QuickFixAction.registerQuickFixAction(info, fixRange, fix); return true; } } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateMethodFromUsageFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateMethodFromUsageFix.java index bbd6ee35f8f0..498da15c11c7 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateMethodFromUsageFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateMethodFromUsageFix.java @@ -1,13 +1,11 @@ -// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.codeInsight.daemon.impl.quickfix; import com.intellij.codeInsight.CodeInsightUtilCore; import com.intellij.codeInsight.ExpectedTypeInfo; -import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerEx; import com.intellij.codeInsight.template.Template; import com.intellij.codeInsight.template.TemplateBuilderImpl; import com.intellij.codeInsight.template.TemplateEditingAdapter; -import com.intellij.lang.annotation.HighlightSeverity; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; @@ -16,7 +14,6 @@ import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Pair; -import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; @@ -42,23 +39,13 @@ public final class CreateMethodFromUsageFix { return false; } - public static boolean hasErrorsInArgumentList(final PsiMethodCallExpression call) { - Project project = call.getProject(); + public static boolean hasVoidInArgumentList(final PsiMethodCallExpression call) { PsiExpressionList argumentList = call.getArgumentList(); for (PsiExpression expression : argumentList.getExpressions()) { PsiType type = expression.getType(); if (type == null || PsiType.VOID.equals(type)) return true; } - Document document = PsiDocumentManager.getInstance(project).getDocument(call.getContainingFile()); - if (document == null) return true; - - final TextRange argRange = argumentList.getTextRange(); - return !DaemonCodeAnalyzerEx.processHighlights(document, project, HighlightSeverity.ERROR, - //strictly inside arg list - argRange.getStartOffset() + 1, - argRange.getEndOffset() - 1, - info -> !(info.getActualStartOffset() > argRange.getStartOffset() && - info.getActualEndOffset() < argRange.getEndOffset())); + return false; } public static PsiMethod createMethod(PsiClass targetClass, diff --git a/java/java-impl/src/com/intellij/lang/java/request/CreateMethodFromJavaUsageRequest.kt b/java/java-impl/src/com/intellij/lang/java/request/CreateMethodFromJavaUsageRequest.kt index 4585deb90f8c..c52bd4bfa905 100644 --- a/java/java-impl/src/com/intellij/lang/java/request/CreateMethodFromJavaUsageRequest.kt +++ b/java/java-impl/src/com/intellij/lang/java/request/CreateMethodFromJavaUsageRequest.kt @@ -1,8 +1,8 @@ -// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.lang.java.request import com.intellij.codeInsight.daemon.impl.quickfix.CreateFromUsageUtils.guessExpectedTypes -import com.intellij.codeInsight.daemon.impl.quickfix.CreateMethodFromUsageFix.hasErrorsInArgumentList +import com.intellij.codeInsight.daemon.impl.quickfix.CreateMethodFromUsageFix.hasVoidInArgumentList import com.intellij.lang.jvm.JvmModifier import com.intellij.lang.jvm.actions.CreateMethodRequest import com.intellij.psi.* @@ -16,7 +16,7 @@ internal class CreateMethodFromJavaUsageRequest( ) : CreateExecutableFromJavaUsageRequest(methodCall, modifiers), CreateMethodRequest { override fun isValid() = super.isValid() && call.let { - it.methodExpression.referenceName != null && !hasErrorsInArgumentList(it) + it.methodExpression.referenceName != null && !hasVoidInArgumentList(it) } override fun getMethodName() = call.methodExpression.referenceName!! diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/afterManyArgs.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/afterManyArgs.java new file mode 100644 index 000000000000..3229b480f204 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/afterManyArgs.java @@ -0,0 +1,11 @@ +// "Change type arguments to " "true" +class Generic { + Generic(E arg, E arg1, int a) { + } +} + +class Tester { + void method() { + new Generic("hi", "hi2", 42); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/beforeManyArgs.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/beforeManyArgs.java new file mode 100644 index 000000000000..c50222172568 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/beforeManyArgs.java @@ -0,0 +1,11 @@ +// "Change type arguments to " "true" +class Generic { + Generic(E arg, E arg1, int a) { + } +} + +class Tester { + void method() { + new Generic("hi", "hi2", 42); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/moveParenthesis/beforeShiftLeft.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/moveParenthesis/beforeShiftLeft.java index 3be06e77e00b..833fbc92b5cd 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/moveParenthesis/beforeShiftLeft.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/moveParenthesis/beforeShiftLeft.java @@ -9,6 +9,6 @@ public class Example { } void test() { - foo(bar("hello", true)); + foo(bar("hello", true)); } } \ No newline at end of file