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/23 01:39:35 UTC
[2/2] groovy git commit: GROOVY-8456: @MapConstructor could provide a
noArg flag
GROOVY-8456: @MapConstructor could provide a noArg flag
Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/aa7e37c2
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/aa7e37c2
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/aa7e37c2
Branch: refs/heads/GROOVY_2_6_X
Commit: aa7e37c246ac9dfcbfe9e961473b623bce1a952b
Parents: 6795309
Author: paulk <pa...@asert.com.au>
Authored: Tue Jan 23 11:32:41 2018 +1000
Committer: paulk <pa...@asert.com.au>
Committed: Tue Jan 23 11:39:18 2018 +1000
----------------------------------------------------------------------
.../groovy/groovy/transform/MapConstructor.java | 15 ++++++++++-----
.../apache/groovy/ast/tools/ClassNodeUtils.java | 11 +++++++++++
.../ExternalizeVerifierASTTransformation.java | 18 ++++--------------
.../MapConstructorASTTransformation.java | 17 +++++++++++++++--
4 files changed, 40 insertions(+), 21 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/groovy/blob/aa7e37c2/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 5608001..64cd1da 100644
--- a/src/main/groovy/groovy/transform/MapConstructor.java
+++ b/src/main/groovy/groovy/transform/MapConstructor.java
@@ -112,6 +112,16 @@ public @interface MapConstructor {
boolean useSetters() default false;
/**
+ * Whether to include all fields and/or properties within the constructor, including those with names that are considered internal.
+ */
+ boolean allNames() default false;
+
+ /**
+ * In addition to the map constructor, provide a no-arg constructor which calls the map constructor with an empty map.
+ */
+ boolean noArg() default false;
+
+ /**
* A Closure containing statements which will be prepended to the generated constructor. The first statement within the Closure may be "super(someArgs)" in which case the no-arg super constructor won't be called.
*/
Class pre() default Undefined.CLASS.class;
@@ -120,9 +130,4 @@ public @interface MapConstructor {
* A Closure containing statements which will be appended to the end of the generated constructor. Useful for validation steps or tweaking the populated fields/properties.
*/
Class post() default Undefined.CLASS.class;
-
- /**
- * Whether to include all fields and/or properties within the constructor, including those with names that are considered internal.
- */
- boolean allNames() default false;
}
http://git-wip-us.apache.org/repos/asf/groovy/blob/aa7e37c2/src/main/java/org/apache/groovy/ast/tools/ClassNodeUtils.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/groovy/ast/tools/ClassNodeUtils.java b/src/main/java/org/apache/groovy/ast/tools/ClassNodeUtils.java
index 98e0fe2..6d28afc 100644
--- a/src/main/java/org/apache/groovy/ast/tools/ClassNodeUtils.java
+++ b/src/main/java/org/apache/groovy/ast/tools/ClassNodeUtils.java
@@ -20,6 +20,7 @@ package org.apache.groovy.ast.tools;
import org.codehaus.groovy.ast.ClassHelper;
import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.ConstructorNode;
import org.codehaus.groovy.ast.MethodNode;
import org.codehaus.groovy.ast.Parameter;
import org.codehaus.groovy.ast.PropertyNode;
@@ -270,4 +271,14 @@ public class ClassNodeUtils {
}
private ClassNodeUtils() { }
+
+ public static boolean hasNoArgConstructor(ClassNode cNode) {
+ List<ConstructorNode> constructors = cNode.getDeclaredConstructors();
+ for (ConstructorNode next : constructors) {
+ if (next.getParameters().length == 0) {
+ return true;
+ }
+ }
+ return false;
+ }
}
http://git-wip-us.apache.org/repos/asf/groovy/blob/aa7e37c2/src/main/java/org/codehaus/groovy/transform/ExternalizeVerifierASTTransformation.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/transform/ExternalizeVerifierASTTransformation.java b/src/main/java/org/codehaus/groovy/transform/ExternalizeVerifierASTTransformation.java
index 23b8689..602d84a 100644
--- a/src/main/java/org/codehaus/groovy/transform/ExternalizeVerifierASTTransformation.java
+++ b/src/main/java/org/codehaus/groovy/transform/ExternalizeVerifierASTTransformation.java
@@ -23,7 +23,6 @@ import org.codehaus.groovy.ast.ASTNode;
import org.codehaus.groovy.ast.AnnotatedNode;
import org.codehaus.groovy.ast.AnnotationNode;
import org.codehaus.groovy.ast.ClassNode;
-import org.codehaus.groovy.ast.ConstructorNode;
import org.codehaus.groovy.ast.FieldNode;
import org.codehaus.groovy.control.CompilePhase;
import org.codehaus.groovy.control.SourceUnit;
@@ -32,13 +31,14 @@ import java.io.Externalizable;
import java.io.Serializable;
import java.util.List;
+import static org.apache.groovy.ast.tools.ClassNodeUtils.hasNoArgConstructor;
import static org.codehaus.groovy.ast.ClassHelper.isPrimitiveType;
import static org.codehaus.groovy.ast.ClassHelper.make;
import static org.codehaus.groovy.ast.tools.GeneralUtils.getInstanceNonPropertyFields;
import static org.codehaus.groovy.ast.tools.GeneralUtils.getInstancePropertyFields;
-@GroovyASTTransformation(phase = CompilePhase.CLASS_GENERATION)
-public class ExternalizeVerifierASTTransformation extends AbstractASTTransformation {
+@org.codehaus.groovy.transform.GroovyASTTransformation(phase = CompilePhase.CLASS_GENERATION)
+public class ExternalizeVerifierASTTransformation extends org.codehaus.groovy.transform.AbstractASTTransformation {
static final Class MY_CLASS = ExternalizeVerifier.class;
static final ClassNode MY_TYPE = make(MY_CLASS);
static final String MY_TYPE_NAME = "@" + MY_TYPE.getNameWithoutPackage();
@@ -53,7 +53,7 @@ public class ExternalizeVerifierASTTransformation extends AbstractASTTransformat
if (parent instanceof ClassNode) {
ClassNode cNode = (ClassNode) parent;
- if (!hasNoargConstructor(cNode)) {
+ if (!hasNoArgConstructor(cNode)) {
addError(MY_TYPE_NAME + ": An Externalizable class requires a no-arg constructor but none found", cNode);
}
if (!implementsExternalizable(cNode)) {
@@ -94,14 +94,4 @@ public class ExternalizeVerifierASTTransformation extends AbstractASTTransformat
return cNode.implementsInterface(SERIALIZABLE_TYPE);
}
- private static boolean hasNoargConstructor(ClassNode cNode) {
- List<ConstructorNode> constructors = cNode.getDeclaredConstructors();
- for (ConstructorNode next : constructors) {
- if (next.getParameters().length == 0) {
- return true;
- }
- }
- return false;
- }
-
}
http://git-wip-us.apache.org/repos/asf/groovy/blob/aa7e37c2/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 7c12237..77f31dc 100644
--- a/src/main/java/org/codehaus/groovy/transform/MapConstructorASTTransformation.java
+++ b/src/main/java/org/codehaus/groovy/transform/MapConstructorASTTransformation.java
@@ -31,9 +31,11 @@ import org.codehaus.groovy.ast.Parameter;
import org.codehaus.groovy.ast.expr.ArgumentListExpression;
import org.codehaus.groovy.ast.expr.ClosureExpression;
import org.codehaus.groovy.ast.expr.Expression;
+import org.codehaus.groovy.ast.expr.MapExpression;
import org.codehaus.groovy.ast.expr.VariableExpression;
import org.codehaus.groovy.ast.stmt.BlockStatement;
import org.codehaus.groovy.ast.stmt.EmptyStatement;
+import org.codehaus.groovy.ast.stmt.Statement;
import org.codehaus.groovy.control.CompilePhase;
import org.codehaus.groovy.control.SourceUnit;
@@ -41,6 +43,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
+import static org.apache.groovy.ast.tools.ClassNodeUtils.hasNoArgConstructor;
import static org.codehaus.groovy.ast.ClassHelper.make;
import static org.codehaus.groovy.ast.ClassHelper.makeWithoutCaching;
import static org.codehaus.groovy.ast.tools.GeneralUtils.args;
@@ -49,6 +52,7 @@ import static org.codehaus.groovy.ast.tools.GeneralUtils.callThisX;
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.getSetterName;
@@ -86,6 +90,7 @@ public class MapConstructorASTTransformation extends AbstractASTTransformation {
boolean includeProperties = !memberHasValue(anno, "includeProperties", false);
boolean includeSuperProperties = memberHasValue(anno, "includeSuperProperties", true);
boolean useSetters = memberHasValue(anno, "useSetters", true);
+ boolean noArg = memberHasValue(anno, "noArg", true);
List<String> excludes = getMemberStringList(anno, "excludes");
List<String> includes = getMemberStringList(anno, "includes");
boolean allNames = memberHasValue(anno, "allNames", true);
@@ -106,7 +111,7 @@ public class MapConstructorASTTransformation extends AbstractASTTransformation {
return;
}
- createConstructor(cNode, includeFields, includeProperties, includeSuperProperties, useSetters, excludes, includes, (ClosureExpression) pre, (ClosureExpression) post, source, allNames);
+ createConstructors(cNode, includeFields, includeProperties, includeSuperProperties, useSetters, noArg, allNames, excludes, includes, (ClosureExpression) pre, (ClosureExpression) post, source);
if (pre != null) {
anno.setMember("pre", new ClosureExpression(new Parameter[0], EmptyStatement.INSTANCE));
}
@@ -116,7 +121,7 @@ public class MapConstructorASTTransformation extends AbstractASTTransformation {
}
}
- public static void createConstructor(ClassNode cNode, boolean includeFields, boolean includeProperties, boolean includeSuperProperties, boolean useSetters, List<String> excludes, List<String> includes, ClosureExpression pre, ClosureExpression post, SourceUnit source, boolean allNames) {
+ public static void createConstructors(ClassNode cNode, boolean includeFields, boolean includeProperties, boolean includeSuperProperties, boolean useSetters, boolean noArg, boolean allNames, 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
@@ -159,6 +164,14 @@ public class MapConstructorASTTransformation extends AbstractASTTransformation {
body.addStatement(transformed.getCode());
}
cNode.addConstructor(new ConstructorNode(ACC_PUBLIC, params(map), ClassNode.EMPTY_ARRAY, body));
+ if (noArg && !(list.isEmpty() && superList.isEmpty()) && !hasNoArgConstructor(cNode)) {
+ createNoArgConstructor(cNode);
+ }
+ }
+
+ private static void createNoArgConstructor(ClassNode cNode) {
+ Statement body = stmt(ctorX(ClassNode.THIS, args(new MapExpression())));
+ cNode.addConstructor(new ConstructorNode(ACC_PUBLIC, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, body));
}
private static void assignField(boolean useSetters, Parameter map, BlockStatement body, String name) {