Skip to content

Commit 93293a9

Browse files
authored
Support newline formatting on text blocks created by quick assist (#2974)
* Add Support newline surrounding textblocks feature on quick assists * Add tests for new quick assist
1 parent 88fd193 commit 93293a9

3 files changed

Lines changed: 172 additions & 7 deletions

File tree

org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/StringConcatToTextBlockFixCore.java

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ public SourceRange computeSourceRange(final ASTNode nodeWithComment) {
295295
});
296296

297297
IJavaElement root= cuRewrite.getRoot().getJavaElement();
298+
boolean needNewLineTextBlock = false;
298299
if (root != null) {
299300
IJavaProject project= root.getJavaProject();
300301
if (project != null) {
@@ -305,6 +306,8 @@ public SourceRange computeSourceRange(final ASTNode nodeWithComment) {
305306
fIndent += " "; //$NON-NLS-1$
306307
}
307308
}
309+
String newLineTextBlockStr = project.getOption(DefaultCodeFormatterConstants.FORMATTER_PUT_TEXT_BLOCK_QUOTES_ON_NEW_LINE, true);
310+
needNewLineTextBlock = DefaultCodeFormatterConstants.TRUE.equals(newLineTextBlockStr);
308311
}
309312
}
310313

@@ -325,12 +328,17 @@ public void accept(Expression t) {
325328
}
326329
});
327330

331+
if (needNewLineTextBlock) {
332+
buf.append("\n" + fIndent); //$NON-NLS-1$
333+
}
334+
328335
buf.append("\"\"\"\n"); //$NON-NLS-1$
329336
boolean newLine= false;
330337
boolean allWhiteSpaceStart= true;
331338
boolean allEmpty= true;
339+
int bufLength = (needNewLineTextBlock) ? 6 : 4;
332340
for (String part : parts) {
333-
if (buf.length() > 4) {// the first part has been added after the text block delimiter and newline
341+
if (buf.length() > bufLength) {// the first part has been added after the text block delimiter and newline
334342
if (!newLine) {
335343
// no line terminator in this part: merge the line by emitting a line continuation escape
336344
buf.append("\\").append(System.lineSeparator()); //$NON-NLS-1$
@@ -373,6 +381,15 @@ public void accept(Expression t) {
373381
buf.append("\\t"); //$NON-NLS-1$
374382
}
375383
}
384+
385+
if (needNewLineTextBlock) {
386+
if (!newLine) {
387+
buf.append("\\"); //$NON-NLS-1$
388+
buf.append("\n"); //$NON-NLS-1$
389+
buf.append(fIndent);
390+
}
391+
}
392+
376393
buf.append("\"\"\""); //$NON-NLS-1$
377394
if (!isTagged) {
378395
TextBlock textBlock= (TextBlock) rewrite.createStringPlaceholder(buf.toString(), ASTNode.TEXT_BLOCK);
@@ -852,7 +869,6 @@ public boolean visit(final VariableDeclarationStatement visited) {
852869

853870
@Override
854871
public boolean visit(VariableDeclarationFragment node) {
855-
// TODO Auto-generated method stub
856872
VariableDeclarationStatement varDeclStmt= ASTNodes.getFirstAncestorOrNull(node, VariableDeclarationStatement.class);
857873
if (varDeclStmt == null || varDeclStmt.fragments().size() != 1) {
858874
return false;
@@ -1189,6 +1205,7 @@ public static StringConcatToTextBlockFixCore createStringLiteralToTextBlockFix(A
11891205
private static StringBuilder createTextBlockBuffer(List<StringLiteral> literals, CompilationUnitRewrite cuRewrite) {
11901206
IJavaElement root= cuRewrite.getRoot().getJavaElement();
11911207
String fIndent= "\t"; //$NON-NLS-1$
1208+
boolean needNewLineTextBlock = false;
11921209
if (root != null) {
11931210
IJavaProject project= root.getJavaProject();
11941211
if (project != null) {
@@ -1199,20 +1216,24 @@ private static StringBuilder createTextBlockBuffer(List<StringLiteral> literals,
11991216
fIndent += " "; //$NON-NLS-1$
12001217
}
12011218
}
1219+
String newLineTextBlockStr = project.getOption(DefaultCodeFormatterConstants.FORMATTER_PUT_TEXT_BLOCK_QUOTES_ON_NEW_LINE, true);
1220+
needNewLineTextBlock = DefaultCodeFormatterConstants.TRUE.equals(newLineTextBlockStr);
12021221
}
12031222
}
1204-
12051223
StringBuilder buf= new StringBuilder();
12061224

12071225
List<String> parts= new ArrayList<>();
12081226
literals.stream().forEach((t) -> { String value= t.getEscapedValue(); parts.addAll(unescapeBlock(value.substring(1, value.length() - 1))); });
1209-
1227+
if(needNewLineTextBlock) {
1228+
buf.append("\n" + fIndent); //$NON-NLS-1$
1229+
}
12101230
buf.append("\"\"\"\n"); //$NON-NLS-1$
12111231
boolean newLine= false;
12121232
boolean allWhiteSpaceStart= true;
12131233
boolean allEmpty= true;
1234+
int bufLength = (needNewLineTextBlock) ? 6 : 4;
12141235
for (String part : parts) {
1215-
if (buf.length() > 4) {// the first part has been added after the text block delimiter and newline
1236+
if (buf.length() > bufLength) {// the first part has been added after the text block delimiter and newline
12161237
if (!newLine) {
12171238
// no line terminator in this part: merge the line by emitting a line continuation escape
12181239
buf.append("\\").append(System.lineSeparator()); //$NON-NLS-1$
@@ -1247,6 +1268,10 @@ private static StringBuilder createTextBlockBuffer(List<StringLiteral> literals,
12471268
buf.append("\\\""); //$NON-NLS-1$
12481269
}
12491270
}
1271+
if(needNewLineTextBlock) {
1272+
if (!newLine)
1273+
buf.append("\\").append(System.lineSeparator()).append(fIndent); //$NON-NLS-1$
1274+
}
12501275
buf.append("\"\"\""); //$NON-NLS-1$
12511276
return buf;
12521277
}

org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/structure/CompilationUnitRewrite.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -311,8 +311,6 @@ public CompilationUnitChange attachChange(CompilationUnitChange cuChange, boolea
311311
String importUpdateName= RefactoringCoreMessages.ASTData_update_imports;
312312
cuChange.addTextEditGroup(new TextEditGroup(importUpdateName, importsEdit));
313313
}
314-
} else {
315-
316314
}
317315
if (isEmptyEdit(multiEdit))
318316
return null;

org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AssistQuickFixTest15.java

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.junit.Test;
2424

2525
import org.eclipse.jdt.testplugin.JavaProjectHelper;
26+
import org.eclipse.jdt.testplugin.TestOptions;
2627

2728
import org.eclipse.jdt.core.ICompilationUnit;
2829
import org.eclipse.jdt.core.IJavaProject;
@@ -38,6 +39,8 @@
3839
import org.eclipse.jdt.ui.text.java.IInvocationContext;
3940
import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal;
4041

42+
import org.eclipse.jdt.internal.ui.fix.MultiFixMessages;
43+
import org.eclipse.jdt.internal.ui.text.correction.AssistContext;
4144
import org.eclipse.jdt.internal.ui.text.correction.CorrectionMessages;
4245

4346
public class AssistQuickFixTest15 extends QuickFixTest {
@@ -2075,4 +2078,143 @@ public void foo(String name, String id) {
20752078
assertExpectedExistInProposals(proposals, new String[] { expected });
20762079
}
20772080

2081+
@Test
2082+
public void testStringConcatToTextBlock() throws Exception {
2083+
//Testing new quick assist to place text block quotes on their own lines if option is enabled
2084+
fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin");
2085+
fJProject1.setRawClasspath(projectSetup.getDefaultClasspath(), null);
2086+
JavaProjectHelper.set15CompilerOptions(fJProject1, false);
2087+
fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
2088+
2089+
String str= """
2090+
module test {
2091+
}
2092+
""";
2093+
IPackageFragment def= fSourceFolder.createPackageFragment("", false, null);
2094+
def.createCompilationUnit("module-info.java", str, false, null);
2095+
2096+
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
2097+
2098+
Hashtable<String, String> options = TestOptions.getDefaultOptions();
2099+
options.put(DefaultCodeFormatterConstants.FORMATTER_PUT_TEXT_BLOCK_QUOTES_ON_NEW_LINE, DefaultCodeFormatterConstants.TRUE);
2100+
JavaCore.setOptions(options);
2101+
2102+
String example1 = """
2103+
package test1;
2104+
public class TestQuickAssistTextBlock {
2105+
2106+
String str1 = "asd" + "bsd\\n" + "cpp" + "osd";
2107+
2108+
public void foo1() {
2109+
System.out.println(str1);
2110+
}
2111+
2112+
public static void main(String[] args) {
2113+
TestQuickAssistTextBlock qatb = new TestQuickAssistTextBlock();
2114+
qatb.foo1();
2115+
}
2116+
}
2117+
""";
2118+
ICompilationUnit cu = pack1.createCompilationUnit("TestQuickAssistTextBlock.java", example1, false, null);
2119+
int offset= example1.indexOf("asd");
2120+
AssistContext context= getCorrectionContext(cu, offset, 0);
2121+
ArrayList<IJavaCompletionProposal> proposals= collectAssists(context, false);
2122+
assertCorrectLabels(proposals);
2123+
assertProposalExists(proposals, MultiFixMessages.StringConcatToTextBlockCleanUp_description);
2124+
String expected = """
2125+
package test1;
2126+
public class TestQuickAssistTextBlock {
2127+
2128+
String str1 =\s
2129+
\"\"\"
2130+
asd\\
2131+
bsd
2132+
cpp\\
2133+
osd\\
2134+
\"\"\";
2135+
2136+
public void foo1() {
2137+
System.out.println(str1);
2138+
}
2139+
2140+
public static void main(String[] args) {
2141+
TestQuickAssistTextBlock qatb = new TestQuickAssistTextBlock();
2142+
qatb.foo1();
2143+
}
2144+
}
2145+
""";
2146+
assertExpectedExistInProposals(proposals, new String[] { expected });
2147+
options.put(DefaultCodeFormatterConstants.FORMATTER_PUT_TEXT_BLOCK_QUOTES_ON_NEW_LINE, DefaultCodeFormatterConstants.FALSE);
2148+
JavaCore.setOptions(options);
2149+
}
2150+
2151+
@Test
2152+
public void testStringBufferToTextBlock() throws Exception {
2153+
//Testing new quick assist to place text block quotes on their own lines if option is enabled
2154+
fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin");
2155+
fJProject1.setRawClasspath(projectSetup.getDefaultClasspath(), null);
2156+
JavaProjectHelper.set15CompilerOptions(fJProject1, false);
2157+
fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
2158+
2159+
String str= """
2160+
module test {
2161+
}
2162+
""";
2163+
IPackageFragment def= fSourceFolder.createPackageFragment("", false, null);
2164+
def.createCompilationUnit("module-info.java", str, false, null);
2165+
2166+
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
2167+
2168+
Hashtable<String, String> options = TestOptions.getDefaultOptions();
2169+
options.put(DefaultCodeFormatterConstants.FORMATTER_PUT_TEXT_BLOCK_QUOTES_ON_NEW_LINE, DefaultCodeFormatterConstants.TRUE);
2170+
JavaCore.setOptions(options);
2171+
2172+
String example1 = """
2173+
package test1;
2174+
public class TestQuickAssistTextBlock {
2175+
2176+
String str1 ="asd\\nbsd\\nasm\\n\\t\\tcpp\\n";
2177+
2178+
public void foo1() {
2179+
System.out.println(str1);
2180+
}
2181+
2182+
public static void main(String[] args) {
2183+
TestQuickAssistTextBlock qatb = new TestQuickAssistTextBlock();
2184+
qatb.foo1();
2185+
}
2186+
}
2187+
""";
2188+
ICompilationUnit cu = pack1.createCompilationUnit("TestQuickAssistTextBlock.java", example1, false, null);
2189+
int offset= example1.indexOf("asd");
2190+
AssistContext context= getCorrectionContext(cu, offset, 10);
2191+
ArrayList<IJavaCompletionProposal> proposals= collectAssists(context, false);
2192+
assertCorrectLabels(proposals);
2193+
assertProposalExists(proposals, MultiFixMessages.StringToTextBlock_description);
2194+
String expected = """
2195+
package test1;
2196+
public class TestQuickAssistTextBlock {
2197+
2198+
String str1 =
2199+
\"\"\"
2200+
asd
2201+
bsd
2202+
asm
2203+
cpp
2204+
\"\"\";
2205+
2206+
public void foo1() {
2207+
System.out.println(str1);
2208+
}
2209+
2210+
public static void main(String[] args) {
2211+
TestQuickAssistTextBlock qatb = new TestQuickAssistTextBlock();
2212+
qatb.foo1();
2213+
}
2214+
}
2215+
""";
2216+
assertExpectedExistInProposals(proposals, new String[] { expected });
2217+
options.put(DefaultCodeFormatterConstants.FORMATTER_PUT_TEXT_BLOCK_QUOTES_ON_NEW_LINE, DefaultCodeFormatterConstants.FALSE);
2218+
JavaCore.setOptions(options);
2219+
}
20782220
}

0 commit comments

Comments
 (0)