You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2020/02/14 05:41:42 UTC

[groovy] branch master updated: GROOVY-8707: SC: use makeSetProperty for compound assignment of property (closes #1167)

This is an automated email from the ASF dual-hosted git repository.

paulk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/master by this push:
     new 77a11e8  GROOVY-8707: SC: use makeSetProperty for compound assignment of property (closes #1167)
77a11e8 is described below

commit 77a11e89b70b4e785fab36b9c3e93c11913288a2
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Thu Feb 13 13:58:54 2020 -0600

    GROOVY-8707: SC: use makeSetProperty for compound assignment of property (closes #1167)
    
    StaticTypesBinaryExpressionMultiTypeDispatcher#evaluateEqual does this
---
 ...icTypesBinaryExpressionMultiTypeDispatcher.java | 35 ++++++++++++++++++++++
 .../groovy/transform/stc/STCAssignmentTest.groovy  | 15 ++++++++++
 .../asm/sc/AssignmentsStaticCompileTest.groovy     | 11 +++++--
 3 files changed, 59 insertions(+), 2 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesBinaryExpressionMultiTypeDispatcher.java b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesBinaryExpressionMultiTypeDispatcher.java
index d97ba23..3d1661a 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesBinaryExpressionMultiTypeDispatcher.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesBinaryExpressionMultiTypeDispatcher.java
@@ -45,6 +45,8 @@ import org.codehaus.groovy.classgen.asm.CompileStack;
 import org.codehaus.groovy.classgen.asm.OperandStack;
 import org.codehaus.groovy.classgen.asm.VariableSlotLoader;
 import org.codehaus.groovy.classgen.asm.WriterController;
+import org.codehaus.groovy.syntax.Token;
+import org.codehaus.groovy.syntax.TokenUtil;
 import org.codehaus.groovy.transform.sc.StaticCompilationMetadataKeys;
 import org.codehaus.groovy.transform.sc.StaticCompilationVisitor;
 import org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport;
@@ -136,6 +138,39 @@ public class StaticTypesBinaryExpressionMultiTypeDispatcher extends BinaryExpres
     }
 
     @Override
+    protected void evaluateBinaryExpressionWithAssignment(final String method, final BinaryExpression expression) {
+        Expression leftExpression = expression.getLeftExpression();
+        if (leftExpression instanceof PropertyExpression) {
+            PropertyExpression pexp = (PropertyExpression) leftExpression;
+
+            BinaryExpression expressionWithoutAssignment = binX(
+                    leftExpression,
+                    Token.newSymbol(
+                            TokenUtil.removeAssignment(expression.getOperation().getType()),
+                            expression.getOperation().getStartLine(),
+                            expression.getOperation().getStartColumn()
+                    ),
+                    expression.getRightExpression()
+            );
+            expressionWithoutAssignment.copyNodeMetaData(expression);
+            expressionWithoutAssignment.setSafe(expression.isSafe());
+            expressionWithoutAssignment.setSourcePosition(expression);
+
+            if (makeSetProperty(
+                    pexp.getObjectExpression(),
+                    pexp.getProperty(),
+                    expressionWithoutAssignment,
+                    pexp.isSafe(),
+                    pexp.isSpreadSafe(),
+                    pexp.isImplicitThis(),
+                    pexp instanceof AttributeExpression)) {
+                return;
+            }
+        }
+        super.evaluateBinaryExpressionWithAssignment(method, expression);
+    }
+
+    @Override
     public void evaluateEqual(final BinaryExpression expression, final boolean defineVariable) {
         Expression leftExpression = expression.getLeftExpression();
         if (!defineVariable) {
diff --git a/src/test/groovy/transform/stc/STCAssignmentTest.groovy b/src/test/groovy/transform/stc/STCAssignmentTest.groovy
index cb688cc..ace7882 100644
--- a/src/test/groovy/transform/stc/STCAssignmentTest.groovy
+++ b/src/test/groovy/transform/stc/STCAssignmentTest.groovy
@@ -138,6 +138,21 @@ class STCAssignmentTest extends StaticTypeCheckingTestCase {
         '''
     }
 
+    void testPlusEqualsOnProperty() {
+        assertScript '''
+            class C {
+                int i
+
+                static main(args) {
+                    def c = new C()
+                    c.i = 5
+                    c.i += 10
+                    assert c.i == 15
+                }
+            }
+        '''
+    }
+
     // GROOVY-9385
     void testPlusEqualsOnPrivateField() {
         assertScript '''
diff --git a/src/test/org/codehaus/groovy/classgen/asm/sc/AssignmentsStaticCompileTest.groovy b/src/test/org/codehaus/groovy/classgen/asm/sc/AssignmentsStaticCompileTest.groovy
index 24b2f73..538589f 100644
--- a/src/test/org/codehaus/groovy/classgen/asm/sc/AssignmentsStaticCompileTest.groovy
+++ b/src/test/org/codehaus/groovy/classgen/asm/sc/AssignmentsStaticCompileTest.groovy
@@ -21,7 +21,14 @@ package org.codehaus.groovy.classgen.asm.sc
 import groovy.transform.stc.STCAssignmentTest
 
 /**
- * Unit tests for static type checking : assignments.
+ * Unit tests for static compilation : assignments.
  */
-class AssignmentsStaticCompileTest extends STCAssignmentTest implements StaticCompilationTestSupport {}
+final class AssignmentsStaticCompileTest extends STCAssignmentTest implements StaticCompilationTestSupport {
 
+    @Override // GROOVY-8707
+    void testPlusEqualsOnProperty() {
+        super.testPlusEqualsOnProperty()
+        String bytecode = astTrees['C'][1]
+        assert !bytecode.contains('ScriptBytecodeAdapter.setGroovyObjectProperty') : '"c.i += 10" should use setter, not dynamic property'
+    }
+}