java introduce parameter: optimization + progress (IDEA-251661)

postpone search for overriding methods until usages in current method is checked

GitOrigin-RevId: 1a68af844d1b590203f42a322812b0b065124f5d
This commit is contained in:
Anna Kozlova
2020-09-29 08:12:55 +00:00
committed by intellij-monorepo-bot
parent 86985147aa
commit c5adb3e2ee
5 changed files with 70 additions and 32 deletions
@@ -3,6 +3,9 @@
package com.intellij.refactoring.introduceParameter;
import com.intellij.codeInsight.generation.GenerateMembersUtil;
import com.intellij.java.JavaBundle;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.search.searches.OverridingMethodsSearch;
@@ -102,9 +105,6 @@ public final class Util {
final PsiParameter[] parameters = method.getParameterList().getParameters();
if (parameters.length == 0) return new TIntArrayList();
PsiMethod[] overridingMethods = OverridingMethodsSearch.search(method).toArray(PsiMethod.EMPTY_ARRAY);
final PsiMethod[] allMethods = ArrayUtil.append(overridingMethods, method);
final TIntHashSet suspects = new TIntHashSet();
expr.accept(new JavaRecursiveElementWalkingVisitor() {
@Override public void visitReferenceExpression(final PsiReferenceExpression expression) {
@@ -119,36 +119,48 @@ public final class Util {
}
});
final TIntIterator iterator = suspects.iterator();
while(iterator.hasNext()) {
final int paramNum = iterator.next();
for (PsiMethod psiMethod : allMethods) {
PsiParameter[] psiParameters = psiMethod.getParameterList().getParameters();
if (paramNum >= psiParameters.length) continue;
PsiParameter parameter = psiParameters[paramNum];
if (!ReferencesSearch.search(parameter, parameter.getResolveScope(), false).forEach(reference -> {
PsiElement element = reference.getElement();
boolean stillCanBeRemoved = false;
if (element != null) {
stillCanBeRemoved = isAncestor(expr, element, false) || PsiUtil.isInsideJavadocComment(getPhysical(element));
if (!stillCanBeRemoved && occurences != null) {
for (PsiExpression occurence : occurences) {
if (isAncestor(occurence, element, false)) {
stillCanBeRemoved = true;
break;
}
}
}
}
if (!stillCanBeRemoved) {
iterator.remove();
return false;
}
return true;
})) break;
}
removeUsed(method, expr, occurences, suspects);
if (suspects.isEmpty()) return new TIntArrayList();
if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(() -> {
OverridingMethodsSearch.search(method).forEach(psiMethod -> {
ReadAction.run(() -> removeUsed(psiMethod, expr, occurences, suspects));
return !suspects.isEmpty();
});
}, JavaBundle.message("progress.title.search.for.overriding.methods"), true, method.getProject())) {
return new TIntArrayList();
}
return new TIntArrayList(suspects.toArray());
}
private static void removeUsed(PsiMethod containingMethod, @NotNull PsiExpression expr,
PsiExpression @Nullable [] occurences,
TIntHashSet suspects) {
final TIntIterator iterator = suspects.iterator();
while (iterator.hasNext()) {
final int paramNum = iterator.next();
PsiParameter[] psiParameters = containingMethod.getParameterList().getParameters();
if (paramNum >= psiParameters.length) continue;
PsiParameter parameter = psiParameters[paramNum];
ReferencesSearch.search(parameter, parameter.getResolveScope(), false).forEach(reference -> {
PsiElement element = reference.getElement();
boolean stillCanBeRemoved = isAncestor(expr, element, false) || PsiUtil.isInsideJavadocComment(getPhysical(element));
if (!stillCanBeRemoved && occurences != null) {
for (PsiExpression occurence : occurences) {
if (isAncestor(occurence, element, false)) {
stillCanBeRemoved = true;
break;
}
}
}
if (!stillCanBeRemoved) {
iterator.remove();
return false;
}
return true;
});
}
}
}
@@ -0,0 +1,11 @@
public class Bar {
public int baz(byte blah1, int anObject) {
return anObject;
}
}
class S extends Bar {
public int baz(byte blah1, int anObject) {
System.out.println(blah1);
return super.baz((byte) 0, anObject); //To change body of overridden methods use File | Settings | File Templates.
}
}
@@ -0,0 +1,11 @@
public class Bar {
public int baz(byte blah, byte blah1, byte blah2) {
return <selection>blah + blah1 + blah2</selection>;
}
}
class S extends Bar {
public int baz(byte blah, byte blah1, byte blah2) {
System.out.println(blah1);
return super.baz((byte) 0, (byte) 0, (byte) 0); //To change body of overridden methods use File | Settings | File Templates.
}
}
@@ -210,6 +210,10 @@ public class IntroduceParameterTest extends LightRefactoringTestCase {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, true, false, false, false);
}
public void testRemoveParameterInHierarchy1() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, true, false, false, false);
}
public void testRemoveParameterWithJavadoc() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, true, false, false, false);
}
@@ -1052,7 +1052,7 @@ progress.title.looking.for.jdk.locations=Looking for JDK locations...
progress.title.looking.for.libraries=Looking for Libraries
progress.title.optimize.imports=Optimize Imports...
progress.title.preprocess.usages=Preprocess Usages
progress.title.search.for.overriding.methods=Search for Overriding Methods...
progress.title.search.for.overriding.methods=Search for overriding methods...
progress.title.searching.for.sub.classes=Searching for Sub-Classes
prompt.choose.base.class.of.the.hierarchy=Choose Base Class of the Hierarchy to Search In
prompt.create.non.existing.package=Package {0} does not exist.\nDo you want to create it?