From c42fa23b858d46b91ab1641e70d6591dea9514cf Mon Sep 17 00:00:00 2001 From: Jeff Johnston Date: Fri, 8 Mar 2024 22:01:14 -0500 Subject: [PATCH] Fix text block conversion when ending in quotes (#1245) - fix StringConcatToTextBlockFixCore to look at resultant buffer before adding final block quotes and if last 1 or 2 characters are un-escaped quotes, replace them with escaped quotes - add new scenarios to CleanUpTest15 - fixes #1238 --- .../fix/StringConcatToTextBlockFixCore.java | 34 ++++++++++++++++++- .../jdt/ui/tests/quickfix/CleanUpTest15.java | 32 +++++++++++++++-- 2 files changed, 63 insertions(+), 3 deletions(-) diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/StringConcatToTextBlockFixCore.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/StringConcatToTextBlockFixCore.java index c1a1cb3ac6a..80e8061e920 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/StringConcatToTextBlockFixCore.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/StringConcatToTextBlockFixCore.java @@ -308,6 +308,22 @@ public void accept(Expression t) { if (newLine) { buf.append(fIndent); } + // Replace trailing un-escaped quotes with escaped quotes before adding text block end + int i= buf.length() - 1; + int count= 0; + while (i >= 0 && buf.charAt(i) == '"' && count <= 3) { + --i; + ++count; + } + if (i >= 0 && buf.charAt(i) == '\\') { + --count; + } + for (i= count; i > 0; --i) { + buf.deleteCharAt(buf.length() - 1); + } + for (i= count; i > 0; --i) { + buf.append("\\\""); //$NON-NLS-1$ + } buf.append("\"\"\""); //$NON-NLS-1$ if (!isTagged) { TextBlock textBlock= (TextBlock) rewrite.createStringPlaceholder(buf.toString(), ASTNode.TEXT_BLOCK); @@ -370,7 +386,6 @@ private static List unescapeBlock(String escapedText) { for (int j = 0; j < quoteCount % 3; j++) { transformed.append("\""); //$NON-NLS-1$ } - readIndex= bsIndex + 2 * quoteCount; } else if (escapedText.startsWith("\\t", bsIndex)) { //$NON-NLS-1$ "\t" transformed.append(escapedText.substring(readIndex, bsIndex)); @@ -729,6 +744,23 @@ public SourceRange computeSourceRange(final ASTNode nodeWithComment) { if (newLine) { buf.append(fIndent); } + + // Replace trailing un-escaped quotes with escaped quotes before adding text block end + int readIndex= buf.length() - 1; + int count= 0; + while (readIndex >= 0 && buf.charAt(readIndex) == '"' && count <= 3) { + --readIndex; + ++count; + } + if (readIndex >= 0 && buf.charAt(readIndex) == '\\') { + --count; + } + for (int i= count; i > 0; --i) { + buf.deleteCharAt(buf.length() - 1); + } + for (int i= count; i > 0; --i) { + buf.append("\\\""); //$NON-NLS-1$ + } buf.append("\"\"\""); //$NON-NLS-1$ MethodInvocation firstToStringCall= fToStringList.get(0); AST ast= firstToStringCall.getAST(); diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest15.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest15.java index 27fe99b1695..09417cd8291 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest15.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest15.java @@ -116,7 +116,15 @@ public void testConcatToTextBlock() throws Exception { + " \"\\t} else\\n\" +\n" // + " \"\\t\\tnoStuff\";\n" // + " }\n" // - + "}\n"; + + " public void testEndEscapedQuotes() {\n" // + + " String a =\n" // + + " \"1\\n\" +\n" // + + " \"2\\n\" +\n" // + + " \"3\\n\" +\n" // + + " \"4\\n\" +\n" // + + " \"\\\"\\\"\\\"\\\"\";\n" // + + " }\n" // + + "}\n"; ICompilationUnit cu1= pack1.createCompilationUnit("E.java", sample, false, null); @@ -195,6 +203,15 @@ public void testConcatToTextBlock() throws Exception { + " \t} else\n" // + " \t\tnoStuff\"\"\";\n" // + " }\n" // + + " public void testEndEscapedQuotes() {\n" // + + " String a =\n" // + + " \"\"\"\n" // + + " 1\n" // + + " 2\n" // + + " 3\n" // + + " 4\n" // + + " \\\"\"\"\\\"\"\"\";\n" // + + " }\n" // + "}\n"; assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }, null); @@ -243,6 +260,11 @@ public void testConcatToTextBlock2() throws Exception { + " \"def\\n\" +\n" // + " \"ghi\\n\";\n" // + " new StringBuffer(\"abc\\n\" + \"def\\n\" + \"ghi\");\n" // + + " new StringBuffer(\"1\\n\" +\n" // + + " \"2\\n\" +\n" // + + " \"3\\n\" +\n" // + + " \"4\\n\" +\n" // + + " \"\\\"\\\"\\\"\");\n" // + " }\n" // + "}"; @@ -301,7 +323,13 @@ public void testConcatToTextBlock2() throws Exception { + " abc\n" // + " def\n" // + " ghi\"\"\");\n" // - + " }\n" // + + " new StringBuffer(\"\"\"\n" // + + " 1\n" // + + " 2\n" // + + " 3\n" // + + " 4\n" // + + " \\\"\\\"\\\"\"\"\");\n" // + + " }\n" // + "}"; assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }, null);