Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public AddNullMethodArgumentVisitor(String methodPattern) {
public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration method, ExecutionContext ctx) {
method = super.visitMethodDeclaration(method, ctx);
J.ClassDeclaration enclosing = getCursor().firstEnclosing(J.ClassDeclaration.class);
if (enclosing != null && methodMatcher.matches(method, enclosing)) {
if (enclosing != null && (methodMatcher.matches(method, enclosing) || methodMatcher.matchesWithInheritance(method, enclosing))) {
for (Statement parameter : method.getParameters()) {
if (parameter instanceof J.VariableDeclarations && ((J.VariableDeclarations) parameter).getVariables().get(0).getSimpleName().equals(parameterName)) {
return method;
Expand Down Expand Up @@ -263,7 +263,7 @@ private static class DeclaresMatchingType extends JavaIsoVisitor<ExecutionContex
private final TypeMatcher typeMatcher;

public DeclaresMatchingType(String type) {
this.typeMatcher = new TypeMatcher(type);
this.typeMatcher = new TypeMatcher(type,true);
}

@Override
Expand Down
23 changes: 23 additions & 0 deletions rewrite-java/src/main/java/org/openrewrite/java/MethodMatcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,29 @@ public boolean matches(J.MethodDeclaration method, J.NewClass enclosing) {
return matchesParameterTypes(parameterTypes);
}

public boolean matchesWithInheritance(J.MethodDeclaration method, J.ClassDeclaration enclosing) {
if (enclosing.getType() == null) {
return false;
}

if (!TypeUtils.isAssignableTo(this::matchesTargetType, enclosing.getType())) {
return false;
}

if (method.getMethodType() != null && !matchesMethodName(method.getMethodType().getName())) {
return false;
}

List<JavaType> parameterTypes = method
.getParameters()
.stream()
.map(MethodMatcher::variableDeclarationsType)
.filter(Objects::nonNull)
.collect(toList());

return matchesParameterTypes(parameterTypes);
}

private static @Nullable JavaType variableDeclarationsType(Statement v) {
if (v instanceof J.VariableDeclarations) {
J.VariableDeclarations vd = (J.VariableDeclarations) v;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import org.openrewrite.java.JavaIsoVisitor;
import org.openrewrite.java.tree.J;
import org.openrewrite.java.tree.JavaType;
import org.openrewrite.java.tree.TypeUtils;
import org.openrewrite.marker.SearchResult;

Expand All @@ -29,8 +30,12 @@ public DeclaresType(String type) {

@Override
public J.ClassDeclaration visitClassDeclaration(J.ClassDeclaration classDecl, P p) {
if (classDecl.getType() != null && TypeUtils.isOfClassType(classDecl.getType(), type)) {
return SearchResult.found(classDecl);
if (classDecl.getType() != null) {
JavaType targetType = JavaType.ShallowClass.build(type);

if (TypeUtils.isAssignableTo(targetType, classDecl.getType())) {
return SearchResult.found(classDecl);
}
}
return super.visitClassDeclaration(classDecl, p);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -305,4 +305,91 @@ public void bar(Object o) {
)
);
}

@Test
void matchesMethodsInClassesThatImplementInterface() {
rewriteRun(
spec -> spec.recipe(new AddMethodParameter("foo.A count(foo.Sheep)", "Wolf", "wolf", null)),
java(
"""
package foo;

public interface A {
int count(Sheep flock);
}
""",
"""
package foo;

public interface A {
int count(Sheep flock, Wolf wolf);
}
"""
),
java(
"""
package foo;

public class Sheep {
public int size() {
return 0;
}
}
"""
),
java(
"""
package foo;

public class Wolf {
}
"""
),
java(
"""
package foo;

public class Sleep implements A {
@Override
public int count(Sheep flock) {
return flock.size();
}
}
""",
"""
package foo;

public class Sleep implements A {
@Override
public int count(Sheep flock, Wolf wolf) {
return flock.size();
}
}
"""
),
java(
"""
package foo;

public class Awake implements A {
@Override
public int count(Sheep flock) {
return 0;
}
}
""",
"""
package foo;

public class Awake implements A {
@Override
public int count(Sheep flock, Wolf wolf) {
return 0;
}
}
"""
)
);
}

}