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()) ||