From e3459bf8c33648354767a3f5668986cd743177e4 Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Wed, 16 Aug 2023 19:28:19 +0200 Subject: [PATCH] Do not partially use text blocks Fixes #260 --- .../java/migrate/lang/UseTextBlocks.java | 25 ++++- .../java/migrate/lang/UseTextBlocksTest.java | 103 ++++++++++-------- 2 files changed, 81 insertions(+), 47 deletions(-) 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 a678436b88..403e1b1fc7 100644 --- a/src/main/java/org/openrewrite/java/migrate/lang/UseTextBlocks.java +++ b/src/main/java/org/openrewrite/java/migrate/lang/UseTextBlocks.java @@ -33,7 +33,10 @@ import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.time.Duration; -import java.util.*; +import java.util.ArrayList; +import java.util.Base64; +import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; import static org.openrewrite.Tree.randomId; @@ -72,6 +75,18 @@ public String getDescription() { return Duration.ofMinutes(3); } + private static boolean allLiterals(Expression left, Expression right) { + boolean leftAll = isRegularStringLiteral(left) || left instanceof J.Binary + && ((J.Binary) left).getOperator() == J.Binary.Type.Addition + && allLiterals(((J.Binary) left).getLeft(), ((J.Binary) left).getRight()); + if (!leftAll) { + return false; + } + return isRegularStringLiteral(right) || right instanceof J.Binary + && ((J.Binary) right).getOperator() == J.Binary.Type.Addition + && allLiterals(((J.Binary) right).getLeft(), ((J.Binary) right).getRight()); + } + @Override public TreeVisitor getVisitor() { return Preconditions.check(new HasJavaVersion("17", true), new JavaVisitor() { @@ -82,6 +97,11 @@ public J visitBinary(J.Binary binary, ExecutionContext ctx) { StringBuilder contentSb = new StringBuilder(); StringBuilder concatenationSb = new StringBuilder(); + boolean allLiterals = allLiterals(binary.getLeft(), binary.getRight()); + if (!allLiterals) { + return binary; // Not super.visitBinary(binary, ctx) because we don't want to visit the children + } + boolean flattenable = flatAdditiveStringLiterals(binary, stringLiterals, contentSb, concatenationSb); if (!flattenable) { return super.visitBinary(binary, ctx); @@ -133,7 +153,7 @@ private J.Literal toTextBlock(J.Binary binary, String content, List s boolean useTab = tabsAndIndentsStyle.getUseTabCharacter(); int tabSize = tabsAndIndentsStyle.getTabSize(); - String indentation = getIndents(concatenation.toString(), useTab, tabSize); + String indentation = getIndents(concatenation, useTab, tabSize); boolean isEndsWithNewLine = content.endsWith("\n"); @@ -194,7 +214,6 @@ private static boolean flatAdditiveStringLiterals(Expression expression, private static boolean isRegularStringLiteral(Expression expr) { if (expr instanceof J.Literal) { J.Literal l = (J.Literal) expr; - return TypeUtils.isString(l.getType()) && l.getValueSource() != null && !l.getValueSource().startsWith("\"\"\""); 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 e85be3144d..024f9cbc38 100644 --- a/src/test/java/org/openrewrite/java/migrate/lang/UseTextBlocksTest.java +++ b/src/test/java/org/openrewrite/java/migrate/lang/UseTextBlocksTest.java @@ -24,6 +24,7 @@ import org.openrewrite.style.NamedStyles; import org.openrewrite.test.RecipeSpec; import org.openrewrite.test.RewriteTest; + import java.util.function.Consumer; import java.util.function.UnaryOperator; @@ -31,7 +32,8 @@ import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; import static org.openrewrite.Tree.randomId; -import static org.openrewrite.java.Assertions.*; +import static org.openrewrite.java.Assertions.java; +import static org.openrewrite.java.Assertions.javaVersion; class UseTextBlocksTest implements RewriteTest { @@ -92,28 +94,13 @@ class Test { ); } - @Test - void preserveTrailingWhiteSpaces2() { - rewriteRun( - java( - """ - class Test { - String color = "red \\n" + - "green \\n" + - "blue \\n"; - } - """, - """ - class Test { - String color = \""" - red \\s - green\\s - blue \\s - ""\"; - } - """ + private static Consumer tabsAndIndents(UnaryOperator with, int tabSize) { + return spec -> spec.parser(JavaParser.fromJavaVersion().styles(singletonList( + new NamedStyles( + randomId(), "TabsOnlyFile", "TabsOnlyFile", "tabSize is x", emptySet(), + singletonList(with.apply(buildTabsAndIndents(tabSize))) ) - ); + ))); } @Test @@ -370,13 +357,29 @@ class Test { ); } - private static Consumer tabsAndIndents(UnaryOperator with, int tabSize) { - return spec -> spec.parser(JavaParser.fromJavaVersion().styles(singletonList( - new NamedStyles( - randomId(), "TabsOnlyFile", "TabsOnlyFile", "tabSize is x", emptySet(), - singletonList(with.apply(buildTabsAndIndents(tabSize))) - ) - ))); + @Test + void preserveTrailingWhiteSpaces2() { + rewriteRun( + //language=java + java( + """ + class Test { + String color = "red \\n" + + "green \\n" + + "blue \\n"; + } + """, + """ + class Test { + String color = \""" + red \\s + green\\s + blue \\s + ""\"; + } + """ + ) + ); } private static TabsAndIndentsStyle buildTabsAndIndents(int tabSize) { @@ -500,6 +503,7 @@ void textBlockDemo() { @Test void newlineAtBeginningOfLines() { rewriteRun( + //language=java java( """ class A { @@ -541,6 +545,7 @@ void log(String s) {} @Test void consecutiveNewLines() { rewriteRun( + //language=java java( """ class Test { @@ -693,6 +698,7 @@ class Test { @Test void eightQuotes() { rewriteRun( + //language=java java( """ class Test { @@ -758,10 +764,12 @@ class Test { ); } - @Disabled @Test - void grouping() { + @Issue("https://github.com/openrewrite/rewrite-migrate-java/issues/260") + //@Issue("https://github.com/openrewrite/rewrite-migrate-java/issues/261") + void doNotPartiallyReplaceWithTextBlocks() { rewriteRun( + //language=java java( """ public class Test { @@ -779,23 +787,30 @@ public void method() { "AFTER the variable. "; } } - """, + """ + ) + ); + } + + @Test + @Issue("https://github.com/openrewrite/rewrite-migrate-java/issues/261") + void doNotPartiallyReplaceWithTextBlocksWithIntLiteral() { + rewriteRun( + //language=java + java( """ public class Test { public void method() { - int variable = 1; String stringWithVariableInIt = - \""" - This \\ - is \\ - text \\ - BEFORE the variable \\ - \""" - This \\ - is \\ - text \\ - AFTER the variable. \\ - \"""; + "This " + + "is " + + "text " + + "BEFORE the variable " + + 1 + + "This " + + "is " + + "text " + + "AFTER the variable. "; } } """