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 2016/08/06 01:35:53 UTC

[1/2] groovy git commit: GROOVY-6245: @EqualsAndHashCode assumes get style getters for boolean properties (port from master)

Repository: groovy
Updated Branches:
  refs/heads/GROOVY_2_4_X ac5ec9dbe -> 32fc63ee6


GROOVY-6245: @EqualsAndHashCode assumes get style getters for boolean properties (port from master)


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/8a861aaf
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/8a861aaf
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/8a861aaf

Branch: refs/heads/GROOVY_2_4_X
Commit: 8a861aaf9130a43b9d10b579f710edb5ca43a7b5
Parents: ac5ec9d
Author: paulk <pa...@asert.com.au>
Authored: Fri Aug 5 19:22:31 2016 +1000
Committer: paulk <pa...@asert.com.au>
Committed: Sat Aug 6 11:26:40 2016 +1000

----------------------------------------------------------------------
 .../codehaus/groovy/ast/tools/GeneralUtils.java | 49 +++++++++++++++-----
 .../EqualsAndHashCodeASTTransformation.java     |  2 +-
 .../transform/ToStringASTTransformation.java    |  2 +-
 3 files changed, 40 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/8a861aaf/src/main/org/codehaus/groovy/ast/tools/GeneralUtils.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/ast/tools/GeneralUtils.java b/src/main/org/codehaus/groovy/ast/tools/GeneralUtils.java
index 9f63d16..fc8f78a 100644
--- a/src/main/org/codehaus/groovy/ast/tools/GeneralUtils.java
+++ b/src/main/org/codehaus/groovy/ast/tools/GeneralUtils.java
@@ -70,11 +70,6 @@ import java.util.Set;
 
 /**
  * Handy methods when working with the Groovy AST
- *
- * @author Guillaume Laforge
- * @author Paul King
- * @author Andre Steingress
- * @author Graeme Rocher
  */
 public class GeneralUtils {
     public static final Token ASSIGN = Token.newSymbol(Types.ASSIGN, -1, -1);
@@ -481,8 +476,8 @@ public class GeneralUtils {
     }
 
     public static BooleanExpression hasSamePropertyX(PropertyNode pNode, Expression other) {
-        String getterName = getGetterName(pNode);
-        return sameX(callThisX(getterName), callX(other, getterName));
+        ClassNode cNode = pNode.getDeclaringClass();
+        return sameX(getterThisX(cNode, pNode), getterX(cNode, other, pNode));
     }
 
     public static Statement ifElseS(Expression cond, Statement thenStmt, Statement elseStmt) {
@@ -633,22 +628,54 @@ public class GeneralUtils {
     }
 
     /**
+     * @deprecated use getterThisX instead
+     */
+    @Deprecated
+    public static Expression getterX(ClassNode annotatedNode, PropertyNode pNode) {
+        ClassNode owner = pNode.getDeclaringClass();
+        if (annotatedNode.equals(owner)) {
+            String getterName = "get" + MetaClassHelper.capitalize(pNode.getName());
+            if (ClassHelper.boolean_TYPE.equals(pNode.getOriginType())) {
+                getterName = "is" + MetaClassHelper.capitalize(pNode.getName());
+            }
+            return callX(new VariableExpression("this"), getterName, ArgumentListExpression.EMPTY_ARGUMENTS);
+        }
+        return propX(new VariableExpression("this"), pNode.getName());
+    }
+
+    /**
      * This method is similar to {@link #propX(Expression, Expression)} but will make sure that if the property
      * being accessed is defined inside the classnode provided as a parameter, then a getter call is generated
      * instead of a field access.
+     *
      * @param annotatedNode the class node where the property node is accessed from
      * @param pNode the property being accessed
      * @return a method call expression or a property expression
      */
-    public static Expression getterX(ClassNode annotatedNode, PropertyNode pNode) {
+    public static Expression getterThisX(ClassNode annotatedNode, PropertyNode pNode) {
+        return getterX(annotatedNode, new VariableExpression("this"), pNode);
+    }
+
+    /**
+     * This method is similar to {@link #propX(Expression, Expression)} but will make sure that if the property
+     * being accessed is defined inside the classnode provided as a parameter, then a getter call is generated
+     * instead of a field access.
+     *
+     * @param annotatedNode the class node where the property node is accessed from
+     * @param receiver the object having the property
+     * @param pNode the property being accessed
+     * @return a method call expression or a property expression
+     */
+    public static Expression getterX(ClassNode annotatedNode, Expression receiver, PropertyNode pNode) {
         ClassNode owner = pNode.getDeclaringClass();
         if (annotatedNode.equals(owner)) {
             String getterName = "get" + MetaClassHelper.capitalize(pNode.getName());
-            if (ClassHelper.boolean_TYPE.equals(pNode.getOriginType())) {
+            boolean existingExplicitGetter = annotatedNode.getGetterMethod(getterName) != null;
+            if (ClassHelper.boolean_TYPE.equals(pNode.getOriginType()) && !existingExplicitGetter) {
                 getterName = "is" + MetaClassHelper.capitalize(pNode.getName());
             }
-            return callX(new VariableExpression("this"), getterName, ArgumentListExpression.EMPTY_ARGUMENTS);
+            return callX(receiver, getterName);
         }
-        return propX(new VariableExpression("this"), pNode.getName());
+        return propX(receiver, pNode.getName());
     }
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/8a861aaf/src/main/org/codehaus/groovy/transform/EqualsAndHashCodeASTTransformation.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/transform/EqualsAndHashCodeASTTransformation.java b/src/main/org/codehaus/groovy/transform/EqualsAndHashCodeASTTransformation.java
index a440b52..24eaf52 100644
--- a/src/main/org/codehaus/groovy/transform/EqualsAndHashCodeASTTransformation.java
+++ b/src/main/org/codehaus/groovy/transform/EqualsAndHashCodeASTTransformation.java
@@ -126,7 +126,7 @@ public class EqualsAndHashCodeASTTransformation extends AbstractASTTransformatio
         for (PropertyNode pNode : pList) {
             if (shouldSkip(pNode.getName(), excludes, includes)) continue;
             // _result = HashCodeHelper.updateHash(_result, getProperty()) // plus self-reference checking
-            Expression getter = getterX(cNode, pNode);
+            Expression getter = getterThisX(cNode, pNode);
             final Expression current = callX(HASHUTIL_TYPE, "updateHash", args(result, getter));
             body.addStatement(ifS(
                     notX(sameX(getter, varX("this"))),

http://git-wip-us.apache.org/repos/asf/groovy/blob/8a861aaf/src/main/org/codehaus/groovy/transform/ToStringASTTransformation.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/transform/ToStringASTTransformation.java b/src/main/org/codehaus/groovy/transform/ToStringASTTransformation.java
index 4ed3303..ff2484f 100644
--- a/src/main/org/codehaus/groovy/transform/ToStringASTTransformation.java
+++ b/src/main/org/codehaus/groovy/transform/ToStringASTTransformation.java
@@ -160,7 +160,7 @@ public class ToStringASTTransformation extends AbstractASTTransformation {
         }
         for (PropertyNode pNode : pList) {
             if (shouldSkip(pNode.getName(), excludes, includes)) continue;
-            Expression getter = getterX(cNode, pNode);
+            Expression getter = getterThisX(cNode, pNode);
 
             appendValue(body, result, first, getter, pNode.getName(), includeNames, ignoreNulls);
         }


[2/2] groovy git commit: GROOVY-5752: DelegateASTTransformation#addGetterIfNeeded doesn't take boolean isX accessors into account (port from master)

Posted by pa...@apache.org.
GROOVY-5752: DelegateASTTransformation#addGetterIfNeeded doesn't take boolean isX accessors into account (port from master)


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/32fc63ee
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/32fc63ee
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/32fc63ee

Branch: refs/heads/GROOVY_2_4_X
Commit: 32fc63ee66cd37e71fc95da36ded4eb14daf434a
Parents: 8a861aa
Author: paulk <pa...@asert.com.au>
Authored: Fri Aug 5 21:17:22 2016 +1000
Committer: paulk <pa...@asert.com.au>
Committed: Sat Aug 6 11:35:04 2016 +1000

----------------------------------------------------------------------
 .../transform/DelegateASTTransformation.java    | 34 ++++++++++++++------
 .../transform/DelegateTransformTest.groovy      | 34 +++++++++++++++++---
 2 files changed, 55 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/32fc63ee/src/main/org/codehaus/groovy/transform/DelegateASTTransformation.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/transform/DelegateASTTransformation.java b/src/main/org/codehaus/groovy/transform/DelegateASTTransformation.java
index d861002..6be955c 100644
--- a/src/main/org/codehaus/groovy/transform/DelegateASTTransformation.java
+++ b/src/main/org/codehaus/groovy/transform/DelegateASTTransformation.java
@@ -171,15 +171,31 @@ public class DelegateASTTransformation extends AbstractASTTransformation {
     }
 
     private void addGetterIfNeeded(FieldNode fieldNode, ClassNode owner, PropertyNode prop, String name, List<String> includes, List<String> excludes) {
-        String getterName = "get" + Verifier.capitalize(name);
-        if (owner.getGetterMethod(getterName) == null
-                && !shouldSkipPropertyMethod(name, getterName, excludes, includes)) {
-            owner.addMethod(getterName,
-                    ACC_PUBLIC,
-                    GenericsUtils.nonGeneric(prop.getType()),
-                    Parameter.EMPTY_ARRAY,
-                    null,
-                    returnS(propX(varX(fieldNode), name)));
+        boolean isPrimBool = prop.getOriginType().equals(ClassHelper.boolean_TYPE);
+        // do a little bit of pre-work since Groovy compiler hasn't added property accessors yet
+        boolean willHaveGetAccessor = true;
+        boolean willHaveIsAccessor = isPrimBool;
+        String suffix = Verifier.capitalize(name);
+        if (isPrimBool) {
+            ClassNode cNode = prop.getDeclaringClass();
+            if (cNode.getGetterMethod("is" + suffix) != null && cNode.getGetterMethod("get" + suffix) == null)
+                willHaveGetAccessor = false;
+            if (cNode.getGetterMethod("get" + suffix) != null && cNode.getGetterMethod("is" + suffix) == null)
+                willHaveIsAccessor = false;
+        }
+        for (String prefix : new String[]{"get", "is"}) {
+            String getterName = prefix + suffix;
+            if (owner.getGetterMethod(getterName) == null
+                    && !shouldSkipPropertyMethod(name, getterName, excludes, includes)) {
+                if (prefix.equals("get") && willHaveGetAccessor || prefix.equals("is") && willHaveIsAccessor) {
+                    owner.addMethod(getterName,
+                            ACC_PUBLIC,
+                            GenericsUtils.nonGeneric(prop.getType()),
+                            Parameter.EMPTY_ARRAY,
+                            null,
+                            returnS(propX(varX(fieldNode), name)));
+                }
+            }
         }
     }
     

http://git-wip-us.apache.org/repos/asf/groovy/blob/32fc63ee/src/test/org/codehaus/groovy/transform/DelegateTransformTest.groovy
----------------------------------------------------------------------
diff --git a/src/test/org/codehaus/groovy/transform/DelegateTransformTest.groovy b/src/test/org/codehaus/groovy/transform/DelegateTransformTest.groovy
index f025494..0d46418 100644
--- a/src/test/org/codehaus/groovy/transform/DelegateTransformTest.groovy
+++ b/src/test/org/codehaus/groovy/transform/DelegateTransformTest.groovy
@@ -21,10 +21,7 @@ package org.codehaus.groovy.transform
 import gls.CompilableTestSupport
 
 /**
- * @author Alex Tkachman
- * @author Guillaume Laforge
- * @author Paul King
- * @author Andre Steingress
+ * Tests for the @{code @Delegate} AST transform.
  */
 class DelegateTransformTest extends CompilableTestSupport {
 
@@ -694,6 +691,35 @@ assert foo.dm.x == '123'
             assert f.internalDelegate == ['bar', 'baz']
         '''
     }
+
+    // GROOVY-5752
+    void testDelegationShouldAccountForPrimitiveBooleanProperties() {
+        assertScript """
+            class A {
+                boolean a
+                boolean b
+                boolean isB() { b }
+                boolean c
+                boolean getC() { c }
+            }
+
+            class B {
+                @Delegate A a = new A(a: true, b: true, c: true)
+            }
+
+            def a = new A(a: true, b: true, c: true)
+            assert a.getA()
+            assert a.isA()
+            assert a.isB()
+            assert a.getC()
+
+            def b = new B()
+            assert b.getA()
+            assert b.isA()
+            assert b.isB()
+            assert b.getC()
+        """
+    }
 }
 
 interface DelegateFoo {