From 94bb0729c0cbea5cd93d4575f06e90cee48e46b4 Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 8 Sep 2011 17:12:11 +0200 Subject: [PATCH] introduce parameter: substitute type parameters on call site --- ...troduceParameterMethodUsagesProcessor.java | 19 +++++++++++++++++-- .../afterSubstituteTypeParams.java | 11 +++++++++++ .../beforeSubstituteTypeParams.java | 11 +++++++++++ .../refactoring/IntroduceParameterTest.java | 4 ++++ .../src/com/intellij/psi/GenericsUtil.java | 2 +- 5 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 java/java-tests/testData/refactoring/introduceParameter/afterSubstituteTypeParams.java create mode 100644 java/java-tests/testData/refactoring/introduceParameter/beforeSubstituteTypeParams.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 99c342f137b1..2733ea05e5b8 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/JavaIntroduceParameterMethodUsagesProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/JavaIntroduceParameterMethodUsagesProcessor.java @@ -20,6 +20,7 @@ import com.intellij.lang.Language; import com.intellij.lang.StdLanguages; import com.intellij.lang.java.JavaLanguage; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.codeStyle.JavaCodeStyleManager; @@ -64,11 +65,12 @@ public class JavaIntroduceParameterMethodUsagesProcessor implements IntroducePar PsiExpression[] oldArgs = argList.getExpressions(); final PsiExpression anchor; - if (!data.getMethodToSearchFor().isVarArgs()) { + final PsiMethod methodToSearchFor = data.getMethodToSearchFor(); + if (!methodToSearchFor.isVarArgs()) { anchor = getLast(oldArgs); } else { - final PsiParameter[] parameters = data.getMethodToSearchFor().getParameterList().getParameters(); + final PsiParameter[] parameters = methodToSearchFor.getParameterList().getParameters(); if (parameters.length > oldArgs.length) { anchor = getLast(oldArgs); } @@ -88,6 +90,7 @@ public class JavaIntroduceParameterMethodUsagesProcessor implements IntroducePar else { PsiElement initializer = ExpressionConverter.getExpression(data.getParameterInitializer().getExpression(), StdLanguages.JAVA, data.getProject()); + substituteTypeParametersInInitializer(initializer, callExpression, argList, methodToSearchFor); assert initializer instanceof PsiExpression; ChangeContextUtil.encodeContextInfo(initializer, true); PsiExpression newArg = (PsiExpression)argList.addAfter(initializer, anchor); @@ -106,6 +109,18 @@ public class JavaIntroduceParameterMethodUsagesProcessor implements IntroducePar return false; } + private static void substituteTypeParametersInInitializer(PsiElement initializer, + PsiCall callExpression, + PsiExpressionList argList, + PsiMethod method) { + final Project project = method.getProject(); + final PsiSubstitutor psiSubstitutor = JavaPsiFacade.getInstance(project).getResolveHelper() + .inferTypeArguments(method.getTypeParameters(), method.getParameterList().getParameters(), + argList.getExpressions(), PsiSubstitutor.EMPTY, callExpression, false); + RefactoringUtil.replaceMovedMemberTypeParameters(initializer, PsiUtil.typeParametersIterable(method), psiSubstitutor, + JavaPsiFacade.getElementFactory(project)); + } + private static void removeParametersFromCall(@NotNull final PsiExpressionList argList, TIntArrayList parametersToRemove) { final PsiExpression[] exprs = argList.getExpressions(); parametersToRemove.forEachDescending(new TIntProcedure() { diff --git a/java/java-tests/testData/refactoring/introduceParameter/afterSubstituteTypeParams.java b/java/java-tests/testData/refactoring/introduceParameter/afterSubstituteTypeParams.java new file mode 100644 index 000000000000..f1aecfdb25e6 --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceParameter/afterSubstituteTypeParams.java @@ -0,0 +1,11 @@ +import java.util.*; +class Test { + void foo(T t, final ArrayList anObject) { + List ls = anObject; + } + + void bar() { + String s = ""; + foo(s, new ArrayList()); + } +} diff --git a/java/java-tests/testData/refactoring/introduceParameter/beforeSubstituteTypeParams.java b/java/java-tests/testData/refactoring/introduceParameter/beforeSubstituteTypeParams.java new file mode 100644 index 000000000000..bb01ea7eef34 --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceParameter/beforeSubstituteTypeParams.java @@ -0,0 +1,11 @@ +import java.util.*; +class Test { + void foo(T t) { + List ls = new ArrayList(); + } + + void bar() { + String s = ""; + foo(s); + } +} diff --git a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterTest.java b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterTest.java index 83cef1f0fba2..7f9b3a88cda4 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterTest.java @@ -276,6 +276,10 @@ public class IntroduceParameterTest extends LightCodeInsightTestCase { doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_ALL, true, false, true, false); } + public void testSubstituteTypeParams() throws Exception { + doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_ALL, true, false, true, false); + } + private void doTestThroughHandler() throws Exception { configureByFile("/refactoring/introduceParameter/before" + getTestName(false) + ".java"); boolean enabled = true; diff --git a/java/openapi/src/com/intellij/psi/GenericsUtil.java b/java/openapi/src/com/intellij/psi/GenericsUtil.java index 412e11a52c85..1b9c18faebc1 100644 --- a/java/openapi/src/com/intellij/psi/GenericsUtil.java +++ b/java/openapi/src/com/intellij/psi/GenericsUtil.java @@ -292,7 +292,7 @@ public class GenericsUtil { substitutor = substitutor.put(typeParameter, toPut); } final PsiAnnotation[] applicableAnnotations = classType.getApplicableAnnotations(); - if (substitutor == PsiSubstitutor.EMPTY && !toExtend && applicableAnnotations.length == 0) return classType; + if (substitutor == PsiSubstitutor.EMPTY && !toExtend && applicableAnnotations.length == 0 && !(aClass instanceof PsiTypeParameter)) return classType; PsiManager manager = aClass.getManager(); PsiType result = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory() .createType(aClass, substitutor, PsiUtil.getLanguageLevel(aClass), applicableAnnotations);