Skip to content

Commit 2338c3a

Browse files
committed
Cover more cases for Predicates.and/or methods
This commit avoids excluding too many cases affected by generic type issues. It only excludes cases where one of the parameters is a call to a static method of `com.google.common.base.Predicates`. Even within this list, specific exclusions are maintained for known cases that are correctly handled by other Guava recipes. Currently, the list of methods from Predicates is: - Predicates.and (already OK before this commit) - Predicates.or (already OK before this commit) - Predicates.equalTo (already OK before this commit) - Predicates.not (KO before this commit) Corresponding tests have been added.
1 parent b70cb61 commit 2338c3a

File tree

2 files changed

+246
-7
lines changed

2 files changed

+246
-7
lines changed

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

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@
2626
import org.openrewrite.java.search.UsesMethod;
2727
import org.openrewrite.java.tree.Expression;
2828
import org.openrewrite.java.tree.J;
29+
import org.openrewrite.java.tree.JavaType;
30+
import org.openrewrite.java.tree.TypeUtils;
2931

32+
import java.util.Arrays;
3033
import java.util.List;
3134
import java.util.Set;
3235

@@ -35,7 +38,8 @@
3538
public class NoGuavaPredicatesAndOr extends Recipe {
3639
private static final MethodMatcher PREDICATES_AND = new MethodMatcher("com.google.common.base.Predicates and(..)");
3740
private static final MethodMatcher PREDICATES_OR = new MethodMatcher("com.google.common.base.Predicates or(..)");
38-
private static final MethodMatcher PREDICATES_EQUAL_TO = new MethodMatcher("com.google.common.base.Predicates equalTo(..)");
41+
private static final List<MethodMatcher> PREDICATES_METHODS_HANDLED = Arrays.asList(new MethodMatcher("com.google.common.base.Predicates equalTo(..)"),
42+
PREDICATES_AND, PREDICATES_OR, new MethodMatcher("com.google.common.base.Predicates not(..)"));
3943

4044
@Override
4145
public String getDisplayName() {
@@ -74,17 +78,17 @@ private J handlePredicatesMethod(J.MethodInvocation method, String operation) {
7478
return method;
7579
}
7680

81+
// Avoid generic type issues, for method of "com.google.common.base.Predicates", by not making any changes just yet
82+
if (atLeastOneArgumentIsMethodInvocationOfPredicates(arguments)) {
83+
return method;
84+
}
85+
7786
maybeRemoveImport("com.google.common.base.Predicates");
7887

7988
// Build the chain: first.operation(second).operation(third)...
8089
Expression result = arguments.get(0);
8190

82-
// Avoid generic type issues by not making any changes just yet
83-
if (result instanceof J.MethodInvocation && !PREDICATES_EQUAL_TO.matches(result)) {
84-
return method;
85-
}
86-
87-
// If the first argument is a method reference or a lambda, wrap it with a cast
91+
// If the first argument is a method reference or a lambda, wrap it with a cast
8892
if ((result instanceof J.MemberReference || result instanceof J.Lambda) && result.getType() != null) {
8993
String typeString = result.getType().toString().replace("com.google.common.base.", "");
9094
result = JavaTemplate.apply("((" + typeString + ") #{any()})", getCursor(), method.getCoordinates().replace(), result);
@@ -100,4 +104,29 @@ private J handlePredicatesMethod(J.MethodInvocation method, String operation) {
100104

101105
});
102106
}
107+
108+
private boolean atLeastOneArgumentIsMethodInvocationOfPredicates(List<Expression> arguments) {
109+
for (Expression expression : arguments) {
110+
if (expression instanceof J.MethodInvocation) {
111+
if (!isMethodHandled((J.MethodInvocation) expression)) {
112+
JavaType.Method methodType = ((J.MethodInvocation) expression).getMethodType();
113+
if (methodType != null) {
114+
if (TypeUtils.isOfClassType(methodType.getDeclaringType(), "com.google.common.base.Predicates")) {
115+
return true;
116+
}
117+
}
118+
}
119+
}
120+
}
121+
return false;
122+
}
123+
124+
private boolean isMethodHandled(J.MethodInvocation methodInvocation) {
125+
for (MethodMatcher methodMatcher : PREDICATES_METHODS_HANDLED) {
126+
if (methodMatcher.matches(methodInvocation)) {
127+
return true;
128+
}
129+
}
130+
return false;
131+
}
103132
}

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

Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,37 @@ class Test {
196196
);
197197
}
198198

199+
@Test
200+
void replacePredicatesOrNestedCalls() {
201+
//language=java
202+
rewriteRun(
203+
spec -> spec.expectedCyclesThatMakeChanges(2),
204+
java(
205+
"""
206+
import com.google.common.base.Predicate;
207+
import com.google.common.base.Predicates;
208+
209+
class Test {
210+
Predicate<Integer> isPositive = n -> n > 0;
211+
Predicate<Integer> isEven = n -> n % 2 == 0;
212+
Predicate<Integer> isLessThan100 = n -> n < 100;
213+
Predicate<Integer> combined = Predicates.and(isPositive, Predicates.or(isEven, isLessThan100));
214+
}
215+
""",
216+
"""
217+
import com.google.common.base.Predicate;
218+
219+
class Test {
220+
Predicate<Integer> isPositive = n -> n > 0;
221+
Predicate<Integer> isEven = n -> n % 2 == 0;
222+
Predicate<Integer> isLessThan100 = n -> n < 100;
223+
Predicate<Integer> combined = isPositive.and(isEven.or(isLessThan100));
224+
}
225+
"""
226+
)
227+
);
228+
}
229+
199230
@Issue("https://github.com/openrewrite/rewrite-migrate-java/issues/893")
200231
@Test
201232
void replacePredicatesAndWithMoreThanTwoParameters() {
@@ -257,4 +288,183 @@ class Test {
257288
)
258289
);
259290
}
291+
292+
@Test
293+
void replacePredicatesAndWithOtherClassMethodAsParameters() {
294+
//language=java
295+
rewriteRun(
296+
java(
297+
"""
298+
import com.google.common.base.Predicate;
299+
import com.google.common.base.Predicates;
300+
import java.util.Objects;
301+
302+
class Test {
303+
Predicate<String> getNotNullPredicate() {
304+
return Objects::nonNull;
305+
}
306+
Predicate<String> getMaxLengthPredicate() {
307+
return s -> s.length() > 5;
308+
}
309+
Predicate<String> combined = Predicates.and(getNotNullPredicate(), getMaxLengthPredicate());
310+
}
311+
""",
312+
"""
313+
import com.google.common.base.Predicate;
314+
import java.util.Objects;
315+
316+
class Test {
317+
Predicate<String> getNotNullPredicate() {
318+
return Objects::nonNull;
319+
}
320+
Predicate<String> getMaxLengthPredicate() {
321+
return s -> s.length() > 5;
322+
}
323+
Predicate<String> combined = getNotNullPredicate().and(getMaxLengthPredicate());
324+
}
325+
"""
326+
)
327+
);
328+
}
329+
330+
@Test
331+
void replacePredicatesAndWithNotMethodAsParameters() {
332+
//language=java
333+
rewriteRun(
334+
java(
335+
"""
336+
import com.google.common.base.Predicate;
337+
import com.google.common.base.Predicates;
338+
import java.util.Objects;
339+
340+
class Test {
341+
Predicate<String> getNotNullPredicate() {
342+
return Objects::nonNull;
343+
}
344+
Predicate<String> getMaxLengthPredicate() {
345+
return s -> s.length() > 5;
346+
}
347+
Predicate<String> combined = Predicates.and(Predicates.not(getNotNullPredicate()), getMaxLengthPredicate());
348+
}
349+
""",
350+
"""
351+
import com.google.common.base.Predicate;
352+
import com.google.common.base.Predicates;
353+
import java.util.Objects;
354+
355+
class Test {
356+
Predicate<String> getNotNullPredicate() {
357+
return Objects::nonNull;
358+
}
359+
Predicate<String> getMaxLengthPredicate() {
360+
return s -> s.length() > 5;
361+
}
362+
Predicate<String> combined = Predicates.not(getNotNullPredicate()).and(getMaxLengthPredicate());
363+
}
364+
"""
365+
)
366+
);
367+
}
368+
369+
370+
@Test
371+
void replacePredicatesAndWithEqualToMethodAsParameters() {
372+
//language=java
373+
rewriteRun(
374+
java(
375+
"""
376+
import com.google.common.base.Predicate;
377+
import com.google.common.base.Predicates;
378+
import java.util.Objects;
379+
380+
class Test {
381+
Predicate<String> getNotNullPredicate() {
382+
return Objects::nonNull;
383+
}
384+
Predicate<String> getMaxLengthPredicate() {
385+
return s -> s.length() < 10;
386+
}
387+
Predicate<String> combined = Predicates.and(Predicates.equalTo("MyTest"), getMaxLengthPredicate());
388+
}
389+
""",
390+
"""
391+
import com.google.common.base.Predicate;
392+
import com.google.common.base.Predicates;
393+
import java.util.Objects;
394+
395+
class Test {
396+
Predicate<String> getNotNullPredicate() {
397+
return Objects::nonNull;
398+
}
399+
Predicate<String> getMaxLengthPredicate() {
400+
return s -> s.length() < 10;
401+
}
402+
Predicate<String> combined = Predicates.equalTo("MyTest").and(getMaxLengthPredicate());
403+
}
404+
"""
405+
)
406+
);
407+
}
408+
409+
@Test
410+
void doNotReplacePredicatesAndWithNotHandledPredicatesMethodAsFirstParameter() {
411+
//language=java
412+
rewriteRun(
413+
java(
414+
"""
415+
import com.google.common.base.Predicate;
416+
import com.google.common.base.Predicates;
417+
418+
import java.util.Collection;
419+
import java.util.Objects;
420+
421+
class Test {
422+
Predicate<String> getMinSizePredicate() {
423+
return new Predicate<String>() {
424+
@Override
425+
public boolean apply(String input) {
426+
return input.length() > 5;
427+
}
428+
};
429+
}
430+
431+
public void test(Collection<String> aCollection) {
432+
Predicate<String> combined = Predicates.and(Predicates.in(aCollection), getMinSizePredicate());
433+
}
434+
}
435+
"""
436+
)
437+
);
438+
}
439+
440+
@Test
441+
void doNotReplacePredicatesAndWithNotHandledPredicatesMethodAsSecondParameter() {
442+
//language=java
443+
rewriteRun(
444+
java(
445+
"""
446+
import com.google.common.base.Predicate;
447+
import com.google.common.base.Predicates;
448+
449+
import java.util.Collection;
450+
import java.util.Objects;
451+
452+
class Test {
453+
Predicate<String> getMinSizePredicate() {
454+
return new Predicate<String>() {
455+
@Override
456+
public boolean apply(String input) {
457+
return input.length() > 5;
458+
}
459+
};
460+
}
461+
462+
public void test(Collection<String> aCollection) {
463+
Predicate<String> combined = Predicates.and(getMinSizePredicate(), Predicates.in(aCollection));
464+
}
465+
}
466+
"""
467+
)
468+
);
469+
}
260470
}

0 commit comments

Comments
 (0)