Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@
import org.openrewrite.java.search.UsesMethod;
import org.openrewrite.java.tree.Expression;
import org.openrewrite.java.tree.J;
import org.openrewrite.java.tree.JavaType;
import org.openrewrite.java.tree.TypeUtils;

import java.util.Arrays;
import java.util.List;
import java.util.Set;

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

@Override
public String getDisplayName() {
Expand Down Expand Up @@ -74,17 +78,17 @@ private J handlePredicatesMethod(J.MethodInvocation method, String operation) {
return method;
}

// Avoid generic type issues, for method of "com.google.common.base.Predicates", by not making any changes just yet
if (atLeastOneArgumentIsMethodInvocationOfPredicates(arguments)) {
return method;
}

maybeRemoveImport("com.google.common.base.Predicates");

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

// Avoid generic type issues by not making any changes just yet
if (result instanceof J.MethodInvocation && !PREDICATES_EQUAL_TO.matches(result)) {
return method;
}

// If the first argument is a method reference or a lambda, wrap it with a cast
// If the first argument is a method reference or a lambda, wrap it with a cast
if ((result instanceof J.MemberReference || result instanceof J.Lambda) && result.getType() != null) {
String typeString = result.getType().toString().replace("com.google.common.base.", "");
result = JavaTemplate.apply("((" + typeString + ") #{any()})", getCursor(), method.getCoordinates().replace(), result);
Expand All @@ -100,4 +104,29 @@ private J handlePredicatesMethod(J.MethodInvocation method, String operation) {

});
}

private boolean atLeastOneArgumentIsMethodInvocationOfPredicates(List<Expression> arguments) {
for (Expression expression : arguments) {
if (expression instanceof J.MethodInvocation) {
if (!isMethodHandled((J.MethodInvocation) expression)) {
JavaType.Method methodType = ((J.MethodInvocation) expression).getMethodType();
if (methodType != null) {
if (TypeUtils.isOfClassType(methodType.getDeclaringType(), "com.google.common.base.Predicates")) {
return true;
}
}
}
}
}
return false;
}

private boolean isMethodHandled(J.MethodInvocation methodInvocation) {
for (MethodMatcher methodMatcher : PREDICATES_METHODS_HANDLED) {
if (methodMatcher.matches(methodInvocation)) {
return true;
}
}
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,37 @@ class Test {
);
}

@Test
void replacePredicatesOrNestedCalls() {
//language=java
rewriteRun(
spec -> spec.expectedCyclesThatMakeChanges(2),
java(
"""
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;

class Test {
Predicate<Integer> isPositive = n -> n > 0;
Predicate<Integer> isEven = n -> n % 2 == 0;
Predicate<Integer> isLessThan100 = n -> n < 100;
Predicate<Integer> combined = Predicates.and(isPositive, Predicates.or(isEven, isLessThan100));
}
""",
"""
import com.google.common.base.Predicate;

class Test {
Predicate<Integer> isPositive = n -> n > 0;
Predicate<Integer> isEven = n -> n % 2 == 0;
Predicate<Integer> isLessThan100 = n -> n < 100;
Predicate<Integer> combined = isPositive.and(isEven.or(isLessThan100));
}
"""
)
);
}

@Issue("https://github.com/openrewrite/rewrite-migrate-java/issues/893")
@Test
void replacePredicatesAndWithMoreThanTwoParameters() {
Expand Down Expand Up @@ -257,4 +288,183 @@ class Test {
)
);
}

@Test
void replacePredicatesAndWithOtherClassMethodAsParameters() {
//language=java
rewriteRun(
java(
"""
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import java.util.Objects;

class Test {
Predicate<String> getNotNullPredicate() {
return Objects::nonNull;
}
Predicate<String> getMaxLengthPredicate() {
return s -> s.length() > 5;
}
Predicate<String> combined = Predicates.and(getNotNullPredicate(), getMaxLengthPredicate());
}
""",
"""
import com.google.common.base.Predicate;
import java.util.Objects;

class Test {
Predicate<String> getNotNullPredicate() {
return Objects::nonNull;
}
Predicate<String> getMaxLengthPredicate() {
return s -> s.length() > 5;
}
Predicate<String> combined = getNotNullPredicate().and(getMaxLengthPredicate());
}
"""
)
);
}

@Test
void replacePredicatesAndWithNotMethodAsParameters() {
//language=java
rewriteRun(
java(
"""
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import java.util.Objects;

class Test {
Predicate<String> getNotNullPredicate() {
return Objects::nonNull;
}
Predicate<String> getMaxLengthPredicate() {
return s -> s.length() > 5;
}
Predicate<String> combined = Predicates.and(Predicates.not(getNotNullPredicate()), getMaxLengthPredicate());
}
""",
"""
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import java.util.Objects;

class Test {
Predicate<String> getNotNullPredicate() {
return Objects::nonNull;
}
Predicate<String> getMaxLengthPredicate() {
return s -> s.length() > 5;
}
Predicate<String> combined = Predicates.not(getNotNullPredicate()).and(getMaxLengthPredicate());
}
"""
)
);
}


@Test
void replacePredicatesAndWithEqualToMethodAsParameters() {
//language=java
rewriteRun(
java(
"""
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import java.util.Objects;

class Test {
Predicate<String> getNotNullPredicate() {
return Objects::nonNull;
}
Predicate<String> getMaxLengthPredicate() {
return s -> s.length() < 10;
}
Predicate<String> combined = Predicates.and(Predicates.equalTo("MyTest"), getMaxLengthPredicate());
}
""",
"""
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import java.util.Objects;

class Test {
Predicate<String> getNotNullPredicate() {
return Objects::nonNull;
}
Predicate<String> getMaxLengthPredicate() {
return s -> s.length() < 10;
}
Predicate<String> combined = Predicates.equalTo("MyTest").and(getMaxLengthPredicate());
}
"""
)
);
}

@Test
void doNotReplacePredicatesAndWithNotHandledPredicatesMethodAsFirstParameter() {
//language=java
rewriteRun(
java(
"""
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;

import java.util.Collection;
import java.util.Objects;

class Test {
Predicate<String> getMinSizePredicate() {
return new Predicate<String>() {
@Override
public boolean apply(String input) {
return input.length() > 5;
}
};
}

public void test(Collection<String> aCollection) {
Predicate<String> combined = Predicates.and(Predicates.in(aCollection), getMinSizePredicate());
}
}
"""
)
);
}

@Test
void doNotReplacePredicatesAndWithNotHandledPredicatesMethodAsSecondParameter() {
//language=java
rewriteRun(
java(
"""
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;

import java.util.Collection;
import java.util.Objects;

class Test {
Predicate<String> getMinSizePredicate() {
return new Predicate<String>() {
@Override
public boolean apply(String input) {
return input.length() > 5;
}
};
}

public void test(Collection<String> aCollection) {
Predicate<String> combined = Predicates.and(getMinSizePredicate(), Predicates.in(aCollection));
}
}
"""
)
);
}
}