Skip to content

Commit fecaa2e

Browse files
authored
Fix AddMissingMethodImplementation generating stubs for inherited methods (#1051)
* Use `getVisibleMethods()` in `AddMissingMethodImplementation` to detect inherited methods Closes #648 * Skip only concrete inherited methods, not abstract interface declarations
1 parent 55f801a commit fecaa2e

2 files changed

Lines changed: 31 additions & 6 deletions

File tree

src/main/java/org/openrewrite/java/migrate/AddMissingMethodImplementation.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,13 @@
2222
import org.openrewrite.java.JavaTemplate;
2323
import org.openrewrite.java.MethodMatcher;
2424
import org.openrewrite.java.search.UsesType;
25+
import org.openrewrite.java.tree.Flag;
2526
import org.openrewrite.java.tree.J;
2627
import org.openrewrite.java.tree.JavaType;
2728
import org.openrewrite.java.tree.TypeUtils;
2829

30+
import java.util.Iterator;
31+
2932
import static org.openrewrite.java.tree.J.ClassDeclaration.Kind.Type.Interface;
3033

3134
@EqualsAndHashCode(callSuper = false)
@@ -80,13 +83,15 @@ public J.ClassDeclaration visitClassDeclaration(J.ClassDeclaration cs, Execution
8083
.anyMatch(methodDeclaration -> methodMatcher.matches(methodDeclaration, classDecl))) {
8184
return classDecl;
8285
}
83-
// If a superclass already provides the method, don't add it.
84-
JavaType.FullyQualified supertype = classDecl.getType() != null ? classDecl.getType().getSupertype() : null;
85-
while (supertype != null) {
86-
if (supertype.getMethods().stream().anyMatch(methodMatcher::matches)) {
87-
return classDecl;
86+
// If a concrete implementation is already available through inheritance, don't add it.
87+
if (classDecl.getType() != null) {
88+
Iterator<JavaType.Method> visibleMethods = classDecl.getType().getVisibleMethods();
89+
while (visibleMethods.hasNext()) {
90+
JavaType.Method method = visibleMethods.next();
91+
if (!method.hasFlags(Flag.Abstract) && methodMatcher.matches(method)) {
92+
return classDecl;
93+
}
8894
}
89-
supertype = supertype.getSupertype();
9095
}
9196

9297
return classDecl.withBody(JavaTemplate.apply( methodTemplateString, new Cursor( getCursor(), classDecl.getBody() ), classDecl.getBody().getCoordinates().lastStatement() ));

src/test/java/org/openrewrite/java/migrate/AddMissingMethodImplementationTest.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,4 +151,24 @@ class SubClass extends SuperClass {}
151151
);
152152
}
153153

154+
@Issue("https://github.com/openrewrite/rewrite-migrate-java/issues/648")
155+
@Test
156+
void skipWhenIndirectSuperclassAlreadyHasMethod() {
157+
//language=java
158+
rewriteRun(
159+
java(
160+
"""
161+
interface I1 {}
162+
class GrandSuperClass implements I1 {
163+
public void m1() {
164+
System.out.println("m1 from grandsuper");
165+
}
166+
}
167+
class SuperClass extends GrandSuperClass {}
168+
class SubClass extends SuperClass {}
169+
"""
170+
)
171+
);
172+
}
173+
154174
}

0 commit comments

Comments
 (0)