Bug 393915 - [dom][refactoring] pull-up with "use the destination type
where possible" throws StackOverflowError
- test (modified existing one) & fix
- additional advance fix for bug 393932
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java
index 17ee54c..8bf2251 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java
@@ -562,6 +562,9 @@
 			ITypeBinding[] newInterfaces = new ITypeBinding[length];
 			int interfacesCounter = 0;
 			for (int i = 0; i < length; i++) {
+//{ObjectTeams: filter synthetic role interfaces:
+				if (internalInterfaces[i].isSynthInterface()) continue;
+// SH}
 				ITypeBinding typeBinding = this.resolver.getTypeBinding(internalInterfaces[i]);
 				if (typeBinding == null) {
 					continue;
diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/pullup/PullUpAdaptor.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/pullup/PullUpAdaptor.java
index 36a9847..b87e7b6 100644
--- a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/pullup/PullUpAdaptor.java
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/pullup/PullUpAdaptor.java
@@ -30,6 +30,7 @@
 import org.eclipse.core.runtime.IProgressMonitor;

 import org.eclipse.core.runtime.NullProgressMonitor;

 import org.eclipse.core.runtime.SubProgressMonitor;

+import org.eclipse.jdt.core.BindingKey;

 import org.eclipse.jdt.core.Flags;

 import org.eclipse.jdt.core.ICompilationUnit;

 import org.eclipse.jdt.core.IField;

@@ -44,6 +45,7 @@
 import org.eclipse.jdt.core.dom.*;

 import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword;

 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;

+import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;

 import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.ImportRewriteContext;

 import org.eclipse.jdt.core.search.IJavaSearchConstants;

 import org.eclipse.jdt.core.search.IJavaSearchScope;

@@ -63,6 +65,7 @@
 import org.eclipse.jdt.internal.corext.refactoring.structure.ImportRewriteUtil;

 import org.eclipse.jdt.internal.corext.refactoring.structure.MemberVisibilityAdjustor.IncomingMemberVisibilityAdjustment;

 import org.eclipse.jdt.internal.corext.refactoring.structure.TypeVariableMaplet;

+import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.TType;

 import org.eclipse.jdt.internal.corext.util.JavaModelUtil;

 import org.eclipse.jdt.internal.corext.util.JdtFlags;

 import org.eclipse.jdt.internal.corext.util.Messages;

@@ -92,6 +95,7 @@
 import org.eclipse.objectteams.otdt.internal.refactoring.util.IOverloadingMessageCreator;

 import org.eclipse.objectteams.otdt.internal.refactoring.util.RefactoringUtil;

 import org.eclipse.osgi.util.NLS;

+import org.eclipse.text.edits.TextEditGroup;

 

 import base org.eclipse.jdt.internal.corext.refactoring.RefactoringAvailabilityTester;

 import base org.eclipse.jdt.internal.corext.refactoring.structure.ASTNodeSearchUtil;

@@ -99,6 +103,7 @@
 import base org.eclipse.jdt.internal.corext.refactoring.structure.MemberVisibilityAdjustor;

 import base org.eclipse.jdt.internal.corext.refactoring.structure.PullUpRefactoringProcessor;

 import base org.eclipse.jdt.internal.corext.refactoring.structure.ReferenceFinderUtil;

+import base org.eclipse.jdt.internal.corext.refactoring.structure.constraints.SuperTypeRefactoringProcessor;

 import base org.eclipse.jdt.internal.ui.refactoring.PullUpMemberPage;

 import base org.eclipse.jdt.internal.ui.refactoring.PullUpMemberPage.MemberActionInfo;

 
@@ -995,4 +1000,22 @@
 			}

 		}

 	}

+

+	// advance fix for Bug 393932 - [refactoring] pull-up with "use the destination type where possible" creates bogus import of nested type

+	protected class UseSuperTypeFix playedBy SuperTypeRefactoringProcessor {

+

+		void rewriteTypeOccurrence(final TType estimate, final CompilationUnitRewrite rewrite, final ASTNode node, final TextEditGroup group)

+		<- replace 

+		void rewriteTypeOccurrence(final TType estimate, final CompilationUnitRewrite rewrite, final ASTNode node, final TextEditGroup group);

+

+		@SuppressWarnings("basecall")

+		callin void rewriteTypeOccurrence(TType estimate, CompilationUnitRewrite rewrite, ASTNode node, TextEditGroup group) {

+			// combined from direct base method plus createCorrespondingNode(..):

+			rewrite.getImportRemover().registerRemovedNode(node);

+			ImportRewrite importRewrite= rewrite.getImportRewrite();

+			ImportRewriteContext context = new ContextSensitiveImportRewriteContext(node, importRewrite);

+			ASTNode correspondingNode = importRewrite.addImportFromSignature(new BindingKey(estimate.getBindingKey()).toSignature(), rewrite.getAST(), context);

+			rewrite.getASTRewrite().replace(node, correspondingNode, group);

+		}

+	}

 }

diff --git a/testplugins/org.eclipse.objectteams.otdt.ui.tests.refactoring/src/org/eclipse/objectteams/otdt/ui/tests/refactoring/pullup/PullUpTests.java b/testplugins/org.eclipse.objectteams.otdt.ui.tests.refactoring/src/org/eclipse/objectteams/otdt/ui/tests/refactoring/pullup/PullUpTests.java
index 799a288..d402621 100644
--- a/testplugins/org.eclipse.objectteams.otdt.ui.tests.refactoring/src/org/eclipse/objectteams/otdt/ui/tests/refactoring/pullup/PullUpTests.java
+++ b/testplugins/org.eclipse.objectteams.otdt.ui.tests.refactoring/src/org/eclipse/objectteams/otdt/ui/tests/refactoring/pullup/PullUpTests.java
@@ -122,6 +122,12 @@
 	}
 	private void performPullUp_pass(String[] cuNames, String[] methodNames, String[][] signatures, boolean[] makeAbstract, String[] fieldNames,
 			boolean deleteAllInSourceType, boolean deleteAllMatchingMethods, int targetClassIndex, String nameOfDeclaringType) throws Exception {
+		performPullUp_pass(cuNames, methodNames, signatures, makeAbstract, fieldNames, deleteAllInSourceType, deleteAllMatchingMethods, targetClassIndex, nameOfDeclaringType, false/*replace*/);
+	}
+	private void performPullUp_pass(String[] cuNames, String[] methodNames, String[][] signatures, boolean[] makeAbstract, String[] fieldNames,
+			boolean deleteAllInSourceType, boolean deleteAllMatchingMethods, int targetClassIndex, String nameOfDeclaringType, boolean replace) 
+					throws Exception 
+	{
 		ICompilationUnit[] cus = createCUs(cuNames);
 		try {
 
@@ -147,6 +153,9 @@
 			if (!methodList.isEmpty())
 				processor.setDeletedMethods(methodList.toArray(new IMethod[methodList.size()]));
 
+			if (replace)
+				processor.setReplace(true);
+
 			RefactoringStatus checkInputResult = ref.checkFinalConditions(new NullProgressMonitor());
 			assertTrue("precondition was supposed to pass", !checkInputResult.hasError());
 			performChange(ref, false);
@@ -355,7 +364,8 @@
 						new String[]{"foo", "getS1", "getS2"}, 
 						new String[][] { new String[0], new String[0], new String[0] }, 
 						new boolean[] {false, true, true}, 
-						new String[0], true, true, 0, "RSub");
+						new String[0], true, true, 0, "RSub",
+						true /*replace*/);
 	}
 	// Bug 386814 - [refactoring] pull-up should distinguish callouts that can be pull-up vs. abstract decl.
 	public void testPullUpCallout1()  throws Exception {
diff --git a/testplugins/org.eclipse.objectteams.otdt.ui.tests.refactoring/testdata/PullUp/testPullUpWithReferenceToCallout2/in/T.java b/testplugins/org.eclipse.objectteams.otdt.ui.tests.refactoring/testdata/PullUp/testPullUpWithReferenceToCallout2/in/T.java
index b2af6c4..a890db2 100644
--- a/testplugins/org.eclipse.objectteams.otdt.ui.tests.refactoring/testdata/PullUp/testPullUpWithReferenceToCallout2/in/T.java
+++ b/testplugins/org.eclipse.objectteams.otdt.ui.tests.refactoring/testdata/PullUp/testPullUpWithReferenceToCallout2/in/T.java
@@ -5,9 +5,13 @@
 	protected class RSub extends RSuper playedBy B {
 		String getS1() -> get String s;
 		String getS2() -> String getS();
-		void foo()
+		protected void foo()
 		{
 			System.out.println(getS1()+getS2());
 		}
 	}
+	
+	void main(RSub r) {
+		r.foo();
+	}
 }
\ No newline at end of file
diff --git a/testplugins/org.eclipse.objectteams.otdt.ui.tests.refactoring/testdata/PullUp/testPullUpWithReferenceToCallout2/out/T.java b/testplugins/org.eclipse.objectteams.otdt.ui.tests.refactoring/testdata/PullUp/testPullUpWithReferenceToCallout2/out/T.java
index 3779040..03282e1 100644
--- a/testplugins/org.eclipse.objectteams.otdt.ui.tests.refactoring/testdata/PullUp/testPullUpWithReferenceToCallout2/out/T.java
+++ b/testplugins/org.eclipse.objectteams.otdt.ui.tests.refactoring/testdata/PullUp/testPullUpWithReferenceToCallout2/out/T.java
@@ -5,7 +5,7 @@
 
 		protected abstract String getS1();
 
-		void foo()
+		protected void foo()
 		{
 			System.out.println(getS1()+getS2());
 		}
@@ -17,4 +17,8 @@
 		@Override
 		protected String getS2() -> String getS();
 	}
+	
+	void main(RSuper r) {
+		r.foo();
+	}
 }
\ No newline at end of file