From 55f930a0e180a732a40ee18a8ae691f1e43b6c27 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 8 Jun 2012 20:34:45 +0400 Subject: [PATCH] change signature: substitute param types according to class hierarchy (IDEA-87146) --- .../JavaChangeSignatureUsageProcessor.java | 14 ++++++-- .../ParamTypeSubst.java | 10 ++++++ .../ParamTypeSubst.java.after | 10 ++++++ .../ChangeSignaturePropagationTest.java | 35 ++++++++++++++----- 4 files changed, 58 insertions(+), 11 deletions(-) create mode 100644 java/java-tests/testData/refactoring/changeSignaturePropagation/ParamTypeSubst.java create mode 100644 java/java-tests/testData/refactoring/changeSignaturePropagation/ParamTypeSubst.java.after 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 2d99c94337d0..a5ead200d950 100644 --- a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java @@ -741,8 +741,13 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr final JavaParameterInfo[] primaryNewParms = changeInfo.getNewParameters(); PsiSubstitutor substitutor = baseMethod == null ? PsiSubstitutor.EMPTY : ChangeSignatureProcessor.calculateSubstitutor(caller, baseMethod); + final PsiClass aClass = changeInfo.getMethod().getContainingClass(); + final PsiClass callerContainingClass = caller.getContainingClass(); + final PsiSubstitutor psiSubstitutor = aClass != null && callerContainingClass != null && callerContainingClass.isInheritor(aClass, true) + ? TypeConversionUtil.getSuperClassSubstitutor(aClass, callerContainingClass, substitutor) + : PsiSubstitutor.EMPTY; for (JavaParameterInfo info : primaryNewParms) { - if (info.getOldIndex() < 0) newParameters.add(createNewParameter(changeInfo, info, substitutor)); + if (info.getOldIndex() < 0) newParameters.add(createNewParameter(changeInfo, info, psiSubstitutor, substitutor)); } PsiParameter[] arrayed = newParameters.toArray(new PsiParameter[newParameters.size()]); boolean[] toRemoveParm = new boolean[arrayed.length]; @@ -802,10 +807,13 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr } private static PsiParameter createNewParameter(JavaChangeInfo changeInfo, JavaParameterInfo newParm, - PsiSubstitutor substitutor) throws IncorrectOperationException { + PsiSubstitutor... substitutor) throws IncorrectOperationException { final PsiParameterList list = changeInfo.getMethod().getParameterList(); final PsiElementFactory factory = JavaPsiFacade.getInstance(list.getProject()).getElementFactory(); - final PsiType type = substitutor.substitute(newParm.createType(list, list.getManager())); + PsiType type = newParm.createType(list, list.getManager()); + for (PsiSubstitutor psiSubstitutor : substitutor) { + type = psiSubstitutor.substitute(type); + } return factory.createParameter(newParm.getName(), type); } diff --git a/java/java-tests/testData/refactoring/changeSignaturePropagation/ParamTypeSubst.java b/java/java-tests/testData/refactoring/changeSignaturePropagation/ParamTypeSubst.java new file mode 100644 index 000000000000..374f3cccbad1 --- /dev/null +++ b/java/java-tests/testData/refactoring/changeSignaturePropagation/ParamTypeSubst.java @@ -0,0 +1,10 @@ +class Base { + void m() { + } +} + +class A extends Base { + void x() { + m(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/changeSignaturePropagation/ParamTypeSubst.java.after b/java/java-tests/testData/refactoring/changeSignaturePropagation/ParamTypeSubst.java.after new file mode 100644 index 000000000000..070698a3d8c6 --- /dev/null +++ b/java/java-tests/testData/refactoring/changeSignaturePropagation/ParamTypeSubst.java.after @@ -0,0 +1,10 @@ +class Base { + void m(T clazz) { + } +} + +class A extends Base { + void x(String clazz) { + m(clazz); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/refactoring/ChangeSignaturePropagationTest.java b/java/java-tests/testSrc/com/intellij/refactoring/ChangeSignaturePropagationTest.java index bdb1445df3ce..6daec4d62b1d 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/ChangeSignaturePropagationTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/ChangeSignaturePropagationTest.java @@ -6,6 +6,8 @@ import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.searches.ClassInheritorsSearch; import com.intellij.psi.search.searches.MethodReferencesSearch; +import com.intellij.psi.search.searches.ReferencesSearch; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.refactoring.changeSignature.ChangeSignatureProcessor; import com.intellij.refactoring.changeSignature.JavaThrownExceptionInfo; import com.intellij.refactoring.changeSignature.ParameterInfoImpl; @@ -29,6 +31,18 @@ public class ChangeSignaturePropagationTest extends LightRefactoringTestCase { parameterPropagationTest(); } + public void testParamTypeSubst() throws Exception { + final PsiMethod method = getPrimaryMethod(); + final HashSet methods = new HashSet(); + for (PsiReference reference : ReferencesSearch.search(method)) { + final PsiMethod psiMethod = PsiTreeUtil.getParentOfType(reference.getElement(), PsiMethod.class); + if (psiMethod != null) { + methods.add(psiMethod); + } + } + parameterPropagationTest(method, methods, JavaPsiFacade.getElementFactory(getProject()).createTypeByFQClassName("T")); + } + public void testExceptionSimple() throws Exception { exceptionPropagationTest(); } @@ -39,7 +53,7 @@ public class ChangeSignaturePropagationTest extends LightRefactoringTestCase { public void testParamWithNoConstructor() throws Exception { final PsiMethod method = getPrimaryMethod(); - parameterPropagationTest(method, collectNonPhysicalMethodsToPropagate(method)); + parameterPropagationTest(method, collectNonPhysicalMethodsToPropagate(method), JavaPsiFacade.getElementFactory(getProject()).createTypeByFQClassName("java.lang.Class", GlobalSearchScope.allScope(getProject()))); } public void testExceptionWithNoConstructor() throws Exception { @@ -62,12 +76,12 @@ public class ChangeSignaturePropagationTest extends LightRefactoringTestCase { public void testParamWithImplicitConstructor() throws Exception { final PsiMethod method = getPrimaryMethod(); - parameterPropagationTest(method, collectDefaultConstructorsToPropagate(method)); + parameterPropagationTest(method, collectDefaultConstructorsToPropagate(method), JavaPsiFacade.getElementFactory(getProject()).createTypeByFQClassName("java.lang.Class", GlobalSearchScope.allScope(getProject()))); } public void testParamWithImplicitConstructors() throws Exception { final PsiMethod method = getPrimaryMethod(); - parameterPropagationTest(method, collectDefaultConstructorsToPropagate(method)); + parameterPropagationTest(method, collectDefaultConstructorsToPropagate(method), JavaPsiFacade.getElementFactory(getProject()).createTypeByFQClassName("java.lang.Class", GlobalSearchScope.allScope(getProject()))); } public void testExceptionWithImplicitConstructor() throws Exception { @@ -84,13 +98,18 @@ public class ChangeSignaturePropagationTest extends LightRefactoringTestCase { } private void parameterPropagationTest() throws Exception { - final PsiMethod method = getPrimaryMethod(); - parameterPropagationTest(method, new HashSet(Arrays.asList(method.getContainingClass().getMethods()))); + parameterPropagationTest(JavaPsiFacade.getElementFactory(getProject()) + .createTypeByFQClassName("java.lang.Class", GlobalSearchScope.allScope(getProject()))); } - private void parameterPropagationTest(final PsiMethod method, final HashSet psiMethods) throws Exception { - PsiType newParamType = JavaPsiFacade.getElementFactory(getProject()).createTypeByFQClassName("java.lang.Class", GlobalSearchScope.allScope(getProject())); - final ParameterInfoImpl[] newParameters = new ParameterInfoImpl[]{new ParameterInfoImpl(-1, "clazz", newParamType, "null")}; + private void parameterPropagationTest(final PsiClassType paramType) throws Exception { + final PsiMethod method = getPrimaryMethod(); + parameterPropagationTest(method, new HashSet(Arrays.asList(method.getContainingClass().getMethods())), + paramType); + } + + private void parameterPropagationTest(final PsiMethod method, final HashSet psiMethods, final PsiType paramType) throws Exception { + final ParameterInfoImpl[] newParameters = new ParameterInfoImpl[]{new ParameterInfoImpl(-1, "clazz", paramType, "null")}; doTest(newParameters, new ThrownExceptionInfo[0], psiMethods, null, method); }