Skip to content

Commit 653dd7c

Browse files
authored
Add avoidLineContinuations option to UseTextBlocks (#975)
Add a new recipe option `avoidLineContinuations` (default: false) that, when enabled, avoids using `\` line continuation escapes in text blocks where the content contains newlines. Non-newline-joined strings are placed on the same text block line instead. Previously with the option enabled, "foo\n" + "bar" + " baz" produces: foo bar baz Without the option (default), the existing behavior is preserved: foo bar\ baz Fixes moderneinc/customer-requests#1763
1 parent c6b1bcf commit 653dd7c

2 files changed

Lines changed: 110 additions & 1 deletion

File tree

src/main/java/org/openrewrite/java/migrate/lang/UseTextBlocks.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,27 @@ public class UseTextBlocks extends Recipe {
5252
required = false)
5353
boolean convertStringsWithoutNewlines;
5454

55+
@Option(displayName = "Whether to avoid line continuation escape sequences.",
56+
description = "When enabled, the recipe avoids using `\\` line continuation escapes in text blocks " +
57+
"where the content contains newlines. Non-newline-joined strings are placed on the same " +
58+
"text block line instead. The default value is false.",
59+
example = "true",
60+
required = false)
61+
boolean avoidLineContinuations;
62+
5563
public UseTextBlocks() {
5664
convertStringsWithoutNewlines = true;
65+
avoidLineContinuations = false;
5766
}
5867

5968
public UseTextBlocks(boolean convertStringsWithoutNewlines) {
6069
this.convertStringsWithoutNewlines = convertStringsWithoutNewlines;
70+
this.avoidLineContinuations = false;
71+
}
72+
73+
public UseTextBlocks(boolean convertStringsWithoutNewlines, boolean avoidLineContinuations) {
74+
this.convertStringsWithoutNewlines = convertStringsWithoutNewlines;
75+
this.avoidLineContinuations = avoidLineContinuations;
6176
}
6277

6378
String displayName = "Use text blocks";
@@ -122,14 +137,15 @@ private J.Literal toTextBlock(J.Binary binary, String content, List<J.Literal> s
122137
stringLiterals = stringLiterals.stream()
123138
.filter(s -> s.getValue() != null && !s.getValue().toString().isEmpty())
124139
.collect(toList());
140+
boolean skipLineContinuations = avoidLineContinuations && containsNewLineInContent(content);
125141
for (int i = 0; i < stringLiterals.size(); i++) {
126142
String s = requireNonNull(stringLiterals.get(i).getValue()).toString();
127143
sb.append(s);
128144
originalContent.append(s);
129145
if (i != stringLiterals.size() - 1) {
130146
String nextLine = requireNonNull(stringLiterals.get(i + 1).getValue()).toString();
131147
char nextChar = nextLine.charAt(0);
132-
if (!s.endsWith("\n") && nextChar != '\n') {
148+
if (!s.endsWith("\n") && nextChar != '\n' && !skipLineContinuations) {
133149
sb.append(passPhrase);
134150
}
135151
}

src/test/java/org/openrewrite/java/migrate/lang/UseTextBlocksTest.java

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -879,6 +879,99 @@ void shouldNotUpdateKotlinCode() {
879879
);
880880
}
881881

882+
@Issue("https://github.com/moderneinc/customer-requests/issues/1763")
883+
@Test
884+
void noLineContinuationWhenContentHasNewlines() {
885+
rewriteRun(
886+
spec -> spec.recipe(new UseTextBlocks(true, true)),
887+
//language=java
888+
java(
889+
"""
890+
class Test {
891+
String query = "select count(1) cls_count\\n" +
892+
"from my_table\\n" +
893+
"where a.id = b.id\\n" +
894+
"and a.ts > b.ts\\n" +
895+
"and a.id = :tag_id \\n" +
896+
"and a.stat_cd = 'ACTV'" +
897+
" and a.del_fl = 'N'" +
898+
" and a.rgn = :region";
899+
}
900+
""",
901+
"""
902+
class Test {
903+
String query = \"""
904+
select count(1) cls_count
905+
from my_table
906+
where a.id = b.id
907+
and a.ts > b.ts
908+
and a.id = :tag_id\\s
909+
and a.stat_cd = 'ACTV' and a.del_fl = 'N' and a.rgn = :region\""";
910+
}
911+
"""
912+
)
913+
);
914+
}
915+
916+
@Issue("https://github.com/moderneinc/customer-requests/issues/1763")
917+
@Test
918+
void noLineContinuationInMixedConcatenation() {
919+
rewriteRun(
920+
spec -> spec.recipe(new UseTextBlocks(true, true)),
921+
//language=java
922+
java(
923+
"""
924+
class Test {
925+
String query = "select b.id, b.val\\n" +
926+
"from my_table b, other_table c\\n" +
927+
"where c.no = :no\\n" +
928+
"and b.vrsn = c.vrsn" +
929+
" and b.rgn = :region" +
930+
" and b.del_fl = 'N'" +
931+
" and c.rgn = :region";
932+
}
933+
""",
934+
"""
935+
class Test {
936+
String query = \"""
937+
select b.id, b.val
938+
from my_table b, other_table c
939+
where c.no = :no
940+
and b.vrsn = c.vrsn and b.rgn = :region and b.del_fl = 'N' and c.rgn = :region\""";
941+
}
942+
"""
943+
)
944+
);
945+
}
946+
947+
@Issue("https://github.com/moderneinc/customer-requests/issues/1763")
948+
@Test
949+
void noLineContinuationInMiddleOfMixedConcatenation() {
950+
rewriteRun(
951+
spec -> spec.recipe(new UseTextBlocks(true, true)),
952+
//language=java
953+
java(
954+
"""
955+
class Test {
956+
String query = "select b.id\\n" +
957+
"from my_table" +
958+
" inner join other_table\\n" +
959+
"where b.id = :id\\n";
960+
}
961+
""",
962+
"""
963+
class Test {
964+
String query = \"""
965+
select b.id
966+
from my_table inner join other_table
967+
where b.id = :id
968+
\""";
969+
}
970+
"""
971+
)
972+
);
973+
}
974+
882975
@Issue("https://github.com/openrewrite/rewrite-migrate-java/issues/555")
883976
@Test
884977
void textBlockTrailingEscape() {

0 commit comments

Comments
 (0)