You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2020/02/04 01:10:50 UTC

[groovy] 01/03: SC: check for getter/setter on implicit-this expression in closure

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

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

commit 8b76135a848c6a27e54a59287587e6a4208dd08e
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sun Feb 2 13:46:28 2020 -0600

    SC: check for getter/setter on implicit-this expression in closure
    
        @groovy.transform.CompileStatic
        void meth(Pogo pogo) {
          pogo.with {
            string += 'x' // LHS could be Pogo#setString(String)
          }
        }
    
    (cherry picked from commit 67509d9bb8ff8c18b07755fc58130e3082d7eedf)
---
 .../transform/stc/StaticTypeCheckingVisitor.java   |  2 +-
 .../asm/sc/ClosuresStaticCompileTest.groovy        | 35 +++++++++++++++++++++-
 2 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
index f72aaa2..86e49f5 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -1523,7 +1523,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
                 PropertyNode property = current.getProperty(propertyName);
                 property = allowStaticAccessToMember(property, staticOnly);
                 // prefer explicit getter or setter over property if receiver is not 'this'
-                if (property == null || !enclosingTypes.contains(objectExpressionType)) {
+                if (property == null || !enclosingTypes.contains(testClass)) {
                     if (readMode) {
                         if (getter != null) {
                             ClassNode returnType = inferReturnTypeGenerics(current, getter, ArgumentListExpression.EMPTY_ARGUMENTS);
diff --git a/src/test/org/codehaus/groovy/classgen/asm/sc/ClosuresStaticCompileTest.groovy b/src/test/org/codehaus/groovy/classgen/asm/sc/ClosuresStaticCompileTest.groovy
index e25d0fb..ce7a420 100644
--- a/src/test/org/codehaus/groovy/classgen/asm/sc/ClosuresStaticCompileTest.groovy
+++ b/src/test/org/codehaus/groovy/classgen/asm/sc/ClosuresStaticCompileTest.groovy
@@ -108,5 +108,38 @@ sample.doStuff('John', 'Doe') { String errors, String formattedFname, String for
         println "${formattedFname}.${formattedLname}"
 }'''
     }
-}
 
+    void testMethodVersusPropertyOnCompoundAssignmentTarget() {
+        assertScript '''
+            import org.codehaus.groovy.ast.expr.*
+            import org.codehaus.groovy.ast.stmt.*
+
+            class Pogo {
+                String string = ''
+                void setString(String string) {
+                    this.string = string
+                }
+            }
+
+            @ASTTest(phase=INSTRUCTION_SELECTION, value={
+                node = node.code.statements[0].expression
+                assert node instanceof MethodCallExpression
+
+                node = node.arguments.expressions[0].code.statements[0].expression
+                assert node instanceof BinaryExpression
+
+                assert node.leftExpression instanceof PropertyExpression
+                def target = node.leftExpression.getNodeMetaData(DIRECT_METHOD_CALL_TARGET)
+
+                assert target != null && target.name == 'setString'
+            })
+            void test(Pogo pogo) {
+                pogo.with {
+                    string += 'x'
+                }
+            }
+
+            test(new Pogo())
+        '''
+    }
+}