Skip to content

Commit 54a8ee5

Browse files
Fix PlainTextParser conversion marker handling (#6157)
* Fixed an issue where conversion would print markers to the text result + to the commit keeping Markup markers present * Fixed an issue where conversion would print markers to the text result + to the commit keeping Markup markers present * Minor polish * Change copyright year in PlainTextParserConversionTest Updated copyright year from 2024 to 2025. --------- Co-authored-by: Tim te Beek <tim@moderne.io>
1 parent d9f535e commit 54a8ee5

3 files changed

Lines changed: 123 additions & 7 deletions

File tree

rewrite-core/src/main/java/org/openrewrite/text/FindAndReplace.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ public Tree visit(@Nullable Tree tree, ExecutionContext ctx) {
155155

156156
return plainText
157157
.withText(newText)
158-
.withMarkers(sourceFile.getMarkers().add(new AlreadyReplaced(randomId(), find, replace)));
158+
.withMarkers(plainText.getMarkers().add(new AlreadyReplaced(randomId(), find, replace)));
159159
}
160160
};
161161

@@ -173,5 +173,4 @@ public PlainText visitText(PlainText text, ExecutionContext ctx) {
173173
}
174174
return visitor;
175175
}
176-
177176
}

rewrite-core/src/main/java/org/openrewrite/text/PlainTextParser.java

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@
1616
package org.openrewrite.text;
1717

1818
import org.jspecify.annotations.Nullable;
19-
import org.openrewrite.ExecutionContext;
20-
import org.openrewrite.Parser;
21-
import org.openrewrite.SourceFile;
19+
import org.openrewrite.*;
2220
import org.openrewrite.internal.EncodingDetectingInputStream;
2321
import org.openrewrite.jgit.diff.RawText;
22+
import org.openrewrite.marker.Marker;
23+
import org.openrewrite.marker.Markup;
24+
import org.openrewrite.marker.SearchResult;
2425
import org.openrewrite.tree.ParseError;
2526
import org.openrewrite.tree.ParsingEventListener;
2627
import org.openrewrite.tree.ParsingExecutionContextView;
@@ -32,7 +33,9 @@
3233
import java.nio.file.Path;
3334
import java.nio.file.PathMatcher;
3435
import java.nio.file.Paths;
36+
import java.util.ArrayList;
3537
import java.util.Collection;
38+
import java.util.List;
3639
import java.util.stream.Stream;
3740
import java.util.stream.StreamSupport;
3841

@@ -52,13 +55,14 @@ public static PlainText convert(SourceFile sourceFile) {
5255
return (PlainText) sourceFile;
5356
}
5457
PlainText text = PlainTextParser.builder().build()
55-
.parse(sourceFile.printAll())
58+
.parse(sourceFile.printAll(new PrintOutputCapture<>(0, PrintOutputCapture.MarkerPrinter.SANITIZED)))
5659
.findFirst()
5760
.orElseThrow(() -> new IllegalStateException("Failed to parse as plain text"))
5861
.withSourcePath(sourceFile.getSourcePath())
5962
.withFileAttributes(sourceFile.getFileAttributes())
6063
.withCharsetBomMarked(sourceFile.isCharsetBomMarked())
61-
.withId(sourceFile.getId());
64+
.withId(sourceFile.getId())
65+
.withMarkers(sourceFile.getMarkers().withMarkers(gatherMarkers(sourceFile)));
6266
if (sourceFile.getCharset() != null) {
6367
text = (PlainText) text.withCharset(sourceFile.getCharset());
6468
}
@@ -156,4 +160,20 @@ public String getDslName() {
156160
return "text";
157161
}
158162
}
163+
164+
private static List<Marker> gatherMarkers(SourceFile sourceFile) {
165+
return new TreeVisitor<Tree, List<Marker>>() {
166+
@Override
167+
public @Nullable Tree visit(@Nullable Tree tree, List<Marker> markers) {
168+
if (tree != null && tree != sourceFile) {
169+
tree.getMarkers().getMarkers().forEach(marker -> {
170+
if (marker instanceof SearchResult || marker instanceof Markup) {
171+
markers.add(marker);
172+
}
173+
});
174+
}
175+
return super.visit(tree, markers);
176+
}
177+
}.reduce(sourceFile, new ArrayList<>(sourceFile.getMarkers().getMarkers()));
178+
}
159179
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
* Copyright 2025 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;
17+
18+
import org.junit.jupiter.api.Test;
19+
import org.openrewrite.DocumentExample;
20+
import org.openrewrite.ExecutionContext;
21+
import org.openrewrite.Recipe;
22+
import org.openrewrite.SourceFile;
23+
import org.openrewrite.java.tree.J;
24+
import org.openrewrite.marker.AlreadyReplaced;
25+
import org.openrewrite.marker.Markup;
26+
import org.openrewrite.marker.RecipesThatMadeChanges;
27+
import org.openrewrite.test.RewriteTest;
28+
import org.openrewrite.text.FindAndReplace;
29+
import org.openrewrite.text.PlainText;
30+
31+
import static org.assertj.core.api.Assertions.assertThat;
32+
import static org.openrewrite.java.Assertions.java;
33+
import static org.openrewrite.test.RewriteTest.toRecipe;
34+
35+
class PlainTextParserConversionTest implements RewriteTest {
36+
37+
private static final Recipe markClassDeclaration = toRecipe(() -> new JavaVisitor<>() {
38+
@Override
39+
public J visitClassDeclaration(J.ClassDeclaration classDecl, ExecutionContext ctx) {
40+
return Markup.info(classDecl, "test");
41+
}
42+
});
43+
44+
@DocumentExample
45+
@Test
46+
void markersAreAddedWhenConvertingToTextLst() {
47+
rewriteRun(
48+
spec -> {
49+
spec.afterRecipe(run -> {
50+
SourceFile result = run.getChangeset().getAllResults().getFirst().getAfter();
51+
assertThat(result).isInstanceOf(PlainText.class);
52+
assertThat(result.getMarkers().getMarkers()).hasSize(3);
53+
assertThat(result.getMarkers().findAll(AlreadyReplaced.class)).isNotEmpty();
54+
assertThat(result.getMarkers().findAll(Markup.class)).isNotEmpty();
55+
assertThat(result.getMarkers().findFirst(RecipesThatMadeChanges.class).get().getRecipes()).hasSize(2);
56+
});
57+
spec.recipes(markClassDeclaration, new FindAndReplace("class", "public class", null, null, null, null, null, null));
58+
},
59+
java(
60+
"""
61+
package com.example;
62+
63+
class Test {
64+
}
65+
""",
66+
"""
67+
~~(test)~~>package com.example;
68+
69+
public class Test {
70+
}
71+
"""
72+
)
73+
);
74+
}
75+
76+
@Test
77+
void markersAreKeptWhenNoConversionToTextLst() {
78+
rewriteRun(
79+
spec ->
80+
spec.recipes(markClassDeclaration, new FindAndReplace("doesNotExist", "willNotAppear", null, null, null, null, null, null)),
81+
java(
82+
"""
83+
package com.example;
84+
85+
class Test {
86+
}
87+
""",
88+
"""
89+
package com.example;
90+
91+
/*~~(test)~~>*/class Test {
92+
}
93+
"""
94+
)
95+
);
96+
}
97+
}

0 commit comments

Comments
 (0)