Skip to content

Commit cef9c1f

Browse files
authored
Convert Guava Predicates.and and .or (#885)
1 parent 67e8d8c commit cef9c1f

File tree

3 files changed

+238
-0
lines changed

3 files changed

+238
-0
lines changed
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
* Copyright 2024 the original author or authors.
3+
* <p>
4+
* Licensed under the Moderne Source Available License (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
* <p>
8+
* https://docs.moderne.io/licensing/moderne-source-available-license
9+
* <p>
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.openrewrite.java.migrate.guava;
17+
18+
import org.openrewrite.ExecutionContext;
19+
import org.openrewrite.Preconditions;
20+
import org.openrewrite.Recipe;
21+
import org.openrewrite.TreeVisitor;
22+
import org.openrewrite.java.JavaTemplate;
23+
import org.openrewrite.java.JavaVisitor;
24+
import org.openrewrite.java.MethodMatcher;
25+
import org.openrewrite.java.search.UsesMethod;
26+
import org.openrewrite.java.tree.J;
27+
28+
import java.util.Set;
29+
30+
import static java.util.Collections.singleton;
31+
32+
public class NoGuavaPredicatesAndOr extends Recipe {
33+
private static final MethodMatcher PREDICATES_AND = new MethodMatcher("com.google.common.base.Predicates and(com.google.common.base.Predicate, com.google.common.base.Predicate)");
34+
private static final MethodMatcher PREDICATES_OR = new MethodMatcher("com.google.common.base.Predicates or(com.google.common.base.Predicate, com.google.common.base.Predicate)");
35+
36+
@Override
37+
public String getDisplayName() {
38+
return "Prefer `Predicate.and(Predicate)`";
39+
}
40+
41+
@Override
42+
public String getDescription() {
43+
return "Prefer `Predicate.and(Predicate)` over `Predicates.and(Predicate, Predicate)`.";
44+
}
45+
46+
@Override
47+
public Set<String> getTags() {
48+
return singleton("guava");
49+
}
50+
51+
@Override
52+
public TreeVisitor<?, ExecutionContext> getVisitor() {
53+
TreeVisitor<?, ExecutionContext> precondition = Preconditions.or(new UsesMethod<>(PREDICATES_AND), new UsesMethod<>(PREDICATES_OR));
54+
return Preconditions.check(precondition, new JavaVisitor<ExecutionContext>() {
55+
@Override
56+
public J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) {
57+
if (PREDICATES_AND.matches(method)) {
58+
maybeRemoveImport("com.google.common.base.Predicate");
59+
maybeRemoveImport("com.google.common.base.Predicates");
60+
maybeAddImport("java.util.function.Predicate");
61+
if (method.getArguments().size() == 2) {
62+
return JavaTemplate.builder("#{any(java.util.function.Predicate)}.and(#{any(java.util.function.Predicate)})")
63+
.build()
64+
.apply(getCursor(),
65+
method.getCoordinates().replace(),
66+
method.getArguments().get(0),
67+
method.getArguments().get(1));
68+
}
69+
}
70+
if (PREDICATES_OR.matches(method)) {
71+
maybeRemoveImport("com.google.common.base.Predicate");
72+
maybeRemoveImport("com.google.common.base.Predicates");
73+
maybeAddImport("java.util.function.Predicate");
74+
if (method.getArguments().size() == 2) {
75+
return JavaTemplate.builder("#{any(java.util.function.Predicate)}.or(#{any(java.util.function.Predicate)})")
76+
.build()
77+
.apply(getCursor(),
78+
method.getCoordinates().replace(),
79+
method.getArguments().get(0),
80+
method.getArguments().get(1));
81+
}
82+
}
83+
84+
return super.visitMethodInvocation(method, ctx);
85+
}
86+
});
87+
}
88+
}

src/main/resources/META-INF/rewrite/no-guava.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ recipeList:
3434
- org.openrewrite.java.migrate.guava.NoGuavaListsNewCopyOnWriteArrayList
3535
- org.openrewrite.java.migrate.guava.NoGuavaListsNewLinkedList
3636
- org.openrewrite.java.migrate.guava.NoGuavaMapsNewTreeMap
37+
- org.openrewrite.java.migrate.guava.NoGuavaPredicatesAndOr
3738
- org.openrewrite.java.migrate.guava.NoGuavaPrimitiveAsList
3839
- org.openrewrite.java.migrate.guava.NoGuavaRefasterRecipes
3940
- org.openrewrite.java.migrate.guava.NoGuavaMapsNewHashMap
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
/*
2+
* Copyright 2024 the original author or authors.
3+
* <p>
4+
* Licensed under the Moderne Source Available License (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
* <p>
8+
* https://docs.moderne.io/licensing/moderne-source-available-license
9+
* <p>
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.openrewrite.java.migrate.guava;
17+
18+
import org.junit.jupiter.api.Test;
19+
import org.openrewrite.DocumentExample;
20+
import org.openrewrite.InMemoryExecutionContext;
21+
import org.openrewrite.java.JavaParser;
22+
import org.openrewrite.test.RecipeSpec;
23+
import org.openrewrite.test.RewriteTest;
24+
25+
import static org.openrewrite.java.Assertions.java;
26+
27+
class NoGuavaPredicatesAndOrTest implements RewriteTest {
28+
29+
@Override
30+
public void defaults(RecipeSpec spec) {
31+
spec
32+
.recipe(new NoGuavaPredicatesAndOr())
33+
.parser(JavaParser.fromJavaVersion().classpathFromResources(new InMemoryExecutionContext(), "guava"));
34+
}
35+
36+
@DocumentExample
37+
@Test
38+
void replacePredicatesAnd() {
39+
//language=java
40+
rewriteRun(
41+
java(
42+
"""
43+
import com.google.common.base.Predicate;
44+
import com.google.common.base.Predicates;
45+
46+
class Test {
47+
Predicate<String> isNotNull = s -> s != null;
48+
Predicate<String> isNotEmpty = s -> !s.isEmpty();
49+
Predicate<String> combined = Predicates.and(isNotNull, isNotEmpty);
50+
}
51+
""",
52+
"""
53+
import com.google.common.base.Predicate;
54+
55+
class Test {
56+
Predicate<String> isNotNull = s -> s != null;
57+
Predicate<String> isNotEmpty = s -> !s.isEmpty();
58+
Predicate<String> combined = isNotNull.and(isNotEmpty);
59+
}
60+
"""
61+
)
62+
);
63+
}
64+
65+
@Test
66+
void replacePredicatesOr() {
67+
//language=java
68+
rewriteRun(
69+
java(
70+
"""
71+
import com.google.common.base.Predicate;
72+
import com.google.common.base.Predicates;
73+
74+
class Test {
75+
Predicate<String> isNotNull = s -> s != null;
76+
Predicate<String> isNotEmpty = s -> !s.isEmpty();
77+
Predicate<String> combined = Predicates.or(isNotNull, isNotEmpty);
78+
}
79+
""",
80+
"""
81+
import com.google.common.base.Predicate;
82+
83+
class Test {
84+
Predicate<String> isNotNull = s -> s != null;
85+
Predicate<String> isNotEmpty = s -> !s.isEmpty();
86+
Predicate<String> combined = isNotNull.or(isNotEmpty);
87+
}
88+
"""
89+
)
90+
);
91+
}
92+
93+
@Test
94+
void replacePredicatesAndWithMethodReferences() {
95+
//language=java
96+
rewriteRun(
97+
java(
98+
"""
99+
import com.google.common.base.Predicate;
100+
import com.google.common.base.Predicates;
101+
import java.util.Objects;
102+
103+
class Test {
104+
Predicate<String> combined = Predicates.and(Objects::nonNull, s -> s.length() > 5);
105+
}
106+
""",
107+
"""
108+
import com.google.common.base.Predicate;
109+
import java.util.Objects;
110+
111+
class Test {
112+
Predicate<String> combined = Objects::nonNull.and(s -> s.length() > 5);
113+
}
114+
"""
115+
)
116+
);
117+
}
118+
119+
@Test
120+
void replacePredicatesAndNestedCalls() {
121+
//language=java
122+
rewriteRun(
123+
spec -> spec.expectedCyclesThatMakeChanges(2),
124+
java(
125+
"""
126+
import com.google.common.base.Predicate;
127+
import com.google.common.base.Predicates;
128+
129+
class Test {
130+
Predicate<Integer> isPositive = n -> n > 0;
131+
Predicate<Integer> isEven = n -> n % 2 == 0;
132+
Predicate<Integer> isLessThan100 = n -> n < 100;
133+
Predicate<Integer> combined = Predicates.and(isPositive, Predicates.and(isEven, isLessThan100));
134+
}
135+
""",
136+
"""
137+
import com.google.common.base.Predicate;
138+
139+
class Test {
140+
Predicate<Integer> isPositive = n -> n > 0;
141+
Predicate<Integer> isEven = n -> n % 2 == 0;
142+
Predicate<Integer> isLessThan100 = n -> n < 100;
143+
Predicate<Integer> combined = isPositive.and(isEven.and(isLessThan100));
144+
}
145+
"""
146+
)
147+
);
148+
}
149+
}

0 commit comments

Comments
 (0)