From e426d5ac3a34e42b3336d13e937408a4d47a93af Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 11 Dec 2015 11:00:10 +0100 Subject: [PATCH] introduce functional: don't treat all parameters as ignored cause they could belong to for loops, nested classes not available at call site, etc --- .../IntroduceParameterHandler.java | 12 +++++-- .../afterInsideForLoop.java | 31 +++++++++++++++++++ .../beforeInsideForLoop.java | 26 ++++++++++++++++ .../IntroduceFunctionalParameterTest.java | 22 ++++++++++++- 4 files changed, 87 insertions(+), 4 deletions(-) create mode 100644 java/java-tests/testData/refactoring/introduceFunctionalParameter/afterInsideForLoop.java create mode 100644 java/java-tests/testData/refactoring/introduceFunctionalParameter/beforeInsideForLoop.java diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java index 5435ec3e5489..717356094b19 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java @@ -558,7 +558,9 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase { ? new PsiElement[] {exprInRange} : CodeInsightUtil.findStatementsInRange(copy, elements[0].getTextRange().getStartOffset(), elements[elements.length - 1].getTextRange().getEndOffset()); - final MyExtractMethodProcessor processor = new MyExtractMethodProcessor(project, editor, elementsCopy); + final List enclosingMethodsInCopy = getEnclosingMethods(Util.getContainingMethod(elementsCopy[0])); + final MyExtractMethodProcessor processor = new MyExtractMethodProcessor(project, editor, elementsCopy, + enclosingMethodsInCopy.get(enclosingMethodsInCopy.size() - 1)); try { if (!processor.prepare()) return false; processor.showDialog(); @@ -700,8 +702,11 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase { } private static class MyExtractMethodProcessor extends ExtractMethodProcessor { - public MyExtractMethodProcessor(Project project, Editor editor, PsiElement[] elements) { + private final PsiMethod myTopEnclosingMethod; + + public MyExtractMethodProcessor(Project project, Editor editor, PsiElement[] elements, PsiMethod topEnclosing) { super(project, editor, elements, null, REFACTORING_NAME, null, null); + myTopEnclosingMethod = topEnclosing; } @Override @@ -755,7 +760,8 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase { final InputVariables inputVariables = getInputVariables(); List datas = new ArrayList(); for (VariableData data : inputVariables.getInputVariables()) { - if (data.variable instanceof PsiParameter) { + final PsiVariable variable = data.variable; + if (variable instanceof PsiParameter && myTopEnclosingMethod.equals(((PsiParameter)variable).getDeclarationScope())) { continue; } datas.add(data); diff --git a/java/java-tests/testData/refactoring/introduceFunctionalParameter/afterInsideForLoop.java b/java/java-tests/testData/refactoring/introduceFunctionalParameter/afterInsideForLoop.java new file mode 100644 index 000000000000..2fb823de3523 --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceFunctionalParameter/afterInsideForLoop.java @@ -0,0 +1,31 @@ + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Function; + +class Test { + + public void run() { + final Normalizer normalizer = new Normalizer(); + final List input = new ArrayList<>(); + final List output = new ArrayList<>(); + + doNormalize(input, output, new Function() { + public String apply(String s) { + return normalizer.normalize(s); + } + }); + } + + private void doNormalize(final List input, final List output, Function anObject) { + for (final String s : input) { + output.add(anObject.apply(s)); + } + } + + public static class Normalizer { + public String normalize(final String s) { + return s; + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/introduceFunctionalParameter/beforeInsideForLoop.java b/java/java-tests/testData/refactoring/introduceFunctionalParameter/beforeInsideForLoop.java new file mode 100644 index 000000000000..dc81f3545a8f --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceFunctionalParameter/beforeInsideForLoop.java @@ -0,0 +1,26 @@ + +import java.util.ArrayList; +import java.util.List; + +class Test { + + public void run() { + final Normalizer normalizer = new Normalizer(); + final List input = new ArrayList<>(); + final List output = new ArrayList<>(); + + doNormalize(input, normalizer, output); + } + + private void doNormalize(final List input, final Normalizer normalizer, final List output) { + for (final String s : input) { + output.add(normalizer.normalize(s)); + } + } + + public static class Normalizer { + public String normalize(final String s) { + return s; + } + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceFunctionalParameterTest.java b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceFunctionalParameterTest.java index 7c0709372700..90222141e247 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceFunctionalParameterTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceFunctionalParameterTest.java @@ -16,8 +16,12 @@ package com.intellij.refactoring; import com.intellij.JavaTestUtil; +import com.intellij.codeInsight.CodeInsightUtil; +import com.intellij.openapi.editor.SelectionModel; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.pom.java.LanguageLevel; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiExpression; import com.intellij.refactoring.introduceParameter.IntroduceParameterHandler; import com.intellij.testFramework.IdeaTestUtil; import com.intellij.testFramework.TestDataPath; @@ -57,6 +61,10 @@ public class IntroduceFunctionalParameterTest extends LightRefactoringTestCase doTest(); } + public void testInsideForLoop() throws Exception { + doTest(); + } + public void testInsideAnonymous() throws Exception { doTest(); } @@ -87,7 +95,19 @@ public class IntroduceFunctionalParameterTest extends LightRefactoringTestCase configureByFile("/refactoring/introduceFunctionalParameter/before" + getTestName(false) + ".java"); enabled = myEditor.getSettings().isVariableInplaceRenameEnabled(); myEditor.getSettings().setVariableInplaceRenameEnabled(false); - new IntroduceParameterHandler().introduceStrategy(getProject(), getEditor(), getFile()); + final SelectionModel selectionModel = getEditor().getSelectionModel(); + if (selectionModel.hasSelection()) { + final int selectionStart = selectionModel.getSelectionStart(); + final int selectionEnd = selectionModel.getSelectionEnd(); + PsiElement[] elements = CodeInsightUtil.findStatementsInRange(getFile(), selectionStart, selectionEnd); + if (elements.length == 0) { + final PsiExpression expression = CodeInsightUtil.findExpressionInRange(getFile(), selectionStart, selectionEnd); + if (expression != null) { + elements = new PsiElement[] {expression}; + } + } + new IntroduceParameterHandler().introduceStrategy(getProject(), getEditor(), getFile(), elements); + } checkResultByFile("/refactoring/introduceFunctionalParameter/after" + getTestName(false) + ".java"); if (conflict != null) { fail("Conflict expected");