diff options
author | Manju Mathew | 2013-09-06 05:31:31 +0000 |
---|---|---|
committer | Manju Mathew | 2013-09-06 05:31:31 +0000 |
commit | 4f78ecc7856d6dcfcd8c573856aa0ef637c7b38e (patch) | |
tree | 3c59caae393c95cd456bb4853ccfbc6093cac6b9 | |
parent | d7e0983c1bde492aef5ef56a395072d3fafa75fc (diff) | |
download | eclipse.jdt.ui-4f78ecc7856d6dcfcd8c573856aa0ef637c7b38e.tar.gz eclipse.jdt.ui-4f78ecc7856d6dcfcd8c573856aa0ef637c7b38e.tar.xz eclipse.jdt.ui-4f78ecc7856d6dcfcd8c573856aa0ef637c7b38e.zip |
Fix for bug 405270: [1.8][refactoring] Handling of receiver parameter
during UI refactoring
28 files changed, 867 insertions, 78 deletions
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testExtractInterface/in/A.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testExtractInterface/in/A.java new file mode 100644 index 0000000000..368c2da41d --- /dev/null +++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testExtractInterface/in/A.java @@ -0,0 +1,9 @@ +package p; +@Target({ ElementType.TYPE_USE, ElementType.METHOD }) +@interface NonNull { + +} +class A{ + public void foo1(@NonNull A this){} + public void foo2(@NonNull A this, String s){} +}
\ No newline at end of file diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testExtractInterface/out/A.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testExtractInterface/out/A.java new file mode 100644 index 0000000000..955a086f98 --- /dev/null +++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testExtractInterface/out/A.java @@ -0,0 +1,15 @@ +package p; +@Target({ ElementType.TYPE_USE, ElementType.METHOD }) +@interface NonNull { + +} +class A implements I{ + /* (non-Javadoc) + * @see p.I#foo1() + */ + public void foo1(@NonNull A this){} + /* (non-Javadoc) + * @see p.I#foo2(java.lang.String) + */ + public void foo2(@NonNull A this, String s){} +}
\ No newline at end of file diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testExtractInterface/out/I.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testExtractInterface/out/I.java new file mode 100644 index 0000000000..6bd3ca9c85 --- /dev/null +++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testExtractInterface/out/I.java @@ -0,0 +1,10 @@ +package p; + +/** typecomment template*/ +interface I { + + public abstract void foo1(@NonNull I this); + + public abstract void foo2(@NonNull I this, String s); + +}
\ No newline at end of file diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testExtractSuperclass/in/A.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testExtractSuperclass/in/A.java new file mode 100644 index 0000000000..fa79f141a6 --- /dev/null +++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testExtractSuperclass/in/A.java @@ -0,0 +1,14 @@ +package p; +@Target({ ElementType.TYPE_USE, ElementType.METHOD }) +@interface NonNull { + +} +class A{ + void foo1(@NonNull A this){ + System.out.println("foo1"); + } + void foo2(@NonNull A this, String s){ + System.out.println("foo2"); + } + +} diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testExtractSuperclass/out/A.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testExtractSuperclass/out/A.java new file mode 100644 index 0000000000..93543be974 --- /dev/null +++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testExtractSuperclass/out/A.java @@ -0,0 +1,8 @@ +package p; +@Target({ ElementType.TYPE_USE, ElementType.METHOD }) +@interface NonNull { + +} +class A extends B{ + +} diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testExtractSuperclass/out/B.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testExtractSuperclass/out/B.java new file mode 100644 index 0000000000..b3abe19188 --- /dev/null +++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testExtractSuperclass/out/B.java @@ -0,0 +1,17 @@ +package p; + +public class B { + + public B() { + super(); + } + + void foo1(@NonNull B this) { + System.out.println("foo1"); + } + + void foo2(@NonNull B this, String s) { + System.out.println("foo2"); + } + +}
\ No newline at end of file diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testMove/in/A.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testMove/in/A.java new file mode 100644 index 0000000000..baf8e412dd --- /dev/null +++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testMove/in/A.java @@ -0,0 +1,19 @@ +package p1; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; + +@Target({ ElementType.TYPE_USE, ElementType.METHOD }) +@interface NonNull { + +} +public class A { + + public void mA1(@NonNull A this, B b) { + b.mB1(); + System.out.println(b + "j"); + } + + public void mA2() {} + +}
\ No newline at end of file diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testMove/in/B.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testMove/in/B.java new file mode 100644 index 0000000000..e9d33c3ff9 --- /dev/null +++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testMove/in/B.java @@ -0,0 +1,7 @@ +package p1; + +public class B { + public void mB1() {} + + public void mB2() {} +}
\ No newline at end of file diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testMove/out/A.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testMove/out/A.java new file mode 100644 index 0000000000..de0b237d28 --- /dev/null +++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testMove/out/A.java @@ -0,0 +1,18 @@ +package p1; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; + +@Target({ ElementType.TYPE_USE, ElementType.METHOD }) +@interface NonNull { + +} +public class A { + + public void mA1(@NonNull A this, B b) { + b.mA1Moved(); + } + + public void mA2() {} + +}
\ No newline at end of file diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testMove/out/B.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testMove/out/B.java new file mode 100644 index 0000000000..daa8e4a81a --- /dev/null +++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testMove/out/B.java @@ -0,0 +1,13 @@ +package p1; + +public class B { + public void mB1() {} + + public void mB2() {} + + public void mA1Moved(@NonNull + B this) { + mB1(); + System.out.println(this + "j"); + } +}
\ No newline at end of file diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testMoveType2File/in/A.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testMoveType2File/in/A.java new file mode 100644 index 0000000000..0545965e7f --- /dev/null +++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testMoveType2File/in/A.java @@ -0,0 +1,14 @@ +package p; +@Target({ ElementType.TYPE_USE, ElementType.METHOD }) +@interface NonNull { + +} +class A{ + +class Inner{ + Inner(@NonNull A A.this){} + public void foo1(@NonNull Inner this){ + System.out.println("Hello"); + } +} +}
\ No newline at end of file diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testMoveType2File/out/A.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testMoveType2File/out/A.java new file mode 100644 index 0000000000..f33abc5e26 --- /dev/null +++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testMoveType2File/out/A.java @@ -0,0 +1,7 @@ +package p; +@Target({ ElementType.TYPE_USE, ElementType.METHOD }) +@interface NonNull { + +} +class A{ +}
\ No newline at end of file diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testMoveType2File/out/Inner.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testMoveType2File/out/Inner.java new file mode 100644 index 0000000000..1a38455261 --- /dev/null +++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testMoveType2File/out/Inner.java @@ -0,0 +1,7 @@ +package p; +class Inner{ + Inner(){} + public void foo1(@NonNull Inner this){ + System.out.println("Hello"); + } +}
\ No newline at end of file diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testPullUp/in/A.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testPullUp/in/A.java new file mode 100644 index 0000000000..334e8e471b --- /dev/null +++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testPullUp/in/A.java @@ -0,0 +1,3 @@ +package p; +class A{ +}
\ No newline at end of file diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testPullUp/in/B.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testPullUp/in/B.java new file mode 100644 index 0000000000..c19f73c251 --- /dev/null +++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testPullUp/in/B.java @@ -0,0 +1,7 @@ +package p; + +import java.util.List; +class B extends A{ + void foo1(@NonNull B this, List l){} + void foo2(@NonNull B this, String s){} +}
\ No newline at end of file diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testPullUp/in/NonNull.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testPullUp/in/NonNull.java new file mode 100644 index 0000000000..fd14798769 --- /dev/null +++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testPullUp/in/NonNull.java @@ -0,0 +1,5 @@ +package p; +@Target({ ElementType.TYPE_USE, ElementType.METHOD }) +@interface NonNull { + +}
\ No newline at end of file diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testPullUp/out/A.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testPullUp/out/A.java new file mode 100644 index 0000000000..4b18ecd5d2 --- /dev/null +++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testPullUp/out/A.java @@ -0,0 +1,10 @@ +package p; + +import java.util.List; + +class A{ + + void foo1(@NonNull A this, List l) {} + + void foo2(@NonNull A this, String s) {} +}
\ No newline at end of file diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testPullUp/out/B.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testPullUp/out/B.java new file mode 100644 index 0000000000..f6e6d24598 --- /dev/null +++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testPullUp/out/B.java @@ -0,0 +1,4 @@ +package p; + +class B extends A{ +}
\ No newline at end of file diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testPushDown/in/A.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testPushDown/in/A.java new file mode 100644 index 0000000000..67948c1199 --- /dev/null +++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testPushDown/in/A.java @@ -0,0 +1,15 @@ +package p; +@Target({ ElementType.TYPE_USE, ElementType.METHOD }) +@interface NonNull { + +} +class A{ + public void foo1(@NonNull A this) { + System.out.println("foo1"); + } + public void foo2(@NonNull A this, String s) { + System.out.println(s); + } +} +class B extends A{ +}
\ No newline at end of file diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testPushDown/out/A.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testPushDown/out/A.java new file mode 100644 index 0000000000..8fa1cf5237 --- /dev/null +++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ReceiverParameter/testPushDown/out/A.java @@ -0,0 +1,17 @@ +package p; +@Target({ ElementType.TYPE_USE, ElementType.METHOD }) +@interface NonNull { + +} +class A{ +} +class B extends A{ + + public void foo1(@NonNull B this) { + System.out.println("foo1"); + } + + public void foo2(@NonNull B this, String s) { + System.out.println(s); + } +}
\ No newline at end of file diff --git a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/ReceiverParameterTests18.java b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/ReceiverParameterTests18.java new file mode 100644 index 0000000000..f8ce88017a --- /dev/null +++ b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/ReceiverParameterTests18.java @@ -0,0 +1,453 @@ +/******************************************************************************* + * Copyright (c) 2013 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * This is an implementation of an early-draft specification developed under the Java Community Process (JCP) and + * is made available for testing and evaluation purposes only. + * The code is not compatible with any specification of the JCP. + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.ui.tests.refactoring; + +import java.util.Arrays; +import java.util.Hashtable; +import java.util.List; + +import junit.framework.Test; +import junit.framework.TestSuite; + +import org.eclipse.jdt.testplugin.TestOptions; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.NullProgressMonitor; + +import org.eclipse.ltk.core.refactoring.Refactoring; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; +import org.eclipse.ltk.core.refactoring.participants.MoveRefactoring; +import org.eclipse.ltk.core.refactoring.participants.ProcessorBasedRefactoring; + +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IField; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IMember; +import org.eclipse.jdt.core.IMethod; +import org.eclipse.jdt.core.IPackageFragment; +import org.eclipse.jdt.core.IType; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.dom.IVariableBinding; +import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants; + +import org.eclipse.jdt.internal.corext.codemanipulation.CodeGenerationSettings; +import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility; +import org.eclipse.jdt.internal.corext.refactoring.RefactoringAvailabilityTester; +import org.eclipse.jdt.internal.corext.refactoring.structure.ExtractInterfaceProcessor; +import org.eclipse.jdt.internal.corext.refactoring.structure.ExtractSupertypeProcessor; +import org.eclipse.jdt.internal.corext.refactoring.structure.MoveInnerToTopRefactoring; +import org.eclipse.jdt.internal.corext.refactoring.structure.MoveInstanceMethodProcessor; +import org.eclipse.jdt.internal.corext.refactoring.structure.PullUpRefactoringProcessor; +import org.eclipse.jdt.internal.corext.refactoring.structure.PushDownRefactoringProcessor; +import org.eclipse.jdt.internal.corext.refactoring.structure.PushDownRefactoringProcessor.MemberActionInfo; +import org.eclipse.jdt.internal.corext.refactoring.util.JavaElementUtil; +import org.eclipse.jdt.internal.corext.template.java.CodeTemplateContextType; + +import org.eclipse.jdt.internal.ui.preferences.JavaPreferencesSettings; + +public class ReceiverParameterTests18 extends RefactoringTest { + + private static final Class clazz= ReceiverParameterTests18.class; + + private static final String REFACTORING_PATH= "ReceiverParameter/"; + + private Hashtable fOldOptions; + + public ReceiverParameterTests18(String name) { + super(name); + } + + public static Test suite() { + return new Java18Setup(new TestSuite(clazz)); + } + + public static Test setUpTest(Test someTest) { + return new Java18Setup(someTest); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + StubUtility.setCodeTemplate(CodeTemplateContextType.NEWTYPE_ID, + "${package_declaration}" + + System.getProperty("line.separator", "\n") + + "${" + CodeTemplateContextType.TYPE_COMMENT + "}" + + System.getProperty("line.separator", "\n") + + "${type_declaration}", null); + + StubUtility.setCodeTemplate(CodeTemplateContextType.TYPECOMMENT_ID, "/** typecomment template*/", null); + + fOldOptions= JavaCore.getOptions(); + + Hashtable options= TestOptions.getDefaultOptions(); + options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_ASSIGNMENT_OPERATOR, DefaultCodeFormatterConstants.TRUE); + options.put(DefaultCodeFormatterConstants.FORMATTER_NUMBER_OF_EMPTY_LINES_TO_PRESERVE, "1"); + options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, JavaCore.TAB); + + JavaCore.setOptions(options); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + JavaCore.setOptions(fOldOptions); + fOldOptions= null; + } + + @Override + protected String getRefactoringPath() { + return REFACTORING_PATH; + } + + private static PullUpRefactoringProcessor createPullUpRefactoringProcessor(IMember[] methods) throws JavaModelException { + IJavaProject project= null; + if (methods != null && methods.length > 0) + project= methods[0].getJavaProject(); + if (RefactoringAvailabilityTester.isPullUpAvailable(methods)) { + PullUpRefactoringProcessor processor= new PullUpRefactoringProcessor(methods, JavaPreferencesSettings.getCodeGenerationSettings(project)); + new ProcessorBasedRefactoring(processor); + return processor; + } + return null; + } + + private static ExtractSupertypeProcessor createExtractSuperclassRefactoringProcessor(IMember[] members) throws JavaModelException { + IJavaProject project= null; + if (members != null && members.length > 0) + project= members[0].getJavaProject(); + if (RefactoringAvailabilityTester.isExtractSupertypeAvailable(members)) { + final CodeGenerationSettings settings= JavaPreferencesSettings.getCodeGenerationSettings(project); + settings.createComments= false; + ExtractSupertypeProcessor processor= new ExtractSupertypeProcessor(members, settings); + new ProcessorBasedRefactoring(processor); + return processor; + } + return null; + } + + private IPackageFragment getPackage(String name) throws JavaModelException { + if ("p".equals(name)) + return getPackageP(); + IPackageFragment pack= getRoot().getPackageFragment(name); + if (pack.exists()) + return pack; + return getRoot().createPackageFragment(name, false, new NullProgressMonitor()); + } + + private static String getTopLevelTypeName(String typeQualifiedTyperName) { + int dotIndex= typeQualifiedTyperName.indexOf('.'); + if (dotIndex == -1) + return typeQualifiedTyperName; + return typeQualifiedTyperName.substring(0, dotIndex); + } + + private void prepareForInputCheck(PushDownRefactoringProcessor processor, IMethod[] selectedMethods, IField[] selectedFields, String[] namesOfMethodsToPullUp, + String[][] signaturesOfMethodsToPullUp, String[] namesOfFieldsToPullUp, String[] namesOfMethodsToDeclareAbstract, String[][] signaturesOfMethodsToDeclareAbstract) { + IMethod[] methodsToPushDown= findMethods(selectedMethods, namesOfMethodsToPullUp, signaturesOfMethodsToPullUp); + IField[] fieldsToPushDown= findFields(selectedFields, namesOfFieldsToPullUp); + List membersToPushDown= Arrays.asList(merge(methodsToPushDown, fieldsToPushDown)); + List methodsToDeclareAbstract= Arrays.asList(findMethods(selectedMethods, namesOfMethodsToDeclareAbstract, signaturesOfMethodsToDeclareAbstract)); + + MemberActionInfo[] infos= processor.getMemberActionInfos(); + for (int i= 0; i < infos.length; i++) { + if (membersToPushDown.contains(infos[i].getMember())) { + infos[i].setAction(MemberActionInfo.PUSH_DOWN_ACTION); + assertTrue(!methodsToDeclareAbstract.contains(infos[i].getMember())); + } + if (methodsToDeclareAbstract.contains(infos[i].getMember())) { + infos[i].setAction(MemberActionInfo.PUSH_ABSTRACT_ACTION); + assertTrue(!membersToPushDown.contains(infos[i].getMember())); + } + } + } + + /** + * Tests "Pull Up" method refactoring involving receiver parameter. + * + * @throws Exception any exception thrown from this test case + */ + public void testPullUp() throws Exception { + String[] methodNames= new String[] { "foo1", "foo2" }; + String[][] signatures= new String[][] { new String[]{"QList;"}, new String[] { "QString;" } }; + boolean deleteAllInSourceType= true; + boolean deleteAllMatchingMethods= false; + ICompilationUnit cuA= createCUfromTestFile(getPackageP(), "A"); + ICompilationUnit cuB= createCUfromTestFile(getPackageP(), "B"); + IMethod[] methods= getMethods(cuB.getType("B"), methodNames, signatures); + + PullUpRefactoringProcessor processor= createPullUpRefactoringProcessor(methods); + Refactoring ref= processor.getRefactoring(); + + assertTrue("activation", ref.checkInitialConditions(new NullProgressMonitor()).isOK()); + + IType[] possibleClasses= processor.getCandidateTypes(new RefactoringStatus(), new NullProgressMonitor()); + assertTrue("No possible class found!", possibleClasses.length > 0); + processor.setDestinationType(processor.getCandidateTypes(new RefactoringStatus(), new NullProgressMonitor())[possibleClasses.length - 1 - 0]); + + if (deleteAllInSourceType) + processor.setDeletedMethods(methods); + if (deleteAllMatchingMethods) { + List l= Arrays.asList(JavaElementUtil.getElementsOfType(processor.getMatchingElements(new NullProgressMonitor(), false), IJavaElement.METHOD)); + processor.setDeletedMethods((IMethod[])l.toArray(new IMethod[l.size()])); + } + + RefactoringStatus checkInputResult= ref.checkFinalConditions(new NullProgressMonitor()); + assertTrue("precondition was supposed to pass", !checkInputResult.hasError()); + performChange(ref, false); + + String expected= getFileContents(getOutputTestFileName("A")); + String actual= cuA.getSource(); + assertEqualLines(expected, actual); + expected= getFileContents(getOutputTestFileName("B")); + actual= cuB.getSource(); + assertEqualLines(expected, actual); + } + + /** + * Tests "Push Down" method refactoring involving receiver parameter. + * + * @throws Exception any exception thrown from this test case + */ + public void testPushDown() throws Exception { + String[] namesOfMethodsToPushDown= { "foo1", "foo2" }; + String[][] signaturesOfMethodsToPushDown= { new String[0], new String[] { "QString;" } }; + String[] selectedFieldNames= {}; + String[] namesOfFieldsToPushDown= {}; + String[] namesOfMethodsToDeclareAbstract= {}; + String[][] signaturesOfMethodsToDeclareAbstract= {}; + + + ICompilationUnit cuA= createCUfromTestFile(getPackageP(), "A"); + + IType type= getType(cuA, "A"); + IMethod[] selectedMethods= getMethods(type, namesOfMethodsToPushDown, signaturesOfMethodsToPushDown); + IField[] selectedFields= getFields(type, selectedFieldNames); + IMember[] selectedMembers= merge(selectedFields, selectedMethods); + + assertTrue(RefactoringAvailabilityTester.isPushDownAvailable(selectedMembers)); + PushDownRefactoringProcessor processor= new PushDownRefactoringProcessor(selectedMembers); + Refactoring ref= new ProcessorBasedRefactoring(processor); + + assertTrue("activation", ref.checkInitialConditions(new NullProgressMonitor()).isOK()); + + prepareForInputCheck(processor, selectedMethods, selectedFields, namesOfMethodsToPushDown, signaturesOfMethodsToPushDown, namesOfFieldsToPushDown, namesOfMethodsToDeclareAbstract, + signaturesOfMethodsToDeclareAbstract); + + RefactoringStatus checkInputResult= ref.checkFinalConditions(new NullProgressMonitor()); + assertTrue("precondition was supposed to pass but got " + checkInputResult.toString(), !checkInputResult.hasError()); + performChange(ref, false); + + String expected= getFileContents(getOutputTestFileName("A")); + String actual= cuA.getSource(); + assertEqualLines("A.java", expected, actual); + + } + + /** + * Tests "Move" method refactoring involving receiver parameter. + * + * @throws Exception any exception thrown from this test case + */ + public void testMove() throws Exception { + String[] cuQNames= new String[] { "p1.A", "p2.B" }; + String selectionCuQName= "p1.A"; + boolean inlineDelegator= false; + boolean removeDelegator= false; + int selectionCuIndex= -1; + for (int i= 0; i < cuQNames.length; i++) + if (cuQNames[i] == null || selectionCuQName.equals(cuQNames[i])) + selectionCuIndex= i; + Assert.isTrue(selectionCuIndex != -1, "parameter selectionCuQName must match some String in cuQNames."); + ICompilationUnit cuA= createCUfromTestFile(getPackage("p1"), "A"); + ICompilationUnit cuB= createCUfromTestFile(getPackage("p1"), "B"); + + int offset= cuA.getSource().indexOf("mA1(@NonNull A this, B b)"); + IJavaElement[] codeSelect= cuA.codeSelect(offset, 3); + assertTrue(codeSelect.length > 0); + assertTrue(codeSelect[0] instanceof IMethod); + IMethod method= (IMethod)codeSelect[0]; + MoveInstanceMethodProcessor processor= new MoveInstanceMethodProcessor(method, JavaPreferencesSettings.getCodeGenerationSettings(cuA.getJavaProject())); + Refactoring ref= new MoveRefactoring(processor); + + assertNotNull("refactoring should be created", ref); + RefactoringStatus preconditionResult= ref.checkInitialConditions(new NullProgressMonitor()); + + assertTrue("activation was supposed to be successful", preconditionResult.isOK()); + + IVariableBinding target= null; + IVariableBinding[] targets= processor.getPossibleTargets(); + for (int i= 0; i < targets.length; i++) { + IVariableBinding candidate= targets[i]; + if (candidate.getName().equals("b")) { + target= candidate; + break; + } + } + assertNotNull("Expected new target not available.", target); + processor.setTarget(target); + + processor.setInlineDelegator(inlineDelegator); + processor.setRemoveDelegator(removeDelegator); + processor.setDeprecateDelegates(false); + processor.setMethodName("mA1Moved"); + + preconditionResult.merge(ref.checkFinalConditions(new NullProgressMonitor())); + + assertTrue("precondition was supposed to pass", !preconditionResult.hasError()); + + performChange(ref, false); + + String outputTestFileName= getOutputTestFileName("A"); + assertEqualLines("Incorrect inline in " + outputTestFileName, getFileContents(outputTestFileName), cuA.getSource()); + + + outputTestFileName= getOutputTestFileName("B"); + assertEqualLines("Incorrect inline in " + outputTestFileName, getFileContents(outputTestFileName), cuB.getSource()); + + } + + /** + * Tests "Move Type to New File" refactoring involving receiver parameter. + * + * @throws Exception any exception thrown from this test case + */ + public void testMoveType2File() throws Exception { + String parentClassName= "A"; + String enclosingInstanceName= "Inner"; + String[] cuNames= new String[] { "A" }; + String[] packageNames= new String[] { "p" }; + String packageName= "p"; + IType parentClas= getType(createCUfromTestFile(getPackage(packageName), parentClassName), parentClassName); + IType clas= parentClas.getType(enclosingInstanceName); + + assertTrue("should be enabled", RefactoringAvailabilityTester.isMoveInnerAvailable(clas)); + MoveInnerToTopRefactoring ref= ((RefactoringAvailabilityTester.isMoveInnerAvailable(clas)) ? new MoveInnerToTopRefactoring(clas, JavaPreferencesSettings.getCodeGenerationSettings(clas + .getJavaProject())) : null); + RefactoringStatus preconditionResult= ref.checkInitialConditions(new NullProgressMonitor()); + assertTrue("activation was supposed to be successful" + preconditionResult.toString(), preconditionResult.isOK()); + + assertEquals("reference creation possible", true, ref.isCreatingInstanceFieldPossible()); + assertEquals("reference creation mandatory", false, ref.isCreatingInstanceFieldMandatory()); + if (ref.isCreatingInstanceFieldPossible() && !ref.isCreatingInstanceFieldMandatory()) + ref.setCreateInstanceField(false); + ref.setEnclosingInstanceName(enclosingInstanceName); + assertTrue("name should be ok ", ref.checkEnclosingInstanceName(enclosingInstanceName).isOK()); + ref.setMarkInstanceFieldAsFinal(false); + ICompilationUnit[] cus= new ICompilationUnit[cuNames.length]; + for (int i= 0; i < cuNames.length; i++) { + if (cuNames[i].equals(clas.getCompilationUnit().findPrimaryType().getElementName())) + cus[i]= clas.getCompilationUnit(); + else + cus[i]= createCUfromTestFile(getPackage(packageNames[i]), cuNames[i]); + } + + RefactoringStatus checkInputResult= ref.checkFinalConditions(new NullProgressMonitor()); + assertTrue("precondition was supposed to pass", !checkInputResult.hasError()); + performChange(ref, false); + + for (int i= 0; i < cus.length; i++) { + String actual= cus[i].getSource(); + String expected= getFileContents(getOutputTestFileName(cuNames[i])); + assertEqualLines(cus[i].getElementName(), expected, actual); + } + ICompilationUnit newCu= clas.getPackageFragment().getCompilationUnit(enclosingInstanceName + ".java"); + String expected= getFileContents(getOutputTestFileName(enclosingInstanceName)); + String actual= newCu.getSource(); + assertEqualLines("new Cu:", expected, actual); + + } + + /** + * Tests "Extract Interface" refactoring involving receiver parameter. + * + * @throws Exception any exception thrown from this test case + */ + public void testExtractInterface() throws Exception { + String className= "A"; + String newInterfaceName= "I"; + + IType clas= getType(createCUfromTestFile(getPackageP(), getTopLevelTypeName(className)), className); + ICompilationUnit cu= clas.getCompilationUnit(); + IPackageFragment pack= (IPackageFragment)cu.getParent(); + + ExtractInterfaceProcessor processor= new ExtractInterfaceProcessor(clas, JavaPreferencesSettings.getCodeGenerationSettings(clas.getJavaProject())); + Refactoring ref= new ProcessorBasedRefactoring(processor); + + processor.setTypeName(newInterfaceName); + assertEquals("interface name should be accepted", RefactoringStatus.OK, processor.checkTypeName(newInterfaceName).getSeverity()); + + processor.setExtractedMembers(processor.getExtractableMembers()); + processor.setReplace(true); + processor.setAnnotations(false); + assertEquals("was supposed to pass", null, performRefactoring(ref)); + assertEqualLines("incorrect changes in " + className, + getFileContents(getOutputTestFileName(className)), + cu.getSource()); + + ICompilationUnit interfaceCu= pack.getCompilationUnit(newInterfaceName + ".java"); + assertEqualLines("incorrect interface created", + getFileContents(getOutputTestFileName(newInterfaceName)), + interfaceCu.getSource()); + } + + /** + * Tests "Extract Superclass" refactoring involving receiver parameter. + * + * @throws Exception any exception thrown from this test case + */ + public void testExtractSuperclass() throws Exception { + String[] methodNames= new String[] { "foo1", "foo2" }; + String[][] signatures= new String[][] { new String[0], new String[] { "QString;" } }; + boolean replaceOccurences= true; + + + ICompilationUnit cu= createCUfromTestFile(getPackageP(), "A"); + IType type= getType(cu, "A"); + IMethod[] methods= getMethods(type, methodNames, signatures); + + ExtractSupertypeProcessor processor= createExtractSuperclassRefactoringProcessor(methods); + Refactoring refactoring= processor.getRefactoring(); + processor.setMembersToMove(methods); + + assertTrue("activation", refactoring.checkInitialConditions(new NullProgressMonitor()).isOK()); + + processor.setTypesToExtract(new IType[] { type }); + processor.setTypeName("B"); + processor.setCreateMethodStubs(true); + processor.setInstanceOf(false); + processor.setReplace(replaceOccurences); + processor.setDeletedMethods(methods); + + RefactoringStatus status= refactoring.checkFinalConditions(new NullProgressMonitor()); + assertTrue("precondition was supposed to pass", !status.hasError()); + performChange(refactoring, false); + + String expected= getFileContents(getOutputTestFileName("A")); + String actual= cu.getSource(); + assertEqualLines(expected, actual); + + expected= getFileContents(getOutputTestFileName("B")); + ICompilationUnit unit= getPackageP().getCompilationUnit("B.java"); + if (!unit.exists()) + assertTrue("extracted compilation unit does not exist", false); + actual= unit.getBuffer().getContents(); + assertEqualLines(expected, actual); + + + } + +} diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/ExtractInterfaceProcessor.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/ExtractInterfaceProcessor.java index 4aee33c87d..f239f13177 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/ExtractInterfaceProcessor.java +++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/ExtractInterfaceProcessor.java @@ -1,10 +1,14 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * + * This is an implementation of an early-draft specification developed under the Java Community Process (JCP) and + * is made available for testing and evaluation purposes only. + * The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ @@ -79,6 +83,8 @@ import org.eclipse.jdt.core.dom.MethodDeclaration; import org.eclipse.jdt.core.dom.Modifier; import org.eclipse.jdt.core.dom.NodeFinder; import org.eclipse.jdt.core.dom.ParameterizedType; +import org.eclipse.jdt.core.dom.SimpleName; +import org.eclipse.jdt.core.dom.SimpleType; import org.eclipse.jdt.core.dom.SingleVariableDeclaration; import org.eclipse.jdt.core.dom.Type; import org.eclipse.jdt.core.dom.TypeDeclaration; @@ -699,6 +705,7 @@ public final class ExtractInterfaceProcessor extends SuperTypeRefactoringProcess if (fAbstract && !abstractFound) rewriter.setModifiers(Modifier.ABSTRACT, 0, null); + updateReceiverParameter(declaration, rewrite, targetDeclaration.getName().getIdentifier()); for (SingleVariableDeclaration param : (List<SingleVariableDeclaration>) declaration.parameters()) { ListRewrite modifierRewrite= rewrite.getListRewrite(param, SingleVariableDeclaration.MODIFIERS2_PROPERTY); for (IExtendedModifier extended : (List<IExtendedModifier>) param.modifiers()) { @@ -730,6 +737,25 @@ public final class ExtractInterfaceProcessor extends SuperTypeRefactoringProcess RefactoringFileBuffers.release(unit); } } + + private void updateReceiverParameter(final MethodDeclaration declaration, final ASTRewrite rewrite, final String targetName) { + if (declaration.getReceiverType() != null) { + AST ast= rewrite.getAST(); + SimpleName simpleName= ast.newSimpleName(targetName); + SimpleType simpleType= ast.newSimpleType(simpleName); + Iterator<Annotation> iterator= declaration.getReceiverType().annotations().iterator(); + while (iterator.hasNext()) { + Annotation annotation= iterator.next(); + simpleType.annotations().add(rewrite.createCopyTarget(annotation)); + } + rewrite.set(declaration, MethodDeclaration.RECEIVER_TYPE_PROPERTY, simpleType, null); + + if (declaration.getReceiverQualifier() != null) { + SimpleName qualifierName= ast.newSimpleName(targetName); + rewrite.set(declaration, MethodDeclaration.RECEIVER_QUALIFIER_PROPERTY, qualifierName, null); + } + } + } /** * Creates the new signature of the source type. diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/HierarchyProcessor.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/HierarchyProcessor.java index 78e1e8a24e..6f0a80db66 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/HierarchyProcessor.java +++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/HierarchyProcessor.java @@ -70,6 +70,7 @@ import org.eclipse.jdt.core.dom.Javadoc; import org.eclipse.jdt.core.dom.MethodDeclaration; import org.eclipse.jdt.core.dom.Modifier; import org.eclipse.jdt.core.dom.SimpleName; +import org.eclipse.jdt.core.dom.SimpleType; import org.eclipse.jdt.core.dom.SingleVariableDeclaration; import org.eclipse.jdt.core.dom.Type; import org.eclipse.jdt.core.dom.TypeDeclaration; @@ -731,4 +732,30 @@ public abstract class HierarchyProcessor extends SuperTypeRefactoringProcessor { return true; return hasNonMovedReferences(member, monitor, status); } + + /** + * Updates the receiver parameter properties of the new method. + * + * @param type the new type where the new method will be placed + * @param oldMethod the existing method from where the receiver parameter properties will be + * copied + * @param newMethod the method whose receiver parameter properties will be updated + * @since 3.9 BETA_JAVA8 + */ + protected void updateReceiverParameter(IType type, MethodDeclaration oldMethod, MethodDeclaration newMethod) { + AST ast= newMethod.getAST(); + String elementName= type.getElementName(); + if (oldMethod.getReceiverType() != null) { + SimpleType simpleType= ast.newSimpleType(ast.newSimpleName(elementName)); + Iterator<Annotation> iterator= oldMethod.getReceiverType().annotations().iterator(); + while (iterator.hasNext()) { + Annotation annotation= iterator.next(); + simpleType.annotations().add(ASTNode.copySubtree(ast, annotation)); + } + newMethod.setReceiverType(simpleType); + if (oldMethod.getReceiverQualifier() != null) { + newMethod.setReceiverQualifier(ast.newSimpleName(elementName)); + } + } + } }
\ No newline at end of file diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/MoveInnerToTopRefactoring.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/MoveInnerToTopRefactoring.java index d602cc1c62..f00d85e205 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/MoveInnerToTopRefactoring.java +++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/MoveInnerToTopRefactoring.java @@ -1,10 +1,14 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * + * This is an implementation of an early-draft specification developed under the Java Community Process (JCP) and + * is made available for testing and evaluation purposes only. + * The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ @@ -901,6 +905,7 @@ public final class MoveInnerToTopRefactoring extends Refactoring { addInheritedTypeQualifications(declaration, targetRewrite, qualifierGroup); addEnclosingInstanceDeclaration(declaration, rewrite); } + updateConstructorReceiverParameter(declaration, rewrite); fTypeImports= new HashSet<ITypeBinding>(); fStaticImports= new HashSet<IBinding>(); ImportRewriteUtil.collectImports(fType.getJavaProject(), declaration, fTypeImports, fStaticImports, false); @@ -1392,6 +1397,26 @@ public final class MoveInnerToTopRefactoring extends Refactoring { } } + /** + * Updates the receiver parameter properties of the constructor. The receiver parameter properties are set to <code>null</code>. + * + * @param declaration the type declaration AST node + * @param rewrite the ASTRewrite node used for the modification + * @since 3.9 BETA_JAVA8 + */ + private void updateConstructorReceiverParameter(AbstractTypeDeclaration declaration, final ASTRewrite rewrite) { + final MethodDeclaration[] declarations= getConstructorDeclarationNodes(declaration); + for (int index= 0; index < declarations.length; index++) { + MethodDeclaration methodDeclaration= declarations[index]; + if (methodDeclaration.getReceiverType() != null) { + rewrite.set(methodDeclaration, MethodDeclaration.RECEIVER_TYPE_PROPERTY, null, null); + if (methodDeclaration.getReceiverQualifier() != null) { + rewrite.set(methodDeclaration, MethodDeclaration.RECEIVER_QUALIFIER_PROPERTY, null, null); + } + } + } + } + private void modifyInterfaceMemberModifiers(final ITypeBinding binding) { Assert.isNotNull(binding); ITypeBinding declaring= binding.getDeclaringClass(); diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/MoveInstanceMethodProcessor.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/MoveInstanceMethodProcessor.java index 48d6687362..8263b1cadc 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/MoveInstanceMethodProcessor.java +++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/MoveInstanceMethodProcessor.java @@ -1,10 +1,14 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * + * This is an implementation of an early-draft specification developed under the Java Community Process (JCP) and + * is made available for testing and evaluation purposes only. + * The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ @@ -69,6 +73,7 @@ import org.eclipse.jdt.core.dom.AST; import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.ASTVisitor; import org.eclipse.jdt.core.dom.AbstractTypeDeclaration; +import org.eclipse.jdt.core.dom.Annotation; import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration; import org.eclipse.jdt.core.dom.AnonymousClassDeclaration; import org.eclipse.jdt.core.dom.Assignment; @@ -95,6 +100,7 @@ import org.eclipse.jdt.core.dom.PrefixExpression; import org.eclipse.jdt.core.dom.PrimitiveType; import org.eclipse.jdt.core.dom.QualifiedName; import org.eclipse.jdt.core.dom.SimpleName; +import org.eclipse.jdt.core.dom.SimpleType; import org.eclipse.jdt.core.dom.SingleVariableDeclaration; import org.eclipse.jdt.core.dom.SuperFieldAccess; import org.eclipse.jdt.core.dom.SuperMethodInvocation; @@ -2255,6 +2261,7 @@ public final class MoveInstanceMethodProcessor extends MoveProcessor implements adjustments.put(fMethod, adjustment); } } + updateReceiverParameter(declaration, rewrite); target= createMethodArguments(rewrites, rewrite, declaration, adjustments, status); createMethodTypeParameters(rewrite, declaration, status); createMethodComment(rewrite, declaration); @@ -2266,6 +2273,25 @@ public final class MoveInstanceMethodProcessor extends MoveProcessor implements return target; } + private void updateReceiverParameter(final MethodDeclaration declaration, final ASTRewrite rewrite) throws JavaModelException { + if (declaration.getReceiverType() != null) { + IType targetType= getTargetType(); + AST ast= rewrite.getAST(); + SimpleName simpleName= ast.newSimpleName(targetType.getElementName()); + SimpleType simpleType= ast.newSimpleType(simpleName); + Iterator<Annotation> iterator= declaration.getReceiverType().annotations().iterator(); + while (iterator.hasNext()) { + Annotation annotation= iterator.next(); + simpleType.annotations().add(rewrite.createCopyTarget(annotation)); + } + rewrite.set(declaration, MethodDeclaration.RECEIVER_TYPE_PROPERTY, simpleType, null); + if (declaration.getReceiverQualifier() != null) { + SimpleName qualifierName= ast.newSimpleName(targetType.getElementName()); + rewrite.set(declaration, MethodDeclaration.RECEIVER_QUALIFIER_PROPERTY, qualifierName, null); + } + } + } + /** * Creates the necessary changes to replace the body of the method * declaration with an expression to invoke the delegate. diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/PullUpRefactoringProcessor.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/PullUpRefactoringProcessor.java index 5c82112d6e..c3b1442756 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/PullUpRefactoringProcessor.java +++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/PullUpRefactoringProcessor.java @@ -514,6 +514,7 @@ public class PullUpRefactoringProcessor extends HierarchyProcessor { copyReturnType(rewriter.getASTRewrite(), getDeclaringType().getCompilationUnit(), methodToCreateStubFor, newMethod, mapping); copyParameters(rewriter.getASTRewrite(), getDeclaringType().getCompilationUnit(), methodToCreateStubFor, newMethod, mapping); copyThrownExceptions(methodToCreateStubFor, newMethod); + updateReceiverParameter(getDestinationType(), methodToCreateStubFor, newMethod); newMethod.setJavadoc(createJavadocForStub(typeToCreateStubIn.getName().getIdentifier(), methodToCreateStubFor, newMethod, newCu, rewriter.getASTRewrite())); ImportRewriteContext context= new ContextSensitiveImportRewriteContext(typeToCreateStubIn, rewriter.getImportRewrite()); ImportRewriteUtil.addImports(rewriter, context, newMethod, new HashMap<Name, String>(), new HashMap<Name, String>(), false); @@ -1037,6 +1038,7 @@ public class PullUpRefactoringProcessor extends HierarchyProcessor { copyReturnType(targetRewrite.getASTRewrite(), getDeclaringType().getCompilationUnit(), oldMethod, newMethod, mapping); copyParameters(targetRewrite.getASTRewrite(), getDeclaringType().getCompilationUnit(), oldMethod, newMethod, mapping); copyThrownExceptions(oldMethod, newMethod); + updateReceiverParameter(getDestinationType(), oldMethod, newMethod); ImportRewriteContext context= new ContextSensitiveImportRewriteContext(destination, targetRewrite.getImportRewrite()); ImportRewriteUtil.addImports(targetRewrite, context, newMethod, new HashMap<Name, String>(), new HashMap<Name, String>(), false); targetRewrite.getASTRewrite().getListRewrite(destination, destination.getBodyDeclarationsProperty()).insertAt(newMethod, ASTNodes.getInsertionIndex(newMethod, destination.bodyDeclarations()), targetRewrite.createCategorizedGroupDescription(RefactoringCoreMessages.PullUpRefactoring_add_abstract_method, SET_PULL_UP)); @@ -1343,6 +1345,7 @@ public class PullUpRefactoringProcessor extends HierarchyProcessor { copyParameters(rewrite, getDeclaringType().getCompilationUnit(), oldMethod, newMethod, mapping); copyThrownExceptions(oldMethod, newMethod); copyTypeParameters(oldMethod, newMethod); + updateReceiverParameter(getDestinationType(), oldMethod, newMethod); return newMethod; } diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/PushDownRefactoringProcessor.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/PushDownRefactoringProcessor.java index c4c4bce12a..2fc036805d 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/PushDownRefactoringProcessor.java +++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/PushDownRefactoringProcessor.java @@ -658,7 +658,7 @@ public final class PushDownRefactoringProcessor extends HierarchyProcessor { } else { final MethodDeclaration oldMethod= ASTNodeSearchUtil.getMethodDeclarationNode((IMethod) infos[offset].getMember(), sourceRewriter.getRoot()); if (oldMethod != null) { - MethodDeclaration newMethod= createNewMethodDeclarationNode(infos[offset], mapping, unitRewriter, oldMethod); + MethodDeclaration newMethod= createNewMethodDeclarationNode(type, infos[offset], mapping, unitRewriter, oldMethod); unitRewriter.getASTRewrite().getListRewrite(declaration, declaration.getBodyDeclarationsProperty()).insertAt(newMethod, ASTNodes.getInsertionIndex(newMethod, declaration.bodyDeclarations()), unitRewriter.createCategorizedGroupDescription(RefactoringCoreMessages.HierarchyRefactoring_add_member, SET_PUSH_DOWN)); ImportRewriteUtil.addImports(unitRewriter, context, oldMethod, new HashMap<Name, String>(), new HashMap<Name, String>(), false); } @@ -823,7 +823,7 @@ public final class PushDownRefactoringProcessor extends HierarchyProcessor { return newField; } - private MethodDeclaration createNewMethodDeclarationNode(MemberActionInfo info, TypeVariableMaplet[] mapping, CompilationUnitRewrite rewriter, MethodDeclaration oldMethod) throws JavaModelException { + private MethodDeclaration createNewMethodDeclarationNode(IType type, MemberActionInfo info, TypeVariableMaplet[] mapping, CompilationUnitRewrite rewriter, MethodDeclaration oldMethod) throws JavaModelException { Assert.isTrue(!info.isFieldInfo()); IMethod method= (IMethod) info.getMember(); ASTRewrite rewrite= rewriter.getASTRewrite(); @@ -847,6 +847,7 @@ public final class PushDownRefactoringProcessor extends HierarchyProcessor { copyParameters(rewrite, method.getCompilationUnit(), oldMethod, newMethod, mapping); copyThrownExceptions(oldMethod, newMethod); copyTypeParameters(oldMethod, newMethod); + updateReceiverParameter(type, oldMethod, newMethod); return newMethod; } diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/constraints/SuperTypeRefactoringProcessor.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/constraints/SuperTypeRefactoringProcessor.java index b2de6bdba4..a5ff5a991d 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/constraints/SuperTypeRefactoringProcessor.java +++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/constraints/SuperTypeRefactoringProcessor.java @@ -1,10 +1,14 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * + * This is an implementation of an early-draft specification developed under the Java Community Process (JCP) and + * is made available for testing and evaluation purposes only. + * The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * Stephan Herrmann <stephan@cs.tu-berlin.de> - [refactoring] pull-up with "use the destination type where possible" creates bogus import of nested type - https://bugs.eclipse.org/393932 @@ -71,6 +75,7 @@ import org.eclipse.jdt.core.dom.NodeFinder; import org.eclipse.jdt.core.dom.QualifiedName; import org.eclipse.jdt.core.dom.SimpleName; import org.eclipse.jdt.core.dom.SingleVariableDeclaration; +import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor; import org.eclipse.jdt.core.dom.Type; import org.eclipse.jdt.core.dom.TypeDeclaration; import org.eclipse.jdt.core.dom.TypeParameter; @@ -846,88 +851,92 @@ public abstract class SuperTypeRefactoringProcessor extends RefactoringProcessor final CompilationUnit target= rewrite.getRoot(); node= NodeFinder.perform(copy, range.getSourceRange()); if (node != null) { - node= ASTNodes.getNormalizedNode(node).getParent(); - if (node instanceof VariableDeclaration) { - binding= ((VariableDeclaration) node).resolveBinding(); - node= target.findDeclaringNode(binding.getKey()); - if (node instanceof SingleVariableDeclaration) { - rewriteTypeOccurrence(estimate, rewrite, ((SingleVariableDeclaration) node).getType(), group); - if (node.getParent() instanceof MethodDeclaration) { - binding= ((VariableDeclaration) node).resolveBinding(); - if (binding != null) - replacements.add(binding.getKey()); + ASTNode normalizedNode= ASTNodes.getNormalizedNode(node); + if (normalizedNode != null) { + StructuralPropertyDescriptor locationInParent= normalizedNode.getLocationInParent(); + node= normalizedNode.getParent(); + if (node instanceof VariableDeclaration) { + binding= ((VariableDeclaration) node).resolveBinding(); + node= target.findDeclaringNode(binding.getKey()); + if (node instanceof SingleVariableDeclaration) { + rewriteTypeOccurrence(estimate, rewrite, ((SingleVariableDeclaration) node).getType(), group); + if (node.getParent() instanceof MethodDeclaration) { + binding= ((VariableDeclaration) node).resolveBinding(); + if (binding != null) + replacements.add(binding.getKey()); + } } - } - } else if (node instanceof VariableDeclarationStatement) { - binding= ((VariableDeclaration) ((VariableDeclarationStatement) node).fragments().get(0)).resolveBinding(); - node= target.findDeclaringNode(binding.getKey()); - if (node instanceof VariableDeclarationFragment) - rewriteTypeOccurrence(estimate, rewrite, ((VariableDeclarationStatement) ((VariableDeclarationFragment) node).getParent()).getType(), group); - } else if (node instanceof MethodDeclaration) { - binding= ((MethodDeclaration) node).resolveBinding(); - node= target.findDeclaringNode(binding.getKey()); - if (node instanceof MethodDeclaration) - rewriteTypeOccurrence(estimate, rewrite, ((MethodDeclaration) node).getReturnType2(), group); - } else if (node instanceof FieldDeclaration) { - binding= ((VariableDeclaration) ((FieldDeclaration) node).fragments().get(0)).resolveBinding(); - node= target.findDeclaringNode(binding.getKey()); - if (node instanceof VariableDeclarationFragment) { - node= node.getParent(); - if (node instanceof FieldDeclaration) - rewriteTypeOccurrence(estimate, rewrite, ((FieldDeclaration) node).getType(), group); - } - } else if (node instanceof ArrayType) { - final ASTNode type= node; - while (node != null && !(node instanceof MethodDeclaration) && !(node instanceof VariableDeclarationFragment)) - node= node.getParent(); - if (node != null) { - final int delta= node.getStartPosition() + node.getLength() - type.getStartPosition(); + } else if (node instanceof VariableDeclarationStatement) { + binding= ((VariableDeclaration) ((VariableDeclarationStatement) node).fragments().get(0)).resolveBinding(); + node= target.findDeclaringNode(binding.getKey()); + if (node instanceof VariableDeclarationFragment) + rewriteTypeOccurrence(estimate, rewrite, ((VariableDeclarationStatement) ((VariableDeclarationFragment) node).getParent()).getType(), group); + } else if (node instanceof MethodDeclaration && MethodDeclaration.RETURN_TYPE2_PROPERTY.equals(locationInParent)) { + binding= ((MethodDeclaration) node).resolveBinding(); + node= target.findDeclaringNode(binding.getKey()); if (node instanceof MethodDeclaration) - binding= ((MethodDeclaration) node).resolveBinding(); - else if (node instanceof VariableDeclarationFragment) - binding= ((VariableDeclarationFragment) node).resolveBinding(); - if (binding != null) { - node= target.findDeclaringNode(binding.getKey()); - if (node instanceof MethodDeclaration || node instanceof VariableDeclarationFragment) { - node= NodeFinder.perform(target, (node.getStartPosition() + node.getLength() - delta), 0); - if (node instanceof SimpleName) - rewriteTypeOccurrence(estimate, rewrite, node, group); + rewriteTypeOccurrence(estimate, rewrite, ((MethodDeclaration) node).getReturnType2(), group); + } else if (node instanceof FieldDeclaration) { + binding= ((VariableDeclaration) ((FieldDeclaration) node).fragments().get(0)).resolveBinding(); + node= target.findDeclaringNode(binding.getKey()); + if (node instanceof VariableDeclarationFragment) { + node= node.getParent(); + if (node instanceof FieldDeclaration) + rewriteTypeOccurrence(estimate, rewrite, ((FieldDeclaration) node).getType(), group); + } + } else if (node instanceof ArrayType) { + final ASTNode type= node; + while (node != null && !(node instanceof MethodDeclaration) && !(node instanceof VariableDeclarationFragment)) + node= node.getParent(); + if (node != null) { + final int delta= node.getStartPosition() + node.getLength() - type.getStartPosition(); + if (node instanceof MethodDeclaration) + binding= ((MethodDeclaration) node).resolveBinding(); + else if (node instanceof VariableDeclarationFragment) + binding= ((VariableDeclarationFragment) node).resolveBinding(); + if (binding != null) { + node= target.findDeclaringNode(binding.getKey()); + if (node instanceof MethodDeclaration || node instanceof VariableDeclarationFragment) { + node= NodeFinder.perform(target, (node.getStartPosition() + node.getLength() - delta), 0); + if (node instanceof SimpleName) + rewriteTypeOccurrence(estimate, rewrite, node, group); + } } } - } - } else if (node instanceof QualifiedName) { - final ASTNode name= node; - while (node != null && !(node instanceof MethodDeclaration) && !(node instanceof VariableDeclarationFragment)) - node= node.getParent(); - if (node != null) { - final int delta= node.getStartPosition() + node.getLength() - name.getStartPosition(); - if (node instanceof MethodDeclaration) + } else if (node instanceof QualifiedName) { + final ASTNode name= node; + while (node != null && !(node instanceof MethodDeclaration) && !(node instanceof VariableDeclarationFragment)) + node= node.getParent(); + if (node != null) { + final int delta= node.getStartPosition() + node.getLength() - name.getStartPosition(); + if (node instanceof MethodDeclaration) + binding= ((MethodDeclaration) node).resolveBinding(); + else if (node instanceof VariableDeclarationFragment) + binding= ((VariableDeclarationFragment) node).resolveBinding(); + if (binding != null) { + node= target.findDeclaringNode(binding.getKey()); + if (node instanceof SimpleName || node instanceof MethodDeclaration || node instanceof VariableDeclarationFragment) { + node= NodeFinder.perform(target, (node.getStartPosition() + node.getLength() - delta), 0); + if (node instanceof SimpleName) + rewriteTypeOccurrence(estimate, rewrite, node, group); + } + } + } + } else if (node instanceof CastExpression) { + final ASTNode expression= node; + while (node != null && !(node instanceof MethodDeclaration)) + node= node.getParent(); + if (node != null) { + final int delta= node.getStartPosition() + node.getLength() - expression.getStartPosition(); binding= ((MethodDeclaration) node).resolveBinding(); - else if (node instanceof VariableDeclarationFragment) - binding= ((VariableDeclarationFragment) node).resolveBinding(); - if (binding != null) { node= target.findDeclaringNode(binding.getKey()); - if (node instanceof SimpleName || node instanceof MethodDeclaration || node instanceof VariableDeclarationFragment) { + if (node instanceof MethodDeclaration) { node= NodeFinder.perform(target, (node.getStartPosition() + node.getLength() - delta), 0); - if (node instanceof SimpleName) - rewriteTypeOccurrence(estimate, rewrite, node, group); + if (node instanceof CastExpression) + rewriteTypeOccurrence(estimate, rewrite, ((CastExpression) node).getType(), group); } } } - } else if (node instanceof CastExpression) { - final ASTNode expression= node; - while (node != null && !(node instanceof MethodDeclaration)) - node= node.getParent(); - if (node != null) { - final int delta= node.getStartPosition() + node.getLength() - expression.getStartPosition(); - binding= ((MethodDeclaration) node).resolveBinding(); - node= target.findDeclaringNode(binding.getKey()); - if (node instanceof MethodDeclaration) { - node= NodeFinder.perform(target, (node.getStartPosition() + node.getLength() - delta), 0); - if (node instanceof CastExpression) - rewriteTypeOccurrence(estimate, rewrite, ((CastExpression) node).getType(), group); - } - } } } } |