Skip to content

Commit 997ff79

Browse files
committed
Only convert Guava Predicate when not used as method argument
1 parent 808ddc1 commit 997ff79

File tree

4 files changed

+232
-33
lines changed

4 files changed

+232
-33
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright 2025 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.ChangeType;
23+
import org.openrewrite.java.search.UsesMethod;
24+
25+
public class NoGuavaPredicate extends Recipe {
26+
@Override
27+
public String getDisplayName() {
28+
return "Change Guava's `Predicate` into `java.util.function.Predicate` where possible";
29+
}
30+
31+
@Override
32+
public String getDescription() {
33+
return "Change the type only where no methods are used that explicitly require a Guava `Predicate`.";
34+
}
35+
36+
@Override
37+
public TreeVisitor<?, ExecutionContext> getVisitor() {
38+
return Preconditions.check(
39+
Preconditions.not(new UsesMethod<>("*..* *(.., com.google.common.base.Predicate)")),
40+
new ChangeType(
41+
"com.google.common.base.Predicate",
42+
"java.util.function.Predicate",
43+
false)
44+
.getVisitor()
45+
);
46+
}
47+
}

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -193,9 +193,7 @@ recipeList:
193193
methodPattern: com.google.common.base.Predicate apply(..)
194194
newMethodName: test
195195
matchOverrides: true
196-
- org.openrewrite.java.ChangeType:
197-
oldFullyQualifiedTypeName: com.google.common.base.Predicate
198-
newFullyQualifiedTypeName: java.util.function.Predicate
196+
- org.openrewrite.java.migrate.guava.NoGuavaPredicate
199197

200198
---
201199
type: specs.openrewrite.org/v1beta/recipe
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
/*
2+
* Copyright 2025 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.Issue;
22+
import org.openrewrite.java.JavaParser;
23+
import org.openrewrite.test.RecipeSpec;
24+
import org.openrewrite.test.RewriteTest;
25+
26+
import static org.openrewrite.java.Assertions.java;
27+
28+
class NoGuavaPredicateTest implements RewriteTest {
29+
@Override
30+
public void defaults(RecipeSpec spec) {
31+
spec
32+
.recipe(new NoGuavaPredicate())
33+
.parser(JavaParser.fromJavaVersion().classpathFromResources(new InMemoryExecutionContext(), "guava"));
34+
}
35+
36+
@DocumentExample
37+
@Test
38+
void changeGuavaPredicateToJavaUtilPredicate() {
39+
rewriteRun(
40+
//language=java
41+
java(
42+
"""
43+
import com.google.common.base.Predicate;
44+
45+
class Test {
46+
Predicate<String> predicate = input -> input != null && !input.isEmpty();
47+
}
48+
""",
49+
"""
50+
import java.util.function.Predicate;
51+
52+
class Test {
53+
Predicate<String> predicate = input -> input != null && !input.isEmpty();
54+
}
55+
"""
56+
)
57+
);
58+
}
59+
60+
@Test
61+
void changeWhenMethodOnlyReturnsGuavaPredicate() {
62+
// Recipe only blocks when Predicate is used as a parameter, not return type
63+
rewriteRun(
64+
//language=java
65+
java(
66+
"""
67+
import com.google.common.base.Predicate;
68+
69+
class Test {
70+
Predicate<String> predicate = input -> input != null;
71+
72+
public Predicate<String> createPredicate() {
73+
return s -> s.isEmpty();
74+
}
75+
}
76+
""",
77+
"""
78+
import java.util.function.Predicate;
79+
80+
class Test {
81+
Predicate<String> predicate = input -> input != null;
82+
83+
public Predicate<String> createPredicate() {
84+
return s -> s.isEmpty();
85+
}
86+
}
87+
"""
88+
)
89+
);
90+
}
91+
92+
// Unfortunately also not changed now that we exclude all methods that take a Guava Predicate as precondition
93+
@Test
94+
void doNotChangePredicatesNot() {
95+
rewriteRun(
96+
//language=java
97+
java(
98+
"""
99+
import com.google.common.base.Predicate;
100+
import com.google.common.base.Predicates;
101+
102+
class A {
103+
public static Predicate<String> notEmptyPredicate() {
104+
Predicate<String> isEmpty = String::isEmpty;
105+
return Predicates.not(isEmpty);
106+
}
107+
}
108+
"""
109+
)
110+
);
111+
}
112+
113+
@Issue("https://github.com/openrewrite/rewrite-migrate-java/issues/897")
114+
@Test
115+
void doNotChangeWhenUsingSetsFilter() {
116+
// Sets.filter requires Guava Predicate as last parameter
117+
rewriteRun(
118+
//language=java
119+
java(
120+
"""
121+
import com.google.common.base.Predicate;
122+
import com.google.common.collect.Sets;
123+
import java.util.Set;
124+
125+
class Test {
126+
Predicate<String> notEmpty = s -> !s.isEmpty();
127+
128+
public Set<String> filterSet(Set<String> input) {
129+
return Sets.filter(input, notEmpty);
130+
}
131+
}
132+
"""
133+
)
134+
);
135+
}
136+
137+
@Issue("https://github.com/openrewrite/rewrite-migrate-java/issues/883")
138+
@Test
139+
void doNotChangeWhenUsingIterablesFilter() {
140+
// Iterables.filter requires Guava Predicate as last parameter
141+
rewriteRun(
142+
//language=java
143+
java(
144+
"""
145+
import com.google.common.base.Predicate;
146+
import com.google.common.collect.Iterables;
147+
import java.util.List;
148+
149+
class Test {
150+
Predicate<Integer> isPositive = n -> n > 0;
151+
152+
public Iterable<Integer> filterPositive(List<Integer> numbers) {
153+
return Iterables.filter(numbers, isPositive);
154+
}
155+
}
156+
"""
157+
)
158+
);
159+
}
160+
161+
@Issue("https://github.com/openrewrite/rewrite-migrate-java/issues/899")
162+
@Test
163+
void doNotChangeWhenUsingCollectionsFilter() {
164+
// Collections2.filter requires Guava Predicate as last parameter
165+
rewriteRun(
166+
//language=java
167+
java(
168+
"""
169+
import com.google.common.base.Predicate;
170+
import com.google.common.collect.Collections2;
171+
import java.util.Collection;
172+
173+
class Test {
174+
Predicate<String> notEmpty = s -> !s.isEmpty();
175+
176+
public Collection<String> filterCollection(Collection<String> input) {
177+
return Collections2.filter(input, notEmpty);
178+
}
179+
}
180+
"""
181+
)
182+
);
183+
}
184+
}

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

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -69,36 +69,6 @@ public boolean test(String input) {
6969
);
7070
}
7171

72-
@Test
73-
void predicatesNotToPredicate() {
74-
rewriteRun(
75-
//language=java
76-
java(
77-
"""
78-
import com.google.common.base.Predicate;
79-
import com.google.common.base.Predicates;
80-
81-
class A {
82-
public static Predicate<String> notEmptyPredicate() {
83-
Predicate<String> isEmpty = String::isEmpty;
84-
return Predicates.not(isEmpty);
85-
}
86-
}
87-
""",
88-
"""
89-
import java.util.function.Predicate;
90-
91-
class A {
92-
public static Predicate<String> notEmptyPredicate() {
93-
Predicate<String> isEmpty = String::isEmpty;
94-
return Predicate.not(isEmpty);
95-
}
96-
}
97-
"""
98-
)
99-
);
100-
}
101-
10272
@Test
10373
void predicatesEqualToToPredicateIsEqual() {
10474
rewriteRun(

0 commit comments

Comments
 (0)