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