From 49b86be2e8bad455f7e9e84e05cbbaa318c8c565 Mon Sep 17 00:00:00 2001 From: Aman Sharma Date: Wed, 20 Jul 2022 10:27:13 +0530 Subject: [PATCH 1/5] Reproduce #4807 --- .../spoon/reflect/visitor/DefaultJavaPrettyPrinterTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/java/spoon/reflect/visitor/DefaultJavaPrettyPrinterTest.java b/src/test/java/spoon/reflect/visitor/DefaultJavaPrettyPrinterTest.java index e5b509b90c8..95d4c98375c 100644 --- a/src/test/java/spoon/reflect/visitor/DefaultJavaPrettyPrinterTest.java +++ b/src/test/java/spoon/reflect/visitor/DefaultJavaPrettyPrinterTest.java @@ -57,7 +57,8 @@ public void testParenOptimizationCorrectlyPrintsParenthesesForExpressions(String @ValueSource(strings = { "int sum = 1 + 2 + 3", "java.lang.String s = \"Sum: \" + (1 + 2)", - "java.lang.String s = \"Sum: \" + 1 + 2" + "java.lang.String s = \"Sum: \" + 1 + 2", + "java.lang.System.out.println(\"1\" + \"2\" + \"3\" + \"4\")" }) public void testParenOptimizationCorrectlyPrintsParenthesesForStatements(String rawStatement) { // contract: When input expressions as part of statements are minimally parenthesized, From 71ceeeff0b115239b86d538aeb52cc464b8e8e48 Mon Sep 17 00:00:00 2001 From: Aman Sharma Date: Wed, 20 Jul 2022 12:52:24 +0530 Subject: [PATCH 2/5] Switch order of binary operators for StringLiteralConcatenation --- src/main/java/spoon/support/compiler/jdt/ParentExiter.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/spoon/support/compiler/jdt/ParentExiter.java b/src/main/java/spoon/support/compiler/jdt/ParentExiter.java index a430d819495..d65d783f72d 100644 --- a/src/main/java/spoon/support/compiler/jdt/ParentExiter.java +++ b/src/main/java/spoon/support/compiler/jdt/ParentExiter.java @@ -445,10 +445,11 @@ public void visitCtBinaryOperator(CtBinaryOperator operator) { } else if (jdtTreeBuilder.getContextBuilder().stack.peek().node instanceof StringLiteralConcatenation) { CtBinaryOperator op = operator.getFactory().Core().createBinaryOperator(); op.setKind(BinaryOperatorKind.PLUS); - op.setLeftHandOperand(operator.getRightHandOperand()); - op.setRightHandOperand((CtExpression) child); + op.setLeftHandOperand(operator.getLeftHandOperand()); + op.setRightHandOperand(operator.getRightHandOperand()); op.setType((CtTypeReference) operator.getFactory().Type().STRING.clone()); - operator.setRightHandOperand(op); + operator.setLeftHandOperand(op); + operator.setRightHandOperand(((CtExpression) child)); int[] lineSeparatorPositions = jdtTreeBuilder.getContextBuilder().getCompilationUnitLineSeparatorPositions(); SourcePosition leftPosition = op.getLeftHandOperand().getPosition(); SourcePosition rightPosition = op.getRightHandOperand().getPosition(); From 986db4d7f0aa7745ccba6eba02d945b799180c24 Mon Sep 17 00:00:00 2001 From: Aman Sharma Date: Wed, 20 Jul 2022 13:21:08 +0530 Subject: [PATCH 3/5] Fix bracket printing in CommentTest::testInLineComment --- src/test/java/spoon/test/comment/CommentTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/java/spoon/test/comment/CommentTest.java b/src/test/java/spoon/test/comment/CommentTest.java index 946ebab0cc9..afb5e767084 100644 --- a/src/test/java/spoon/test/comment/CommentTest.java +++ b/src/test/java/spoon/test/comment/CommentTest.java @@ -465,9 +465,9 @@ public void testInLineComment() { CtLocalVariable ctLocalVariableString = m1.getBody().getStatement(12); - assertEquals(createFakeComment(f, "comment multi line string"), ((CtBinaryOperator) ((CtBinaryOperator) ctLocalVariableString.getDefaultExpression()).getRightHandOperand()).getLeftHandOperand().getComments().get(0)); - assertEquals("\"\" + (\"\"// comment multi line string" + newLine - + " + \"\")", ctLocalVariableString.getDefaultExpression().toString()); + assertEquals(createFakeComment(f, "comment multi line string"), (((CtBinaryOperator) ctLocalVariableString.getDefaultExpression()).getLeftHandOperand()).getComments().get(0)); + assertEquals("(\"\" + \"\")// comment multi line string" + newLine + + " + \"\"", ctLocalVariableString.getDefaultExpression().toString()); ctLocalVariable1 = m1.getBody().getStatement(13); assertEquals("boolean c = (i == 1) ? // comment before then boolean CtConditional" + newLine From 8d59817cf5be7cd0c3ce34dc480eb78c706ad2a2 Mon Sep 17 00:00:00 2001 From: Aman Sharma Date: Thu, 21 Jul 2022 12:24:24 +0530 Subject: [PATCH 4/5] Add test to verify patch at AST level --- .../spoon/reflect/ast/AstCheckerTest.java | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/test/java/spoon/reflect/ast/AstCheckerTest.java b/src/test/java/spoon/reflect/ast/AstCheckerTest.java index bc7e2f284bf..1e194102e43 100644 --- a/src/test/java/spoon/reflect/ast/AstCheckerTest.java +++ b/src/test/java/spoon/reflect/ast/AstCheckerTest.java @@ -22,13 +22,14 @@ import spoon.reflect.declaration.CtClass; import spoon.reflect.reference.CtExecutableReference; import spoon.support.modelobs.FineModelChangeListener; +import spoon.reflect.code.CtBinaryOperator; import spoon.reflect.code.CtBlock; +import spoon.reflect.code.CtExpression; import spoon.reflect.code.CtFieldRead; import spoon.reflect.code.CtIf; import spoon.reflect.code.CtInvocation; import spoon.reflect.code.CtReturn; import spoon.reflect.code.CtThrow; -import spoon.reflect.declaration.CtExecutable; import spoon.reflect.declaration.CtMethod; import spoon.reflect.declaration.ModifierKind; import spoon.reflect.factory.Factory; @@ -42,6 +43,7 @@ import spoon.support.util.internal.ElementNameMap; import spoon.support.util.ModelList; + import java.util.Arrays; import java.util.Collection; import java.util.List; @@ -50,10 +52,35 @@ import java.util.Set; import java.util.stream.Collectors; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.IsEqual.equalTo; import static org.junit.jupiter.api.Assertions.assertEquals; public class AstCheckerTest { + @Test + void leftOperandShouldBeGivenPriorityForStoringTheNestedOperator_stringLiteralConcatenation() { + // contract: string concatenation should be left associative. + // arrange + Launcher launcher = new Launcher(); + Factory factory = launcher.getFactory(); + CtClass classContainingStringLiteral = Launcher.parseClass("class A { private String x = \"a\" + \"b\" + \"c\" }"); + + // act + CtBinaryOperator binaryOperator = classContainingStringLiteral + .filterChildren(element -> element instanceof CtBinaryOperator) + .first(); + + // assert + CtExpression firstOperand = ((CtBinaryOperator)binaryOperator.getLeftHandOperand()).getLeftHandOperand(); + CtExpression secondOperand = ((CtBinaryOperator)binaryOperator.getLeftHandOperand()).getRightHandOperand(); + CtExpression thirdOperand = binaryOperator.getRightHandOperand(); + + assertThat(firstOperand, equalTo(factory.createLiteral("a"))); + assertThat(secondOperand, equalTo(factory.createLiteral("b"))); + assertThat(thirdOperand, equalTo(factory.createLiteral("c"))); + } + @Test public void testExecutableReference() { From 60d6e64a80e142568595410afc33f15cced097f2 Mon Sep 17 00:00:00 2001 From: Aman Sharma Date: Thu, 21 Jul 2022 12:25:42 +0530 Subject: [PATCH 5/5] Remove line break --- src/test/java/spoon/reflect/ast/AstCheckerTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/spoon/reflect/ast/AstCheckerTest.java b/src/test/java/spoon/reflect/ast/AstCheckerTest.java index 1e194102e43..c085dc15f2f 100644 --- a/src/test/java/spoon/reflect/ast/AstCheckerTest.java +++ b/src/test/java/spoon/reflect/ast/AstCheckerTest.java @@ -43,7 +43,6 @@ import spoon.support.util.internal.ElementNameMap; import spoon.support.util.ModelList; - import java.util.Arrays; import java.util.Collection; import java.util.List;