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 2018/01/31 12:40:51 UTC

[3/5] groovy git commit: MapConstructor should have an includeSuperFields annotation attribute plus some refactoring

MapConstructor should have an includeSuperFields annotation attribute plus some refactoring


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

Branch: refs/heads/GROOVY_2_6_X
Commit: 4be8c777537b8775eb82f840c9ae1e8d31f43f34
Parents: 3ad9a0e
Author: paulk <pa...@asert.com.au>
Authored: Sun Jan 28 17:00:13 2018 +1000
Committer: paulk <pa...@asert.com.au>
Committed: Wed Jan 31 22:40:31 2018 +1000

----------------------------------------------------------------------
 .../groovy/groovy/transform/MapConstructor.java |  5 ++
 .../java/org/codehaus/groovy/ast/FieldNode.java |  7 +++
 .../codehaus/groovy/ast/tools/GeneralUtils.java | 21 +++++---
 .../MapConstructorASTTransformation.java        | 54 +++++++++-----------
 .../TupleConstructorASTTransformation.java      |  4 +-
 5 files changed, 52 insertions(+), 39 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/4be8c777/src/main/groovy/groovy/transform/MapConstructor.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/transform/MapConstructor.java b/src/main/groovy/groovy/transform/MapConstructor.java
index ccd127a..55dee78 100644
--- a/src/main/groovy/groovy/transform/MapConstructor.java
+++ b/src/main/groovy/groovy/transform/MapConstructor.java
@@ -111,6 +111,11 @@ public @interface MapConstructor {
     boolean includeSuperProperties() default false;
 
     /**
+     * Include fields from super classes in the constructor.
+     */
+    boolean includeSuperFields() default false;
+
+    /**
      * Whether to include all properties (as per the JavaBean spec) in the generated constructor.
      * When true, Groovy treats any explicitly created setXxx() methods as property setters as per the JavaBean
      * specification.

http://git-wip-us.apache.org/repos/asf/groovy/blob/4be8c777/src/main/java/org/codehaus/groovy/ast/FieldNode.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/FieldNode.java b/src/main/java/org/codehaus/groovy/ast/FieldNode.java
index d38f4f4..33e15c3 100644
--- a/src/main/java/org/codehaus/groovy/ast/FieldNode.java
+++ b/src/main/java/org/codehaus/groovy/ast/FieldNode.java
@@ -143,6 +143,13 @@ public class FieldNode extends AnnotatedNode implements Opcodes, Variable, Groov
         return (modifiers & ACC_PROTECTED) != 0;
     }
 
+   /**
+     * @return true if the field is private
+     */
+    public boolean isPrivate() {
+        return (modifiers & ACC_PRIVATE) != 0;
+    }
+
     /**
      * @param owner The owner to set.
      */

http://git-wip-us.apache.org/repos/asf/groovy/blob/4be8c777/src/main/java/org/codehaus/groovy/ast/tools/GeneralUtils.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/tools/GeneralUtils.java b/src/main/java/org/codehaus/groovy/ast/tools/GeneralUtils.java
index 807ea7d..4c55515 100644
--- a/src/main/java/org/codehaus/groovy/ast/tools/GeneralUtils.java
+++ b/src/main/java/org/codehaus/groovy/ast/tools/GeneralUtils.java
@@ -466,16 +466,16 @@ public class GeneralUtils {
         return result;
     }
 
-    public static List<PropertyNode> getAllProperties(Set<String> names, ClassNode cNode, boolean includeProperties, boolean includeFields, boolean allProperties, boolean traverseSuperClasses) {
-        return getAllProperties(names, cNode, cNode, includeProperties, includeFields, allProperties, traverseSuperClasses);
+    public static List<PropertyNode> getAllProperties(Set<String> names, ClassNode cNode, boolean includeProperties, boolean includeFields, boolean allProperties, boolean traverseSuperClasses, boolean skipReadonly) {
+        return getAllProperties(names, cNode, cNode, includeProperties, includeFields, allProperties, traverseSuperClasses, skipReadonly);
     }
 
-    private static List<PropertyNode> getAllProperties(Set<String> names, ClassNode origType, ClassNode cNode, boolean includeProperties, boolean includeFields, boolean allProperties, boolean traverseSuperClasses) {
+    public static List<PropertyNode> getAllProperties(Set<String> names, ClassNode origType, ClassNode cNode, boolean includeProperties, boolean includeFields, boolean allProperties, boolean traverseSuperClasses, boolean skipReadonly) {
         final List<PropertyNode> result;
         if (cNode == ClassHelper.OBJECT_TYPE || !traverseSuperClasses) {
             result = new ArrayList<PropertyNode>();
         } else {
-            result = getAllProperties(names, origType, cNode.getSuperClass(), includeProperties, includeFields, allProperties, true);
+            result = getAllProperties(names, origType, cNode.getSuperClass(), includeProperties, includeFields, allProperties, true, skipReadonly);
         }
         if (includeProperties) {
             for (PropertyNode pNode : cNode.getProperties()) {
@@ -490,10 +490,17 @@ public class GeneralUtils {
         }
         if (includeFields) {
             for (FieldNode fNode : cNode.getFields()) {
-                if (!fNode.isStatic() && cNode.getProperty(fNode.getName()) == null && !names.contains(fNode.getName())) {
-                    result.add(new PropertyNode(fNode, fNode.getModifiers(), null, null));
-                    names.add(fNode.getName());
+                if (fNode.isStatic() || cNode.getProperty(fNode.getName()) != null || names.contains(fNode.getName())) {
+                    continue;
                 }
+                if (fNode.isPrivate() && !cNode.equals(origType)) {
+                    continue;
+                }
+                if (fNode.isFinal() && fNode.getInitialExpression() != null && skipReadonly) {
+                    continue;
+                }
+                result.add(new PropertyNode(fNode, fNode.getModifiers(), null, null));
+                names.add(fNode.getName());
             }
         }
         return result;

http://git-wip-us.apache.org/repos/asf/groovy/blob/4be8c777/src/main/java/org/codehaus/groovy/transform/MapConstructorASTTransformation.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/transform/MapConstructorASTTransformation.java b/src/main/java/org/codehaus/groovy/transform/MapConstructorASTTransformation.java
index b6407d3..fb2f94b 100644
--- a/src/main/java/org/codehaus/groovy/transform/MapConstructorASTTransformation.java
+++ b/src/main/java/org/codehaus/groovy/transform/MapConstructorASTTransformation.java
@@ -41,8 +41,10 @@ import org.codehaus.groovy.control.CompilePhase;
 import org.codehaus.groovy.control.SourceUnit;
 
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import static org.apache.groovy.ast.tools.ClassNodeUtils.hasNoArgConstructor;
 import static org.codehaus.groovy.ast.ClassHelper.make;
@@ -54,10 +56,8 @@ import static org.codehaus.groovy.ast.tools.GeneralUtils.callX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.constX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.copyStatementsWithSuperAdjustment;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.ctorX;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.getInstanceNonPropertyFields;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.getInstancePropertyFields;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.getAllProperties;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.getSetterName;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.getSuperPropertyFields;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.ifS;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.notNullX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.param;
@@ -76,9 +76,6 @@ public class MapConstructorASTTransformation extends AbstractASTTransformation {
     static final ClassNode MY_TYPE = make(MY_CLASS);
     static final String MY_TYPE_NAME = "@" + MY_TYPE.getNameWithoutPackage();
     private static final ClassNode MAP_TYPE = makeWithoutCaching(Map.class, false);
-//    private static final ClassNode IMMUTABLE_CLASS_TYPE = makeWithoutCaching(KnownImmutable.class, false);
-//    private static final ClassNode IMMUTABLE_BASE_TYPE = makeWithoutCaching(ImmutableBase.class, false);
-//    private static final ClassNode CHECK_METHOD_TYPE = make(ImmutableASTTransformation.class);
 
     public void visit(ASTNode[] nodes, SourceUnit source) {
         init(nodes, source);
@@ -92,6 +89,7 @@ public class MapConstructorASTTransformation extends AbstractASTTransformation {
             boolean includeFields = memberHasValue(anno, "includeFields", true);
             boolean includeProperties = !memberHasValue(anno, "includeProperties", false);
             boolean includeSuperProperties = memberHasValue(anno, "includeSuperProperties", true);
+            boolean includeSuperFields = memberHasValue(anno, "includeSuperFields", true);
             boolean useSetters = memberHasValue(anno, "useSetters", true);
             boolean allProperties = memberHasValue(anno, "allProperties", true);
             boolean noArg = memberHasValue(anno, "noArg", true);
@@ -116,7 +114,7 @@ public class MapConstructorASTTransformation extends AbstractASTTransformation {
                 return;
             }
 
-            createConstructors(this, cNode, includeFields, includeProperties, includeSuperProperties, useSetters, noArg, allNames, allProperties, makeImmutable, excludes, includes, (ClosureExpression) pre, (ClosureExpression) post, source);
+            createConstructors(this, cNode, includeFields, includeProperties, includeSuperProperties, includeSuperFields, useSetters, noArg, allNames, allProperties, makeImmutable, excludes, includes, (ClosureExpression) pre, (ClosureExpression) post, source);
 
             if (pre != null) {
                 anno.setMember("pre", new ClosureExpression(new Parameter[0], EmptyStatement.INSTANCE));
@@ -127,37 +125,33 @@ public class MapConstructorASTTransformation extends AbstractASTTransformation {
         }
     }
 
-    private static void createConstructors(AbstractASTTransformation xform, ClassNode cNode, boolean includeFields, boolean includeProperties, boolean includeSuperProperties, boolean useSetters, boolean noArg, boolean allNames, boolean allProperties, boolean makeImmutable, List<String> excludes, List<String> includes, ClosureExpression pre, ClosureExpression post, SourceUnit source) {
+    private static void createConstructors(AbstractASTTransformation xform, ClassNode cNode, boolean includeFields, boolean includeProperties, boolean includeSuperProperties, boolean includeSuperFields, boolean useSetters, boolean noArg, boolean allNames, boolean allProperties, boolean makeImmutable, List<String> excludes, List<String> includes, ClosureExpression pre, ClosureExpression post, SourceUnit source) {
         List<ConstructorNode> constructors = cNode.getDeclaredConstructors();
         boolean foundEmpty = constructors.size() == 1 && constructors.get(0).getFirstStatement() == null;
         // HACK: JavaStubGenerator could have snuck in a constructor we don't want
         if (foundEmpty) constructors.remove(0);
 
-        // TODO remove duplicated code from alternative paths below
+        Set<String> names = new HashSet<String>();
+        List<PropertyNode> superList;
+        if (includeSuperProperties || includeSuperFields) {
+            superList = getAllProperties(names, cNode, cNode.getSuperClass(), includeSuperProperties, includeSuperFields, allProperties, true, true);
+        } else {
+            superList = new ArrayList<PropertyNode>();
+        }
+        List<PropertyNode> list = getAllProperties(names, cNode, true, includeFields, allProperties, false, true);
+
         if (makeImmutable) {
-            List<PropertyNode> list = ImmutableASTTransformation.getProperties(cNode, includeSuperProperties, allProperties);
-            boolean specialHashMapCase = ImmutableASTTransformation.isSpecialHashMapCase(list);
+            boolean specialHashMapCase = (ImmutableASTTransformation.isSpecialHashMapCase(list) && superList.isEmpty()) ||
+                    (ImmutableASTTransformation.isSpecialHashMapCase(superList) && list.isEmpty());
+            superList.addAll(list);
             if (specialHashMapCase) {
-                ImmutableASTTransformation.createConstructorMapSpecial(cNode, list);
+                ImmutableASTTransformation.createConstructorMapSpecial(cNode, superList);
             } else {
-                ImmutableASTTransformation.createConstructorMap(xform, cNode, list);
+                ImmutableASTTransformation.createConstructorMap(xform, cNode, superList);
             }
             return;
         }
 
-        List<FieldNode> superList = new ArrayList<FieldNode>();
-        if (includeSuperProperties) {
-            superList.addAll(getSuperPropertyFields(cNode.getSuperClass()));
-        }
-
-        List<FieldNode> list = new ArrayList<FieldNode>();
-        if (includeProperties) {
-            list.addAll(getInstancePropertyFields(cNode));
-        }
-        if (includeFields) {
-            list.addAll(getInstanceNonPropertyFields(cNode));
-        }
-
         Parameter map = param(MAP_TYPE, "args");
         final BlockStatement body = new BlockStatement();
         ClassCodeExpressionTransformer transformer = makeMapTypedArgsTransformer();
@@ -166,13 +160,13 @@ public class MapConstructorASTTransformation extends AbstractASTTransformation {
             copyStatementsWithSuperAdjustment(transformed, body);
         }
         final BlockStatement inner = new BlockStatement();
-        for (FieldNode fNode : superList) {
-            String name = fNode.getName();
+        for (PropertyNode pNode : superList) {
+            String name = pNode.getName();
             if (shouldSkip(name, excludes, includes, allNames)) continue;
             assignField(useSetters, map, inner, name);
         }
-        for (FieldNode fNode : list) {
-            String name = fNode.getName();
+        for (PropertyNode pNode : list) {
+            String name = pNode.getName();
             if (shouldSkip(name, excludes, includes, allNames)) continue;
             assignField(useSetters, map, inner, name);
         }

http://git-wip-us.apache.org/repos/asf/groovy/blob/4be8c777/src/main/java/org/codehaus/groovy/transform/TupleConstructorASTTransformation.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/transform/TupleConstructorASTTransformation.java b/src/main/java/org/codehaus/groovy/transform/TupleConstructorASTTransformation.java
index 7cefac6..ec6a4c0 100644
--- a/src/main/java/org/codehaus/groovy/transform/TupleConstructorASTTransformation.java
+++ b/src/main/java/org/codehaus/groovy/transform/TupleConstructorASTTransformation.java
@@ -179,12 +179,12 @@ public class TupleConstructorASTTransformation extends AbstractASTTransformation
         Set<String> names = new HashSet<String>();
         List<PropertyNode> superList;
         if (includeSuperProperties || includeSuperFields) {
-            superList = getAllProperties(names, cNode.getSuperClass(), includeSuperProperties, includeSuperFields, allProperties, true);
+            superList = getAllProperties(names, cNode.getSuperClass(), includeSuperProperties, includeSuperFields, allProperties, true, true);
         } else {
             superList = new ArrayList<PropertyNode>();
         }
 
-        List<PropertyNode> list = getAllProperties(names, cNode, true, includeFields, allProperties, false);
+        List<PropertyNode> list = getAllProperties(names, cNode, true, includeFields, allProperties, false, true);
 
         if (makeImmutable) {
             boolean specialHashMapCase = (ImmutableASTTransformation.isSpecialHashMapCase(list) && superList.isEmpty()) ||