Skip to content

Commit e4b72b6

Browse files
Allow AddMethodParameter to match overridden methods (#6294)
* Issue #6287: enable AddMethodParameter to match overridden methods * Minimize changes to `MethodMatcher` * Rename variable to clarify meaning in this context * Expand tests in DeclaresTypeTest --------- Co-authored-by: Tim te Beek <tim@moderne.io>
1 parent 7216f15 commit e4b72b6

File tree

4 files changed

+169
-19
lines changed

4 files changed

+169
-19
lines changed

rewrite-java/src/main/java/org/openrewrite/java/AddMethodParameter.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,14 +83,18 @@ public TreeVisitor<?, ExecutionContext> getVisitor() {
8383
int idx = methodPattern.indexOf('#');
8484
idx = idx == -1 ? methodPattern.indexOf(' ') : idx;
8585
boolean typePattern = idx != -1 && methodPattern.lastIndexOf('*', idx) != -1;
86-
return Preconditions.check(typePattern ? new DeclaresMatchingType(methodPattern.substring(0, idx)) : new DeclaresType<>(methodPattern.substring(0, idx)), new AddNullMethodArgumentVisitor(methodPattern));
86+
return Preconditions.check(
87+
typePattern ?
88+
new DeclaresMatchingType(methodPattern.substring(0, idx)) :
89+
new DeclaresType<>(methodPattern.substring(0, idx), true),
90+
new AddNullMethodArgumentVisitor(methodPattern));
8791
}
8892

8993
private class AddNullMethodArgumentVisitor extends JavaIsoVisitor<ExecutionContext> {
9094
private final MethodMatcher methodMatcher;
9195

9296
public AddNullMethodArgumentVisitor(String methodPattern) {
93-
this.methodMatcher = new MethodMatcher(methodPattern);
97+
this.methodMatcher = new MethodMatcher(methodPattern, true);
9498
}
9599

96100
@Override
@@ -263,7 +267,7 @@ private static class DeclaresMatchingType extends JavaIsoVisitor<ExecutionContex
263267
private final TypeMatcher typeMatcher;
264268

265269
public DeclaresMatchingType(String type) {
266-
this.typeMatcher = new TypeMatcher(type);
270+
this.typeMatcher = new TypeMatcher(type, true);
267271
}
268272

269273
@Override

rewrite-java/src/main/java/org/openrewrite/java/search/DeclaresType.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,24 @@
2222

2323
public class DeclaresType<P> extends JavaIsoVisitor<P> {
2424
private final String type;
25+
private final boolean includeSubtypes;
2526

2627
public DeclaresType(String type) {
28+
this(type, false);
29+
}
30+
31+
public DeclaresType(String type, boolean includeSubtypes) {
2732
this.type = type;
33+
this.includeSubtypes = includeSubtypes;
2834
}
2935

3036
@Override
3137
public J.ClassDeclaration visitClassDeclaration(J.ClassDeclaration classDecl, P p) {
32-
if (classDecl.getType() != null && TypeUtils.isOfClassType(classDecl.getType(), type)) {
33-
return SearchResult.found(classDecl);
38+
if (classDecl.getType() != null) {
39+
if (includeSubtypes && TypeUtils.isAssignableTo(type, classDecl.getType()) ||
40+
TypeUtils.isOfClassType(classDecl.getType(), type)) {
41+
return SearchResult.found(classDecl);
42+
}
3443
}
3544
return super.visitClassDeclaration(classDecl, p);
3645
}

rewrite-java/src/test/java/org/openrewrite/java/AddMethodParameterTest.java

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,4 +305,91 @@ public void bar(Object o) {
305305
)
306306
);
307307
}
308+
309+
@Test
310+
void matchesMethodsInClassesThatImplementInterface() {
311+
rewriteRun(
312+
spec -> spec.recipe(new AddMethodParameter("foo.A count(foo.Sheep)", "Wolf", "wolf", null)),
313+
java(
314+
"""
315+
package foo;
316+
317+
public interface A {
318+
int count(Sheep flock);
319+
}
320+
""",
321+
"""
322+
package foo;
323+
324+
public interface A {
325+
int count(Sheep flock, Wolf wolf);
326+
}
327+
"""
328+
),
329+
java(
330+
"""
331+
package foo;
332+
333+
public class Sheep {
334+
public int size() {
335+
return 0;
336+
}
337+
}
338+
"""
339+
),
340+
java(
341+
"""
342+
package foo;
343+
344+
public class Wolf {
345+
}
346+
"""
347+
),
348+
java(
349+
"""
350+
package foo;
351+
352+
public class Sleep implements A {
353+
@Override
354+
public int count(Sheep flock) {
355+
return flock.size();
356+
}
357+
}
358+
""",
359+
"""
360+
package foo;
361+
362+
public class Sleep implements A {
363+
@Override
364+
public int count(Sheep flock, Wolf wolf) {
365+
return flock.size();
366+
}
367+
}
368+
"""
369+
),
370+
java(
371+
"""
372+
package foo;
373+
374+
public class Awake implements A {
375+
@Override
376+
public int count(Sheep flock) {
377+
return 0;
378+
}
379+
}
380+
""",
381+
"""
382+
package foo;
383+
384+
public class Awake implements A {
385+
@Override
386+
public int count(Sheep flock, Wolf wolf) {
387+
return 0;
388+
}
389+
}
390+
"""
391+
)
392+
);
393+
}
394+
308395
}

rewrite-java/src/test/java/org/openrewrite/java/search/DeclaresTypeTest.java

Lines changed: 64 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.openrewrite.DocumentExample;
2020
import org.openrewrite.test.RecipeSpec;
2121
import org.openrewrite.test.RewriteTest;
22+
import org.openrewrite.test.SourceSpec;
2223

2324
import static org.openrewrite.java.Assertions.java;
2425

@@ -31,23 +32,72 @@ public void defaults(RecipeSpec spec) {
3132
@DocumentExample
3233
@Test
3334
void declares() {
34-
rewriteRun(java(
35-
"""
36-
package com.sample;
37-
public class Foo{}
38-
""",
39-
"""
40-
package com.sample;
41-
/*~~>*/public class Foo{}
42-
"""));
35+
rewriteRun(
36+
java(
37+
"""
38+
package com.sample;
39+
public class Foo{}
40+
""",
41+
"""
42+
package com.sample;
43+
/*~~>*/public class Foo{}
44+
"""
45+
)
46+
);
47+
}
48+
49+
@Test
50+
void detectSubtypeWhenEnabled() {
51+
rewriteRun(
52+
spec -> spec.recipe(RewriteTest.toRecipe(() -> new DeclaresType<>("com.sample.Foo", true))),
53+
java(
54+
"""
55+
package com.sample;
56+
public interface Foo{}
57+
""",
58+
SourceSpec::skip
59+
),
60+
java(
61+
"""
62+
import com.sample.Foo;
63+
class A implements Foo{}
64+
""",
65+
"""
66+
import com.sample.Foo;
67+
/*~~>*/class A implements Foo{}
68+
"""
69+
)
70+
);
71+
}
72+
73+
@Test
74+
void subtypeNotEnabledByDefault() {
75+
rewriteRun(
76+
java(
77+
"""
78+
package com.sample;
79+
public interface Foo{}
80+
""",
81+
SourceSpec::skip
82+
),
83+
java(
84+
"""
85+
import com.sample.Foo;
86+
class A implements Foo{}
87+
"""
88+
)
89+
);
4390
}
4491

4592
@Test
4693
void notDeclares() {
47-
rewriteRun(java(
48-
"""
49-
package com.sample;
50-
public class Fooz{}
51-
"""));
94+
rewriteRun(
95+
java(
96+
"""
97+
package com.sample;
98+
public class Fooz{}
99+
"""
100+
)
101+
);
52102
}
53103
}

0 commit comments

Comments
 (0)