From 32f0a9f3ef046cd95b3cf4f921ff34dc23eaeaba Mon Sep 17 00:00:00 2001 From: Pavel Dolgov Date: Tue, 3 Oct 2017 12:57:10 +0300 Subject: [PATCH] Java: Support parameter folding in parametrized duplicates of the extracted method (IDEA-179924) --- .../extractMethod/InputVariables.java | 2 +- .../util/duplicates/DuplicatesFinder.java | 50 +++++-- .../duplicates/ExtractableExpressionPart.java | 14 +- .../util/duplicates/ParameterFolding.java | 130 ++++++++++++++++++ .../JavaDuplicatesExtractMethodProcessor.java | 32 +++-- .../extractMethod/ParametrizedDuplicates.java | 10 +- ...uggestChangeSignatureWithArrayFolding.java | 6 + ...ChangeSignatureWithArrayFolding_after.java | 10 ++ ...ggestChangeSignatureWithGetterFolding.java | 8 ++ ...hangeSignatureWithGetterFolding_after.java | 12 ++ ...uggestChangeSignatureWithMultiFolding.java | 13 ++ ...ChangeSignatureWithMultiFolding_after.java | 17 +++ ...ggestChangeSignatureWithTwoWayFolding.java | 13 ++ ...hangeSignatureWithTwoWayFolding_after.java | 17 +++ .../java/refactoring/ExtractMethodTest.java | 18 ++- 15 files changed, 321 insertions(+), 31 deletions(-) create mode 100644 java/java-analysis-impl/src/com/intellij/refactoring/util/duplicates/ParameterFolding.java create mode 100644 java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithArrayFolding.java create mode 100644 java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithArrayFolding_after.java create mode 100644 java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithGetterFolding.java create mode 100644 java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithGetterFolding_after.java create mode 100644 java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithMultiFolding.java create mode 100644 java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithMultiFolding_after.java create mode 100644 java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithTwoWayFolding.java create mode 100644 java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithTwoWayFolding_after.java diff --git a/java/java-analysis-impl/src/com/intellij/refactoring/extractMethod/InputVariables.java b/java/java-analysis-impl/src/com/intellij/refactoring/extractMethod/InputVariables.java index 018f7f9f0e1d..a2535b3d9872 100644 --- a/java/java-analysis-impl/src/com/intellij/refactoring/extractMethod/InputVariables.java +++ b/java/java-analysis-impl/src/com/intellij/refactoring/extractMethod/InputVariables.java @@ -63,7 +63,7 @@ public class InputVariables { /** * copy use only */ - public InputVariables(List inputVariables, + private InputVariables(List inputVariables, Project project, LocalSearchScope scope) { myProject = project; diff --git a/java/java-analysis-impl/src/com/intellij/refactoring/util/duplicates/DuplicatesFinder.java b/java/java-analysis-impl/src/com/intellij/refactoring/util/duplicates/DuplicatesFinder.java index c1a3b976ec63..f86b4de167ac 100644 --- a/java/java-analysis-impl/src/com/intellij/refactoring/util/duplicates/DuplicatesFinder.java +++ b/java/java-analysis-impl/src/com/intellij/refactoring/util/duplicates/DuplicatesFinder.java @@ -50,6 +50,8 @@ public class DuplicatesFinder { private boolean myMultipleExitPoints; @Nullable private final ReturnValue myReturnValue; private final boolean myWithExtractedParameters; + private ParameterFolding myPatternParameterFolding; + private ParameterFolding myCandidateParameterFolding; public DuplicatesFinder(@NotNull PsiElement[] pattern, InputVariables parameters, @@ -321,10 +323,12 @@ public class DuplicatesFinder { if (pattern == null || candidate == null) return pattern == candidate; if (pattern.getUserData(PARAMETER) != null) { final Pair parameter = pattern.getUserData(PARAMETER); - return match.putParameter(parameter, candidate); + if(!myWithExtractedParameters || parameter.second.equals(parameter.first.getType())) { + return match.putParameter(parameter, candidate); + } } - Boolean matchedExtractablePart = matchExtractableExpression(pattern, candidate, candidates, match); + Boolean matchedExtractablePart = matchExtractableExpression(pattern, candidate, candidates, match, false); if (matchedExtractablePart != null) return matchedExtractablePart; if (!canBeEquivalent(pattern, candidate)) return false; // Q : is it correct to check implementation classes? @@ -539,7 +543,10 @@ public class DuplicatesFinder { for (int i = 0; i < children1.length; i++) { PsiElement child1 = children1[i]; PsiElement child2 = children2[i]; - if (!matchPattern(child1, child2, candidates, match)) return false; + if (!matchPattern(child1, child2, candidates, match)) { + matchedExtractablePart = matchExtractableExpression(child1, child2, candidates, match, true); + return matchedExtractablePart != null && matchedExtractablePart; + } } if (children1.length == 0) { @@ -553,24 +560,43 @@ public class DuplicatesFinder { } @Nullable - private Boolean matchExtractableExpression(PsiElement pattern, PsiElement candidate, List candidates, Match match) { - if (!(pattern instanceof PsiExpression) || !(candidate instanceof PsiExpression)) { + private Boolean matchExtractableExpression(PsiElement pattern, PsiElement candidate, + List candidates, Match match, + boolean withFolding) { + if (!(pattern instanceof PsiExpression) || !(candidate instanceof PsiExpression) || withFolding && !myWithExtractedParameters) { return null; } - ExtractableExpressionPart part1 = ExtractableExpressionPart.match((PsiExpression)pattern, myPatternAsList); - if (part1 == null) { + + ParameterFolding patternFolding = null; + if (withFolding) { + if (myPatternParameterFolding == null) { + myPatternParameterFolding = new ParameterFolding(myPatternAsList); + } + patternFolding = myPatternParameterFolding; + } + ExtractableExpressionPart patternPart = ExtractableExpressionPart.match((PsiExpression)pattern, myPatternAsList, patternFolding); + if (patternPart == null) { return null; } - ExtractableExpressionPart part2 = ExtractableExpressionPart.match((PsiExpression)candidate, candidates); - if (part2 == null) { + + ParameterFolding candidatesFolding = null; + if (withFolding) { + if (myCandidateParameterFolding == null || myCandidateParameterFolding.getScope() != candidates) { + myCandidateParameterFolding = new ParameterFolding(candidates); + } + candidatesFolding = myCandidateParameterFolding; + } + ExtractableExpressionPart candidatePart = ExtractableExpressionPart.match((PsiExpression)candidate, candidates, candidatesFolding); + if (candidatePart == null) { return null; } - if (part1.myValue != null && part2.myValue != null && part1.myValue.equals(part2.myValue)) { + + if (patternPart.myValue != null && candidatePart.myValue != null && patternPart.myValue.equals(candidatePart.myValue)) { return true; } - if (part1.myVariable == null || part2.myVariable == null) { + if (patternPart.myVariable == null || candidatePart.myVariable == null) { return myWithExtractedParameters && - match.putExtractedParameter(part1, part2); + match.putExtractedParameter(patternPart, candidatePart); } return null; } diff --git a/java/java-analysis-impl/src/com/intellij/refactoring/util/duplicates/ExtractableExpressionPart.java b/java/java-analysis-impl/src/com/intellij/refactoring/util/duplicates/ExtractableExpressionPart.java index def58bd8db59..298139ddbdec 100644 --- a/java/java-analysis-impl/src/com/intellij/refactoring/util/duplicates/ExtractableExpressionPart.java +++ b/java/java-analysis-impl/src/com/intellij/refactoring/util/duplicates/ExtractableExpressionPart.java @@ -15,6 +15,7 @@ */ package com.intellij.refactoring.util.duplicates; +import com.intellij.codeInsight.JavaPsiEquivalenceUtil; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; @@ -63,11 +64,14 @@ public class ExtractableExpressionPart { if (myValue != null && myValue.equals(part.myValue)) { return true; } - return false; + return JavaPsiEquivalenceUtil.areExpressionsEquivalent(PsiUtil.skipParenthesizedExprDown(myUsage), + PsiUtil.skipParenthesizedExprDown(part.myUsage)); } @Nullable - static ExtractableExpressionPart match(@NotNull PsiExpression expression, @Nullable List scope) { + static ExtractableExpressionPart match(@NotNull PsiExpression expression, + @NotNull List scope, + @Nullable ParameterFolding parameterFolding) { if (PsiUtil.isConstantExpression(expression)) { if (PsiTreeUtil.findChildOfType(expression, PsiJavaCodeReferenceElement.class) != null) { return null; @@ -77,6 +81,12 @@ public class ExtractableExpressionPart { if (expression instanceof PsiReferenceExpression) { return matchVariable((PsiReferenceExpression)expression, scope); } + if (parameterFolding != null && parameterFolding.isAcceptableComplexity(expression)) { + PsiType type = expression.getType(); + if (type != null && !PsiType.VOID.equals(type)) { + return new ExtractableExpressionPart(expression, null, null, type); + } + } return null; } diff --git a/java/java-analysis-impl/src/com/intellij/refactoring/util/duplicates/ParameterFolding.java b/java/java-analysis-impl/src/com/intellij/refactoring/util/duplicates/ParameterFolding.java new file mode 100644 index 000000000000..f0348cfb6647 --- /dev/null +++ b/java/java-analysis-impl/src/com/intellij/refactoring/util/duplicates/ParameterFolding.java @@ -0,0 +1,130 @@ +// Copyright 2000-2017 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. +package com.intellij.refactoring.util.duplicates; + +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.util.PsiUtil; +import com.intellij.util.containers.ObjectIntHashMap; + +import java.util.List; + +/** + * @author Pavel.Dolgov + */ +class ParameterFolding { + static final int MAX_ACCEPTABLE = 9; + static final int TOO_COMPLEX = 100; + + private final ObjectIntHashMap myCache = new ObjectIntHashMap<>(); + private final List myScope; + + ParameterFolding(List scope) {myScope = scope;} + + boolean isAcceptableComplexity(PsiExpression expression) { + return getComplexity(expression) <= MAX_ACCEPTABLE; + } + + private int getComplexity(PsiExpression expression) { + int complexity = myCache.get(expression); + if (complexity < 0) { + complexity = computeComplexity(expression); + myCache.put(expression, complexity); + } + return complexity; + } + + private int computeComplexity(PsiExpression expression) { + expression = PsiUtil.skipParenthesizedExprDown(expression); + + if (expression instanceof PsiLiteralExpression || expression instanceof PsiQualifiedExpression) { + return 1; + } + + if (expression instanceof PsiAssignmentExpression) { + return TOO_COMPLEX; + } + + if (expression instanceof PsiUnaryExpression) { + IElementType tokenType = ((PsiUnaryExpression)expression).getOperationTokenType(); + if (JavaTokenType.PLUSPLUS.equals(tokenType) || JavaTokenType.MINUSMINUS.equals(tokenType)) { + return TOO_COMPLEX; + } + return 1 + getComplexity(((PsiUnaryExpression)expression).getOperand()); + } + + if (expression instanceof PsiBinaryExpression) { + int complexity = 1 + getComplexity(((PsiBinaryExpression)expression).getLOperand()); + if (complexity > MAX_ACCEPTABLE) return complexity; + return complexity + getComplexity(((PsiBinaryExpression)expression).getROperand()); + } + + if (expression instanceof PsiConditionalExpression) { + int complexity = 1 + getComplexity(((PsiConditionalExpression)expression).getCondition()); + if (complexity > MAX_ACCEPTABLE) return complexity; + + complexity += getComplexity(((PsiConditionalExpression)expression).getThenExpression()); + if (complexity > MAX_ACCEPTABLE) return complexity; + + return complexity + getComplexity(((PsiConditionalExpression)expression).getElseExpression()); + } + + if (expression instanceof PsiArrayAccessExpression) { + int complexity = 3 + getComplexity(((PsiArrayAccessExpression)expression).getArrayExpression()); + if (complexity > MAX_ACCEPTABLE) return complexity; + + return complexity + getComplexity(((PsiArrayAccessExpression)expression).getIndexExpression()); + } + + if (expression instanceof PsiReferenceExpression) { + PsiElement resolved = ((PsiReferenceExpression)expression).resolve(); + if (resolved == null || isWithinScope(resolved)) { + return TOO_COMPLEX; + } + if (resolved instanceof PsiVariable && + ((PsiVariable)resolved).hasModifierProperty(PsiModifier.STATIC) && + ((PsiVariable)resolved).hasModifierProperty(PsiModifier.FINAL)) { + return 1; + } + + PsiExpression qualifier = ((PsiReferenceExpression)expression).getQualifierExpression(); + if (qualifier == null) { + return 2; + } + return 2 + getComplexity(qualifier); + } + + if (expression instanceof PsiMethodCallExpression) { + PsiReferenceExpression methodExpression = ((PsiMethodCallExpression)expression).getMethodExpression(); + PsiElement resolved = methodExpression.resolve(); + if (resolved == null || isWithinScope(resolved)) { + return TOO_COMPLEX; + } + int complexity = 3; + PsiExpression qualifier = methodExpression.getQualifierExpression(); + if (qualifier != null) { + complexity += getComplexity(qualifier); + if (complexity > MAX_ACCEPTABLE) { + return complexity; + } + } + PsiExpression[] arguments = ((PsiMethodCallExpression)expression).getArgumentList().getExpressions(); + for (PsiExpression argument : arguments) { + complexity += getComplexity(argument); + if (complexity > MAX_ACCEPTABLE) { + return complexity; + } + } + return complexity; + } + + return TOO_COMPLEX; + } + + private boolean isWithinScope(PsiElement resolved) { + return DuplicatesFinder.isUnder(resolved, myScope); + } + + public List getScope() { + return myScope; + } +} diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/JavaDuplicatesExtractMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/JavaDuplicatesExtractMethodProcessor.java index d16cb4f36e3e..67884e54f1b9 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractMethod/JavaDuplicatesExtractMethodProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/JavaDuplicatesExtractMethodProcessor.java @@ -6,6 +6,8 @@ package com.intellij.refactoring.extractMethod; import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.*; import com.intellij.psi.codeStyle.JavaCodeStyleManager; +import com.intellij.psi.search.LocalSearchScope; +import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.refactoring.HelpID; @@ -15,7 +17,9 @@ import com.intellij.refactoring.util.VariableData; import com.intellij.refactoring.util.duplicates.*; import com.intellij.util.ArrayUtil; import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.*; @@ -42,24 +46,28 @@ public class JavaDuplicatesExtractMethodProcessor extends ExtractMethodProcessor myOutputVariable = ArrayUtil.getFirstElement(myOutputVariables); myArtificialOutputVariable = variablesMapping.getOrDefault(from.myArtificialOutputVariable, from.myArtificialOutputVariable); - int parameterCount = Math.max(myInputVariables.getInputVariables().size(), from.myVariableDatum.length); - myVariableDatum = new VariableData[parameterCount]; + List variableDatum = new ArrayList<>(); for (int i = 0; i < from.myVariableDatum.length; i++) { VariableData fromData = from.myVariableDatum[i]; PsiVariable mappedVariable = variablesMapping.get(fromData.variable); - if (mappedVariable == null) { - myVariableDatum[i] = fromData; - } - else { - myVariableDatum[i] = new VariableData(mappedVariable, fromData.type); - myVariableDatum[i].name = fromData.name; - myVariableDatum[i].originalName = fromData.originalName; - myVariableDatum[i].passAsParameter = fromData.passAsParameter; + if (isReferenced(mappedVariable)) { + VariableData newData = new VariableData(mappedVariable, fromData.type); + newData.name = fromData.name; + newData.originalName = fromData.originalName; + newData.passAsParameter = fromData.passAsParameter; + variableDatum.add(newData); } } - for (int i = from.myVariableDatum.length; i < myVariableDatum.length; i++) { - myVariableDatum[i] = myInputVariables.getInputVariables().get(i); + List inputVariables = getInputVariables().getInputVariables(); + for (int i = variableDatum.size(); i < inputVariables.size(); i++) { + variableDatum.add(inputVariables.get(i)); } + myVariableDatum = variableDatum.toArray(new VariableData[0]); + } + + @Contract("null -> false") + private boolean isReferenced(@Nullable PsiVariable variable) { + return variable != null && ReferencesSearch.search(variable, new LocalSearchScope(myElements)).findFirst() != null; } public void applyDefaults(@NotNull String methodName, @PsiModifier.ModifierConstant @NotNull String visibility) { diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ParametrizedDuplicates.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/ParametrizedDuplicates.java index d7b49f0a0be3..9f43bb3ab7dc 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ParametrizedDuplicates.java +++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/ParametrizedDuplicates.java @@ -22,6 +22,7 @@ import com.intellij.psi.*; import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.codeStyle.SuggestedNameInfo; import com.intellij.psi.codeStyle.VariableKind; +import com.intellij.psi.search.LocalSearchScope; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.refactoring.introduceParameter.IntroduceParameterHandler; @@ -30,6 +31,7 @@ import com.intellij.refactoring.util.duplicates.DuplicatesFinder; import com.intellij.refactoring.util.duplicates.ExtractedParameter; import com.intellij.refactoring.util.duplicates.Match; import com.intellij.refactoring.util.duplicates.VariableReturnValue; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.text.UniqueNameGenerator; import gnu.trove.THashMap; import gnu.trove.THashSet; @@ -53,7 +55,7 @@ public class ParametrizedDuplicates { private PsiMethodCallExpression myParametrizedCall; private VariableData[] myVariableData; - public ParametrizedDuplicates(PsiElement[] pattern) { + private ParametrizedDuplicates(PsiElement[] pattern) { if (pattern[0] instanceof PsiStatement) { Project project = pattern[0].getProject(); PsiElement[] copy = IntroduceParameterHandler.getElementsInCopy(project, pattern[0].getContainingFile(), pattern); @@ -90,10 +92,12 @@ public class ParametrizedDuplicates { private static List findOriginalDuplicates(@NotNull ExtractMethodProcessor processor) { PsiElement[] elements = getFilteredElements(processor.myElements); - DuplicatesFinder finder = new DuplicatesFinder(elements, processor.myInputVariables.copy(), + List variables = ContainerUtil.map(processor.myInputVariables.getInputVariables(), iv -> iv.variable); + InputVariables inputVariables = new InputVariables(variables, processor.myProject, new LocalSearchScope(processor.myElements), false); + DuplicatesFinder finder = new DuplicatesFinder(elements, inputVariables, processor.myOutputVariable != null ? new VariableReturnValue(processor.myOutputVariable) : null, - Arrays.asList(processor.myOutputVariables), true) { + Collections.emptyList(), true) { @Override protected boolean isSelf(@NotNull PsiElement candidate) { for (PsiElement element : elements) { diff --git a/java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithArrayFolding.java b/java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithArrayFolding.java new file mode 100644 index 000000000000..b10ee64b020e --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithArrayFolding.java @@ -0,0 +1,6 @@ +class Test { + public static void main(String[] args, int i) { + System.out.println("hi"); + System.out.println(args[i]); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithArrayFolding_after.java b/java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithArrayFolding_after.java new file mode 100644 index 000000000000..dc1a71690f50 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithArrayFolding_after.java @@ -0,0 +1,10 @@ +class Test { + public static void main(String[] args, int i) { + newMethod("hi"); + newMethod(args[i]); + } + + private static void newMethod(String hi) { + System.out.println(hi); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithGetterFolding.java b/java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithGetterFolding.java new file mode 100644 index 000000000000..78ca0dddcabf --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithGetterFolding.java @@ -0,0 +1,8 @@ +import java.util.List; + +class Test { + public static void foo(List args, int i) { + System.out.println("hi"); + System.out.println(args.get(i)); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithGetterFolding_after.java b/java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithGetterFolding_after.java new file mode 100644 index 000000000000..99c31a02848d --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithGetterFolding_after.java @@ -0,0 +1,12 @@ +import java.util.List; + +class Test { + public static void foo(List args, int i) { + newMethod("hi"); + newMethod(args.get(i)); + } + + private static void newMethod(String hi) { + System.out.println(hi); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithMultiFolding.java b/java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithMultiFolding.java new file mode 100644 index 000000000000..3ba8dd73c499 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithMultiFolding.java @@ -0,0 +1,13 @@ +import java.util.List; + +class Test { + void foo(String[] a, List b) { + for (int i = 0; i < a.length; i++) { + System.out.println("a:" + a[i]); + } + + for (int i = 0; i < b.size(); i++) { + System.out.println("b:" + b.get(i)); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithMultiFolding_after.java b/java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithMultiFolding_after.java new file mode 100644 index 000000000000..1638eee50596 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithMultiFolding_after.java @@ -0,0 +1,17 @@ +import java.util.List; + +class Test { + void foo(String[] a, List b) { + for (int i = 0; i < a.length; i++) { + newMethod("a:", a[i]); + } + + for (int i = 0; i < b.size(); i++) { + newMethod("b:", b.get(i)); + } + } + + private void newMethod(String s, String s2) { + System.out.println(s + s2); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithTwoWayFolding.java b/java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithTwoWayFolding.java new file mode 100644 index 000000000000..69afe34330d4 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithTwoWayFolding.java @@ -0,0 +1,13 @@ +import java.util.List; + +class Test { + void foo(String[] a, List b) { + for (int i = 0; i < a.length; i++) { + System.out.println(a[i]); + } + + for (int i = 0; i < b.size(); i++) { + System.out.println(b.get(i)); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithTwoWayFolding_after.java b/java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithTwoWayFolding_after.java new file mode 100644 index 000000000000..a0c0bee6199b --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithTwoWayFolding_after.java @@ -0,0 +1,17 @@ +import java.util.List; + +class Test { + void foo(String[] a, List b) { + for (int i = 0; i < a.length; i++) { + newMethod(a[i]); + } + + for (int i = 0; i < b.size(); i++) { + newMethod(b.get(i)); + } + } + + private void newMethod(String s) { + System.out.println(s); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/refactoring/ExtractMethodTest.java b/java/java-tests/testSrc/com/intellij/java/refactoring/ExtractMethodTest.java index 6df391d63567..c41c1b483693 100644 --- a/java/java-tests/testSrc/com/intellij/java/refactoring/ExtractMethodTest.java +++ b/java/java-tests/testSrc/com/intellij/java/refactoring/ExtractMethodTest.java @@ -783,7 +783,23 @@ public class ExtractMethodTest extends LightCodeInsightTestCase { doDuplicatesTest(); } - public void _testSuggestChangeSignatureWithFolding() throws Exception { + public void testSuggestChangeSignatureWithFolding() throws Exception { + doDuplicatesTest(); + } + + public void testSuggestChangeSignatureWithArrayFolding() throws Exception { + doDuplicatesTest(); + } + + public void testSuggestChangeSignatureWithGetterFolding() throws Exception { + doDuplicatesTest(); + } + + public void testSuggestChangeSignatureWithMultiFolding() throws Exception { + doDuplicatesTest(); + } + + public void testSuggestChangeSignatureWithTwoWayFolding() throws Exception { doDuplicatesTest(); }