From 8fd79a665c9490e2e819e8725c8373a7eae938a5 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Fri, 27 May 2022 13:44:01 +0200 Subject: [PATCH] [java-inspections] IDEA-294900 Remove repeating call fix on unresolved call error GitOrigin-RevId: 220979068250f873c725310dc8cf38a36d1e7fdf --- .../messages/JavaAnalysisBundle.properties | 4 +- .../impl/analysis/HighlightMethodUtil.java | 1 + .../impl/quickfix/RemoveRepeatingCallFix.java | 60 +++++++++++++++++++ .../removeRepeatingCall/afterSimple.java | 6 ++ .../afterWithParameters.java | 8 +++ .../removeRepeatingCall/beforeSimple.java | 6 ++ .../beforeWithDifferentParameters.java | 8 +++ .../beforeWithParameters.java | 8 +++ .../quickFix/RemoveRepeatingCallFixTest.java | 27 +++++++++ 9 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveRepeatingCallFix.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/removeRepeatingCall/afterSimple.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/removeRepeatingCall/afterWithParameters.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/removeRepeatingCall/beforeSimple.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/removeRepeatingCall/beforeWithDifferentParameters.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/removeRepeatingCall/beforeWithParameters.java create mode 100644 java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/quickFix/RemoveRepeatingCallFixTest.java diff --git a/java/java-analysis-api/resources/messages/JavaAnalysisBundle.properties b/java/java-analysis-api/resources/messages/JavaAnalysisBundle.properties index f5267bbf6b88..27477f44519f 100644 --- a/java/java-analysis-api/resources/messages/JavaAnalysisBundle.properties +++ b/java/java-analysis-api/resources/messages/JavaAnalysisBundle.properties @@ -615,4 +615,6 @@ intention.family.name.move.annotation.to.array=Move annotation to array inspection.redundant.requires.statement.message.transitive.dependencies.on.can.be.used.directly=Transitive dependencies on ''{0}'' can be used directly. inspection.redundant.requires.statement.message.module.unused=No usages of module packages are found. inspection.redundant.requires.statement.message.java.base.implicitly.required='java.base' is implicitly required. -reassign.variable.display.name=Reassigned variable \ No newline at end of file +reassign.variable.display.name=Reassigned variable +intention.family.name.remove.repeating.call=Remove repeating call +intention.name.remove.repeating.call=Remove repeating call ''{0}()'' \ No newline at end of file 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 3ab65343b609..3f90f3f6fe5c 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 @@ -815,6 +815,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); + QuickFixAction.registerQuickFixAction(info, fixRange, RemoveRepeatingCallFix.createFix(methodCall)); registerChangeParameterClassFix(methodCall, list, info, fixRange); if (candidates.length == 0 && info != null) { UnresolvedReferenceQuickFixProvider.registerReferenceFixes(methodCall.getMethodExpression(), new QuickFixActionRegistrarImpl(info)); diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveRepeatingCallFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveRepeatingCallFix.java new file mode 100644 index 000000000000..308b675d9ca1 --- /dev/null +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveRepeatingCallFix.java @@ -0,0 +1,60 @@ +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.codeInsight.daemon.impl.quickfix; + +import com.intellij.codeInsight.PsiEquivalenceUtil; +import com.intellij.codeInsight.daemon.impl.actions.IntentionActionWithFixAllOption; +import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement; +import com.intellij.java.analysis.JavaAnalysisBundle; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiMethodCallExpression; +import com.siyeh.ig.psiutils.MethodCallUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class RemoveRepeatingCallFix extends LocalQuickFixAndIntentionActionOnPsiElement implements IntentionActionWithFixAllOption { + private final String myMethodName; + + private RemoveRepeatingCallFix(PsiMethodCallExpression call, String methodName) { + super(call); + myMethodName = methodName; + } + + @Override + public void invoke(@NotNull Project project, + @NotNull PsiFile file, + @Nullable Editor editor, + @NotNull PsiElement startElement, + @NotNull PsiElement endElement) { + PsiMethodCallExpression call = (PsiMethodCallExpression)startElement; + PsiExpression qualifier = call.getMethodExpression().getQualifierExpression(); + if (qualifier == null) { + return; + } + call.replace(qualifier); + } + + @Override + public @NotNull String getText() { + return JavaAnalysisBundle.message("intention.name.remove.repeating.call", myMethodName); + } + + @Override + public @NotNull String getFamilyName() { + return JavaAnalysisBundle.message("intention.family.name.remove.repeating.call"); + } + + public static @Nullable RemoveRepeatingCallFix createFix(@NotNull PsiMethodCallExpression call) { + String name = call.getMethodExpression().getReferenceName(); + if (name == null) return null; + PsiMethodCallExpression qualifierCall = MethodCallUtils.getQualifierMethodCall(call); + if (qualifierCall == null) return null; + String qualifierName = qualifierCall.getMethodExpression().getReferenceName(); + if (!name.equals(qualifierName)) return null; + if (!PsiEquivalenceUtil.areElementsEquivalent(call.getArgumentList(), qualifierCall.getArgumentList())) return null; + return new RemoveRepeatingCallFix(call, name); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/removeRepeatingCall/afterSimple.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/removeRepeatingCall/afterSimple.java new file mode 100644 index 000000000000..ee35a0a924f3 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/removeRepeatingCall/afterSimple.java @@ -0,0 +1,6 @@ +// "Remove repeating call 'hashCode()'" "true" +class Test { + void test(Object obj) { + int x = obj.hashCode(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/removeRepeatingCall/afterWithParameters.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/removeRepeatingCall/afterWithParameters.java new file mode 100644 index 000000000000..29bd26cd3441 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/removeRepeatingCall/afterWithParameters.java @@ -0,0 +1,8 @@ +// "Remove repeating call 'equals()'" "true" +class Test { + void test(String s) { + if (s.equals("foo")) { + + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/removeRepeatingCall/beforeSimple.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/removeRepeatingCall/beforeSimple.java new file mode 100644 index 000000000000..6b708c47177d --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/removeRepeatingCall/beforeSimple.java @@ -0,0 +1,6 @@ +// "Remove repeating call 'hashCode()'" "true" +class Test { + void test(Object obj) { + int x = obj.hashCode().hashCode(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/removeRepeatingCall/beforeWithDifferentParameters.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/removeRepeatingCall/beforeWithDifferentParameters.java new file mode 100644 index 000000000000..1ac4af49dc24 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/removeRepeatingCall/beforeWithDifferentParameters.java @@ -0,0 +1,8 @@ +// "Remove repeating call 'equals()'" "false" +class Test { + void test(String s) { + if (s.equals("foo").equals("bar")) { + + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/removeRepeatingCall/beforeWithParameters.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/removeRepeatingCall/beforeWithParameters.java new file mode 100644 index 000000000000..5444fb164455 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/removeRepeatingCall/beforeWithParameters.java @@ -0,0 +1,8 @@ +// "Remove repeating call 'equals()'" "true" +class Test { + void test(String s) { + if (s.equals("foo").equals("foo")) { + + } + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/quickFix/RemoveRepeatingCallFixTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/quickFix/RemoveRepeatingCallFixTest.java new file mode 100644 index 000000000000..cbf69c1190d4 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/quickFix/RemoveRepeatingCallFixTest.java @@ -0,0 +1,27 @@ +/* + * Copyright 2000-2017 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. + */ +package com.intellij.java.codeInsight.daemon.quickFix; + +import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase; + +public class RemoveRepeatingCallFixTest extends LightQuickFixParameterizedTestCase { + + @Override + protected String getBasePath() { + return "/codeInsight/daemonCodeAnalyzer/quickFix/removeRepeatingCall"; + } + +}