diff --git a/src/main/java/org/openrewrite/java/migrate/AddMissingMethodImplementation.java b/src/main/java/org/openrewrite/java/migrate/AddMissingMethodImplementation.java index 05998f6ff4..1f3dc3d23e 100644 --- a/src/main/java/org/openrewrite/java/migrate/AddMissingMethodImplementation.java +++ b/src/main/java/org/openrewrite/java/migrate/AddMissingMethodImplementation.java @@ -22,10 +22,13 @@ import org.openrewrite.java.JavaTemplate; import org.openrewrite.java.MethodMatcher; import org.openrewrite.java.search.UsesType; +import org.openrewrite.java.tree.Flag; import org.openrewrite.java.tree.J; import org.openrewrite.java.tree.JavaType; import org.openrewrite.java.tree.TypeUtils; +import java.util.Iterator; + import static org.openrewrite.java.tree.J.ClassDeclaration.Kind.Type.Interface; @EqualsAndHashCode(callSuper = false) @@ -80,13 +83,15 @@ public J.ClassDeclaration visitClassDeclaration(J.ClassDeclaration cs, Execution .anyMatch(methodDeclaration -> methodMatcher.matches(methodDeclaration, classDecl))) { return classDecl; } - // If a superclass already provides the method, don't add it. - JavaType.FullyQualified supertype = classDecl.getType() != null ? classDecl.getType().getSupertype() : null; - while (supertype != null) { - if (supertype.getMethods().stream().anyMatch(methodMatcher::matches)) { - return classDecl; + // If a concrete implementation is already available through inheritance, don't add it. + if (classDecl.getType() != null) { + Iterator visibleMethods = classDecl.getType().getVisibleMethods(); + while (visibleMethods.hasNext()) { + JavaType.Method method = visibleMethods.next(); + if (!method.hasFlags(Flag.Abstract) && methodMatcher.matches(method)) { + return classDecl; + } } - supertype = supertype.getSupertype(); } return classDecl.withBody(JavaTemplate.apply( methodTemplateString, new Cursor( getCursor(), classDecl.getBody() ), classDecl.getBody().getCoordinates().lastStatement() )); diff --git a/src/test/java/org/openrewrite/java/migrate/AddMissingMethodImplementationTest.java b/src/test/java/org/openrewrite/java/migrate/AddMissingMethodImplementationTest.java index dcc11f09d9..fc0b01d2e6 100644 --- a/src/test/java/org/openrewrite/java/migrate/AddMissingMethodImplementationTest.java +++ b/src/test/java/org/openrewrite/java/migrate/AddMissingMethodImplementationTest.java @@ -151,4 +151,24 @@ class SubClass extends SuperClass {} ); } + @Issue("https://github.com/openrewrite/rewrite-migrate-java/issues/648") + @Test + void skipWhenIndirectSuperclassAlreadyHasMethod() { + //language=java + rewriteRun( + java( + """ + interface I1 {} + class GrandSuperClass implements I1 { + public void m1() { + System.out.println("m1 from grandsuper"); + } + } + class SuperClass extends GrandSuperClass {} + class SubClass extends SuperClass {} + """ + ) + ); + } + }