Skip to content

Commit ddc4dcb

Browse files
committed
Java: realign Javadoc cursor for stripped continuation-line whitespace
Java 23+ javac's `DCText`/`DCComment` `getBody()` strips per-line leading whitespace that older versions preserved. The cleaned source still carries that whitespace, so when an older parser (e.g. `rewrite-java-21`) runs on a Java 25 JVM, `visitText` falls one character behind on every continuation line — dropping the `*`-margin trailing space and emitting a duplicated trailing char from the leftover-source branch in `visitDocComment`. After consuming a `\n`, advance the cursor over any source whitespace that the body lacks at the corresponding position. Mirrors what the Java 25 visitor already does inline.
1 parent 23be80c commit ddc4dcb

5 files changed

Lines changed: 92 additions & 0 deletions

File tree

rewrite-java-11/src/main/java/org/openrewrite/java/isolated/ReloadableJava11JavadocVisitor.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -932,6 +932,16 @@ public List<Javadoc> visitText(String node) {
932932
cursor++;
933933
Javadoc.LineBreak lineBreak = lineBreaks.remove(cursor);
934934
texts.add(lineBreak);
935+
936+
// Java 23+ javac's DCText/DCComment getBody() strips per-line leading whitespace that
937+
// older versions preserved; the cleaned source still carries that whitespace, so realign
938+
// cursor by appending any source whitespace before node's next non-whitespace character.
939+
if (i + 1 < node.length() && !Character.isWhitespace(node.charAt(i + 1))) {
940+
while (cursor < source.length() && source.charAt(cursor) != '\n' && Character.isWhitespace(source.charAt(cursor))) {
941+
text.append(source.charAt(cursor));
942+
cursor++;
943+
}
944+
}
935945
} else if (source.charAt(cursor) != c && (source.startsWith(unicodeEscaped(c), cursor) || source.startsWith(unicodeEscaped(c).toLowerCase(), cursor) )) {
936946
int escapedCharLength = unicodeEscaped(c).length();
937947
text.append(source, cursor, cursor + escapedCharLength);

rewrite-java-17/src/main/java/org/openrewrite/java/isolated/ReloadableJava17JavadocVisitor.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -934,6 +934,16 @@ public List<Javadoc> visitText(String node) {
934934
cursor++;
935935
Javadoc.LineBreak lineBreak = lineBreaks.remove(cursor);
936936
texts.add(lineBreak);
937+
938+
// Java 23+ javac's DCText/DCComment getBody() strips per-line leading whitespace that
939+
// older versions preserved; the cleaned source still carries that whitespace, so realign
940+
// cursor by appending any source whitespace before node's next non-whitespace character.
941+
if (i + 1 < node.length() && !Character.isWhitespace(node.charAt(i + 1))) {
942+
while (cursor < source.length() && source.charAt(cursor) != '\n' && Character.isWhitespace(source.charAt(cursor))) {
943+
text.append(source.charAt(cursor));
944+
cursor++;
945+
}
946+
}
937947
} else if (source.charAt(cursor) != c && (source.startsWith(unicodeEscaped(c), cursor) || source.startsWith(unicodeEscaped(c).toLowerCase(), cursor) )) {
938948
int escapedCharLength = unicodeEscaped(c).length();
939949
text.append(source, cursor, cursor + escapedCharLength);

rewrite-java-21/src/main/java/org/openrewrite/java/isolated/ReloadableJava21JavadocVisitor.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -975,6 +975,16 @@ public List<Javadoc> visitText(String node) {
975975
cursor++;
976976
Javadoc.LineBreak lineBreak = lineBreaks.remove(cursor);
977977
texts.add(lineBreak);
978+
979+
// Java 23+ javac's DCText/DCComment getBody() strips per-line leading whitespace that
980+
// older versions preserved; the cleaned source still carries that whitespace, so realign
981+
// cursor by appending any source whitespace before node's next non-whitespace character.
982+
if (i + 1 < node.length() && !Character.isWhitespace(node.charAt(i + 1))) {
983+
while (cursor < source.length() && source.charAt(cursor) != '\n' && Character.isWhitespace(source.charAt(cursor))) {
984+
text.append(source.charAt(cursor));
985+
cursor++;
986+
}
987+
}
978988
} else if (source.charAt(cursor) != c && (source.startsWith(unicodeEscaped(c), cursor) || source.startsWith(unicodeEscaped(c).toLowerCase(), cursor) )) {
979989
int escapedCharLength = unicodeEscaped(c).length();
980990
text.append(source, cursor, cursor + escapedCharLength);

rewrite-java-8/src/main/java/org/openrewrite/java/ReloadableJava8JavadocVisitor.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -870,6 +870,16 @@ public List<Javadoc> visitText(String node) {
870870
cursor++;
871871
Javadoc.LineBreak lineBreak = lineBreaks.remove(cursor);
872872
texts.add(lineBreak);
873+
874+
// Java 23+ javac's DCText/DCComment getBody() strips per-line leading whitespace that
875+
// older versions preserved; the cleaned source still carries that whitespace, so realign
876+
// cursor by appending any source whitespace before node's next non-whitespace character.
877+
if (i + 1 < node.length() && !Character.isWhitespace(node.charAt(i + 1))) {
878+
while (cursor < source.length() && source.charAt(cursor) != '\n' && Character.isWhitespace(source.charAt(cursor))) {
879+
text.append(source.charAt(cursor));
880+
cursor++;
881+
}
882+
}
873883
} else if (source.charAt(cursor) != c && (source.startsWith(unicodeEscaped(c), cursor) || source.startsWith(unicodeEscaped(c).toLowerCase(), cursor) )) {
874884
int escapedCharLength = unicodeEscaped(c).length();
875885
text.append(source, cursor, cursor + escapedCharLength);

rewrite-java-tck/src/main/java/org/openrewrite/java/tree/JavadocTest.java

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2231,6 +2231,58 @@ class Test {}
22312231
);
22322232
}
22332233

2234+
@Test
2235+
void plainAsciiJavadocRoundTrips() {
2236+
rewriteRun(
2237+
java(
2238+
"""
2239+
/**
2240+
* This is a regular ASCII comment.
2241+
* No changes should be made here.
2242+
*/
2243+
public class Example {
2244+
/**
2245+
* Another regular method comment.
2246+
*/
2247+
public void regularMethod() {
2248+
}
2249+
}
2250+
"""
2251+
)
2252+
);
2253+
}
2254+
2255+
@Test
2256+
void plainNonAsciiJavadocRoundTrips() {
2257+
rewriteRun(
2258+
java(
2259+
"""
2260+
/**
2261+
* Coração de leão.
2262+
* Mañana es otro día.
2263+
*/
2264+
public class Example {
2265+
}
2266+
"""
2267+
)
2268+
);
2269+
}
2270+
2271+
@Test
2272+
void htmlCommentFollowedByPlainTextInSameJavadoc() {
2273+
rewriteRun(
2274+
java(
2275+
"""
2276+
/**
2277+
* <!-- inline html comment -->
2278+
* Following plain text on its own line.
2279+
*/
2280+
class Test {}
2281+
"""
2282+
)
2283+
);
2284+
}
2285+
22342286
@Issue("https://github.com/openrewrite/rewrite/issues/5443")
22352287
@Test
22362288
void parsingIncorrectJavadocValueReference() {

0 commit comments

Comments
 (0)