diff --git a/src/main/java/org/openrewrite/java/migrate/lang/UseTextBlocks.java b/src/main/java/org/openrewrite/java/migrate/lang/UseTextBlocks.java index 18af677e73..ddbb3f9b57 100644 --- a/src/main/java/org/openrewrite/java/migrate/lang/UseTextBlocks.java +++ b/src/main/java/org/openrewrite/java/migrate/lang/UseTextBlocks.java @@ -52,12 +52,27 @@ public class UseTextBlocks extends Recipe { required = false) boolean convertStringsWithoutNewlines; + @Option(displayName = "Whether to avoid line continuation escape sequences.", + description = "When enabled, the recipe 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. The default value is false.", + example = "true", + required = false) + boolean avoidLineContinuations; + public UseTextBlocks() { convertStringsWithoutNewlines = true; + avoidLineContinuations = false; } public UseTextBlocks(boolean convertStringsWithoutNewlines) { this.convertStringsWithoutNewlines = convertStringsWithoutNewlines; + this.avoidLineContinuations = false; + } + + public UseTextBlocks(boolean convertStringsWithoutNewlines, boolean avoidLineContinuations) { + this.convertStringsWithoutNewlines = convertStringsWithoutNewlines; + this.avoidLineContinuations = avoidLineContinuations; } String displayName = "Use text blocks"; @@ -122,6 +137,7 @@ private J.Literal toTextBlock(J.Binary binary, String content, List s stringLiterals = stringLiterals.stream() .filter(s -> s.getValue() != null && !s.getValue().toString().isEmpty()) .collect(toList()); + boolean skipLineContinuations = avoidLineContinuations && containsNewLineInContent(content); for (int i = 0; i < stringLiterals.size(); i++) { String s = requireNonNull(stringLiterals.get(i).getValue()).toString(); sb.append(s); @@ -129,7 +145,7 @@ private J.Literal toTextBlock(J.Binary binary, String content, List s if (i != stringLiterals.size() - 1) { String nextLine = requireNonNull(stringLiterals.get(i + 1).getValue()).toString(); char nextChar = nextLine.charAt(0); - if (!s.endsWith("\n") && nextChar != '\n') { + if (!s.endsWith("\n") && nextChar != '\n' && !skipLineContinuations) { sb.append(passPhrase); } } diff --git a/src/test/java/org/openrewrite/java/migrate/lang/UseTextBlocksTest.java b/src/test/java/org/openrewrite/java/migrate/lang/UseTextBlocksTest.java index ff4ecc1727..787baee40e 100644 --- a/src/test/java/org/openrewrite/java/migrate/lang/UseTextBlocksTest.java +++ b/src/test/java/org/openrewrite/java/migrate/lang/UseTextBlocksTest.java @@ -879,6 +879,99 @@ void shouldNotUpdateKotlinCode() { ); } + @Issue("https://github.com/moderneinc/customer-requests/issues/1763") + @Test + void noLineContinuationWhenContentHasNewlines() { + rewriteRun( + spec -> spec.recipe(new UseTextBlocks(true, true)), + //language=java + java( + """ + class Test { + String query = "select count(1) cls_count\\n" + + "from my_table\\n" + + "where a.id = b.id\\n" + + "and a.ts > b.ts\\n" + + "and a.id = :tag_id \\n" + + "and a.stat_cd = 'ACTV'" + + " and a.del_fl = 'N'" + + " and a.rgn = :region"; + } + """, + """ + class Test { + String query = \""" + select count(1) cls_count + from my_table + where a.id = b.id + and a.ts > b.ts + and a.id = :tag_id\\s + and a.stat_cd = 'ACTV' and a.del_fl = 'N' and a.rgn = :region\"""; + } + """ + ) + ); + } + + @Issue("https://github.com/moderneinc/customer-requests/issues/1763") + @Test + void noLineContinuationInMixedConcatenation() { + rewriteRun( + spec -> spec.recipe(new UseTextBlocks(true, true)), + //language=java + java( + """ + class Test { + String query = "select b.id, b.val\\n" + + "from my_table b, other_table c\\n" + + "where c.no = :no\\n" + + "and b.vrsn = c.vrsn" + + " and b.rgn = :region" + + " and b.del_fl = 'N'" + + " and c.rgn = :region"; + } + """, + """ + class Test { + String query = \""" + select b.id, b.val + from my_table b, other_table c + where c.no = :no + and b.vrsn = c.vrsn and b.rgn = :region and b.del_fl = 'N' and c.rgn = :region\"""; + } + """ + ) + ); + } + + @Issue("https://github.com/moderneinc/customer-requests/issues/1763") + @Test + void noLineContinuationInMiddleOfMixedConcatenation() { + rewriteRun( + spec -> spec.recipe(new UseTextBlocks(true, true)), + //language=java + java( + """ + class Test { + String query = "select b.id\\n" + + "from my_table" + + " inner join other_table\\n" + + "where b.id = :id\\n"; + } + """, + """ + class Test { + String query = \""" + select b.id + from my_table inner join other_table + where b.id = :id + \"""; + } + """ + ) + ); + } + @Issue("https://github.com/openrewrite/rewrite-migrate-java/issues/555") @Test void textBlockTrailingEscape() {