From 5673683e95f7d048b8ad47ea7b3d673a22b375bb Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 1 Mar 2016 14:09:53 +0100 Subject: [PATCH] extract method suggester: unique parameter names (IDEA-152334); update output variables when suggester replaces the initial method --- .../extractMethod/ExtractMethodProcessor.java | 16 ++++++++++ .../ExtractMethodSignatureSuggester.java | 6 ++++ ...estChangeSignatureWithOutputVariables.java | 25 ++++++++++++++++ ...ngeSignatureWithOutputVariables_after.java | 29 +++++++++++++++++++ .../refactoring/ExtractMethodTest.java | 4 +++ 5 files changed, 80 insertions(+) create mode 100644 java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithOutputVariables.java create mode 100644 java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithOutputVariables_after.java diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java index 570d4d57f563..0368e04bfa49 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java @@ -1728,6 +1728,22 @@ public class ExtractMethodProcessor implements MatchProvider { myExtractedMethod = suggester.getExtractedMethod(); myMethodCall = suggester.getMethodCall(); myVariableDatum = suggester.getVariableData(); + + final List outputVariables = new ArrayList<>(); + for (PsiReturnStatement statement : PsiUtil.findReturnStatements(myExtractedMethod)) { + final PsiExpression returnValue = statement.getReturnValue(); + if (returnValue instanceof PsiReferenceExpression) { + final PsiElement resolve = ((PsiReferenceExpression)returnValue).resolve(); + if (resolve instanceof PsiLocalVariable) { + outputVariables.add((PsiVariable)resolve); + } + } + } + + if (outputVariables.size() == 1) { + myOutputVariable = outputVariables.get(0); + } + return null; } } diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodSignatureSuggester.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodSignatureSuggester.java index ceac680e7c47..0748b6f83351 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodSignatureSuggester.java +++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodSignatureSuggester.java @@ -334,6 +334,12 @@ public class ExtractMethodSignatureSuggester { for (PsiParameter parameter : parameters) { uniqueNameGenerator.addExistingName(parameter.getName()); } + + SyntaxTraverser.psiTraverser().withRoot(myExtractedMethod.getBody()) + .filter(element -> element instanceof PsiVariable) + .forEach(element -> uniqueNameGenerator.addExistingName(((PsiVariable)element).getName())); + + final THashMap unique = new THashMap(ourEquivalenceStrategy); final Map replacement = new HashMap(); for (PsiExpression expr : exprs) { diff --git a/java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithOutputVariables.java b/java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithOutputVariables.java new file mode 100644 index 000000000000..d2d648133430 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithOutputVariables.java @@ -0,0 +1,25 @@ + +class Test { + + private BigDecimal getRevenue() { + final String query = createNamedQuery("revenues"); + String revenues = ""; + final String revenue; + revenue = "a"; + + return revenue; + } + + public BigDecimal getExpense() { + final String query = createNamedQuery("expenses"); + String expenses = ""; + final String expense; + expense = "a"; + + return expense; + } + + private String createNamedQuery(String expenses) { + return null; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithOutputVariables_after.java b/java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithOutputVariables_after.java new file mode 100644 index 000000000000..2397db581d4c --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithOutputVariables_after.java @@ -0,0 +1,29 @@ +import org.jetbrains.annotations.NotNull; + +class Test { + + private BigDecimal getRevenue() { + final String revenue = newMethod("revenues"); + + return revenue; + } + + @NotNull + private String newMethod(String revenues2) { + final String query = createNamedQuery(revenues2); + String revenues = ""; + final String revenue; + revenue = "a"; + return revenue; + } + + public BigDecimal getExpense() { + final String expense = newMethod("expenses"); + + return expense; + } + + private String createNamedQuery(String expenses) { + return null; + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java index 27032f4532cf..650badbd68c0 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java @@ -675,6 +675,10 @@ public class ExtractMethodTest extends LightCodeInsightTestCase { doDuplicatesTest(); } + public void testSuggestChangeSignatureWithOutputVariables() 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");