Skip to content

Commit 23015ee

Browse files
authored
Merge branch 'main' into java_toolchain_21
2 parents 85de250 + 401c2f5 commit 23015ee

File tree

6 files changed

+177
-17
lines changed

6 files changed

+177
-17
lines changed

src/main/java/org/openrewrite/java/migrate/util/IteratorNext.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.openrewrite.java.search.UsesMethod;
2626
import org.openrewrite.java.tree.Expression;
2727
import org.openrewrite.java.tree.J;
28+
import org.openrewrite.java.tree.JavaType;
2829
import org.openrewrite.java.tree.TypeUtils;
2930

3031
public class IteratorNext extends Recipe {
@@ -57,13 +58,13 @@ public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, Execu
5758
J.MethodInvocation nextInvocation = super.visitMethodInvocation(method, ctx);
5859
if (NEXT_MATCHER.matches(nextInvocation) && ITERATOR_MATCHER.matches(nextInvocation.getSelect())) {
5960
J.MethodInvocation iteratorInvocation = (J.MethodInvocation) nextInvocation.getSelect();
60-
if (TypeUtils.isAssignableTo("java.util.SequencedCollection", iteratorInvocation.getSelect().getType())) {
61-
J.MethodInvocation getFirstInvocation = nextInvocation.withSelect(iteratorInvocation.getSelect())
62-
.withName(nextInvocation.getName().withSimpleName("getFirst"))
63-
.withMethodType(nextInvocation.getMethodType()
64-
.withName("getFirst")
65-
.withDeclaringType(iteratorInvocation.getMethodType().getDeclaringType()));
66-
return getFirstInvocation;
61+
Expression iteratorSelect = iteratorInvocation.getSelect();
62+
if (TypeUtils.isAssignableTo("java.util.SequencedCollection", iteratorSelect.getType())) {
63+
JavaType.Method getFirst = iteratorInvocation.getMethodType().withName("getFirst");
64+
return iteratorInvocation
65+
.withName(iteratorInvocation.getName().withSimpleName("getFirst").withType(getFirst))
66+
.withMethodType(getFirst)
67+
.withPrefix(nextInvocation.getPrefix());
6768
}
6869
}
6970
return nextInvocation;

src/main/java/org/openrewrite/java/migrate/util/ListFirstAndLast.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,7 @@
1515
*/
1616
package org.openrewrite.java.migrate.util;
1717

18-
import org.openrewrite.ExecutionContext;
19-
import org.openrewrite.Preconditions;
20-
import org.openrewrite.Recipe;
21-
import org.openrewrite.TreeVisitor;
18+
import org.openrewrite.*;
2219
import org.openrewrite.java.JavaIsoVisitor;
2320
import org.openrewrite.java.MethodMatcher;
2421
import org.openrewrite.java.search.UsesJavaVersion;
@@ -109,7 +106,7 @@ public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, Execu
109106
.withParameterNames(null)
110107
.withParameterTypes(null);
111108
}
112-
return mi.withName(mi.getName().withSimpleName(operation + firstOrLast))
109+
return mi.withName(mi.getName().withSimpleName(operation + firstOrLast).withType(newMethodType))
113110
.withArguments(arguments)
114111
.withMethodType(newMethodType);
115112
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
* Copyright 2024 the original author or authors.
3+
* <p>
4+
* Licensed under the Apache License, Version 2.0 (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://www.apache.org/licenses/LICENSE-2.0
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.util;
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.JavaIsoVisitor;
23+
import org.openrewrite.java.MethodMatcher;
24+
import org.openrewrite.java.search.UsesJavaVersion;
25+
import org.openrewrite.java.search.UsesMethod;
26+
import org.openrewrite.java.tree.J;
27+
import org.openrewrite.java.tree.JavaType;
28+
import org.openrewrite.java.tree.TypeUtils;
29+
30+
public class StreamFindFirst extends Recipe {
31+
private static final MethodMatcher COLLECTION_STREAM_MATCHER = new MethodMatcher("java.util.Collection stream()", true);
32+
private static final MethodMatcher STREAM_FIND_FIRST_MATCHER = new MethodMatcher("java.util.stream.Stream findFirst()", true);
33+
private static final MethodMatcher OPTIONAL_OR_ELSE_THROW_MATCHER = new MethodMatcher("java.util.Optional orElseThrow()", true);
34+
35+
@Override
36+
public String getDisplayName() {
37+
return "Use `getFirst()` instead of `stream().findFirst().orElseThrow()`";
38+
}
39+
40+
@Override
41+
public String getDescription() {
42+
return "For SequencedCollections, use `collection.getFirst()` instead of `collection.stream().findFirst().orElseThrow()`.";
43+
}
44+
45+
@Override
46+
public TreeVisitor<?, ExecutionContext> getVisitor() {
47+
JavaIsoVisitor<ExecutionContext> javaIsoVisitor = new JavaIsoVisitor<ExecutionContext>() {
48+
@Override
49+
public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) {
50+
J.MethodInvocation mi = super.visitMethodInvocation(method, ctx);
51+
52+
if (!OPTIONAL_OR_ELSE_THROW_MATCHER.matches(mi) || !(mi.getSelect() instanceof J.MethodInvocation)) {
53+
return mi;
54+
}
55+
J.MethodInvocation optional = (J.MethodInvocation) mi.getSelect();
56+
if (!STREAM_FIND_FIRST_MATCHER.matches(optional) || !(optional.getSelect() instanceof J.MethodInvocation)) {
57+
return mi;
58+
}
59+
J.MethodInvocation stream = (J.MethodInvocation) optional.getSelect();
60+
if (!COLLECTION_STREAM_MATCHER.matches(stream) ||
61+
!TypeUtils.isOfClassType(stream.getSelect().getType(), "java.util.SequencedCollection")) {
62+
return mi;
63+
}
64+
JavaType.Method methodType = stream.getMethodType().withName("getFirst");
65+
return stream
66+
.withName(stream.getName().withSimpleName("getFirst").withType(methodType))
67+
.withMethodType(methodType)
68+
.withPrefix(mi.getPrefix());
69+
}
70+
71+
72+
};
73+
return Preconditions.check(
74+
Preconditions.and(
75+
new UsesJavaVersion<>(21),
76+
new UsesMethod<>(COLLECTION_STREAM_MATCHER),
77+
new UsesMethod<>(STREAM_FIND_FIRST_MATCHER),
78+
new UsesMethod<>(OPTIONAL_OR_ELSE_THROW_MATCHER)
79+
),
80+
javaIsoVisitor);
81+
}
82+
}

src/test/java/org/openrewrite/java/migrate/util/IteratorNextTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ void bar(Collection<String> collection) {
8080
}
8181

8282
@Test
83-
void nextCommentRetained() {
83+
void nextCommentLost() {
8484
rewriteRun(
8585
//language=java
8686
java(
@@ -102,7 +102,6 @@ void bar(List<String> collection) {
102102
class Foo {
103103
void bar(List<String> collection) {
104104
String first = collection
105-
// Next comment
106105
.getFirst();
107106
}
108107
}
@@ -112,7 +111,7 @@ void bar(List<String> collection) {
112111
}
113112

114113
@Test
115-
void iteratorCommentLost() {
114+
void iteratorCommentRetained() {
116115
rewriteRun(
117116
//language=java
118117
java(
@@ -134,6 +133,7 @@ void bar(List<String> collection) {
134133
class Foo {
135134
void bar(List<String> collection) {
136135
String first = collection
136+
// Iterator comment
137137
.getFirst();
138138
}
139139
}

src/test/java/org/openrewrite/java/migrate/util/ListFirstAndLastTest.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,9 @@
2626
import static org.openrewrite.java.Assertions.java;
2727
import static org.openrewrite.java.Assertions.javaVersion;
2828

29-
3029
@Issue("https://github.com/openrewrite/rewrite-migrate-java/issues/243")
3130
@EnabledForJreRange(min = JRE.JAVA_21)
3231
class ListFirstAndLastTest implements RewriteTest {
33-
3432
@Override
3533
public void defaults(RecipeSpec spec) {
3634
spec.recipe(new ListFirstAndLast())
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
* Copyright 2024 the original author or authors.
3+
* <p>
4+
* Licensed under the Apache License, Version 2.0 (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://www.apache.org/licenses/LICENSE-2.0
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.util;
17+
18+
import org.junit.jupiter.api.Test;
19+
import org.junit.jupiter.api.condition.EnabledForJreRange;
20+
import org.junit.jupiter.api.condition.JRE;
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+
import static org.openrewrite.java.Assertions.javaVersion;
27+
28+
@EnabledForJreRange(min = JRE.JAVA_21)
29+
class StreamFindFirstTest implements RewriteTest {
30+
@Override
31+
public void defaults(RecipeSpec spec) {
32+
spec
33+
.recipe(new StreamFindFirst())
34+
.parser(JavaParser.fromJavaVersion().logCompilationWarningsAndErrors(true))
35+
.allSources(src -> src.markers(javaVersion(21)));
36+
}
37+
38+
@Test
39+
void sequencedCollection() {
40+
rewriteRun(
41+
//language=java
42+
java(
43+
"""
44+
import java.util.*;
45+
46+
class Foo {
47+
void bar(SequencedCollection<String> collection) {
48+
String first = collection.stream().findFirst().orElseThrow();
49+
}
50+
}
51+
""",
52+
"""
53+
import java.util.*;
54+
55+
class Foo {
56+
void bar(SequencedCollection<String> collection) {
57+
String first = collection.getFirst();
58+
}
59+
}
60+
"""
61+
)
62+
);
63+
}
64+
65+
@Test
66+
void regularCollection() {
67+
rewriteRun(
68+
//language=java
69+
java(
70+
"""
71+
import java.util.*;
72+
73+
class Foo {
74+
void bar(Collection<String> collection) {
75+
String first = collection.stream().findFirst().orElseThrow();
76+
}
77+
}
78+
"""
79+
)
80+
);
81+
}
82+
}

0 commit comments

Comments
 (0)