You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2022/03/26 16:43:14 UTC

[groovy] branch GROOVY_4_0_X updated: GROOVY-10552: `@AutoImplement`: add `@Override` and set type parameters

This is an automated email from the ASF dual-hosted git repository.

emilles pushed a commit to branch GROOVY_4_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/GROOVY_4_0_X by this push:
     new 0ceb1f7  GROOVY-10552: `@AutoImplement`: add `@Override` and set type parameters
0ceb1f7 is described below

commit 0ceb1f73f41626c55bd3057c2dbe8ce7fe3db1a2
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sat Mar 26 11:15:47 2022 -0500

    GROOVY-10552: `@AutoImplement`: add `@Override` and set type parameters
---
 .../codehaus/groovy/ast/tools/GenericsUtils.java   | 18 ++++++++--------
 .../transform/AutoImplementASTTransformation.java  | 13 ++++++------
 .../transform/AutoImplementTransformTest.groovy    | 24 ++++++++++++++++++++++
 3 files changed, 40 insertions(+), 15 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java b/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java
index fd3cbc9..374204f 100644
--- a/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java
+++ b/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java
@@ -348,14 +348,16 @@ public class GenericsUtils {
     public static MethodNode correctToGenericsSpec(Map<String, ClassNode> genericsSpec, MethodNode mn) {
         if (genericsSpec == null) return mn;
         if (mn.getGenericsTypes() != null) genericsSpec = addMethodGenerics(mn, genericsSpec);
-        ClassNode correctedType = correctToGenericsSpecRecurse(genericsSpec, mn.getReturnType());
-        Parameter[] origParameters = mn.getParameters();
-        Parameter[] newParameters = new Parameter[origParameters.length];
-        for (int i = 0; i < origParameters.length; i++) {
-            Parameter origParameter = origParameters[i];
-            newParameters[i] = new Parameter(correctToGenericsSpecRecurse(genericsSpec, origParameter.getType()), origParameter.getName(), origParameter.getInitialExpression());
-        }
-        return new MethodNode(mn.getName(), mn.getModifiers(), correctedType, newParameters, mn.getExceptions(), mn.getCode());
+        ClassNode returnType = correctToGenericsSpecRecurse(genericsSpec, mn.getReturnType());
+        Parameter[] oldParameters = mn.getParameters(); int nParameters= oldParameters.length;
+        Parameter[] newParameters = new Parameter[nParameters];
+        for (int i = 0; i < nParameters; i += 1) {
+            Parameter oldParameter = oldParameters[i];
+            newParameters[i] = new Parameter(correctToGenericsSpecRecurse(genericsSpec, oldParameter.getType()), oldParameter.getName(), oldParameter.getInitialExpression());
+        }
+        MethodNode newMethod = new MethodNode(mn.getName(), mn.getModifiers(), returnType, newParameters, mn.getExceptions(), mn.getCode());
+        newMethod.setGenericsTypes(mn.getGenericsTypes());
+        return newMethod;
     }
 
     public static ClassNode correctToGenericsSpecRecurse(Map<String, ClassNode> genericsSpec, ClassNode type) {
diff --git a/src/main/java/org/codehaus/groovy/transform/AutoImplementASTTransformation.java b/src/main/java/org/codehaus/groovy/transform/AutoImplementASTTransformation.java
index 00db645..b870016 100644
--- a/src/main/java/org/codehaus/groovy/transform/AutoImplementASTTransformation.java
+++ b/src/main/java/org/codehaus/groovy/transform/AutoImplementASTTransformation.java
@@ -58,9 +58,6 @@ import static org.codehaus.groovy.ast.tools.GenericsUtils.correctToGenericsSpec;
 import static org.codehaus.groovy.ast.tools.GenericsUtils.correctToGenericsSpecRecurse;
 import static org.codehaus.groovy.ast.tools.GenericsUtils.createGenericsSpec;
 import static org.codehaus.groovy.ast.tools.ParameterUtils.parametersEqual;
-import static org.codehaus.groovy.ast.ClassHelper.isGroovyObjectType;
-import static org.codehaus.groovy.ast.ClassHelper.isObjectType;
-import static org.codehaus.groovy.ast.ClassHelper.isPrimitiveBoolean;
 
 /**
  * Generates code for the {@code @AutoImplement} annotation.
@@ -104,7 +101,7 @@ public class AutoImplementASTTransformation extends AbstractASTTransformation {
     private void createMethods(final ClassNode cNode, final ClassNode exception, final String message, final ClosureExpression code) {
         for (MethodNode candidate : getAllCorrectedMethodsMap(cNode).values()) {
             if (candidate.isAbstract()) {
-                addGeneratedMethod(cNode,
+                MethodNode mNode = addGeneratedMethod(cNode,
                         candidate.getName(),
                         candidate.getModifiers() & 0x7, // visibility only
                         candidate.getReturnType(),
@@ -112,6 +109,8 @@ public class AutoImplementASTTransformation extends AbstractASTTransformation {
                         candidate.getExceptions(),
                         createMethodBody(cNode, candidate, exception, message, code)
                 );
+                mNode.addAnnotation(ClassHelper.OVERRIDE_TYPE);
+                mNode.setGenericsTypes(candidate.getGenericsTypes()); // GROOVY-10552
             }
         }
     }
@@ -173,7 +172,7 @@ public class AutoImplementASTTransformation extends AbstractASTTransformation {
             while (!interfaces.isEmpty()) {
                 ClassNode origInterface = interfaces.remove(0);
                 // ignore java.lang.Object; also methods added by Verifier for GroovyObject are already good enough
-                if (!isObjectType(origInterface) && !isGroovyObjectType(origInterface)) {
+                if (!ClassHelper.isObjectType(origInterface) && !ClassHelper.isGroovyObjectType(origInterface)) {
                     updatedGenericsSpec = createGenericsSpec(origInterface, updatedGenericsSpec);
                     ClassNode correctedInterface = correctToGenericsSpecRecurse(updatedGenericsSpec, origInterface);
                     for (MethodNode nextMethod : correctedInterface.getMethods()) {
@@ -196,12 +195,12 @@ public class AutoImplementASTTransformation extends AbstractASTTransformation {
         }
 
         // GROOVY-9816: remove entries for to-be-generated property access and mutate methods
-        for (ClassNode cn = cNode; cn != null && !isObjectType(cn); cn = cn.getSuperClass()) {
+        for (ClassNode cn = cNode; cn != null && !ClassHelper.isObjectType(cn); cn = cn.getSuperClass()) {
             for (PropertyNode pn : cn.getProperties()) {
                 if (!pn.getField().isFinal()) {
                     result.remove(pn.getSetterNameOrDefault() + ":" + pn.getType().getText() + ",");
                 }
-                if (!isPrimitiveBoolean(pn.getType())) {
+                if (!ClassHelper.isPrimitiveBoolean(pn.getType())) {
                     result.remove(pn.getGetterNameOrDefault() + ":");
                 } else if (pn.getGetterName() != null) {
                     result.remove(pn.getGetterName() + ":");
diff --git a/src/test/org/codehaus/groovy/transform/AutoImplementTransformTest.groovy b/src/test/org/codehaus/groovy/transform/AutoImplementTransformTest.groovy
index 8de4040..536d881 100644
--- a/src/test/org/codehaus/groovy/transform/AutoImplementTransformTest.groovy
+++ b/src/test/org/codehaus/groovy/transform/AutoImplementTransformTest.groovy
@@ -299,4 +299,28 @@ final class AutoImplementTransformTest {
             assert !(new ThisClassFails().findAll())
         '''
     }
+
+    @Test // GROOVY-10552
+    void testMethodWithTypeParameter() {
+        assertScript shell, '''
+            interface I {
+                def <T> T m(List<T> list)
+            }
+
+            @AutoImplement
+            class C implements I {
+            }
+
+            Object result = new C().m([])
+            assert result == null
+        '''
+
+        assertScript shell, '''
+            @AutoImplement
+            class C implements java.sql.Connection {
+            }
+
+            new C().commit()
+        '''
+    }
 }