diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/structure/MoveInstanceMethodProcessor.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/structure/MoveInstanceMethodProcessor.java index 20842c30ee9..3755d5e35a9 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/structure/MoveInstanceMethodProcessor.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/structure/MoveInstanceMethodProcessor.java @@ -2238,6 +2238,7 @@ protected TextChangeManager createChangeManager(final RefactoringStatus status, adjustor.rewriteVisibility(Progress.subMonitor(monitor, 1)); sourceRewrite.rewriteAST(document, fMethod.getCompilationUnit().getOptions(true)); createMethodSignature(document, declaration, sourceRewrite, rewrites); + modifyInheritedMethodCalls(document, declaration, sourceRewrite, rewrites); ICompilationUnit unit= null; CompilationUnitRewrite rewrite= null; for (final Iterator iterator= rewrites.keySet().iterator(); iterator.hasNext();) { @@ -3035,6 +3036,89 @@ protected void createMethodSignature(final IDocument document, final MethodDecla } } + private class SuperMethodChecker extends ASTVisitor { + private final CompilationUnitRewrite fRewriter; + + public SuperMethodChecker(final CompilationUnitRewrite rewriter) { + fRewriter= rewriter; + } + + @Override + public boolean visit(MethodInvocation node) { + if (node.getName().getFullyQualifiedName().equals(fMethodName)) { + IMethodBinding methodBinding= node.resolveMethodBinding(); + if (methodBinding != null) { + ITypeBinding typeBinding= methodBinding.getDeclaringClass(); + if (typeBinding != null) { + ITypeBinding targetTypeBinding= fTarget.getType(); + if (!typeBinding.isEqualTo(targetTypeBinding) && findInHierarchy(typeBinding, targetTypeBinding)) { + ASTRewrite astRewrite= fRewriter.getASTRewrite(); + AST ast= node.getAST(); + SuperMethodInvocation superMethod= ast.newSuperMethodInvocation(); + superMethod.setName(ast.newSimpleName(node.getName().getFullyQualifiedName())); + ListRewrite typeArgs= astRewrite.getListRewrite(node, MethodInvocation.TYPE_ARGUMENTS_PROPERTY); + List originalTypeList= typeArgs.getOriginalList(); + if (originalTypeList.size() > 0) { + ASTNode typeArgsCopy= typeArgs.createCopyTarget(originalTypeList.get(0), originalTypeList.get(originalTypeList.size() - 1)); + superMethod.typeArguments().add(typeArgsCopy); + } + ListRewrite args= astRewrite.getListRewrite(node, MethodInvocation.ARGUMENTS_PROPERTY); + List originalArgsList= args.getOriginalList(); + if (originalArgsList.size() > 0) { + ASTNode argsCopy= typeArgs.createCopyTarget(originalArgsList.get(0), originalArgsList.get(originalTypeList.size() - 1)); + superMethod.arguments().add(argsCopy); + } + astRewrite.replace(node, superMethod, null); + } + } + } + } + return true; + } + + private boolean findInHierarchy(ITypeBinding toFind, ITypeBinding binding) { + if (binding == null) { + return false; + } + if (toFind.isEqualTo(binding)) { + return true; + } + if (findInHierarchy(toFind, binding.getSuperclass())) { + return true; + } + ITypeBinding[] bindingInterfaces= binding.getInterfaces(); + for (ITypeBinding bindingInterface : bindingInterfaces) { + if (findInHierarchy(toFind, bindingInterface)) { + return true; + } + } + return false; + } + } + + /** + * @param document + * the buffer containing the source of the source compilation + * unit + * @param declaration + * the method declaration to use as source + * @param rewrite + * the ast rewrite to use for the copy of the method body + * @param rewrites + * the compilation unit rewrites + * @throws JavaModelException + * if the insertion point cannot be found + */ + protected void modifyInheritedMethodCalls(final IDocument document, final MethodDeclaration declaration, final ASTRewrite rewrite, final Map rewrites) throws JavaModelException { + Assert.isNotNull(document); + Assert.isNotNull(declaration); + Assert.isNotNull(rewrite); + Assert.isNotNull(rewrites); + final CompilationUnitRewrite rewriter= getCompilationUnitRewrite(rewrites, getTargetType().getCompilationUnit()); + final AbstractTypeDeclaration type= ASTNodeSearchUtil.getAbstractTypeDeclarationNode(getTargetType(), rewriter.getRoot()); + type.accept(new SuperMethodChecker(rewriter)); + } + /** * Creates the necessary changes to remove method type parameters if they * match with enclosing type parameters. diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test80/in/A.java b/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test80/in/A.java new file mode 100644 index 00000000000..3e8e02eed49 --- /dev/null +++ b/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test80/in/A.java @@ -0,0 +1,21 @@ +package p1; + +class A { + B b; + + void method() { + System.out.println("A class method"); + } +} + +class ParentClass { + void method() { + System.out.println("ParentClass method"); + } +} + +class B extends ParentClass { + void test() { + method(); + } +} diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test80/out/A.java b/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test80/out/A.java new file mode 100644 index 00000000000..7bb4630e6e2 --- /dev/null +++ b/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test80/out/A.java @@ -0,0 +1,21 @@ +package p1; + +class A { + B b; +} + +class ParentClass { + void method() { + System.out.println("ParentClass method"); + } +} + +class B extends ParentClass { + void test() { + super.method(); + } + + void method() { + System.out.println("A class method"); + } +} diff --git a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/MoveInstanceMethodTests.java b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/MoveInstanceMethodTests.java index cdfe9092d1d..ff70ea1c778 100644 --- a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/MoveInstanceMethodTests.java +++ b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/MoveInstanceMethodTests.java @@ -708,6 +708,13 @@ public void test78() throws Exception { public void test79() throws Exception { helper1(new String[] { "A" }, "A", 11, 17, 11, 18, FIELD, "b", true, true); } + + @Test + public void test80() throws Exception { + helper1(new String[] { "A" }, "A", 6, 10, 6, 16, FIELD, "b", true, true); + } + + // Move mA1 to field fB, do not inline delegator @Test public void test3() throws Exception {