Skip to content

Commit d47fcad

Browse files
timtebeekclaude
andcommitted
Add support for method references as first predicate
When the first argument to Predicates.and() or Predicates.or() is a method reference, wrap it with a cast to enable calling .and()/.or() on it. Example: Before: Predicates.and(Objects::nonNull, s -> s.length() > 5) After: ((Predicate<String>) Objects::nonNull).and(s -> s.length() > 5) Changes: - Detect J.MemberReference as first argument - Extract parameterized type information - Build cast template with proper type string - Added test case for method reference scenario 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 4be0a50 commit d47fcad

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed

src/main/java/org/openrewrite/java/migrate/guava/NoGuavaPredicatesAndOr.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import org.openrewrite.java.search.UsesMethod;
2626
import org.openrewrite.java.tree.Expression;
2727
import org.openrewrite.java.tree.J;
28+
import org.openrewrite.java.tree.JavaType;
29+
import org.openrewrite.java.tree.TypeUtils;
2830

2931
import java.util.List;
3032
import java.util.Set;
@@ -78,6 +80,20 @@ private J handlePredicatesMethod(J.MethodInvocation method, String operation) {
7880

7981
// Build the chain: first.operation(second).operation(third)...
8082
Expression result = arguments.get(0);
83+
84+
// If the first argument is a method reference, wrap it with a cast
85+
if (result instanceof J.MemberReference && result.getType() != null) {
86+
JavaType type = result.getType();
87+
String typeString = getTypeString(type);
88+
if (typeString != null) {
89+
result = JavaTemplate.builder("((" + typeString + ") #{any()})")
90+
.build()
91+
.apply(getCursor(),
92+
method.getCoordinates().replace(),
93+
result);
94+
}
95+
}
96+
8197
for (int i = 1; i < arguments.size(); i++) {
8298
result = JavaTemplate.builder("#{any(java.util.function.Predicate)}." + operation + "(#{any(java.util.function.Predicate)})")
8399
.build()
@@ -89,6 +105,28 @@ private J handlePredicatesMethod(J.MethodInvocation method, String operation) {
89105

90106
return result;
91107
}
108+
109+
private String getTypeString(JavaType type) {
110+
if (type instanceof JavaType.Parameterized) {
111+
JavaType.Parameterized parameterized = (JavaType.Parameterized) type;
112+
JavaType.FullyQualified fq = TypeUtils.asFullyQualified(parameterized.getType());
113+
if (fq != null && !parameterized.getTypeParameters().isEmpty()) {
114+
StringBuilder sb = new StringBuilder(fq.getClassName());
115+
sb.append("<");
116+
for (int i = 0; i < parameterized.getTypeParameters().size(); i++) {
117+
if (i > 0) sb.append(", ");
118+
JavaType param = parameterized.getTypeParameters().get(i);
119+
JavaType.FullyQualified paramFq = TypeUtils.asFullyQualified(param);
120+
if (paramFq != null) {
121+
sb.append(paramFq.getClassName());
122+
}
123+
}
124+
sb.append(">");
125+
return sb.toString();
126+
}
127+
}
128+
return null;
129+
}
92130
});
93131
}
94132
}

src/test/java/org/openrewrite/java/migrate/guava/NoGuavaPredicatesAndOrTest.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,32 @@ class Test {
119119
);
120120
}
121121

122+
@Test
123+
void replacePredicatesAndWithMethodReference() {
124+
//language=java
125+
rewriteRun(
126+
java(
127+
"""
128+
import com.google.common.base.Predicate;
129+
import com.google.common.base.Predicates;
130+
import java.util.Objects;
131+
132+
class Test {
133+
Predicate<String> combined = Predicates.and(Objects::nonNull, s -> s.length() > 5);
134+
}
135+
""",
136+
"""
137+
import com.google.common.base.Predicate;
138+
import java.util.Objects;
139+
140+
class Test {
141+
Predicate<String> combined = ((Predicate<String>) Objects::nonNull).and(s -> s.length() > 5);
142+
}
143+
"""
144+
)
145+
);
146+
}
147+
122148
@Test
123149
void replacePredicatesAndNestedCalls() {
124150
//language=java

0 commit comments

Comments
 (0)