Skip to content

Commit 0517175

Browse files
committed
There are more major iterations of JavaTemplate than superhero movies
1 parent ee5fc69 commit 0517175

62 files changed

Lines changed: 4345 additions & 3166 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

rewrite-core/src/main/java/org/openrewrite/Cursor.java

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,8 @@ private CursorIterator(Cursor cursor, Predicate<Object> filter) {
8282

8383
@Override
8484
public boolean hasNext() {
85-
for(Cursor c = cursor; c != null; c = c.parent) {
86-
if(filter.test(c.value)) {
85+
for (Cursor c = cursor; c != null; c = c.parent) {
86+
if (filter.test(c.value)) {
8787
return true;
8888
}
8989
}
@@ -92,9 +92,9 @@ public boolean hasNext() {
9292

9393
@Override
9494
public Object next() {
95-
for(; cursor != null; cursor = cursor.parent) {
95+
for (; cursor != null; cursor = cursor.parent) {
9696
Object v = cursor.value;
97-
if(filter.test(v)) {
97+
if (filter.test(v)) {
9898
cursor = cursor.parent;
9999
return v;
100100
}
@@ -137,7 +137,7 @@ public String toString() {
137137

138138
public Cursor dropParentUntil(Predicate<Object> valuePredicate) {
139139
Cursor cursor = parent;
140-
while(cursor != null && !valuePredicate.test(cursor.value)) {
140+
while (cursor != null && !valuePredicate.test(cursor.value)) {
141141
cursor = cursor.parent;
142142
}
143143
if (cursor == null) {
@@ -148,7 +148,7 @@ public Cursor dropParentUntil(Predicate<Object> valuePredicate) {
148148

149149
public Cursor dropParentWhile(Predicate<Object> valuePredicate) {
150150
Cursor cursor = parent;
151-
while(cursor != null && valuePredicate.test(cursor.value)) {
151+
while (cursor != null && valuePredicate.test(cursor.value)) {
152152
cursor = cursor.parent;
153153
}
154154
if (cursor == null) {
@@ -276,4 +276,14 @@ public <T> T pollMessage(String key) {
276276
//noinspection unchecked
277277
return messages == null ? null : (T) messages.remove(key);
278278
}
279+
280+
/**
281+
* Creates a cursor at the same position, but with its own messages that can't influence
282+
* the messages of the cursor that was forked.
283+
*
284+
* @return A new cursor with the same position but an initially clear set of messages.
285+
*/
286+
public Cursor fork() {
287+
return new Cursor(parent == null ? null : parent.fork(), value);
288+
}
279289
}

rewrite-core/src/main/java/org/openrewrite/internal/ListUtils.java

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.util.concurrent.ForkJoinTask;
2525
import java.util.concurrent.atomic.AtomicReference;
2626
import java.util.function.BiFunction;
27+
import java.util.function.Function;
2728
import java.util.function.UnaryOperator;
2829

2930
import static java.util.Collections.singletonList;
@@ -139,6 +140,58 @@ public static <T> List<T> map(List<T> ls, UnaryOperator<T> map) {
139140
return map(ls, (i, t) -> map.apply(t));
140141
}
141142

143+
public static <T> List<T> flatMap(List<T> ls, BiFunction<Integer, T, Object> flatMap) {
144+
if (ls == null || ls.isEmpty()) {
145+
return ls;
146+
}
147+
List<T> newLs = ls;
148+
int j = 0;
149+
for (int i = 0; i < ls.size(); i++, j++) {
150+
T tree = ls.get(i);
151+
Object newTreeOrTrees = flatMap.apply(i, tree);
152+
if (newTreeOrTrees != tree) {
153+
if (newLs == ls) {
154+
newLs = new ArrayList<>(ls);
155+
}
156+
157+
if (newTreeOrTrees instanceof Iterable) {
158+
int n = 0;
159+
//noinspection unchecked
160+
for (T newTree : (Iterable<T>) newTreeOrTrees) {
161+
if (j >= newLs.size()) {
162+
newLs.add(newTree);
163+
} else if(n == 0) {
164+
newLs.set(j, newTree);
165+
} else {
166+
newLs.add(j, newTree);
167+
}
168+
j++;
169+
n++;
170+
}
171+
} else {
172+
if (j >= newLs.size()) {
173+
//noinspection unchecked
174+
newLs.add((T) newTreeOrTrees);
175+
} else {
176+
//noinspection unchecked
177+
newLs.set(j, (T) newTreeOrTrees);
178+
}
179+
}
180+
}
181+
}
182+
183+
if (newLs != ls) {
184+
//noinspection StatementWithEmptyBody
185+
while (newLs.remove(null)) ;
186+
}
187+
188+
return newLs;
189+
}
190+
191+
public static <T> List<T> flatMap(List<T> ls, Function<T, Object> flatMap) {
192+
return flatMap(ls, (i, t) -> flatMap.apply(t));
193+
}
194+
142195
public static <T> List<T> map(List<T> ls, ForkJoinPool pool, UnaryOperator<T> map) {
143196
return map(ls, pool, (i, t) -> map.apply(t));
144197
}

rewrite-core/src/main/java/org/openrewrite/internal/PropertyPlaceholderHelper.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,12 @@ protected String parseStringValue(String value, Function<String, String> placeho
104104
// previously resolved placeholder value.
105105
propVal = parseStringValue(propVal, placeholderResolver, visitedPlaceholders);
106106
result.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal);
107-
startIndex = result.indexOf(this.placeholderPrefix, startIndex + propVal.length());
107+
108+
if(propVal.length() < placeholderPrefix.length() + placeholderSuffix.length()) {
109+
endIndex -= (placeholderPrefix.length() + placeholderSuffix.length()) - propVal.length() - 1;
110+
}
108111
}
112+
109113
// Proceed with unprocessed value.
110114
startIndex = result.indexOf(this.placeholderPrefix, endIndex + this.placeholderSuffix.length());
111115
visitedPlaceholders.remove(originalPlaceholder);
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright 2020 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.internal
17+
18+
import org.assertj.core.api.Assertions.assertThat
19+
import org.junit.jupiter.api.Test
20+
21+
class ListUtilsTest {
22+
23+
@Test
24+
fun flatMap() {
25+
val l = listOf(1.0, 2.0, 3.0)
26+
assertThat(ListUtils.flatMap(l) { l2 ->
27+
if(l2.toInt() % 2 == 0) {
28+
listOf(2.0, 2.1, 2.2)
29+
} else {
30+
l2
31+
}
32+
}).containsExactly(1.0, 2.0, 2.1, 2.2, 3.0)
33+
}
34+
}

rewrite-java-11/src/test/kotlin/org/openrewrite/java/Java11VisitorDebugTests.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ class Java11AddImportTest : Java11Test, AddImportTest
3636
@ExtendWith(JavaParserResolver::class)
3737
class Java11AddLicenseHeaderTest : Java11Test, AddLicenseHeaderTest
3838

39+
@DebugOnly
40+
@ExtendWith(JavaParserResolver::class)
41+
class Java11AnnotationTemplateGeneratorTest : Java11Test, AnnotationTemplateGeneratorTest
42+
3943
@DebugOnly
4044
@ExtendWith(JavaParserResolver::class)
4145
class Java11BigDecimalRoundingConstantsToEnumsTestTest : Java11Test, BigDecimalRoundingConstantsToEnumsTest
@@ -44,6 +48,10 @@ class Java11BigDecimalRoundingConstantsToEnumsTestTest : Java11Test, BigDecimalR
4448
@ExtendWith(JavaParserResolver::class)
4549
class Java11BlankLinesTest : Java11Test, BlankLinesTest
4650

51+
@DebugOnly
52+
@ExtendWith(JavaParserResolver::class)
53+
class Java11BlockStatementTemplateGeneratorTest : Java11Test, BlockStatementTemplateGeneratorTest
54+
4755
@DebugOnly
4856
@ExtendWith(JavaParserResolver::class)
4957
class Java11ChangeFieldNameTest : Java11Test, ChangeFieldNameTest
@@ -152,6 +160,10 @@ class Java11ImplementInterfaceTest : Java11Test, ImplementInterfaceTest
152160
@ExtendWith(JavaParserResolver::class)
153161
class Java11JavaTemplateTest : Java11Test, JavaTemplateTest
154162

163+
@DebugOnly
164+
@ExtendWith(JavaParserResolver::class)
165+
class Java11JavaTemplateSubstitutionsTest : Java11Test, JavaTemplateSubstitutionsTest
166+
155167
@DebugOnly
156168
@ExtendWith(JavaParserResolver::class)
157169
class Java11JavaVisitorTest : Java11Test, JavaVisitorTest

rewrite-java-8/src/test/kotlin/org/openrewrite/java/Java8VisitorDebugTest.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ class Java8AddImportTest : Java8Test, AddImportTest
3636
@ExtendWith(JavaParserResolver::class)
3737
class Java8AddLicenseHeaderTest : Java8Test, AddLicenseHeaderTest
3838

39+
@DebugOnly
40+
@ExtendWith(JavaParserResolver::class)
41+
class Java8AnnotationTemplateGeneratorTest : Java8Test, AnnotationTemplateGeneratorTest
42+
3943
@DebugOnly
4044
@ExtendWith(JavaParserResolver::class)
4145
class Java8BigDecimalRoundingConstantsToEnumsTestTest : Java8Test, BigDecimalRoundingConstantsToEnumsTest
@@ -44,6 +48,10 @@ class Java8BigDecimalRoundingConstantsToEnumsTestTest : Java8Test, BigDecimalRou
4448
@ExtendWith(JavaParserResolver::class)
4549
class Java8BlankLinesTest : Java8Test, BlankLinesTest
4650

51+
@DebugOnly
52+
@ExtendWith(JavaParserResolver::class)
53+
class Java8BlockStatementTemplateGeneratorTest : Java8Test, BlockStatementTemplateGeneratorTest
54+
4755
@DebugOnly
4856
@ExtendWith(JavaParserResolver::class)
4957
class Java8ChangeFieldNameTest : Java8Test, ChangeFieldNameTest
@@ -152,6 +160,10 @@ class Java8ImplementInterfaceTest : Java8Test, ImplementInterfaceTest
152160
@ExtendWith(JavaParserResolver::class)
153161
class Java8JavaTemplateTest : Java8Test, JavaTemplateTest
154162

163+
@DebugOnly
164+
@ExtendWith(JavaParserResolver::class)
165+
class Java8JavaTemplateSubstitutionsTest : Java8Test, JavaTemplateSubstitutionsTest
166+
155167
@DebugOnly
156168
@ExtendWith(JavaParserResolver::class)
157169
class Java8JavaVisitorTest : Java8Test, JavaVisitorTest
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
lexer grammar TemplateParameterLexer;
2+
3+
LPAREN : '(';
4+
RPAREN : ')';
5+
LBRACK : '[';
6+
RBRACK : ']';
7+
DOT : '.';
8+
9+
COMMA : ',';
10+
SPACE : ' ';
11+
12+
FullyQualifiedName
13+
: 'boolean'
14+
| 'byte'
15+
| 'char'
16+
| 'double'
17+
| 'float'
18+
| 'int'
19+
| 'long'
20+
| 'short'
21+
| 'String'
22+
| 'Object'
23+
| Identifier (DOT Identifier)+
24+
;
25+
26+
Number
27+
: [0-9]+
28+
;
29+
30+
Identifier
31+
: JavaLetter JavaLetterOrDigit*
32+
;
33+
34+
fragment
35+
JavaLetter
36+
: [a-zA-Z$_] // these are the "java letters" below 0x7F
37+
| // covers all characters above 0x7F which are not a surrogate
38+
~[\u0000-\u007F\uD800-\uDBFF]
39+
{Character.isJavaIdentifierStart(_input.LA(-1))}?
40+
| // covers UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF
41+
[\uD800-\uDBFF] [\uDC00-\uDFFF]
42+
{Character.isJavaIdentifierStart(Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1)))}?
43+
;
44+
45+
fragment
46+
JavaLetterOrDigit
47+
: [a-zA-Z0-9$_] // these are the "java letters or digits" below 0x7F
48+
| // covers all characters above 0x7F which are not a surrogate
49+
~[\u0000-\u007F\uD800-\uDBFF]
50+
{Character.isJavaIdentifierPart(_input.LA(-1))}?
51+
| // covers UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF
52+
[\uD800-\uDBFF] [\uDC00-\uDFFF]
53+
{Character.isJavaIdentifierPart(Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1)))}?
54+
;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
LPAREN=1
2+
RPAREN=2
3+
LBRACK=3
4+
RBRACK=4
5+
DOT=5
6+
COMMA=6
7+
SPACE=7
8+
FullyQualifiedName=8
9+
Number=9
10+
Identifier=10
11+
'('=1
12+
')'=2
13+
'['=3
14+
']'=4
15+
'.'=5
16+
','=6
17+
' '=7
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
parser grammar TemplateParameterParser;
2+
3+
options { tokenVocab=TemplateParameterLexer; }
4+
5+
matcherPattern
6+
: matcherName LPAREN matcherParameter* RPAREN
7+
;
8+
9+
matcherParameter
10+
: FullyQualifiedName
11+
| Number
12+
;
13+
14+
matcherName
15+
: Identifier
16+
;

rewrite-java/src/main/java/org/openrewrite/java/ChangePackage.java

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,6 @@
4545
@Value
4646
@EqualsAndHashCode(callSuper = true)
4747
public class ChangePackage extends Recipe {
48-
private static final ThreadLocal<JavaParser> JAVA_PARSER_THREAD_LOCAL =
49-
ThreadLocal.withInitial(() -> JavaParser.fromJavaVersion().build());
50-
5148
@Option(displayName = "Old package name",
5249
description = "The package name to replace.")
5350
String oldPackageName;
@@ -100,9 +97,6 @@ private class ChangePackageVisitor extends JavaIsoVisitor<ExecutionContext> {
10097
private static final String RENAME_TO_KEY = "renameTo";
10198
private static final String RENAME_FROM_KEY = "renameFrom";
10299

103-
private final JavaTemplate packageExprTemplate =
104-
template("package #{}").javaParser(JAVA_PARSER_THREAD_LOCAL.get()).build();
105-
106100
private final JavaType.Class newPackageType = JavaType.Class.build(newPackageName);
107101
private final JavaType.Class oldPackageType = JavaType.Class.build(oldPackageName);
108102

@@ -248,12 +242,12 @@ public J.Package visitPackage(J.Package pkg, ExecutionContext context) {
248242

249243
if (original.equals(oldPackageName)) {
250244
getCursor().putMessageOnFirstEnclosing(J.CompilationUnit.class, RENAME_TO_KEY, newPackageName);
251-
pkg = pkg.withTemplate(packageExprTemplate, pkg.getCoordinates().replace(), newPackageName);
245+
pkg = pkg.withTemplate(template(newPackageName).build(), pkg.getCoordinates().replace());
252246
} else if ((recursive == null || recursive)
253247
&& original.startsWith(oldPackageName) && !original.startsWith(newPackageName)) {
254248
String changingTo = newPackageName + original.substring(oldPackageName.length());
255249
getCursor().putMessageOnFirstEnclosing(J.CompilationUnit.class, RENAME_TO_KEY, changingTo);
256-
pkg = pkg.withTemplate(packageExprTemplate, pkg.getCoordinates().replace(), changingTo);
250+
pkg = pkg.withTemplate(template(changingTo).build(), pkg.getCoordinates().replace());
257251
}
258252
return pkg;
259253
}

0 commit comments

Comments
 (0)