[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
This commit is contained in:
Anna Kozlova
2021-11-23 12:33:47 +00:00
committed by intellij-monorepo-bot
parent 17504c005a
commit 6a2a667f6b
12 changed files with 102 additions and 100 deletions
@@ -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<IntentionAction> 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));
}
}
}
@@ -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<PsiExpression> 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));
}
}
@@ -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));
}
@@ -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 {
@@ -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<PsiLiteralExpression> 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<PsiLiteralExpression> 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<? extends PsiLiteralExpression> 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);
}
}
@@ -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);
}
}
@@ -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;
}
}
@@ -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,
@@ -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<PsiMethodCallExpression>(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!!
@@ -0,0 +1,11 @@
// "Change type arguments to <String>" "true"
class Generic<E> {
Generic(E arg, E arg1, int a) {
}
}
class Tester {
void method() {
new Generic<String>("hi", "hi2", 42);
}
}
@@ -0,0 +1,11 @@
// "Change type arguments to <String>" "true"
class Generic<E> {
Generic(E arg, E arg1, int a) {
}
}
class Tester {
void method() {
new Generic<Integer>("hi", <caret>"hi2", 42);
}
}
@@ -9,6 +9,6 @@ public class Example {
}
void test() {
foo(bar("hello"<caret>, true));
foo(bar("hello", t<caret>rue));
}
}