From 9b56725bd0a433eb3d1b633ad4d53d8c645b27e4 Mon Sep 17 00:00:00 2001 From: Maxim Medvedev Date: Sun, 30 May 2010 17:28:36 +0400 Subject: [PATCH] fixes & tests --- .../JavaChangeSignatureUsageProcessor.java | 49 ++++++-- .../changeSignature/MethodCallUsageInfo.java | 17 ++- .../ReplaceVarargWithArray.java | 14 +++ .../ReplaceVarargWithArray_after.java | 14 +++ .../refactoring/ChangeSignatureTest.java | 12 ++ .../statements/params/GrParameterImpl.java | 20 ++-- .../GrChageSignatureUsageSearcher.java | 23 +--- .../GrChangeSignatureDialog.java | 29 +++-- .../GrChangeSignatureUsageProcessor.java | 25 ++-- .../GrMethodCallUsageInfo.java | 42 ++++--- .../changeSignature/GrParameterInfo.java | 100 +++++++--------- .../GrParameterTableModel.java | 16 +-- .../changeSignature/GrTableParameterInfo.java | 110 ++++++++++++++++++ .../changeSignature/ChangeSignatureTest.java | 13 ++- .../ChangeSignatureTestCase.java | 56 ++++----- .../MoveVarArgParameters.groovy | 2 +- .../MoveVarArgParameters_after.groovy | 2 +- .../MoveVarArgParameters_after.java | 2 +- .../ReplaceVarargWithArray.groovy | 14 +++ .../ReplaceVarargWithArray_after.groovy | 14 +++ 20 files changed, 401 insertions(+), 173 deletions(-) create mode 100644 java/java-tests/testData/refactoring/changeSignature/ReplaceVarargWithArray.java create mode 100644 java/java-tests/testData/refactoring/changeSignature/ReplaceVarargWithArray_after.java create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrTableParameterInfo.java create mode 100644 plugins/groovy/testdata/refactoring/changeSignature/ReplaceVarargWithArray.groovy create mode 100644 plugins/groovy/testdata/refactoring/changeSignature/ReplaceVarargWithArray_after.groovy diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java index 56985374bbc5..08ea1f00f740 100644 --- a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java @@ -19,6 +19,7 @@ import com.intellij.codeInsight.ExceptionUtil; import com.intellij.lang.StdLanguages; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Ref; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.codeStyle.JavaCodeStyleManager; @@ -123,7 +124,7 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr else if (usage instanceof MethodCallUsageInfo) { final MethodCallUsageInfo methodCallInfo = (MethodCallUsageInfo)usage; processMethodUsage(methodCallInfo.getElement(), (JavaChangeInfo)changeInfo, methodCallInfo.isToChangeArguments(), - methodCallInfo.isToCatchExceptions(), methodCallInfo.getReferencedMethod(), usages); + methodCallInfo.isToCatchExceptions(), methodCallInfo.getReferencedMethod(), methodCallInfo.getSubstitutor(), usages); return true; } else if (usage instanceof ChangeSignatureParameterUsageInfo) { @@ -137,7 +138,7 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr return true; } else if (element instanceof PsiEnumConstant) { - fixActualArgumentsList(((PsiEnumConstant)element).getArgumentList(), (JavaChangeInfo)changeInfo, true); + fixActualArgumentsList(((PsiEnumConstant)element).getArgumentList(), (JavaChangeInfo)changeInfo, true, PsiSubstitutor.EMPTY); return true; } else if (!(usage instanceof OverriderUsageInfo)) { @@ -179,7 +180,9 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr final PsiElement parent = aClass.getParent(); if (parent instanceof PsiNewExpression) { final PsiExpressionList argumentList = ((PsiNewExpression)parent).getArgumentList(); - fixActualArgumentsList(argumentList, changeInfo, true); + final PsiClass baseClass = changeInfo.getMethod().getContainingClass(); + final PsiSubstitutor substitutor = TypeConversionUtil.getSuperClassSubstitutor(baseClass, aClass, PsiSubstitutor.EMPTY); + fixActualArgumentsList(argumentList, changeInfo, true, substitutor); } } } @@ -198,14 +201,17 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr superCall = (PsiExpressionStatement)body.add(superCall); } PsiMethodCallExpression callExpression = (PsiMethodCallExpression)superCall.getExpression(); - processMethodUsage(callExpression.getMethodExpression(), changeInfo, true, false, callee, usages); + final PsiClass aClass = constructor.getContainingClass(); + final PsiClass baseClass = changeInfo.getMethod().getContainingClass(); + final PsiSubstitutor substitutor = TypeConversionUtil.getSuperClassSubstitutor(baseClass, aClass, PsiSubstitutor.EMPTY); + processMethodUsage(callExpression.getMethodExpression(), changeInfo, true, false, callee, substitutor, usages); } private static void processMethodUsage(PsiElement ref, JavaChangeInfo changeInfo, boolean toChangeArguments, boolean toCatchExceptions, - PsiMethod callee, final UsageInfo[] usages) throws IncorrectOperationException { + PsiMethod callee, PsiSubstitutor subsitutor, final UsageInfo[] usages) throws IncorrectOperationException { if (changeInfo.isNameChanged()) { if (ref instanceof PsiJavaCodeReferenceElement) { PsiElement last = ((PsiJavaCodeReferenceElement)ref).getReferenceNameElement(); @@ -226,7 +232,7 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr } } - fixActualArgumentsList(list, changeInfo, toInsertDefaultValue); + fixActualArgumentsList(list, changeInfo, toInsertDefaultValue, subsitutor); } if (toCatchExceptions) { @@ -352,7 +358,7 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr //This methods works equally well for primary usages as well as for propagated callers' usages private static void fixActualArgumentsList(PsiExpressionList list, JavaChangeInfo changeInfo, - boolean toInsertDefaultValue) throws IncorrectOperationException { + boolean toInsertDefaultValue, PsiSubstitutor substitutor) throws IncorrectOperationException { final PsiElementFactory factory = JavaPsiFacade.getInstance(list.getProject()).getElementFactory(); if (changeInfo.isParameterSetOrOrderChanged()) { if (changeInfo instanceof JavaChangeInfoImpl && ((JavaChangeInfoImpl)changeInfo).isPropagationEnabled) { @@ -402,8 +408,31 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr newNonVarargCount = newParms.length; newArgsLength = newParms.length; } + + String[] oldVarargs = null; + if (changeInfo.wasVararg() && !changeInfo.isRetainsVarargs()) { + oldVarargs = new String[varargCount]; + for (int i = nonVarargCount; i < args.length; i++) { + oldVarargs[i - nonVarargCount] = args[i].getText(); + } + } + final PsiExpression[] newArgs = new PsiExpression[newArgsLength]; for (int i = 0; i < newNonVarargCount; i++) { + if (newParms[i].getOldIndex() == nonVarargCount && oldVarargs != null) { + PsiType type = newParms[i].createType(changeInfo.getMethod(), list.getManager()); + if (type instanceof PsiArrayType) { + type = substitutor.substitute(type); + type = TypeConversionUtil.erasure(type); + String typeText = type.getCanonicalText(); + if (type instanceof PsiEllipsisType) { + typeText = typeText.replace("...", "[]"); + } + String text = "new " + typeText + "{" + StringUtil.join(oldVarargs, ",") + "}"; + newArgs[i] = factory.createExpressionFromText(text, changeInfo.getMethod()); + continue; + } + } newArgs[i] = createActualArgument(changeInfo, list, newParms[i], toInsertDefaultValue, args); } if (changeInfo.isArrayToVarargs()) { @@ -839,7 +868,11 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr for (JavaParameterInfo info : parameters) { - final PsiType parameterType = info.createType(method, manager); + PsiType parameterType = info.createType(method, manager); + if (parameterType == null) { + parameterType = + JavaPsiFacade.getElementFactory(method.getProject()).createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, method); + } PsiParameter param = factory.createParameter(info.getName(), parameterType); prototype.getParameterList().add(param); } diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/MethodCallUsageInfo.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/MethodCallUsageInfo.java index 616ec7f5c32e..62068a0977ba 100644 --- a/java/java-impl/src/com/intellij/refactoring/changeSignature/MethodCallUsageInfo.java +++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/MethodCallUsageInfo.java @@ -27,6 +27,7 @@ public class MethodCallUsageInfo extends UsageInfo { private final boolean myToChangeArguments; private final boolean myToCatchExceptions; private final PsiMethod myReferencedMethod; + private final PsiSubstitutor mySubstitutor; public boolean isToCatchExceptions() { return myToCatchExceptions; @@ -40,17 +41,19 @@ public class MethodCallUsageInfo extends UsageInfo { super(ref); myToChangeArguments = isToChangeArguments; myToCatchExceptions = isToCatchExceptions; - myReferencedMethod = resolveMethod(ref); + final JavaResolveResult resolveResult = resolveMethod(ref); + myReferencedMethod = (PsiMethod)resolveResult.getElement(); + mySubstitutor = resolveResult.getSubstitutor(); } - private static PsiMethod resolveMethod(final PsiElement ref) { - if (ref instanceof PsiEnumConstant) return ((PsiEnumConstant)ref).resolveConstructor(); + private static JavaResolveResult resolveMethod(final PsiElement ref) { + if (ref instanceof PsiEnumConstant) return ((PsiEnumConstant)ref).resolveMethodGenerics(); PsiElement parent = ref.getParent(); if (parent instanceof PsiCall) { - return ((PsiCall)parent).resolveMethod(); + return ((PsiCall)parent).resolveMethodGenerics(); } else if (parent instanceof PsiAnonymousClass) { - return ((PsiNewExpression)parent.getParent()).resolveConstructor(); + return ((PsiNewExpression)parent.getParent()).resolveMethodGenerics(); } LOG.error("Unknown reference"); @@ -60,4 +63,8 @@ public class MethodCallUsageInfo extends UsageInfo { public PsiMethod getReferencedMethod() { return myReferencedMethod; } + + public PsiSubstitutor getSubstitutor() { + return mySubstitutor; + } } diff --git a/java/java-tests/testData/refactoring/changeSignature/ReplaceVarargWithArray.java b/java/java-tests/testData/refactoring/changeSignature/ReplaceVarargWithArray.java new file mode 100644 index 000000000000..20f9b40c633f --- /dev/null +++ b/java/java-tests/testData/refactoring/changeSignature/ReplaceVarargWithArray.java @@ -0,0 +1,14 @@ +class List {} + +class Base { + void foo(String s, List... l) {} +} + +class Inheritor extends Base { + void foo(String s, List... l) {} + + { + new Inheritor().foo("a", new List()); + } +} + diff --git a/java/java-tests/testData/refactoring/changeSignature/ReplaceVarargWithArray_after.java b/java/java-tests/testData/refactoring/changeSignature/ReplaceVarargWithArray_after.java new file mode 100644 index 000000000000..e2a0388bf7ec --- /dev/null +++ b/java/java-tests/testData/refactoring/changeSignature/ReplaceVarargWithArray_after.java @@ -0,0 +1,14 @@ +class List {} + +class Base { + void foo(List[] l, String s) {} +} + +class Inheritor extends Base { + void foo(List[] l, String s) {} + + { + new Inheritor().foo(new List[]{new List()}, "a"); + } +} + diff --git a/java/java-tests/testSrc/com/intellij/refactoring/ChangeSignatureTest.java b/java/java-tests/testSrc/com/intellij/refactoring/ChangeSignatureTest.java index 00238154d697..f6525766f150 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/ChangeSignatureTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/ChangeSignatureTest.java @@ -210,6 +210,18 @@ public class ChangeSignatureTest extends LightCodeInsightTestCase { doTest(null, new ParameterInfoImpl[] {new ParameterInfoImpl(1), new ParameterInfoImpl(0)}, false); } + public void testReplaceVarargWithArray() throws Exception { + doTest(null, null, null, new GenParams() { + public ParameterInfoImpl[] genParams(PsiMethod method) throws IncorrectOperationException { + final PsiElementFactory factory = JavaPsiFacade.getInstance(method.getProject()).getElementFactory(); + return new ParameterInfoImpl[] { + new ParameterInfoImpl(1, "l", factory.createTypeFromText("List[]", method.getParameterList()), "null", false), + new ParameterInfoImpl(0, "s", factory.createTypeFromText("String", method.getParameterList())) + }; + } + }, false); + } + private void doTest(String newReturnType, ParameterInfoImpl[] parameterInfos, final boolean generateDelegate) throws Exception { doTest(null, null, newReturnType, parameterInfos, new ThrownExceptionInfo[0], generateDelegate); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/params/GrParameterImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/params/GrParameterImpl.java index cb47e248809a..7a347fe253ec 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/params/GrParameterImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/params/GrParameterImpl.java @@ -96,22 +96,24 @@ public class GrParameterImpl extends GrVariableImpl implements GrParameter { } - @NotNull - public PsiType getType() { - /*PsiType type = getTypeGroovy(); - if (type == null) type = super.getType();*/ - PsiType type = super.getType(); + @Override + public PsiType getDeclaredType() { + final PsiType type = super.getDeclaredType(); if (isVarArgs()) { return new PsiEllipsisType(type); } - else if (isMainMethodFirstUntypedParameter()) { + return type; + } + + @NotNull + public PsiType getType() { + PsiType type = super.getType(); + if (isMainMethodFirstUntypedParameter()) { PsiClassType stringType = JavaPsiFacade.getInstance(getProject()).getElementFactory().createTypeByFQClassName("java.lang.String", getResolveScope()); return stringType.createArrayType(); } - else { - return type; - } + return type; } private boolean isMainMethodFirstUntypedParameter() { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChageSignatureUsageSearcher.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChageSignatureUsageSearcher.java index 448b63129244..01a4d03ea1f6 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChageSignatureUsageSearcher.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChageSignatureUsageSearcher.java @@ -39,8 +39,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnonymousClassDefinition; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrEnumConstant; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; -import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature; -import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import java.util.ArrayList; @@ -207,24 +205,16 @@ class GrChageSignatureUsageSearcher { if (!GroovyFileType.GROOVY_LANGUAGE.equals(element.getLanguage())) continue; boolean isToCatchExceptions = isToThrowExceptions && needToCatchExceptions(RefactoringUtil.getEnclosingMethod(element)); - //todo check for applicability of arguments to method if (PsiUtil.isMethodUsage(element)) { - GrClosureSignature signature = GrClosureSignatureUtil.createSignature(method, PsiSubstitutor.EMPTY); final GrArgumentList argList = PsiUtil.getArgumentsList(element); //enum constant may not have argList if (argList == null) { if (element instanceof GrEnumConstant) { - result.add( - new GrMethodCallUsageInfo(element, GrClosureSignatureUtil.createSignature(method, PsiSubstitutor.EMPTY), isToModifyArgs, - isToCatchExceptions, new GrClosureSignatureUtil.ArgInfo[0])); + result.add(new GrMethodCallUsageInfo(element, isToModifyArgs, isToCatchExceptions)); } } else { - GrClosureSignatureUtil.ArgInfo[] map = - GrClosureSignatureUtil.mapParametersToArguments(signature, argList, method.getManager(), method.getResolveScope()); - result.add( - new GrMethodCallUsageInfo(element, GrClosureSignatureUtil.createSignature(method, PsiSubstitutor.EMPTY), isToModifyArgs, - isToCatchExceptions, map)); + result.add(new GrMethodCallUsageInfo(element, isToModifyArgs,isToCatchExceptions)); } } else if (element instanceof GrDocTagValueToken) { @@ -239,11 +229,7 @@ class GrChageSignatureUsageSearcher { LOG.assertTrue(method.isConstructor()); final PsiClass psiClass = (PsiClass)element; if (psiClass instanceof GrAnonymousClassDefinition) { - GrClosureSignature signature = GrClosureSignatureUtil.createSignature(method, PsiSubstitutor.EMPTY); - GrClosureSignatureUtil.ArgInfo[] map = GrClosureSignatureUtil - .mapParametersToArguments(signature, PsiUtil.getArgumentsList(element), method.getManager(), method.getResolveScope()); - result.add( - new GrMethodCallUsageInfo(element, GrClosureSignatureUtil.createSignature(method, PsiSubstitutor.EMPTY), isToModifyArgs, isToCatchExceptions, map)); + result.add(new GrMethodCallUsageInfo(element, isToModifyArgs, isToCatchExceptions)); continue; } /*if (!(myChangeInfo instanceof JavaChangeInfoImpl)) continue; todo propagate methods @@ -296,6 +282,9 @@ class GrChageSignatureUsageSearcher { UsageInfo usageInfo = new ChangeSignatureParameterUsageInfo(parmRef, parameter.getName(), info.getName()); results.add(usageInfo); } + if (info.getName() != parameter.getName()) { + + } } private boolean needToCatchExceptions(PsiMethod caller) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureDialog.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureDialog.java index 36a09576add5..a395ba7e7e53 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureDialog.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureDialog.java @@ -217,10 +217,10 @@ public class GrChangeSignatureDialog extends RefactoringDialog { builder.append(type).append(' '); builder.append(name).append('('); - final List infos = myParameterModel.getParameterInfos(); + final List infos = myParameterModel.getParameterInfos(); if (infos.size() > 0) { - final List paramsText = ContainerUtil.map(infos, new Function() { - public String fun(GrParameterInfo grParameterInfo) { + final List paramsText = ContainerUtil.map(infos, new Function() { + public String fun(GrTableParameterInfo grParameterInfo) { return generateParameterText(grParameterInfo); } }); @@ -245,7 +245,7 @@ public class GrChangeSignatureDialog extends RefactoringDialog { } - private static String generateParameterText(GrParameterInfo info) { + private static String generateParameterText(GrTableParameterInfo info) { StringBuilder builder = new StringBuilder(); final PsiTypeCodeFragment typeFragment = info.getTypeFragment(); String typeText = typeFragment != null ? typeFragment.getText().trim() : GrModifier.DEF; @@ -290,14 +290,19 @@ public class GrChangeSignatureDialog extends RefactoringDialog { } String newName = getNewName(); - final List parameterInfos = myParameterModel.getParameterInfos(); - + final List tableParameterInfos = myParameterModel.getParameterInfos(); + final List parameterInfos = ContainerUtil.map(tableParameterInfos, new Function() { + public GrParameterInfo fun(GrTableParameterInfo info) { + return info.generateParameterInfo(); + } + }); final ThrownExceptionInfo[] exceptionInfos = myExceptionTableModel.getThrownExceptions(); - invokeRefactoring(new GrChangeSignatureProcessor( - myProject, - new GrChangeInfoImpl(myMethod, modifier, returnType == null ? null : CanonicalTypes.createTypeWrapper(returnType), newName, - parameterInfos, exceptionInfos, myDelegateRadioButton.isSelected()))); - + invokeRefactoring(new GrChangeSignatureProcessor(myProject, new GrChangeInfoImpl(myMethod, modifier, returnType == null + ? null + : CanonicalTypes + .createTypeWrapper(returnType), + newName, parameterInfos, exceptionInfos, + myDelegateRadioButton.isSelected()))); } private String getNewName() { @@ -319,7 +324,7 @@ public class GrChangeSignatureDialog extends RefactoringDialog { return false; } - for (GrParameterInfo info : myParameterModel.getParameterInfos()) { + for (GrTableParameterInfo info : myParameterModel.getParameterInfos()) { if (!StringUtil.isJavaIdentifier(info.getName())) { showErrorHint(message("name.is.wrong", info.getName())); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureUsageProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureUsageProcessor.java index 979a99994e26..dc01b03df1b5 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureUsageProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureUsageProcessor.java @@ -52,7 +52,8 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArg import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSafeCastExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameterList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition; @@ -291,7 +292,7 @@ public class GrChangeSignatureUsageProcessor implements ChangeSignatureUsageProc if (usageInfo instanceof GrMethodCallUsageInfo) { processMethodUsage(element, ((JavaChangeInfo)changeInfo), ((GrMethodCallUsageInfo)usageInfo).isToChangeArguments(), ((GrMethodCallUsageInfo)usageInfo).isToCatchExceptions(), - ((GrMethodCallUsageInfo)usageInfo).getMapToArguments()); + ((GrMethodCallUsageInfo)usageInfo).getMapToArguments(), ((GrMethodCallUsageInfo)usageInfo).getSubstitutor()); return true; } else if (usageInfo instanceof DefaultConstructorImplicitUsageInfo) { @@ -334,18 +335,21 @@ public class GrChangeSignatureUsageProcessor implements ChangeSignatureUsageProc } constructor = (GrConstructor)psiClass.add(constructor); - processConstructor(constructor, changeInfo); } private static void processConstructor(GrMethod constructor, JavaChangeInfo changeInfo) { + final PsiClass containingClass = constructor.getContainingClass(); + final PsiClass baseClass = changeInfo.getMethod().getContainingClass(); + final PsiSubstitutor substitutor = TypeConversionUtil.getSuperClassSubstitutor(baseClass, containingClass, PsiSubstitutor.EMPTY); + GrOpenBlock block = constructor.getBlock(); GrConstructorInvocation invocation = GroovyPsiElementFactory.getInstance(constructor.getProject()).createConstructorInvocation("super()"); invocation = (GrConstructorInvocation)block.addStatementBefore(invocation, getFirstStatement(block)); processMethodUsage(invocation.getThisOrSuperKeyword(), changeInfo, changeInfo.isParameterSetOrOrderChanged() || changeInfo.isParameterNamesChanged(), - changeInfo.isExceptionSetChanged(), GrClosureSignatureUtil.ArgInfo.EMPTY_ARRAY); + changeInfo.isExceptionSetChanged(), GrClosureSignatureUtil.ArgInfo.EMPTY_ARRAY, substitutor); } @Nullable @@ -359,7 +363,7 @@ public class GrChangeSignatureUsageProcessor implements ChangeSignatureUsageProc JavaChangeInfo changeInfo, boolean toChangeArguments, boolean toCatchExceptions, - GrClosureSignatureUtil.ArgInfo[] map) { + GrClosureSignatureUtil.ArgInfo[] map, PsiSubstitutor substitutor) { if (map == null) return; if (changeInfo.isNameChanged()) { if (element instanceof GrReferenceElement) { @@ -414,10 +418,17 @@ public class GrChangeSignatureUsageProcessor implements ChangeSignatureUsageProc argument.delete(); } argText.replace(argText.length() - 2, argText.length(), "]"); - if (!(arguments.size() > 0 && arguments.iterator().next() instanceof GrNamedArgument)) { - argText.append(" as ").append(parameter.getTypeText()); + PsiType type = parameter.createType(changeInfo.getMethod().getParameterList(), argumentList.getManager()); + if (type instanceof PsiArrayType) { + type = substitutor.substitute(type); + String typeText = type.getCanonicalText(); + if (type instanceof PsiEllipsisType) { + typeText = typeText.replace("...", "[]"); + } + argText.append(" as ").append(typeText); } anchor = argumentList.addAfter(factory.createExpressionFromText(argText.toString()), anchor); + PsiUtil.shortenReferences((GroovyPsiElement)anchor); } } else { //arguments for simple parameters diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrMethodCallUsageInfo.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrMethodCallUsageInfo.java index b077913edf33..a92476e6e3c1 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrMethodCallUsageInfo.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrMethodCallUsageInfo.java @@ -17,10 +17,12 @@ package org.jetbrains.plugins.groovy.refactoring.changeSignature; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiMethod; -import com.intellij.psi.PsiNewExpression; +import com.intellij.psi.PsiSubstitutor; import com.intellij.usageView.UsageInfo; import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrConstructorInvocation; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrApplicationStatement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; @@ -28,6 +30,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrC import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrEnumConstant; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature; import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil; +import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; /** * @author Maxim.Medvedev @@ -37,6 +40,7 @@ public class GrMethodCallUsageInfo extends UsageInfo { private final boolean myToCatchExceptions; private final PsiMethod myReferencedMethod; private GrClosureSignatureUtil.ArgInfo[] myMapToArguments; + private PsiSubstitutor mySubstitutor; public boolean isToCatchExceptions() { return myToCatchExceptions; @@ -46,35 +50,39 @@ public class GrMethodCallUsageInfo extends UsageInfo { return myToChangeArguments; } - public GrMethodCallUsageInfo(PsiElement element, - GrClosureSignature oldSignature, - boolean isToChangeArguments, - boolean isToCatchExceptions, GrClosureSignatureUtil.ArgInfo[] mapToArguments) { + public GrMethodCallUsageInfo(PsiElement element, boolean isToChangeArguments, boolean isToCatchExceptions) { super(element); myToChangeArguments = isToChangeArguments; myToCatchExceptions = isToCatchExceptions; - myMapToArguments = mapToArguments; - myReferencedMethod = resolveMethod(element); + final GroovyResolveResult resolveResult = resolveMethod(element); + myReferencedMethod = (PsiMethod)resolveResult.getElement(); + mySubstitutor = resolveResult.getSubstitutor(); + final GrArgumentList list = PsiUtil.getArgumentsList(element); + if (list == null) { + myMapToArguments = GrClosureSignatureUtil.ArgInfo.EMPTY_ARRAY; + } + else { + final GrClosureSignature signature = GrClosureSignatureUtil.createSignature(myReferencedMethod, mySubstitutor); + myMapToArguments = + GrClosureSignatureUtil.mapParametersToArguments(signature, list, element.getManager(), myReferencedMethod.getResolveScope()); + } } @Nullable - private static PsiMethod resolveMethod(final PsiElement ref) { - if (ref instanceof GrEnumConstant) return ((GrEnumConstant)ref).resolveConstructor(); + private static GroovyResolveResult resolveMethod(final PsiElement ref) { + if (ref instanceof GrEnumConstant) return ((GrEnumConstant)ref).resolveConstructorGenerics(); PsiElement parent = ref.getParent(); if (parent instanceof GrCallExpression) { - return ((GrCallExpression)parent).resolveMethod(); + return ((GrCallExpression)parent).getMethodVariants()[0]; } else if (parent instanceof GrApplicationStatement) { final GrExpression expression = ((GrApplicationStatement)parent).getFunExpression(); if (expression instanceof GrReferenceExpression) { - final PsiElement element = ((GrReferenceExpression)expression).resolve(); - if (element instanceof PsiMethod) { - return (PsiMethod)element; - } + return ((GrReferenceExpression)expression).advancedResolve(); } } else if (parent instanceof GrConstructorInvocation) { - return ((PsiNewExpression)parent.getParent()).resolveConstructor(); + return ((GrConstructorInvocation)parent).resolveConstructorGenerics(); } return null; @@ -87,4 +95,8 @@ public class GrMethodCallUsageInfo extends UsageInfo { public GrClosureSignatureUtil.ArgInfo[] getMapToArguments() { return myMapToArguments; } + + public PsiSubstitutor getSubstitutor() { + return mySubstitutor; + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrParameterInfo.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrParameterInfo.java index 5d47ba7c138a..77f9f4544090 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrParameterInfo.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrParameterInfo.java @@ -17,12 +17,11 @@ package org.jetbrains.plugins.groovy.refactoring.changeSignature; import com.intellij.openapi.project.Project; import com.intellij.psi.*; -import com.intellij.psi.search.GlobalSearchScope; import com.intellij.refactoring.changeSignature.JavaParameterInfo; import com.intellij.refactoring.util.CanonicalTypes; import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.plugins.groovy.debugger.fragments.GroovyCodeFragment; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; @@ -30,60 +29,52 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; * @author Maxim.Medvedev */ public class GrParameterInfo implements JavaParameterInfo { - private GroovyCodeFragment myName; - private GroovyCodeFragment myDefaultValue; - private PsiTypeCodeFragment myType; - private GroovyCodeFragment myDefaultInitializer; + private String myName; + private final String myDefaultValue; + private final String myDefaultInitializer; private final int myPosition; private CanonicalTypes.Type myTypeWrapper; public GrParameterInfo(GrParameter parameter, int position) { myPosition = position; final Project project = parameter.getProject(); - myName = new GroovyCodeFragment(project, parameter.getName()); + myName = parameter.getName(); final PsiType type = parameter.getDeclaredType(); if (type != null) { - myType = JavaPsiFacade.getElementFactory(project).createTypeCodeFragment(type.getCanonicalText(), parameter, true, true); + myTypeWrapper = CanonicalTypes.createTypeWrapper(type); } else { - myType = JavaPsiFacade.getElementFactory(project).createTypeCodeFragment("", parameter, true, true); + myTypeWrapper = null; } final GrExpression defaultInitializer = parameter.getDefaultInitializer(); if (defaultInitializer != null) { - myDefaultInitializer = new GroovyCodeFragment(project, defaultInitializer.getText()); + myDefaultInitializer = defaultInitializer.getText(); } else { - myDefaultInitializer = new GroovyCodeFragment(project, ""); + myDefaultInitializer = ""; } - myDefaultValue = new GroovyCodeFragment(project, ""); + myDefaultValue = ""; } - public GrParameterInfo(Project project, PsiElement context) { - this.myPosition = -1; - myName = new GroovyCodeFragment(project, ""); - myDefaultValue = new GroovyCodeFragment(project, ""); - myType = JavaPsiFacade.getElementFactory(project).createTypeCodeFragment("", context, true, true); - myDefaultInitializer = new GroovyCodeFragment(project, ""); - } - - public GroovyCodeFragment getNameFragment() { - return myName; - } - - public GroovyCodeFragment getDefaultValueFragment() { - return myDefaultValue; - } - - public PsiTypeCodeFragment getTypeFragment() { - return myType; - } - - public GroovyCodeFragment getDefaultInitializerFragment() { - return myDefaultInitializer; + public GrParameterInfo(@NotNull String name, + @Nullable String defaultValue, + @Nullable String defaultInitializer, + @Nullable PsiType type, + int position) { + myName = name; + myDefaultValue = defaultValue; + myDefaultInitializer = defaultInitializer; + myPosition = position; + if (type != null) { + myTypeWrapper = CanonicalTypes.createTypeWrapper(type); + } + else { + myTypeWrapper = null; + } } public String getName() { - return myName.getText().trim(); + return myName; } public int getOldIndex() { @@ -91,46 +82,30 @@ public class GrParameterInfo implements JavaParameterInfo { } public String getDefaultValue() { - return myDefaultValue.getText().trim(); + return myDefaultValue; } @Nullable public PsiType createType(PsiElement context, final PsiManager manager) throws IncorrectOperationException { - try { - return myType.getType(); - } - catch (PsiTypeCodeFragment.TypeSyntaxException e) { - return null; - } - catch (PsiTypeCodeFragment.NoTypeException e) { - return JavaPsiFacade.getElementFactory(manager.getProject()) - .createTypeByFQClassName(CommonClassNames.JAVA_LANG_OBJECT, GlobalSearchScope.allScope(manager.getProject())); - } + if (myTypeWrapper == null) return null; + return myTypeWrapper.getType(context, manager); } - public String getTypeText() { - CanonicalTypes.Type type = getTypeWrapper(); - if (type != null) { - return type.getTypeText(); + if (myTypeWrapper != null) { + return myTypeWrapper.getTypeText(); } return ""; } @Nullable public CanonicalTypes.Type getTypeWrapper() { - if (myTypeWrapper == null) { - PsiType type = createType(myType.getContext(), myType.getManager()); - if (type != null) { - myTypeWrapper = CanonicalTypes.createTypeWrapper(type); - } - } return myTypeWrapper; } public PsiExpression getValue(PsiCallExpression callExpression) { return JavaPsiFacade.getInstance(callExpression.getProject()).getElementFactory() - .createExpressionFromText(myDefaultValue.getText(), callExpression); + .createExpressionFromText(myDefaultValue, callExpression); } public boolean isVarargType() { @@ -146,10 +121,17 @@ public class GrParameterInfo implements JavaParameterInfo { } public String getDefaultInitializer() { - return myDefaultInitializer.getText().trim(); + return myDefaultInitializer; } public boolean hasNoType() { - return myType.getText().trim().length() == 0; + return getTypeText().length() == 0; + } + + /** + * for testing only + */ + public void setName(String newName) { + myName = newName; } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrParameterTableModel.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrParameterTableModel.java index ee6287c3afc2..81a4c9d08865 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrParameterTableModel.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrParameterTableModel.java @@ -32,7 +32,7 @@ import java.util.List; * @author Maxim.Medvedev */ public class GrParameterTableModel extends AbstractTableModel implements RowEditableTableModel { - private final List infos; + private final List infos; private final GrMethod myMethod; private final GrChangeSignatureDialog myDialog; private final Project myProject; @@ -41,17 +41,17 @@ public class GrParameterTableModel extends AbstractTableModel implements RowEdit myMethod = method; myDialog = dialog; final GrParameter[] parameters = myMethod.getParameters(); - infos = new ArrayList(parameters.length); + infos = new ArrayList(parameters.length); for (int i = 0; i < parameters.length; i++) { GrParameter parameter = parameters[i]; - infos.add(new GrParameterInfo(parameter, i)); + infos.add(new GrTableParameterInfo(parameter, i)); } myProject = project; } public void addRow() { final int row = infos.size(); - infos.add(new GrParameterInfo(myProject, myMethod)); + infos.add(new GrTableParameterInfo(myProject, myMethod)); fireTableRowsInserted(row, row); } @@ -61,7 +61,7 @@ public class GrParameterTableModel extends AbstractTableModel implements RowEdit } public void exchangeRows(int index1, int index2) { - final GrParameterInfo info = infos.get(index1); + final GrTableParameterInfo info = infos.get(index1); infos.set(index1, infos.get(index2)); infos.set(index2, info); fireTableRowsUpdated(Math.min(index1, index2), Math.max(index1, index2)); @@ -79,7 +79,7 @@ public class GrParameterTableModel extends AbstractTableModel implements RowEdit @Nullable public Object getValueAt(int rowIndex, int columnIndex) { if (rowIndex < 0 || rowIndex >= infos.size()) return null; - final GrParameterInfo info = infos.get(rowIndex); + final GrTableParameterInfo info = infos.get(rowIndex); switch (columnIndex) { case 0: return info.getTypeFragment(); @@ -135,11 +135,11 @@ public class GrParameterTableModel extends AbstractTableModel implements RowEdit @Override public boolean isCellEditable(int rowIndex, int columnIndex) { if (columnIndex < 3) return true; - GrParameterInfo info = infos.get(rowIndex); + GrTableParameterInfo info = infos.get(rowIndex); return info.getOldIndex() < 0; } - public List getParameterInfos() { + public List getParameterInfos() { return infos; } } \ No newline at end of file diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrTableParameterInfo.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrTableParameterInfo.java new file mode 100644 index 000000000000..ff5d2fe96b43 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrTableParameterInfo.java @@ -0,0 +1,110 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.refactoring.changeSignature; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.JavaPsiFacade; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiType; +import com.intellij.psi.PsiTypeCodeFragment; +import org.jetbrains.plugins.groovy.debugger.fragments.GroovyCodeFragment; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; + +/** + * @author Maxim.Medvedev + */ +public class GrTableParameterInfo { + private GroovyCodeFragment myName; + private GroovyCodeFragment myDefaultValue; + private PsiTypeCodeFragment myType; + private GroovyCodeFragment myDefaultInitializer; + private final int myPosition; + + public GrTableParameterInfo(GrParameter parameter, int position) { + myPosition = position; + final Project project = parameter.getProject(); + myName = new GroovyCodeFragment(project, parameter.getName()); + final PsiType type = parameter.getDeclaredType(); + if (type != null) { + String typeText = type.getCanonicalText(); + if (typeText == null) typeText = type.getPresentableText(); + myType = JavaPsiFacade.getElementFactory(project).createTypeCodeFragment(typeText, parameter, true, true, true); + } + else { + myType = JavaPsiFacade.getElementFactory(project).createTypeCodeFragment("", parameter, true, true, true); + } + final GrExpression defaultInitializer = parameter.getDefaultInitializer(); + if (defaultInitializer != null) { + myDefaultInitializer = new GroovyCodeFragment(project, defaultInitializer.getText()); + } + else { + myDefaultInitializer = new GroovyCodeFragment(project, ""); + } + myDefaultValue = new GroovyCodeFragment(project, ""); + } + + public GrTableParameterInfo(Project project, PsiElement context) { + this.myPosition = -1; + myName = new GroovyCodeFragment(project, ""); + myDefaultValue = new GroovyCodeFragment(project, ""); + myType = JavaPsiFacade.getElementFactory(project).createTypeCodeFragment("", context, true, true); + myDefaultInitializer = new GroovyCodeFragment(project, ""); + } + + public GroovyCodeFragment getNameFragment() { + return myName; + } + + public GroovyCodeFragment getDefaultValueFragment() { + return myDefaultValue; + } + + public PsiTypeCodeFragment getTypeFragment() { + return myType; + } + + public GroovyCodeFragment getDefaultInitializerFragment() { + return myDefaultInitializer; + } + + public String getName() { + return myName.getText().trim(); + } + + public int getOldIndex() { + return myPosition; + } + + public String getDefaultValue() { + return myDefaultValue.getText().trim(); + } + + public GrParameterInfo generateParameterInfo() { + String defaultInitializer = myDefaultInitializer.getText().trim(); + PsiType type; + try { + type = myType.getType(); + } + catch (PsiTypeCodeFragment.TypeSyntaxException e) { + type = null; + } + catch (PsiTypeCodeFragment.NoTypeException e) { + type = null; + } + return new GrParameterInfo(getName(), getDefaultValue(), defaultInitializer, type, myPosition); + } +} diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/changeSignature/ChangeSignatureTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/changeSignature/ChangeSignatureTest.java index c384a1ea8066..746ef3c2b8e4 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/changeSignature/ChangeSignatureTest.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/changeSignature/ChangeSignatureTest.java @@ -15,7 +15,10 @@ */ package org.jetbrains.plugins.groovy.refactoring.changeSignature; -import com.intellij.psi.*; +import com.intellij.psi.CommonClassNames; +import com.intellij.psi.JavaPsiFacade; +import com.intellij.psi.PsiClassType; +import com.intellij.psi.PsiType; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.refactoring.changeSignature.JavaThrownExceptionInfo; import com.intellij.refactoring.changeSignature.ThrownExceptionInfo; @@ -35,7 +38,7 @@ public class ChangeSignatureTest extends ChangeSignatureTestCase { public void testOneNewParameter() throws Exception { doTest(new SimpleInfo[]{ - new SimpleInfo("p", -1, "\"5\"", null, createType(CommonClassNames.JAVA_LANG_STRING))}); + new SimpleInfo("p", -1, "\"5\"", null, CommonClassNames.JAVA_LANG_STRING)}); } public void testRemoveParameter() throws Exception { @@ -194,7 +197,7 @@ public class ChangeSignatureTest extends ChangeSignatureTestCase { } public void testTypeParameters() throws Exception { - doTest(new SimpleInfo[]{new SimpleInfo("list", -1, "null", null, createType("java.util.List")), new SimpleInfo(0)}); + doTest(new SimpleInfo[]{new SimpleInfo("list", -1, "null", null, "java.util.List"), new SimpleInfo(0)}); } public void testEnumConstructor() throws Exception { @@ -205,6 +208,10 @@ public class ChangeSignatureTest extends ChangeSignatureTestCase { doTest(new SimpleInfo[] {new SimpleInfo(1), new SimpleInfo(0)}); } + public void testReplaceVarargWithArray() throws Exception { + doTest(new SimpleInfo[]{new SimpleInfo("l", 1, null, null, "List[]"), new SimpleInfo(0)}); + } + private PsiType createType(String typeText) { return JavaPsiFacade.getElementFactory(getProject()).createTypeByFQClassName(typeText, GlobalSearchScope.allScope(getProject())); } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/changeSignature/ChangeSignatureTestCase.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/changeSignature/ChangeSignatureTestCase.java index fc9a22d75d60..bb342d1d5c93 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/changeSignature/ChangeSignatureTestCase.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/changeSignature/ChangeSignatureTestCase.java @@ -16,15 +16,13 @@ package org.jetbrains.plugins.groovy.refactoring.changeSignature; import com.intellij.codeInsight.TargetElementUtilBase; -import com.intellij.openapi.application.Result; -import com.intellij.openapi.application.WriteAction; -import com.intellij.openapi.editor.Document; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.refactoring.changeSignature.ThrownExceptionInfo; import com.intellij.refactoring.util.CanonicalTypes; import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; import com.intellij.util.IncorrectOperationException; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; @@ -84,43 +82,43 @@ public abstract class ChangeSignatureTestCase extends LightCodeInsightFixtureTes GrParameter[] params = method.getParameterList().getParameters(); GrParameterInfo[] result = new GrParameterInfo[myInfos.length]; for (int i = 0; i < myInfos.length; i++) { + final SimpleInfo sim = myInfos[i]; int oldIndex = sim.myOldIndex; + final GrParameterInfo info; + String name = null; + String defInitializer = null; + PsiType type = null; + String defValue = null; if (oldIndex > -1) { - info = new GrParameterInfo(params[oldIndex], oldIndex); - } - else { - info = new GrParameterInfo(myProject, method); + final GrParameter p = params[oldIndex]; + name = p.getName(); + final GrExpression initializer = p.getDefaultInitializer(); + defInitializer = initializer != null ? initializer.getText() : null; + type = p.getDeclaredType(); } + if (sim.myNewName != null) { - setText(info.getNameFragment(), sim.myNewName); + name = sim.myNewName; } - if (sim.myType != null) { - setText(info.getTypeFragment(), sim.myType.getCanonicalText()); + if (sim.myType != null && sim.myType.length() > 0) { + type = JavaPsiFacade.getElementFactory(myProject).createTypeFromText(sim.myType, method); } if (sim.myDefaultInitializer != null) { - setText(info.getDefaultInitializerFragment(), sim.myDefaultInitializer); + defInitializer = sim.myDefaultInitializer; } if (sim.myDefaultValue != null) { - setText(info.getDefaultValueFragment(), sim.myDefaultValue); + defValue = sim.myDefaultValue; } + + assert (oldIndex < 0 && defValue != null) || oldIndex >= 0; + assert name != null; + info = new GrParameterInfo(name, defValue, defInitializer, type, oldIndex); result[i] = info; } return result; } - - private void setText(final PsiCodeFragment codeFragment, final String newText) { - new WriteAction() { - @Override - protected void run(Result result) throws Throwable { - final PsiDocumentManager docManager = PsiDocumentManager.getInstance(myProject); - final Document document = docManager.getDocument(codeFragment); - document.setText(newText); - docManager.commitDocument(document); - } - }.execute(); - } } interface GenExceptions { @@ -151,22 +149,26 @@ public abstract class ChangeSignatureTestCase extends LightCodeInsightFixtureTes String myNewName; String myDefaultValue; String myDefaultInitializer; - private PsiType myType; + private String myType; SimpleInfo(int oldIndex) { this(null, oldIndex); } SimpleInfo(String newName, int oldIndex) { - this(newName, oldIndex, "", null, null); + this(newName, oldIndex, "", null, ""); } - SimpleInfo(String newName, int oldIndex, String defaultValue, String defaultInitializer, PsiType type) { + SimpleInfo(String newName, int oldIndex, String defaultValue, String defaultInitializer, String type) { myOldIndex = oldIndex; myNewName = newName; myDefaultValue = defaultValue; myDefaultInitializer = defaultInitializer; myType = type; } + + SimpleInfo(String newName, int oldIndex, String defaultValue, String defaultInitializer, PsiType type) { + this(newName, oldIndex, defaultValue, defaultInitializer, type.getCanonicalText()); + } } } diff --git a/plugins/groovy/testdata/refactoring/changeSignature/MoveVarArgParameters.groovy b/plugins/groovy/testdata/refactoring/changeSignature/MoveVarArgParameters.groovy index 1b9feb37d300..3c4bcbe90285 100644 --- a/plugins/groovy/testdata/refactoring/changeSignature/MoveVarArgParameters.groovy +++ b/plugins/groovy/testdata/refactoring/changeSignature/MoveVarArgParameters.groovy @@ -1,3 +1,3 @@ -def foo(String s, String[] args) {} +def foo(String s, String... args) {} foo("a", "b", "c") \ No newline at end of file diff --git a/plugins/groovy/testdata/refactoring/changeSignature/MoveVarArgParameters_after.groovy b/plugins/groovy/testdata/refactoring/changeSignature/MoveVarArgParameters_after.groovy index d34406f1958f..9a4978f320ed 100644 --- a/plugins/groovy/testdata/refactoring/changeSignature/MoveVarArgParameters_after.groovy +++ b/plugins/groovy/testdata/refactoring/changeSignature/MoveVarArgParameters_after.groovy @@ -1,3 +1,3 @@ -def foo(String[] args, String s) {} +def foo(String... args, String s) {} foo(["b", "c"] as String[], "a") \ No newline at end of file diff --git a/plugins/groovy/testdata/refactoring/changeSignature/MoveVarArgParameters_after.java b/plugins/groovy/testdata/refactoring/changeSignature/MoveVarArgParameters_after.java index 3c8a30ae9d82..682ce050f6a7 100644 --- a/plugins/groovy/testdata/refactoring/changeSignature/MoveVarArgParameters_after.java +++ b/plugins/groovy/testdata/refactoring/changeSignature/MoveVarArgParameters_after.java @@ -1,5 +1,5 @@ class Foo { public static void main(String[] args) { - new MoveVarArgParameters().foo(new String[]{"b", "c"}, "a") + new MoveVarArgParameters().foo(new String[]{"b","c"},"a" ) } } \ No newline at end of file diff --git a/plugins/groovy/testdata/refactoring/changeSignature/ReplaceVarargWithArray.groovy b/plugins/groovy/testdata/refactoring/changeSignature/ReplaceVarargWithArray.groovy new file mode 100644 index 000000000000..d47669e10e5a --- /dev/null +++ b/plugins/groovy/testdata/refactoring/changeSignature/ReplaceVarargWithArray.groovy @@ -0,0 +1,14 @@ +class List {} + +class Base { + void foo(String s, List... l) {} +} + +class Inheritor extends Base { + void foo(String s, List... l) {} + + { + new Inheritor().foo("a", new ArrayList()); + } +} + diff --git a/plugins/groovy/testdata/refactoring/changeSignature/ReplaceVarargWithArray_after.groovy b/plugins/groovy/testdata/refactoring/changeSignature/ReplaceVarargWithArray_after.groovy new file mode 100644 index 000000000000..be83d989534c --- /dev/null +++ b/plugins/groovy/testdata/refactoring/changeSignature/ReplaceVarargWithArray_after.groovy @@ -0,0 +1,14 @@ +class List {} + +class Base { + void foo(List[] l, String s) {} +} + +class Inheritor extends Base { + void foo(List[] l, String s) {} + + { + new Inheritor().foo([new List()] as List[], "a"); + } +} +