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 2019/05/12 10:53:34 UTC

[groovy] 02/02: GROOVY-9054: Missing @Generated annotation in @Builder (tests plus minor refactor)

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 c32cc5a012f524dad2c292579ba727fe10d9406b
Author: Paul King <pa...@asert.com.au>
AuthorDate: Sun May 12 20:51:34 2019 +1000

    GROOVY-9054: Missing @Generated annotation in @Builder (tests plus minor refactor)
---
 .../groovy/transform/builder/DefaultStrategy.java  | 14 ++++++------
 .../groovy/transform/builder/ExternalStrategy.java |  2 --
 .../transform/builder/InitializerStrategy.java     | 25 +++++++++++-----------
 .../groovy/transform/builder/SimpleStrategy.java   | 10 ++++-----
 .../groovy/transform/BuilderTransformTest.groovy   | 13 +++++++++++
 5 files changed, 36 insertions(+), 28 deletions(-)

diff --git a/src/main/groovy/groovy/transform/builder/DefaultStrategy.java b/src/main/groovy/groovy/transform/builder/DefaultStrategy.java
index f92be1e..fa64ba3 100644
--- a/src/main/groovy/groovy/transform/builder/DefaultStrategy.java
+++ b/src/main/groovy/groovy/transform/builder/DefaultStrategy.java
@@ -35,7 +35,7 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
-import static org.apache.groovy.ast.tools.AnnotatedNodeUtils.markAsGenerated;
+import static org.apache.groovy.ast.tools.ClassNodeUtils.addGeneratedInnerClass;
 import static org.apache.groovy.ast.tools.ClassNodeUtils.addGeneratedMethod;
 import static org.codehaus.groovy.ast.ClassHelper.OBJECT_TYPE;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.args;
@@ -184,13 +184,12 @@ public class DefaultStrategy extends BuilderASTTransformation.AbstractBuilderStr
         }
         ClassNode buildee = mNode.getDeclaringClass();
         ClassNode builder = createBuilder(anno, buildee);
-        markAsGenerated(buildee, builder);
         createBuilderFactoryMethod(anno, buildee, builder);
         for (Parameter parameter : mNode.getParameters()) {
             builder.addField(createFieldCopy(buildee, parameter));
-            builder.addMethod(createBuilderMethodForProp(builder, new PropertyInfo(parameter.getName(), parameter.getType()), getPrefix(anno)));
+            addGeneratedMethod(builder, createBuilderMethodForProp(builder, new PropertyInfo(parameter.getName(), parameter.getType()), getPrefix(anno)));
         }
-        addGeneratedMethod(buildee, createBuildMethodForMethod(anno, buildee, mNode, mNode.getParameters()));
+        addGeneratedMethod(builder, createBuildMethodForMethod(anno, buildee, mNode, mNode.getParameters()));
     }
 
     public void buildClass(BuilderASTTransformation transform, ClassNode buildee, AnnotationNode anno) {
@@ -200,7 +199,6 @@ public class DefaultStrategy extends BuilderASTTransformation.AbstractBuilderStr
         if (!getIncludeExclude(transform, anno, buildee, excludes, includes)) return;
         if (includes.size() == 1 && Undefined.isUndefined(includes.get(0))) includes = null;
         ClassNode builder = createBuilder(anno, buildee);
-        markAsGenerated(buildee, builder);
         createBuilderFactoryMethod(anno, buildee, builder);
 //        List<FieldNode> fields = getFields(transform, anno, buildee);
         boolean allNames = transform.memberHasValue(anno, "allNames", true);
@@ -216,13 +214,13 @@ public class DefaultStrategy extends BuilderASTTransformation.AbstractBuilderStr
     }
 
     private static ClassNode getCorrectedType(ClassNode buildee, ClassNode fieldType, ClassNode declaringClass) {
-        Map<String,ClassNode> genericsSpec = createGenericsSpec(declaringClass);
+        Map<String, ClassNode> genericsSpec = createGenericsSpec(declaringClass);
         extractSuperClassGenerics(fieldType, buildee, genericsSpec);
         return correctToGenericsSpecRecurse(genericsSpec, fieldType);
     }
 
     private static void createBuilderFactoryMethod(AnnotationNode anno, ClassNode buildee, ClassNode builder) {
-        buildee.getModule().addClass(builder);
+        addGeneratedInnerClass(buildee, builder);
         addGeneratedMethod(buildee, createBuilderMethod(anno, builder));
     }
 
@@ -278,7 +276,7 @@ public class DefaultStrategy extends BuilderASTTransformation.AbstractBuilderStr
     }
 
     private static FieldNode createFieldCopy(ClassNode buildee, Parameter param) {
-        Map<String,ClassNode> genericsSpec = createGenericsSpec(buildee);
+        Map<String, ClassNode> genericsSpec = createGenericsSpec(buildee);
         extractSuperClassGenerics(param.getType(), buildee, genericsSpec);
         ClassNode correctedParamType = correctToGenericsSpecRecurse(genericsSpec, param.getType());
         return new FieldNode(param.getName(), ACC_PRIVATE, correctedParamType, buildee, param.getInitialExpression());
diff --git a/src/main/groovy/groovy/transform/builder/ExternalStrategy.java b/src/main/groovy/groovy/transform/builder/ExternalStrategy.java
index 22e1953..bfcd174 100644
--- a/src/main/groovy/groovy/transform/builder/ExternalStrategy.java
+++ b/src/main/groovy/groovy/transform/builder/ExternalStrategy.java
@@ -31,7 +31,6 @@ import org.codehaus.groovy.transform.BuilderASTTransformation;
 import java.util.ArrayList;
 import java.util.List;
 
-import static org.apache.groovy.ast.tools.AnnotatedNodeUtils.markAsGenerated;
 import static org.apache.groovy.ast.tools.ClassNodeUtils.addGeneratedMethod;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.assignX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.block;
@@ -105,7 +104,6 @@ public class ExternalStrategy extends BuilderASTTransformation.AbstractBuilderSt
             transform.addError("Error during " + MY_TYPE_NAME + " processing: 'forClass' must be specified for " + getClass().getName(), anno);
             return;
         }
-        markAsGenerated(buildee, builder);
         List<String> excludes = new ArrayList<String>();
         List<String> includes = new ArrayList<String>();
         includes.add(Undefined.STRING);
diff --git a/src/main/groovy/groovy/transform/builder/InitializerStrategy.java b/src/main/groovy/groovy/transform/builder/InitializerStrategy.java
index 8c32051..b48d5af 100644
--- a/src/main/groovy/groovy/transform/builder/InitializerStrategy.java
+++ b/src/main/groovy/groovy/transform/builder/InitializerStrategy.java
@@ -41,7 +41,8 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
-import static org.apache.groovy.ast.tools.AnnotatedNodeUtils.markAsGenerated;
+import static org.apache.groovy.ast.tools.ClassNodeUtils.addGeneratedConstructor;
+import static org.apache.groovy.ast.tools.ClassNodeUtils.addGeneratedInnerClass;
 import static org.apache.groovy.ast.tools.ClassNodeUtils.addGeneratedMethod;
 import static org.codehaus.groovy.ast.ClassHelper.OBJECT_TYPE;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.args;
@@ -213,14 +214,14 @@ public class InitializerStrategy extends BuilderASTTransformation.AbstractBuilde
     private void buildCommon(ClassNode buildee, AnnotationNode anno, List<FieldNode> fieldNodes, ClassNode builder) {
         String prefix = getMemberStringValue(anno, "prefix", "");
         String buildMethodName = getMemberStringValue(anno, "buildMethodName", "create");
+        addGeneratedInnerClass(buildee, builder);
         createBuilderConstructors(builder, buildee, fieldNodes);
-        buildee.getModule().addClass(builder);
         String builderMethodName = getMemberStringValue(anno, "builderMethodName", "createInitializer");
-        buildee.addMethod(createBuilderMethod(buildMethodName, builder, fieldNodes.size(), builderMethodName));
+        addGeneratedMethod(buildee, createBuilderMethod(buildMethodName, builder, fieldNodes.size(), builderMethodName));
         for (int i = 0; i < fieldNodes.size(); i++) {
-            builder.addMethod(createBuilderMethodForField(builder, fieldNodes, prefix, i));
+            addGeneratedMethod(builder, createBuilderMethodForField(builder, fieldNodes, prefix, i));
         }
-        builder.addMethod(createBuildMethod(builder, buildMethodName, fieldNodes));
+        addGeneratedMethod(builder, createBuildMethod(builder, buildMethodName, fieldNodes));
     }
 
     private static List<FieldNode> convertParamsToFields(ClassNode builder, Parameter[] parameters) {
@@ -270,22 +271,20 @@ public class InitializerStrategy extends BuilderASTTransformation.AbstractBuilde
     }
 
     private static void createBuilderConstructors(ClassNode builder, ClassNode buildee, List<FieldNode> fields) {
-        builder.addConstructor(ACC_PRIVATE, NO_PARAMS, NO_EXCEPTIONS, block(ctorSuperS()));
+        addGeneratedConstructor(builder, ACC_PRIVATE, NO_PARAMS, NO_EXCEPTIONS, block(ctorSuperS()));
         final BlockStatement body = new BlockStatement();
         body.addStatement(ctorSuperS());
         initializeFields(fields, body, false);
-        builder.addConstructor(ACC_PRIVATE, getParams(fields, buildee), NO_EXCEPTIONS, body);
+        addGeneratedConstructor(builder, ACC_PRIVATE, getParams(fields, buildee), NO_EXCEPTIONS, body);
     }
 
     private static void createBuildeeConstructors(BuilderASTTransformation transform, ClassNode buildee, ClassNode builder, List<FieldNode> fields, boolean needsConstructor, boolean useSetters) {
-        ConstructorNode initializer = createInitializerConstructor(buildee, builder, fields);
-        markAsGenerated(buildee, initializer);
+        createInitializerConstructor(buildee, builder, fields);
         if (needsConstructor) {
             final BlockStatement body = new BlockStatement();
             body.addStatement(ctorSuperS());
             initializeFields(fields, body, useSetters);
-            ConstructorNode helperCons = buildee.addConstructor(ACC_PRIVATE | ACC_SYNTHETIC, getParams(fields, buildee), NO_EXCEPTIONS, body);
-            markAsGenerated(buildee, helperCons);
+            addGeneratedConstructor(buildee, ACC_PRIVATE | ACC_SYNTHETIC, getParams(fields, buildee), NO_EXCEPTIONS, body);
         }
     }
 
@@ -297,7 +296,7 @@ public class InitializerStrategy extends BuilderASTTransformation.AbstractBuilde
             argsList.add(propX(varX(initParam), fieldNode.getName()));
         }
         String newName = "$" + mNode.getName(); // can't have private and public methods of the same name, so rename original
-        buildee.addMethod(mNode.getName(), PUBLIC_STATIC, mNode.getReturnType(), params(param(paramType, "initializer")), NO_EXCEPTIONS,
+        addGeneratedMethod(buildee, mNode.getName(), PUBLIC_STATIC, mNode.getReturnType(), params(param(paramType, "initializer")), NO_EXCEPTIONS,
                 block(stmt(callX(buildee, newName, args(argsList)))));
         renameMethod(buildee, mNode, newName);
     }
@@ -327,7 +326,7 @@ public class InitializerStrategy extends BuilderASTTransformation.AbstractBuilde
         for (FieldNode fieldNode : fields) {
             argsList.add(propX(varX(initParam), fieldNode.getName()));
         }
-        return buildee.addConstructor(ACC_PUBLIC, params(param(paramType, "initializer")), NO_EXCEPTIONS, block(ctorThisS(args(argsList))));
+        return addGeneratedConstructor(buildee, ACC_PUBLIC, params(param(paramType, "initializer")), NO_EXCEPTIONS, block(ctorThisS(args(argsList))));
     }
 
     private static MethodNode createBuildMethod(ClassNode builder, String buildMethodName, List<FieldNode> fields) {
diff --git a/src/main/groovy/groovy/transform/builder/SimpleStrategy.java b/src/main/groovy/groovy/transform/builder/SimpleStrategy.java
index f1857fa..7abad5d 100644
--- a/src/main/groovy/groovy/transform/builder/SimpleStrategy.java
+++ b/src/main/groovy/groovy/transform/builder/SimpleStrategy.java
@@ -115,11 +115,11 @@ public class SimpleStrategy extends BuilderASTTransformation.AbstractBuilderStra
                 String methodName = getSetterName(prefix, fieldName);
                 Parameter parameter = param(field.getType(), fieldName);
                 addGeneratedMethod(buildee, methodName, Opcodes.ACC_PUBLIC, newClass(buildee), params(parameter), NO_EXCEPTIONS, block(
-                    stmt(useSetters && !field.isFinal()
-                        ? callThisX(getSetterName("set", fieldName), varX(parameter))
-                        : assignX(fieldX(field), varX(parameter))
-                    ),
-                    returnS(varX("this")))
+                        stmt(useSetters && !field.isFinal()
+                                ? callThisX(getSetterName("set", fieldName), varX(parameter))
+                                : assignX(fieldX(field), varX(parameter))
+                        ),
+                        returnS(varX("this")))
                 );
             }
         }
diff --git a/src/test/org/codehaus/groovy/transform/BuilderTransformTest.groovy b/src/test/org/codehaus/groovy/transform/BuilderTransformTest.groovy
index 9894752..0a707ec 100644
--- a/src/test/org/codehaus/groovy/transform/BuilderTransformTest.groovy
+++ b/src/test/org/codehaus/groovy/transform/BuilderTransformTest.groovy
@@ -39,6 +39,10 @@ class BuilderTransformTest extends CompilableTestSupport {
             assert person.firstName == "Robert"
             assert person.lastName == "Lewandowski"
             assert person.age == 21
+
+            def methods = Person.methods.findAll{ it.name.startsWith('set') && it.name.endsWith('e') }
+            assert methods*.name.toSet() == ['setLastName', 'setAge', 'setFirstName'] as Set
+            assert methods.every{ it.getAnnotation(groovy.transform.Generated) }
          """
     }
 
@@ -195,6 +199,9 @@ class BuilderTransformTest extends CompilableTestSupport {
             assert person.firstName == "Robert"
             assert person.lastName == "Lewandowski"
             assert person.age == 21
+
+            def methods = Person.builder().getClass().methods.findAll{ it.name in ['firstName', 'lastName', 'age'] }
+            assert methods.every{ it.getAnnotation(groovy.transform.Generated) }
         """
     }
 
@@ -354,6 +361,9 @@ class BuilderTransformTest extends CompilableTestSupport {
             def person = new PersonBuilder().firstName("Robert").lastName("Lewandowski").build()
             assert person.firstName == "Robert"
             assert person.lastName == "Lewandowski"
+
+            def methods = PersonBuilder.methods.findAll{ it.name in ['firstName', 'lastName', 'age'] }
+            assert methods.every{ it.getAnnotation(groovy.transform.Generated) }
         """
     }
 
@@ -511,6 +521,9 @@ class BuilderTransformTest extends CompilableTestSupport {
             firstLastAge()
             // dynamic case
             assert new Person(Person.createInitializer().firstName("John").lastName("Smith").age(21)).toString() == 'Person(John, Smith, 21)'
+
+            def methods = Person.createInitializer().getClass().methods.findAll{ it.name in ['firstName', 'lastName', 'age'] }
+            assert methods.every{ it.getAnnotation(groovy.transform.Generated) }
         '''
         def message = shouldNotCompile '''
             import groovy.transform.builder.*