[java-inspections] IDEA-342216 Fix place for call inspection ExtractMethodRecommenderInspection

GitOrigin-RevId: 507f2d2fabb98a46e7a519a9edf904182fe5b3fb
This commit is contained in:
Mikhail Pyltsin
2024-01-04 16:15:41 +00:00
committed by intellij-monorepo-bot
parent f3c91b6516
commit 5568197815
6 changed files with 223 additions and 7 deletions
@@ -110,7 +110,8 @@ public final class ExtractMethodRecommenderInspection extends AbstractBaseJavaLo
}
}
List<LocalQuickFix> fixes = new ArrayList<>();
fixes.add(new ExtractMethodFix(from, count, output, inputVariables));
ExtractMethodFix extractFix = new ExtractMethodFix(from, count, output, inputVariables);
fixes.add(extractFix);
if (inputVariables.size() > 1) {
fixes.add(LocalQuickFix.from(new UpdateInspectionOptionFix(
ExtractMethodRecommenderInspection.this, "maxParameters",
@@ -128,9 +129,10 @@ public final class ExtractMethodRecommenderInspection extends AbstractBaseJavaLo
if (firstLineBreak > -1) {
textRange = TextRange.from(textRange.getStartOffset(), firstLineBreak);
TextRange firstStatementRange = statements[from].getTextRangeInParent();
if (firstStatementRange.getStartOffset() == textRange.getStartOffset() &&
if (firstStatementRange.getStartOffset() == textRange.getStartOffset() &&
firstStatementRange.getEndOffset() >= textRange.getEndOffset()) {
anchor = statements[from];
extractFix.shouldUseParent();
textRange = textRange.shiftLeft(textRange.getStartOffset());
}
}
@@ -440,6 +442,8 @@ public final class ExtractMethodRecommenderInspection extends AbstractBaseJavaLo
private final String myOutputName;
private final String myInputNames;
private boolean shouldUseParent = false;
private ExtractMethodFix(int from, int length, PsiVariable variable, List<PsiVariable> inputVariables) {
myFrom = from;
myLength = length;
@@ -454,7 +458,11 @@ public final class ExtractMethodRecommenderInspection extends AbstractBaseJavaLo
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiCodeBlock block = ObjectUtils.tryCast(descriptor.getStartElement(), PsiCodeBlock.class);
PsiElement element = descriptor.getStartElement();
if (shouldUseParent) {
element = element.getParent();
}
PsiCodeBlock block = ObjectUtils.tryCast(element, PsiCodeBlock.class);
TextRange range = getRange(block);
if (range == null) return;
new MethodExtractor().doExtract(block.getContainingFile(), range.shiftRight(block.getTextRange().getStartOffset()));
@@ -488,5 +496,9 @@ public final class ExtractMethodRecommenderInspection extends AbstractBaseJavaLo
return new IntentionPreviewInfo.Html(
JavaAnalysisBundle.message("inspection.extract.method.preview.html", myLength,input,myOutputName));
}
private void shouldUseParent() {
shouldUseParent = true;
}
}
}
@@ -0,0 +1,55 @@
class Test {
public static void main(String[] args) {
}
private static void test(Object o) {
for (int i = 0; i < 10; i++) {
System.out.println(1);
System.out.println(2);
System.out.println(3);
System.out.println(4);
System.out.println(5);
System.out.println(6);
System.out.println(7);
System.out.println(8);
System.out.println(9);
System.out.println(10);
<weak_warning descr="It's possible to extract method returning 's' from a long surrounding method">String <caret>s;</weak_warning>
if (o instanceof String s2 && s2.length() == 1) {
s = "1";
} else if (o instanceof String s2 && s2.length() == 2) {
s = "2";
} else if (o instanceof String s2 && s2.length() == 3) {
s = "3";
} else if (o instanceof String s2 && s2.length() == 4) {
s = "4";
} else if (o instanceof String s2 && s2.length() == 5) {
s = "5";
} else if (o instanceof String s2 && s2.length() == 6) {
s = "6";
} else if (o instanceof String s2 && s2.length() == 7) {
s = "7";
} else if (o instanceof String s2 && s2.length() == 8) {
s = "8";
} else {
s = "null";
}
System.out.println(s);
System.out.println(s);
System.out.println(s);
System.out.println(s);
System.out.println(s);
System.out.println(s);
System.out.println(s);
System.out.println(s);
System.out.println(s);
System.out.println(s);
System.out.println(s);
System.out.println(s);
System.out.println(s);
}
}
}
@@ -0,0 +1,24 @@
import java.util.ArrayList;
import java.util.List;
class Test {
public static void main(String[] args) {
}
List<List<String>> simpleWithPrecedingComment() {
<weak_warning descr="It's possible to extract method returning 'list' from a long surrounding method">// Cre<caret>ate list</weak_warning>
// Comment
List<String> list = new ArrayList<>();
list.add("one");
list.add("two");
list.add("three");
list.add("four");
List<String> list2 = new ArrayList<>();
list2.add("v1");
list2.add("v2");
list2.add("v3");
list2.add("v4");
return List.of(list, list2);
}
}
@@ -0,0 +1,63 @@
import org.jetbrains.annotations.NotNull;
class Test {
public static void main(String[] args) {
}
private static void test(Object o) {
for (int i = 0; i < 10; i++) {
System.out.println(1);
System.out.println(2);
System.out.println(3);
System.out.println(4);
System.out.println(5);
System.out.println(6);
System.out.println(7);
System.out.println(8);
System.out.println(9);
System.out.println(10);
String s = getString<caret>(o);
System.out.println(s);
System.out.println(s);
System.out.println(s);
System.out.println(s);
System.out.println(s);
System.out.println(s);
System.out.println(s);
System.out.println(s);
System.out.println(s);
System.out.println(s);
System.out.println(s);
System.out.println(s);
System.out.println(s);
}
}
@NotNull
private static String getString(Object o) {
String s;
if (o instanceof String s2 && s2.length() == 1) {
s = "1";
} else if (o instanceof String s2 && s2.length() == 2) {
s = "2";
} else if (o instanceof String s2 && s2.length() == 3) {
s = "3";
} else if (o instanceof String s2 && s2.length() == 4) {
s = "4";
} else if (o instanceof String s2 && s2.length() == 5) {
s = "5";
} else if (o instanceof String s2 && s2.length() == 6) {
s = "6";
} else if (o instanceof String s2 && s2.length() == 7) {
s = "7";
} else if (o instanceof String s2 && s2.length() == 8) {
s = "8";
} else {
s = "null";
}
return s;
}
}
@@ -0,0 +1,32 @@
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
class Test {
public static void main(String[] args) {
}
List<List<String>> simpleWithPrecedingComment() {
// Create list
// Comment
List<String> list = getStrings();
List<String> list2 = new ArrayList<>();
list2.add("v1");
list2.add("v2");
list2.add("v3");
list2.add("v4");
return List.of(list, list2);
}
@NotNull
private static List<String> getStrings() {
List<String> list = new ArrayList<>();
list.add("one");
list.add("two");
list.add("three");
list.add("four");
return list;
}
}
@@ -2,15 +2,13 @@
package com.intellij.refactoring.extractMethod;
import com.intellij.JavaTestUtil;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInspection.RedundantSuppressInspection;
import com.intellij.java.JavaBundle;
import com.intellij.testFramework.LightProjectDescriptor;
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ExtractMethodRecommenderInspectionTest extends LightJavaCodeInsightFixtureTestCase {
public void testExtractMethodRecommender() {
ExtractMethodRecommenderInspection inspection = new ExtractMethodRecommenderInspection();
@@ -35,6 +33,38 @@ public class ExtractMethodRecommenderInspectionTest extends LightJavaCodeInsight
myFixture.checkHighlighting();
}
/**
* Test that quickfix can extract if anchor is moved to the declaration
*/
public void testCallExtract() {
ExtractMethodRecommenderInspection inspection = new ExtractMethodRecommenderInspection();
inspection.minLength = 20;
myFixture.enableInspections(inspection);
myFixture.configureByFile(getTestName(false) + ".java");
myFixture.checkHighlighting();
IntentionAction intention = myFixture.getAvailableIntention(JavaBundle.message("intention.extract.method.text"));
assertNotNull(intention);
intention.invoke(getProject(), getEditor(), getFile());
myFixture.checkResultByFile("after" + getTestName(false) + ".java");
}
/**
* Based on {@link ExtractMethodRecommenderInspectionTest#testExtractMethodRecommender()}
* when the suggestion is placed on comments, even though this place is not really convenient.
* This method checks that quickfix works even for this place
*/
public void testCallExtractFirstNotDeclaration() {
ExtractMethodRecommenderInspection inspection = new ExtractMethodRecommenderInspection();
inspection.minLength = 10;
myFixture.enableInspections(inspection);
myFixture.configureByFile(getTestName(false) + ".java");
myFixture.checkHighlighting();
IntentionAction intention = myFixture.getAvailableIntention(JavaBundle.message("intention.extract.method.text"));
assertNotNull(intention);
intention.invoke(getProject(), getEditor(), getFile());
myFixture.checkResultByFile("after" + getTestName(false) + ".java");
}
@Override
protected @NotNull LightProjectDescriptor getProjectDescriptor() {
return JAVA_21;