introduce parameter: don't wrap arrays for non-vararg calls (IDEA-136859)

This commit is contained in:
Anna Kozlova
2018-06-27 12:33:52 +03:00
parent 99ec7c7866
commit 8c43bb8bea
5 changed files with 51 additions and 8 deletions
@@ -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);
}
@@ -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<Map.Entry<PsiExpression, String>> 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<PsiExpression, String> 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);
}
}
}
@@ -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<String> strings = Arrays.asList(array);
foo(strings);
}
private static void foo(List<String> anObject){
}
}
@@ -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<String> str<caret>eam = Arrays.asList(src);
}
}
@@ -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);
}