From 8c43bb8bea7d24c853b4a8044eae84e0448da9ea Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 26 Jun 2018 19:41:19 +0300 Subject: [PATCH] introduce parameter: don't wrap arrays for non-vararg calls (IDEA-136859) --- ...troduceParameterMethodUsagesProcessor.java | 7 ++++++- .../OldReferenceResolver.java | 20 ++++++++++++------- .../afterVarargMethodStricktlyCalled.java | 14 +++++++++++++ .../beforeVarargMethodStricktlyCalled.java | 14 +++++++++++++ .../refactoring/IntroduceParameterTest.java | 4 ++++ 5 files changed, 51 insertions(+), 8 deletions(-) create mode 100644 java/java-tests/testData/refactoring/introduceParameter/afterVarargMethodStricktlyCalled.java create mode 100644 java/java-tests/testData/refactoring/introduceParameter/beforeVarargMethodStricktlyCalled.java diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/JavaIntroduceParameterMethodUsagesProcessor.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/JavaIntroduceParameterMethodUsagesProcessor.java index 9bb2280a7d51..3cecf767e531 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/JavaIntroduceParameterMethodUsagesProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/JavaIntroduceParameterMethodUsagesProcessor.java @@ -28,6 +28,7 @@ import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.impl.ExpressionConverter; import com.intellij.psi.impl.PsiDiamondTypeUtil; import com.intellij.psi.impl.source.resolve.DefaultParameterTypeInferencePolicy; +import com.intellij.psi.infos.MethodCandidateInfo; import com.intellij.psi.javadoc.PsiDocTag; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; @@ -78,6 +79,10 @@ public class JavaIntroduceParameterMethodUsagesProcessor implements IntroducePar PsiExpressionList argList = RefactoringUtil.getArgumentListByMethodReference(ref); if (argList == null) return true; PsiExpression[] oldArgs = argList.getExpressions(); + JavaResolveResult result = callExpression.resolveMethodGenerics(); + boolean varargs = result instanceof MethodCandidateInfo && + ((MethodCandidateInfo)result).getApplicabilityLevel() == MethodCandidateInfo.ApplicabilityLevel.VARARGS; + final PsiExpression anchor; final PsiMethod methodToSearchFor = data.getMethodToSearchFor(); @@ -119,7 +124,7 @@ public class JavaIntroduceParameterMethodUsagesProcessor implements IntroducePar // here comes some postprocessing... new OldReferenceResolver(callExpression, newArg, data.getMethodToReplaceIn(), data.getReplaceFieldsWithGetters(), initializer) - .resolve(); + .resolve(varargs); } diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/OldReferenceResolver.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/OldReferenceResolver.java index a788a75931e7..f6755785e30e 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/OldReferenceResolver.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/OldReferenceResolver.java @@ -28,9 +28,9 @@ import com.intellij.refactoring.IntroduceParameterRefactoring; import com.intellij.refactoring.util.RefactoringUtil; import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.ContainerUtil; -import java.util.HashMap; import org.jetbrains.annotations.Nullable; +import java.util.HashMap; import java.util.Map; import java.util.Set; @@ -88,8 +88,8 @@ public class OldReferenceResolver { myInstanceRef = instanceRef; } - public void resolve() throws IncorrectOperationException { - resolveOldReferences(myExpr, myParameterInitializer); + public void resolve(boolean varargs) throws IncorrectOperationException { + resolveOldReferences(myExpr, myParameterInitializer, varargs); Set> mappingsSet = myTempVars.entrySet(); @@ -107,7 +107,7 @@ public class OldReferenceResolver { } - private void resolveOldReferences(PsiElement expr, PsiElement oldExpr) throws IncorrectOperationException { + private void resolveOldReferences(PsiElement expr, PsiElement oldExpr, boolean varargs) throws IncorrectOperationException { if (expr == null || !expr.isValid() || oldExpr == null) return; PsiElementFactory factory = JavaPsiFacade.getInstance(myProject).getElementFactory(); PsiElement newExpr = expr; // references continue being resolved in the children of newExpr @@ -138,8 +138,14 @@ public class OldReferenceResolver { if (parameter.isVarArgs() && parameterType instanceof PsiEllipsisType) { final String varargsJoin = StringUtil.join(ContainerUtil.map2Array(myActualArgs, String.class, expression -> expression != null ? expression.getText() : "null"), index + 1, myActualArgs.length, ","); - String newArrayInitializer = "new " + ((PsiEllipsisType)parameterType).toArrayType().getCanonicalText() + " {" + varargsJoin + "}"; - final String tempVar = getTempVar((PsiExpression)JavaCodeStyleManager.getInstance(myProject).shortenClassReferences(factory.createExpressionFromText(newArrayInitializer, myContext))); + final String tempVar; + if (varargs) { + String newArrayInitializer = "new " + ((PsiEllipsisType)parameterType).toArrayType().getCanonicalText() + " {" + varargsJoin + "}"; + tempVar = getTempVar((PsiExpression)JavaCodeStyleManager.getInstance(myProject).shortenClassReferences(factory.createExpressionFromText(newArrayInitializer, myContext))); + } + else { + tempVar = myActualArgs[myActualArgs.length - 1].getText(); + } final Map map = new HashMap<>(); if (initializer instanceof PsiReferenceExpression && Comparing.strEqual(parameter.getName(), initializer.getText())) { newExpr.replace(factory.createExpressionFromText(tempVar, myContext)); @@ -221,7 +227,7 @@ public class OldReferenceResolver { if (oldChildren.length == newChildren.length) { for (int i = 0; i < oldChildren.length; i++) { - resolveOldReferences(newChildren[i], oldChildren[i]); + resolveOldReferences(newChildren[i], oldChildren[i], varargs); } } } diff --git a/java/java-tests/testData/refactoring/introduceParameter/afterVarargMethodStricktlyCalled.java b/java/java-tests/testData/refactoring/introduceParameter/afterVarargMethodStricktlyCalled.java new file mode 100644 index 000000000000..4354d7d7da78 --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceParameter/afterVarargMethodStricktlyCalled.java @@ -0,0 +1,14 @@ +import java.util.Arrays; +import java.util.List; + +class Main { + + public static void main(String...args){ + String[] array = new String[]{"a", "b", "c"}; + final List strings = Arrays.asList(array); + foo(strings); + } + + private static void foo(List anObject){ + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/introduceParameter/beforeVarargMethodStricktlyCalled.java b/java/java-tests/testData/refactoring/introduceParameter/beforeVarargMethodStricktlyCalled.java new file mode 100644 index 000000000000..879d95dfbdfc --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceParameter/beforeVarargMethodStricktlyCalled.java @@ -0,0 +1,14 @@ +import java.util.Arrays; +import java.util.List; + +class Main { + + public static void main(String...args){ + String[] array = new String[]{"a", "b", "c"}; + foo(array); + } + + private static void foo(String... src){ + final List stream = Arrays.asList(src); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/refactoring/IntroduceParameterTest.java b/java/java-tests/testSrc/com/intellij/java/refactoring/IntroduceParameterTest.java index acd3b0f2d5ac..bd5e3db1ec3f 100644 --- a/java/java-tests/testSrc/com/intellij/java/refactoring/IntroduceParameterTest.java +++ b/java/java-tests/testSrc/com/intellij/java/refactoring/IntroduceParameterTest.java @@ -162,6 +162,10 @@ public class IntroduceParameterTest extends LightRefactoringTestCase { doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, true, false, false, false); } + public void testVarargMethodStricktlyCalled() { + doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, true, false, false, false); + } + public void testMethodCallRefToVararg() { doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, true, false, false, false); }