mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-05 01:50:56 +07:00
Java: Prevent introducing parameter that contains subexpression replaced by another parameter (IDEA-180801)
This commit is contained in:
@@ -18,6 +18,7 @@ import com.intellij.refactoring.util.VariableData;
|
||||
import com.intellij.refactoring.util.duplicates.*;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -59,9 +60,12 @@ public class JavaDuplicatesExtractMethodProcessor extends ExtractMethodProcessor
|
||||
variableDatum.add(newData);
|
||||
}
|
||||
}
|
||||
Set<PsiVariable> parameterVariables = ContainerUtil.map2Set(variableDatum, data -> data.variable);
|
||||
List<VariableData> inputVariables = getInputVariables().getInputVariables();
|
||||
for (int i = variableDatum.size(); i < inputVariables.size(); i++) {
|
||||
variableDatum.add(inputVariables.get(i));
|
||||
for (VariableData data : inputVariables) {
|
||||
if (!parameterVariables.contains(data.variable)) {
|
||||
variableDatum.add(data);
|
||||
}
|
||||
}
|
||||
myVariableDatum = variableDatum.toArray(new VariableData[0]);
|
||||
}
|
||||
|
||||
@@ -145,6 +145,8 @@ public class ParametrizedDuplicates {
|
||||
if (myElements.length == 0) {
|
||||
return false;
|
||||
}
|
||||
matches = filterNestedSubexpressions(matches);
|
||||
|
||||
myUsagesList = new ArrayList<>();
|
||||
Map<PsiExpression, ClusterOfUsages> usagesMap = new THashMap<>();
|
||||
Set<Match> badMatches = new THashSet<>();
|
||||
@@ -185,6 +187,38 @@ public class ParametrizedDuplicates {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static List<Match> filterNestedSubexpressions(List<Match> matches) {
|
||||
Map<PsiExpression, Set<Match>> patternUsages = new THashMap<>();
|
||||
for (Match match : matches) {
|
||||
for (ExtractedParameter parameter : match.getExtractedParameters()) {
|
||||
for (PsiExpression patternUsage : parameter.myPatternUsages) {
|
||||
patternUsages.computeIfAbsent(patternUsage, k -> new THashSet<>()).add(match);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Set<Match> badMatches = new THashSet<>();
|
||||
for (Map.Entry<PsiExpression, Set<Match>> entry : patternUsages.entrySet()) {
|
||||
PsiExpression patternUsage = entry.getKey();
|
||||
Set<Match> patternMatches = entry.getValue();
|
||||
for (PsiExpression maybeNestedUsage : patternUsages.keySet()) {
|
||||
if (patternUsage == maybeNestedUsage) {
|
||||
continue;
|
||||
}
|
||||
if (PsiTreeUtil.isAncestor(patternUsage, maybeNestedUsage, true)) {
|
||||
badMatches.addAll(patternMatches);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!badMatches.isEmpty()) {
|
||||
matches = new ArrayList<>(matches);
|
||||
matches.removeAll(badMatches);
|
||||
}
|
||||
return matches;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static List<ClusterOfUsages> getUsagesInMatch(@NotNull Map<PsiExpression, ClusterOfUsages> usagesMap, @NotNull Match match) {
|
||||
List<ClusterOfUsages> result = new ArrayList<>();
|
||||
@@ -217,7 +251,6 @@ public class ParametrizedDuplicates {
|
||||
}
|
||||
parametrizedProcessor.applyFrom(originalProcessor, variablesMapping);
|
||||
parametrizedProcessor.doExtract();
|
||||
parametrizedProcessor.setDataFromInputVariables();
|
||||
myParametrizedMethod = parametrizedProcessor.getExtractedMethod();
|
||||
myParametrizedCall = parametrizedProcessor.getMethodCall();
|
||||
myVariableDatum = unmapVariableData(parametrizedProcessor.myVariableDatum, variablesMapping);
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
class C {
|
||||
public void foo(C c, long d, int i, String s) {
|
||||
<selection>b(s, 1).m(d, i())</selection>;
|
||||
b(s, i).m(d, k(d));
|
||||
c.m(d, i);
|
||||
}
|
||||
|
||||
private C b(String s, int i) { return new C(); }
|
||||
void m(long d, int i) { }
|
||||
|
||||
private int i() { return 0; }
|
||||
private int k(long d) { return 0; }
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
class C {
|
||||
public void foo(C c, long d, int i, String s) {
|
||||
newMethod(d, s, 1, i());
|
||||
newMethod(d, s, i, k(d));
|
||||
c.m(d, i);
|
||||
}
|
||||
|
||||
private void newMethod(long d, String s, int i, int i2) {
|
||||
b(s, i).m(d, i2);
|
||||
}
|
||||
|
||||
private C b(String s, int i) { return new C(); }
|
||||
void m(long d, int i) { }
|
||||
|
||||
private int i() { return 0; }
|
||||
private int k(long d) { return 0; }
|
||||
}
|
||||
@@ -868,6 +868,10 @@ public class ExtractMethodTest extends LightCodeInsightTestCase {
|
||||
doDuplicatesTest();
|
||||
}
|
||||
|
||||
public void testParametrizedDuplicateNestedSubexpression() throws Exception {
|
||||
doDuplicatesTest();
|
||||
}
|
||||
|
||||
public void testSuggestChangeSignatureWithChangedParameterName() throws Exception {
|
||||
configureByFile(BASE_PATH + getTestName(false) + ".java");
|
||||
boolean success = performExtractMethod(true, true, getEditor(), getFile(), getProject(), false, null, false, "p");
|
||||
|
||||
Reference in New Issue
Block a user