Skip to content

Commit 18287b2

Browse files
committed
Polish to minimize loops & logic
1 parent 9423d0e commit 18287b2

2 files changed

Lines changed: 30 additions & 41 deletions

File tree

src/main/java/org/openrewrite/staticanalysis/EqualsToContentEquals.java

Lines changed: 27 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -22,67 +22,56 @@
2222
import org.openrewrite.java.JavaIsoVisitor;
2323
import org.openrewrite.java.MethodMatcher;
2424
import org.openrewrite.java.search.UsesType;
25-
import org.openrewrite.java.tree.*;
25+
import org.openrewrite.java.tree.Expression;
26+
import org.openrewrite.java.tree.J;
27+
import org.openrewrite.java.tree.TypeUtils;
2628

27-
import java.util.Arrays;
2829
import java.util.Collections;
29-
import java.util.List;
30-
import java.util.stream.Stream;
30+
import java.util.Set;
3131

3232
public class EqualsToContentEquals extends Recipe {
33-
private static final MethodMatcher equals_matcher = new MethodMatcher("java.lang.String equals(..)");
3433
private static final TreeVisitor<?, ExecutionContext> PRECONDITION = Preconditions.or(
34+
new UsesType<>("java.lang.CharSequence", false),
3535
new UsesType<>("java.lang.StringBuffer", false),
36-
new UsesType<>("java.lang.StringBuilder", false),
37-
new UsesType<>("java.lang.CharSequence", false));
38-
private static final List<MethodMatcher> TOSTRING_MATCHERS = Arrays.asList(
39-
new MethodMatcher("java.lang.String toString()"),
40-
new MethodMatcher("java.lang.StringBuffer toString()"),
41-
new MethodMatcher("java.lang.StringBuilder toString()"),
42-
new MethodMatcher("java.lang.CharSequence toString()"));
36+
new UsesType<>("java.lang.StringBuilder", false)
37+
);
4338

4439
@Override
4540
public String getDisplayName() {
46-
return "Use contentEquals to compare StringBuilder to a String";
41+
return "Use `String.contentEquals(CharSequence)` instead of `String.equals(CharSequence.toString())`";
4742
}
43+
4844
@Override
4945
public String getDescription() {
50-
return "Use contentEquals to compare StringBuilder to a String.";
46+
return "Use `String.contentEquals(CharSequence)` instead of `String.equals(CharSequence.toString())`.";
5147
}
5248

5349
public TreeVisitor<?, ExecutionContext> getVisitor() {
5450
return Preconditions.check(PRECONDITION, new EqualsToContentEqualsVisitor());
5551
}
5652

5753
private static class EqualsToContentEqualsVisitor extends JavaIsoVisitor<ExecutionContext> {
54+
private static final MethodMatcher EQUALS_MATCHER = new MethodMatcher("String equals(Object)");
55+
private static final MethodMatcher TOSTRING_MATCHER = new MethodMatcher("java.lang.* toString()");
56+
5857
@Override
5958
public J.MethodInvocation visitMethodInvocation(J.MethodInvocation mi, ExecutionContext ctx) {
6059
J.MethodInvocation m = super.visitMethodInvocation(mi, ctx);
61-
// create method matcher on equals(String)
62-
if (equals_matcher.matches(m)) {
63-
Expression argument = m.getArguments().get(0);
64-
65-
// checks whether the argument is a toString() method call on a StringBuffer or CharSequence
66-
if (TOSTRING_MATCHERS.stream().anyMatch(matcher -> matcher.matches(argument))) {
67-
J.MethodInvocation inv = (J.MethodInvocation) argument;
68-
Expression newArg = inv.getSelect();
69-
if (inv.getSelect() == null) { return m; }
70-
71-
Stream<JavaType> TYPES = Stream.of(
72-
JavaType.buildType("java.lang.StringBuilder"),
73-
JavaType.buildType("java.lang.StringBuffer"),
74-
JavaType.buildType("java.lang.CharSequence")
75-
);
76-
77-
if (TYPES.anyMatch(type -> TypeUtils.isOfType(newArg.getType(), type))) {
78-
// strip out the toString() on the argument
79-
return m.withArguments(Collections.singletonList(newArg))
80-
.withName(m.getName().withSimpleName("contentEquals"));
81-
}
82-
}
60+
if (!EQUALS_MATCHER.matches(m)) {
61+
return m;
8362
}
84-
85-
return m;
63+
Expression equalsArgument = m.getArguments().get(0);
64+
if (!TOSTRING_MATCHER.matches(equalsArgument)) {
65+
return m;
66+
}
67+
J.MethodInvocation inv = (J.MethodInvocation) equalsArgument;
68+
Expression toStringSelect = inv.getSelect();
69+
if (toStringSelect == null || !TypeUtils.isAssignableTo("java.lang.CharSequence", toStringSelect.getType())) {
70+
return m;
71+
}
72+
// Strip out the toString() on the argument and replace with contentEquals
73+
return m.withArguments(Collections.singletonList(toStringSelect))
74+
.withName(m.getName().withSimpleName("contentEquals"));
8675
}
8776
}
8877
}

src/test/java/org/openrewrite/staticanalysis/EqualsToContentEqualsTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
import static org.openrewrite.java.Assertions.java;
2525

26-
public class EqualsToContentEqualsTest implements RewriteTest {
26+
class EqualsToContentEqualsTest implements RewriteTest {
2727

2828
@Override
2929
public void defaults(RecipeSpec spec) {
@@ -34,7 +34,7 @@ public void defaults(RecipeSpec spec) {
3434

3535
@Test
3636
@DocumentExample
37-
public void replaceStringBuilder() {
37+
void replaceStringBuilder() {
3838
//language=java
3939
rewriteRun(
4040
java(
@@ -59,7 +59,7 @@ boolean foo(StringBuilder sb) {
5959
}
6060

6161
@Test
62-
public void onlyRunsOnCorrectInvocations() {
62+
void onlyRunsOnCorrectInvocations() {
6363
//language=java
6464
rewriteRun(
6565
java(

0 commit comments

Comments
 (0)