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/06/23 11:26:19 UTC

[groovy] 01/02: GROOVY-9554: Script: before adding to binding, check for property setter (closes #1280)

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

commit 8d52da3199e4e8b60bbf0b04e5bf09c5fe2823cf
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sun Jun 14 13:37:46 2020 -0500

    GROOVY-9554: Script: before adding to binding, check for property setter (closes #1280)
---
 src/main/java/groovy/lang/Script.java              | 27 ++++++++++++++++++----
 .../groovy/transform/FieldTransformTest.groovy     | 16 +++++++++++++
 2 files changed, 39 insertions(+), 4 deletions(-)

diff --git a/src/main/java/groovy/lang/Script.java b/src/main/java/groovy/lang/Script.java
index b9bda4b..de29c9b 100644
--- a/src/main/java/groovy/lang/Script.java
+++ b/src/main/java/groovy/lang/Script.java
@@ -18,6 +18,7 @@
  */
 package groovy.lang;
 
+import org.apache.groovy.util.BeanUtils;
 import org.codehaus.groovy.ast.expr.ArgumentListExpression;
 import org.codehaus.groovy.control.CompilationFailedException;
 import org.codehaus.groovy.runtime.DefaultGroovyMethods;
@@ -25,6 +26,7 @@ import org.codehaus.groovy.runtime.InvokerHelper;
 
 import java.io.File;
 import java.io.IOException;
+import java.lang.reflect.Method;
 
 /**
  * This object represents a Groovy script
@@ -57,12 +59,29 @@ public abstract class Script extends GroovyObjectSupport {
     }
 
     public void setProperty(String property, Object newValue) {
-        if ("binding".equals(property))
+        if ("binding".equals(property)) {
             setBinding((Binding) newValue);
-        else if("metaClass".equals(property))
-            setMetaClass((MetaClass)newValue);
-        else
+        } else if ("metaClass".equals(property)) {
+            setMetaClass((MetaClass) newValue);
+        } else if (!binding.hasVariable(property)
+                // GROOVY-9554: @Field adds setter
+                && hasSetterMethodFor(property)) {
+            super.setProperty(property, newValue);
+        } else {
             binding.setVariable(property, newValue);
+        }
+    }
+
+    private boolean hasSetterMethodFor(String property) {
+        String setterName = "set" + BeanUtils.capitalize(property);
+        for (Method method : getClass().getDeclaredMethods()) {
+            if (method.getParameterCount() == 1
+                    // TODO: Test modifiers or return type?
+                    && method.getName().equals(setterName)) {
+                return true;
+            }
+        }
+        return false;
     }
 
     /**
diff --git a/src/test/org/codehaus/groovy/transform/FieldTransformTest.groovy b/src/test/org/codehaus/groovy/transform/FieldTransformTest.groovy
index 469ca33..9146c6f 100644
--- a/src/test/org/codehaus/groovy/transform/FieldTransformTest.groovy
+++ b/src/test/org/codehaus/groovy/transform/FieldTransformTest.groovy
@@ -260,6 +260,22 @@ class FieldTransformTest extends CompilableTestSupport {
         '''
     }
 
+    void testClosureReferencesToField() {
+        // GROOVY-9554
+        assertScript '''
+            @groovy.transform.Field String abc
+            binding.variables.clear()
+            abc = 'abc'
+            assert !binding.hasVariable('abc')
+            ['D','E','F'].each {
+                abc += it
+            }
+            assert !binding.hasVariable('abc')
+            assert this.@abc == 'abcDEF'
+            assert abc == 'abcDEF'
+        '''
+    }
+
     void testFieldTransformWithFinalField() {
         // GROOVY-8430
         assertScript '''