From 2c096166309352ba35cd82e20a7b168234ac354a Mon Sep 17 00:00:00 2001 From: Suby S Surendran Date: Mon, 12 Feb 2024 14:59:50 +0530 Subject: [PATCH] Added unit test for multi lines and its fixes --- .../ASTRewritingStringTemplateTest.java | 148 +++++++++++++++++- .../core/dom/rewrite/ASTRewriteAnalyzer.java | 87 +++++----- 2 files changed, 190 insertions(+), 45 deletions(-) diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingStringTemplateTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingStringTemplateTest.java index 8cfed97f35f..2a5e5f878c4 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingStringTemplateTest.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingStringTemplateTest.java @@ -35,7 +35,7 @@ public class ASTRewritingStringTemplateTest extends ASTRewritingTest { static { - TESTS_NAMES = new String[] {"test006"}; + TESTS_NAMES = new String[] {"test007_c"}; } public ASTRewritingStringTemplateTest(String name, int apiLevel) { @@ -83,6 +83,7 @@ public void test001() throws Exception { MethodDeclaration methodDecl= findMethodDeclaration(type, "foo"); Block block= methodDecl.getBody(); List blockStatements = block.statements(); + //add component to first fragment assertEquals("Incorrect number of statements", 1, blockStatements.size()); { VariableDeclarationFragment varFragment = ast.newVariableDeclarationFragment(); @@ -499,6 +500,7 @@ public void test005_b() throws Exception { assertEqualString(preview, buf.toString()); } + //SINGLE LINE to MULTI LINE with Component @SuppressWarnings({ "rawtypes", "deprecation" }) public void test006_a() throws Exception { if (this.apiLevel != 21) { @@ -548,6 +550,7 @@ public void test006_a() throws Exception { } @SuppressWarnings({ "rawtypes", "deprecation" }) + //SINGLE LINE to MULTI LINE without Component public void test006_b() throws Exception { if (this.apiLevel != 21) { System.err.println("Test "+getName()+" requires a JRE 21"); @@ -594,7 +597,76 @@ public void test006_b() throws Exception { assertEqualString(preview, buf.toString()); } + @SuppressWarnings({ "rawtypes", "deprecation" }) + //SINGLE LINE to MULTI LINE with Multiple Components + public void test006_c() throws Exception { + if (this.apiLevel != 21) { + System.err.println("Test "+getName()+" requires a JRE 21"); + return; + } + IPackageFragment pack1= this.sourceFolder.createPackageFragment("test1", false, null); + StringBuilder buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("public class X {\n"); + buf.append(" void foo(Object o) {\n"); + buf.append(" String name = \"Jay\";\n"); + buf.append(" String s = STR.\"Hello \\{name} \";\n"); + buf.append(" }\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("X.java", buf.toString(), false, null); + + CompilationUnit astRoot= createAST(cu); + ASTRewrite rewrite= ASTRewrite.create(astRoot.getAST()); + AST ast= astRoot.getAST(); + + assertTrue("Parse errors", (astRoot.getFlags() & ASTNode.MALFORMED) == 0); + TypeDeclaration type= findTypeDeclaration(astRoot, "X"); + MethodDeclaration methodDecl= findMethodDeclaration(type, "foo"); + Block block= methodDecl.getBody(); + List blockStatements = block.statements(); + assertEquals("Incorrect number of statements", 2, blockStatements.size()); + { + VariableDeclarationStatement varStmt = (VariableDeclarationStatement) blockStatements.get(1); + assertEquals("Incorrect number of fragents", 1, varStmt.fragments().size()); + VariableDeclarationFragment varFragment = (VariableDeclarationFragment) varStmt.fragments().get(0); + StringTemplateExpression templateExp = (StringTemplateExpression) varFragment.getInitializer(); + + StringTemplateComponent component = ast.newStringTemplateComponent(); + SimpleName name = ast.newSimpleName("os"); + StringFragment fragment = ast.newStringFragment(); + fragment.setEscapedValue(" is your OS. "); + component.setStringFragment(fragment); + component.setEmbeddedExpression(name); + + StringTemplateComponent component1 = ast.newStringTemplateComponent(); + SimpleName name1 = ast.newSimpleName("xyz"); + StringFragment fragment1 = ast.newStringFragment(); + fragment1.setEscapedValue(" is xyz."); + component1.setStringFragment(fragment1); + component1.setEmbeddedExpression(name1); + + rewrite.getListRewrite(templateExp, StringTemplateExpression.STRING_TEMPLATE_COMPONENTS).insertLast(component, null); + rewrite.getListRewrite(templateExp, StringTemplateExpression.STRING_TEMPLATE_COMPONENTS).insertLast(component1, null); + rewrite.set(templateExp, StringTemplateExpression.MULTI_LINE, Boolean.TRUE, null); + } + + String preview = evaluateRewrite(cu, rewrite); + + buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("public class X {\n"); + buf.append(" void foo(Object o) {\n"); + buf.append(" String name = \"Jay\";\n"); + buf.append(" String s = STR.\"\"\"\nHello \\{name} \\{os} is your OS. \\{xyz} is xyz.\n\"\"\";\n"); + buf.append(" }\n"); + buf.append("}\n"); + + assertEqualString(preview, buf.toString()); + } + + @SuppressWarnings({ "rawtypes", "deprecation" }) + //MULTI LINE to SINGLE LINE -> with Component public void test007_a() throws Exception { if (this.apiLevel != 21) { System.err.println("Test "+getName()+" requires a JRE 21"); @@ -606,7 +678,7 @@ public void test007_a() throws Exception { buf.append("public class X {\n"); buf.append(" void foo(Object o) {\n"); buf.append(" String name = \"Jay\";\n"); - buf.append(" String s = STR.\"\"\"\nHello \\{name}!\n\"\"\";\n"); + buf.append(" String s = STR.\"\"\"\nHello \\{name}\n\"\"\";\n"); buf.append(" }\n"); buf.append("}\n"); ICompilationUnit cu= pack1.createCompilationUnit("X.java", buf.toString(), false, null); @@ -635,14 +707,14 @@ public void test007_a() throws Exception { buf.append("public class X {\n"); buf.append(" void foo(Object o) {\n"); buf.append(" String name = \"Jay\";\n"); - buf.append(" String s = STR.\"Hello \\{name}!\";\n"); + buf.append(" String s = STR.\"Hello \\{name}\";\n"); buf.append(" }\n"); buf.append("}\n"); assertEqualString(preview, buf.toString()); } - @SuppressWarnings({ "rawtypes", "deprecation" }) + //MULTI LINE to SINGLE LINE -> without Component public void test007_b() throws Exception { if (this.apiLevel != 21) { System.err.println("Test "+getName()+" requires a JRE 21"); @@ -689,4 +761,72 @@ public void test007_b() throws Exception { assertEqualString(preview, buf.toString()); } + + @SuppressWarnings({ "rawtypes", "deprecation" }) + //MULTI LINE to SINGLE LINE -> with multiple Component + public void test007_c() throws Exception { + if (this.apiLevel != 21) { + System.err.println("Test "+getName()+" requires a JRE 21"); + return; + } + IPackageFragment pack1= this.sourceFolder.createPackageFragment("test1", false, null); + StringBuilder buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("public class X {\n"); + buf.append(" void foo(Object o) {\n"); + buf.append(" String name = \"Jay\";\n"); + //buf.append(" String s = STR.\"\"\"\n\"Hello \\{name} \n\"\"\"\";\n"); + buf.append(" String s = STR.\"\"\"\nHello \\{name} \n\"\"\";\n"); + buf.append(" }\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("X.java", buf.toString(), false, null); + + CompilationUnit astRoot= createAST(cu); + ASTRewrite rewrite= ASTRewrite.create(astRoot.getAST()); + AST ast= astRoot.getAST(); + + assertTrue("Parse errors", (astRoot.getFlags() & ASTNode.MALFORMED) == 0); + TypeDeclaration type= findTypeDeclaration(astRoot, "X"); + MethodDeclaration methodDecl= findMethodDeclaration(type, "foo"); + Block block= methodDecl.getBody(); + List blockStatements = block.statements(); + assertEquals("Incorrect number of statements", 2, blockStatements.size()); + { + VariableDeclarationStatement varStmt = (VariableDeclarationStatement) blockStatements.get(1); + assertEquals("Incorrect number of fragents", 1, varStmt.fragments().size()); + VariableDeclarationFragment varFragment = (VariableDeclarationFragment) varStmt.fragments().get(0); + StringTemplateExpression templateExp = (StringTemplateExpression) varFragment.getInitializer(); + + StringTemplateComponent component = ast.newStringTemplateComponent(); + SimpleName name = ast.newSimpleName("os"); + StringFragment fragment = ast.newStringFragment(); + fragment.setEscapedValue(" is your OS. "); + component.setStringFragment(fragment); + component.setEmbeddedExpression(name); + +// StringTemplateComponent component1 = ast.newStringTemplateComponent(); +// SimpleName name1 = ast.newSimpleName("xyz"); +// StringFragment fragment1 = ast.newStringFragment(); +// fragment1.setEscapedValue(" is xyz."); +// component1.setStringFragment(fragment1); +// component1.setEmbeddedExpression(name1); + + rewrite.getListRewrite(templateExp, StringTemplateExpression.STRING_TEMPLATE_COMPONENTS).insertLast(component, null); + //rewrite.getListRewrite(templateExp, StringTemplateExpression.STRING_TEMPLATE_COMPONENTS).insertLast(component1, null); + rewrite.set(templateExp, StringTemplateExpression.MULTI_LINE, Boolean.FALSE, null); + } + + String preview = evaluateRewrite(cu, rewrite); + + buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("public class X {\n"); + buf.append(" void foo(Object o) {\n"); + buf.append(" String name = \"Jay\";\n"); + buf.append(" String s = STR.\"Hello \\{name} \\{os} is your OS. \";\n"); + buf.append(" }\n"); + buf.append("}\n"); + + assertEqualString(preview, buf.toString()); + } } diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java index 7ee591680ac..ac320dbea68 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java @@ -604,12 +604,7 @@ private int rewriteList( int offset) { this.startPos= offset; this.list= getEvent(parent, property).getChildren(); - int total; - - if(this.list == null) - total = 0; - else - total= this.list.length; + int total= this.list.length; if (total == 0) { return this.startPos; @@ -670,8 +665,13 @@ private int rewriteList( if (separatorState == EXISTING) { updateIndent(prevMark, currPos, i, editGroup); } - - doTextInsert(currPos, node, getNodeIndent(i), true, editGroup); // insert node + doTextInsert( + (parent instanceof StringTemplateExpression && ((StringTemplateExpression) parent).isMultiline()) ? currPos-4 : currPos, + //currPos, + node, + getNodeIndent(i), + true, + editGroup); separatorState= NEW; if (i != lastNonDelete) { @@ -918,6 +918,42 @@ private int rewriteJavadoc(ASTNode node, StructuralPropertyDescriptor property) return pos; } + private void rewriteStringTemplateNode(StringTemplateExpression node, int pos) { + RewriteEvent event= getEvent(node, StringTemplateExpression.MULTI_LINE); + + if (event != null) { + switch (event.getChangeKind()) { + case RewriteEvent.REPLACED: { + boolean originalNode= ((Boolean) event.getOriginalValue()).booleanValue(); + boolean newValue= ((Boolean) event.getNewValue()).booleanValue(); + + int pos1 = rewriteRequiredNode(node, StringTemplateExpression.TEMPLATE_PROCESSOR); + int pos2 = rewriteRequiredNode(node, StringTemplateExpression.STRING_TEMPLATE_COMPONENTS); + + if(newValue && !originalNode) {// SINGLE LINE to MULTI LINE + if(pos2 == 0 ) { // without component + doTextReplace(pos1 +1, 1, "\"\"\"\n", getEditGroup(event)); //$NON-NLS-1$ + doTextReplace(pos -1, 1, "\n\"\"\"", getEditGroup(event)); //$NON-NLS-1$ + } else { // with Component + doTextReplace(pos1 +1, 1, "\"\"\"\n", getEditGroup(event)); //$NON-NLS-1$ + doTextReplace(pos2, 1, "\n\"\"\"", getEditGroup(event)); //$NON-NLS-1$ + } + + } else if(!newValue && originalNode) {// MULTI LINE to SINGLE LINE + if(pos2 == 0) { // without Component + doTextReplace(pos1 +1, 4, "\"", getEditGroup(event)); //$NON-NLS-1$ + doTextReplace(pos-4, 4, "\"", getEditGroup(event)); //$NON-NLS-1$ + } else { // with Component + doTextReplace(pos1 +1, 4, "\"", getEditGroup(event)); //$NON-NLS-1$ + doTextReplace(pos2-4, 4, "\"", getEditGroup(event)); //$NON-NLS-1$ + } + } + break; + } + } + } + } + /* * endpos can be -1 -> use the end pos of the body @@ -1430,8 +1466,7 @@ private int getPosAfterLeftBrace(int pos) { * Next token is a right parenthesis. Returns the offset after the parenthesis. For incomplete code, return the start offset. */ private int getPosAfterRightParenthesis(int pos) { - try { - return getPosAfterToken(pos, TerminalTokens.TokenNameRPAREN); + try { return getPosAfterToken(pos, TerminalTokens.TokenNameRPAREN); } catch (IllegalArgumentException e) { return pos; } @@ -1526,7 +1561,6 @@ final void doTextInsert(int insertOffset, ASTNode node, int initialIndentLevel, doTextInsert(insertOffset, insertStr, editGroup); } } - private boolean needsNewLineForLineComment(ASTNode node, String formatted, int offset) { if (!this.lineCommentEndOffsets.isEndOfLineComment(getExtendedEnd(node), this.content)) { return false; @@ -4684,38 +4718,8 @@ public boolean visit(StringTemplateExpression node) { if (!hasChildrenChanges(node)) { return doVisitUnchangedChildren(node); } - RewriteEvent event= getEvent(node, StringTemplateExpression.MULTI_LINE); - int pos1 = rewriteRequiredNode(node, StringTemplateExpression.TEMPLATE_PROCESSOR); int pos = rewriteRequiredNode(node, StringTemplateExpression.FIRST_STRING_FRAGMENT); - int pos2 = rewriteRequiredNode(node, StringTemplateExpression.STRING_TEMPLATE_COMPONENTS); - if (event != null) { - switch (event.getChangeKind()) { - case RewriteEvent.REPLACED: { - boolean originalNode= ((Boolean) event.getOriginalValue()).booleanValue(); - boolean newValue= ((Boolean) event.getNewValue()).booleanValue(); - if(newValue && !originalNode) {// SINGLE LINE to MULTI LINE - if(pos2 == 0 ) { // without component - doTextReplace(pos1 +1, 1, "\"\"\"\n", getEditGroup(event)); //$NON-NLS-1$ - doTextReplace(pos -1, 1, "\n\"\"\"", getEditGroup(event)); //$NON-NLS-1$ - } else { // with Component - doTextReplace(pos1 +1, 1, "\"\"\"\n", getEditGroup(event)); //$NON-NLS-1$ - doTextReplace(pos2, 1, "\n\"\"\"", getEditGroup(event)); //$NON-NLS-1$ - } - - } else if(!newValue && originalNode) {// MULTI LINE to SINGLE LINE - if(pos2 == 0) { // without Component - doTextReplace(pos1 +1, 4, "\"", getEditGroup(event)); //$NON-NLS-1$ - doTextReplace(pos-4, 4, "\"", getEditGroup(event)); //$NON-NLS-1$ - } else { // with Component - doTextReplace(pos1 +1, 4, "\"", getEditGroup(event)); //$NON-NLS-1$ - doTextReplace(pos2-4, 4, "\"", getEditGroup(event)); //$NON-NLS-1$ - } - } - break; - } - } - } if (node.getAST().isPreviewEnabled()) { rewriteNodeList( node, @@ -4725,6 +4729,7 @@ public boolean visit(StringTemplateExpression node) { "", //$NON-NLS-1$ "", //$NON-NLS-1$ ""); //$NON-NLS-1$ + rewriteStringTemplateNode(node, pos);//handles SINGLE LINE to MULTI LINE and vice versa } return false;