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 2023/01/18 00:02:42 UTC

[groovy] branch GROOVY_2_5_X updated (8971542375 -> 7f7a5010e7)

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

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


    from 8971542375 GROOVY-10902: stubgen: dynamic initializer to prevent constant inlining
     new 3986dfb39e GROOVY-9777: stubgen: add cast for Object parameter in special ctor call
     new 8cbb4e3736 GROOVY-7306: stubgen: apply type args of super to constructor parameters
     new 548490ef58 GROOVY-6282, GROOVY-10122: stubgen: type of factory in special ctor call
     new f9cf0421e1 GROOVY-5859, GROOVY-10407: stubgen: write param type arguments (not raw)
     new 7f7a5010e7 GROOVY-10464: stubgen: super ctor call: handle class cases

The 5 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../groovy/tools/javac/JavaStubGenerator.java      | 181 +++++++++++----------
 src/test/groovy/bugs/Groovy1759_Bug.groovy         |  13 +-
 src/test/groovy/bugs/Groovy596_Bug.groovy          |  27 ++-
 src/test/groovy/bugs/Groovy7620Bug.groovy          |  12 +-
 src/test/groovy/lang/MapOfClosureTest.groovy       |  36 ++--
 .../{Groovy7482.groovy => Groovy10122.groovy}      |  17 +-
 .../{Groovy7482.groovy => Groovy10122pt2.groovy}   |  23 ++-
 .../{Groovy10522.groovy => Groovy10407.groovy}     |  31 ++--
 .../{Groovy7482.groovy => Groovy10464.groovy}      |  25 ++-
 .../{Groovy7482.groovy => Groovy10464pt2.groovy}   |  21 ++-
 .../{Groovy10522.groovy => Groovy5859.groovy}      |  28 ++--
 .../tools/stubgenerator/Groovy5859Bug.groovy       |  41 -----
 .../{Groovy7482.groovy => Groovy7306.groovy}       |  31 ++--
 .../groovy/tools/stubgenerator/Groovy7482.groovy   |   5 +-
 .../{Groovy7482.groovy => Groovy9777.groovy}       |  33 ++--
 15 files changed, 247 insertions(+), 277 deletions(-)
 copy src/test/org/codehaus/groovy/tools/stubgenerator/{Groovy7482.groovy => Groovy10122.groovy} (78%)
 copy src/test/org/codehaus/groovy/tools/stubgenerator/{Groovy7482.groovy => Groovy10122pt2.groovy} (73%)
 copy src/test/org/codehaus/groovy/tools/stubgenerator/{Groovy10522.groovy => Groovy10407.groovy} (67%)
 copy src/test/org/codehaus/groovy/tools/stubgenerator/{Groovy7482.groovy => Groovy10464.groovy} (73%)
 copy src/test/org/codehaus/groovy/tools/stubgenerator/{Groovy7482.groovy => Groovy10464pt2.groovy} (74%)
 copy src/test/org/codehaus/groovy/tools/stubgenerator/{Groovy10522.groovy => Groovy5859.groovy} (68%)
 delete mode 100644 src/test/org/codehaus/groovy/tools/stubgenerator/Groovy5859Bug.groovy
 copy src/test/org/codehaus/groovy/tools/stubgenerator/{Groovy7482.groovy => Groovy7306.groovy} (62%)
 copy src/test/org/codehaus/groovy/tools/stubgenerator/{Groovy7482.groovy => Groovy9777.groovy} (60%)


[groovy] 02/05: GROOVY-7306: stubgen: apply type args of super to constructor parameters

Posted by em...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 8cbb4e3736038114c5904f2f9198c35169221ee9
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sun Mar 21 09:36:15 2021 -0500

    GROOVY-7306: stubgen: apply type args of super to constructor parameters
---
 .../groovy/tools/javac/JavaStubGenerator.java      | 37 ++++++++------
 .../groovy/tools/stubgenerator/Groovy7306.groovy   | 58 ++++++++++++++++++++++
 2 files changed, 80 insertions(+), 15 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java b/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java
index 9580265cfb..b8551e282e 100644
--- a/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java
+++ b/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java
@@ -523,25 +523,32 @@ public class JavaStubGenerator {
         }
     }
 
-    private static Parameter[] selectAccessibleConstructorFromSuper(ConstructorNode node) {
-        ClassNode type = node.getDeclaringClass();
-        ClassNode superType = type.getUnresolvedSuperClass();
+    private static Parameter[] selectAccessibleConstructorFromSuper(final ConstructorNode source) {
+        ClassNode superType = source.getDeclaringClass().getUnresolvedSuperClass();
+        Map<String, ClassNode> superTypeGenerics = createGenericsSpec(superType);
 
         Parameter[] bestMatch = null;
-        for (ConstructorNode c : superType.getDeclaredConstructors()) {
-            // Only look at things we can actually call
-            if (!c.isPublic() && !c.isProtected()) continue;
-            Parameter[] parameters = c.getParameters();
-            // workaround for GROOVY-5859: remove generic type info
-            Parameter[] copy = new Parameter[parameters.length];
-            for (int i = 0; i < copy.length; i++) {
-                Parameter orig = parameters[i];
-                copy[i] = new Parameter(orig.getOriginType().getPlainNodeReference(), orig.getName());
+        for (ConstructorNode target : superType.getDeclaredConstructors()) {
+            // only look at things we can actually call
+            // TODO: package-private and types are peers
+            if (!target.isPublic() && !target.isProtected()) continue;
+
+            Parameter[] parameters = target.getParameters();
+            Parameter[] normalized = new Parameter[parameters.length];
+            for (int i = 0, n = parameters.length; i < n; i += 1) {
+                ClassNode normalizedType = parameters[i].getOriginType();
+                // GROOVY-7306: apply type arguments from declaring type to parameter type
+                normalizedType = correctToGenericsSpec(superTypeGenerics, normalizedType);
+                // workaround for GROOVY-5859: remove generic type info
+                normalizedType = normalizedType.getPlainNodeReference();
+
+                normalized[i] = new Parameter(normalizedType, parameters[i].getName());
             }
-            if (noExceptionToAvoid(node,c)) return copy;
-            if (bestMatch==null) bestMatch = copy;
+
+            if (noExceptionToAvoid(source, target)) return normalized;
+            if (bestMatch == null) bestMatch = normalized;
         }
-        if (bestMatch!=null) return bestMatch;
+        if (bestMatch != null) return bestMatch;
 
         // fall back for parameterless constructor
         if (superType.isPrimaryClassNode()) {
diff --git a/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy7306.groovy b/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy7306.groovy
new file mode 100644
index 0000000000..fec232a30d
--- /dev/null
+++ b/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy7306.groovy
@@ -0,0 +1,58 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.codehaus.groovy.tools.stubgenerator
+
+final class Groovy7306 extends StringSourcesStubTestCase {
+
+    @Override
+    Map<String, String> provideSources() {
+        [
+            'A7306.groovy': '''
+                abstract class A7306<T extends Number> {
+                    final T value
+                    A7306(T value) {
+                        this.value = value
+                    }
+                }
+            ''',
+            'C7306.groovy': '''
+                class C7306 extends A7306<Integer> {
+                    C7306(Integer value) {
+                        super(value)
+                    }
+                }
+            ''',
+            'Main.java': '''
+                public class Main {
+                    public static void main(String[] args) {
+                        new C7306();
+                    }
+                }
+            ''',
+        ]
+    }
+
+    @Override
+    void verifyStubs() {
+        compile([new File(stubDir,'A7306.java'), new File(stubDir,'C7306.java')])
+
+        def specialCtorCall = (stubJavaSourceFor('C7306') =~ /super\s*\((.+?)\);/)
+        assert specialCtorCall.find() && specialCtorCall.group(1) == '(java.lang.Integer)null'
+    }
+}


[groovy] 05/05: GROOVY-10464: stubgen: super ctor call: handle class cases

Posted by em...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 7f7a5010e76df08d40b13ce6149700bb1757f7ba
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Thu Jan 27 11:10:21 2022 -0600

    GROOVY-10464: stubgen: super ctor call: handle class cases
---
 .../groovy/tools/javac/JavaStubGenerator.java      | 19 ++++++--
 .../tools/stubgenerator/Groovy10122pt2.groovy      | 54 ++++++++++++++++++++++
 .../groovy/tools/stubgenerator/Groovy10464.groovy  | 52 +++++++++++++++++++++
 .../tools/stubgenerator/Groovy10464pt2.groovy      | 54 ++++++++++++++++++++++
 4 files changed, 176 insertions(+), 3 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java b/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java
index 03d716af93..8a1a7d07b0 100644
--- a/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java
+++ b/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java
@@ -25,6 +25,7 @@ import org.codehaus.groovy.ast.AnnotationNode;
 import org.codehaus.groovy.ast.ClassHelper;
 import org.codehaus.groovy.ast.ClassNode;
 import org.codehaus.groovy.ast.ConstructorNode;
+import org.codehaus.groovy.ast.DynamicVariable;
 import org.codehaus.groovy.ast.FieldNode;
 import org.codehaus.groovy.ast.GenericsType;
 import org.codehaus.groovy.ast.ImportNode;
@@ -33,6 +34,7 @@ import org.codehaus.groovy.ast.MethodNode;
 import org.codehaus.groovy.ast.ModuleNode;
 import org.codehaus.groovy.ast.Parameter;
 import org.codehaus.groovy.ast.PropertyNode;
+import org.codehaus.groovy.ast.Variable;
 import org.codehaus.groovy.ast.decompiled.DecompiledClassNode;
 import org.codehaus.groovy.ast.expr.ArgumentListExpression;
 import org.codehaus.groovy.ast.expr.ClassExpression;
@@ -76,6 +78,7 @@ import java.util.Map;
 import java.util.Set;
 
 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;
 
 public class JavaStubGenerator {
@@ -177,7 +180,7 @@ public class JavaStubGenerator {
                         Map<String, ClassNode> generics = trait.isUsingGenerics() ? createGenericsSpec(trait) : null;
                         for (PropertyNode traitProperty : trait.getProperties()) {
                             ClassNode traitPropertyType = traitProperty.getType();
-                            traitProperty.setType(correctToGenericsSpec(generics, traitPropertyType));
+                            traitProperty.setType(correctToGenericsSpecRecurse(generics, traitPropertyType));
                             super.visitProperty(traitProperty);
                             traitProperty.setType(traitPropertyType);
                         }
@@ -538,7 +541,7 @@ public class JavaStubGenerator {
                     normalizedType = normalizedType.getPlainNodeReference();
                 } else {
                     // GROOVY-7306: apply type arguments from declaring type to parameter type
-                    normalizedType = correctToGenericsSpec(superTypeGenerics, normalizedType);
+                    normalizedType = correctToGenericsSpecRecurse(superTypeGenerics, normalizedType);
                 }
                 normalized[i] = new Parameter(normalizedType, parameters[i].getName());
             }
@@ -624,7 +627,17 @@ public class JavaStubGenerator {
 
     private static ClassNode getConstructorArgumentType(final Expression arg, final ConstructorNode ctor) {
         if (arg instanceof VariableExpression) {
-            return ((VariableExpression) arg).getAccessedVariable().getType();
+            Variable variable = ((VariableExpression) arg).getAccessedVariable();
+            if (variable instanceof DynamicVariable) { // GROOVY-10464
+                return ClassHelper.CLASS_Type.getPlainNodeReference();
+            }
+            return variable.getType(); // field, property, parameter
+        }
+        if (arg instanceof PropertyExpression) {
+            if ("class".equals(((PropertyExpression) arg).getPropertyAsString())) {
+                return ClassHelper.CLASS_Type.getPlainNodeReference();
+            }
+            return null;
         }
         if (arg instanceof MethodCallExpression) { // GROOVY-10122
             MethodCallExpression mce = (MethodCallExpression) arg;
diff --git a/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy10122pt2.groovy b/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy10122pt2.groovy
new file mode 100644
index 0000000000..cf7b24518a
--- /dev/null
+++ b/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy10122pt2.groovy
@@ -0,0 +1,54 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.codehaus.groovy.tools.stubgenerator
+
+final class Groovy10122pt2 extends StringSourcesStubTestCase {
+
+    @Override
+    Map<String, String> provideSources() {
+        [
+            'A.java': '''
+                public abstract class A<T> {
+                    A(T t) {
+                    }
+                }
+            ''',
+            'C.groovy': '''
+                class C<T> extends A<T> {
+                    C(T t) {
+                        super(t)
+                    }
+                }
+            ''',
+            'Main.java': '''
+                public class Main {
+                    public static void main(String[] args) {
+                        new C(null);
+                    }
+                }
+            ''',
+        ]
+    }
+
+    @Override
+    void verifyStubs() {
+        def specialCtorCall = (stubJavaSourceFor('C') =~ /super\s*\((.+?)\);/)
+        assert specialCtorCall.find() && specialCtorCall.group(1) == '(T)null'
+    }
+}
diff --git a/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy10464.groovy b/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy10464.groovy
new file mode 100644
index 0000000000..38760a8d05
--- /dev/null
+++ b/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy10464.groovy
@@ -0,0 +1,52 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.codehaus.groovy.tools.stubgenerator
+
+final class Groovy10464 extends StringSourcesStubTestCase {
+
+    @Override
+    Map<String, String> provideSources() {
+        [
+            'C.groovy': '''
+                public abstract class A<B> {
+                    A(Class<B> class_of_b) {
+                    }
+                }
+                class C extends A<String> {
+                    C() {
+                        super(String.class)
+                    }
+                }
+            ''',
+            'Main.java': '''
+                public class Main {
+                    public static void main(String[] args) {
+                        new C();
+                    }
+                }
+            ''',
+        ]
+    }
+
+    @Override
+    void verifyStubs() {
+        def specialCtorCall = (stubJavaSourceFor('C') =~ /super\s*\((.+?)\);/)
+        assert specialCtorCall.find() && specialCtorCall.group(1) == '(java.lang.Class<java.lang.String>)null'
+    }
+}
diff --git a/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy10464pt2.groovy b/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy10464pt2.groovy
new file mode 100644
index 0000000000..bef8ae462f
--- /dev/null
+++ b/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy10464pt2.groovy
@@ -0,0 +1,54 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.codehaus.groovy.tools.stubgenerator
+
+final class Groovy10464pt2 extends StringSourcesStubTestCase {
+
+    @Override
+    Map<String, String> provideSources() {
+        [
+            'A.java': '''
+                public abstract class A<B> {
+                    A(Class<B> class_of_b) {
+                    }
+                }
+            ''',
+            'C.groovy': '''
+                class C extends A<String> {
+                    C() {
+                        super(String)
+                    }
+                }
+            ''',
+            'Main.java': '''
+                public class Main {
+                    public static void main(String[] args) {
+                        new C();
+                    }
+                }
+            ''',
+        ]
+    }
+
+    @Override
+    void verifyStubs() {
+        def specialCtorCall = (stubJavaSourceFor('C') =~ /super\s*\((.+?)\);/)
+        assert specialCtorCall.find() && specialCtorCall.group(1) == '(java.lang.Class)null'
+    }
+}


[groovy] 01/05: GROOVY-9777: stubgen: add cast for Object parameter in special ctor call

Posted by em...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 3986dfb39e0b348cb3af91d5a265c03b361d9814
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Wed Jan 27 14:04:57 2021 -0600

    GROOVY-9777: stubgen: add cast for Object parameter in special ctor call
---
 .../groovy/tools/javac/JavaStubGenerator.java      | 16 +++---
 .../groovy/tools/stubgenerator/Groovy9777.groovy   | 60 ++++++++++++++++++++++
 2 files changed, 67 insertions(+), 9 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java b/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java
index eb10193ac7..9580265cfb 100644
--- a/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java
+++ b/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java
@@ -574,15 +574,15 @@ public class JavaStubGenerator {
 
     private void printSpecialConstructorArgs(PrintWriter out, ConstructorNode node, ConstructorCallExpression constrCall) {
         // Select a constructor from our class, or super-class which is legal to call,
-        // then write out an invoke w/nulls using casts to avoid ambiguous crapo
+        // then write out an invoke w/nulls using casts to avoid ambiguous calls
 
         Parameter[] params = selectAccessibleConstructorFromSuper(node);
         if (params != null) {
             out.print("super (");
 
-            for (int i = 0; i < params.length; i++) {
+            for (int i = 0, n = params.length; i < n; i += 1) {
                 printDefaultValue(out, params[i].getType());
-                if (i + 1 < params.length) {
+                if (i + 1 < n) {
                     out.print(", ");
                 }
             }
@@ -762,7 +762,7 @@ public class JavaStubGenerator {
     }
 
     private void printDefaultValue(final PrintWriter out, final ClassNode type) {
-        if (!type.equals(ClassHelper.OBJECT_TYPE) && !type.equals(ClassHelper.boolean_TYPE)) {
+        if (!type.equals(ClassHelper.boolean_TYPE)) {
             out.print("(");
             printType(out, type);
             out.print(")");
@@ -869,13 +869,11 @@ public class JavaStubGenerator {
 
     private void printAnnotation(PrintWriter out, AnnotationNode annotation) {
         out.print("@" + annotation.getClassNode().getName().replace('$', '.') + "(");
-        boolean first = true;
+        int i = 0;
         Map<String, Expression> members = annotation.getMembers();
         for (Map.Entry<String, Expression> entry : members.entrySet()) {
-            String key = entry.getKey();
-            if (first) first = false;
-            else out.print(", ");
-            out.print(key + "=" + getAnnotationValue(entry.getValue()));
+            if (i++ != 0) out.print(", ");
+            out.print(entry.getKey() + "=" + getAnnotationValue(entry.getValue()));
         }
         out.print(") ");
     }
diff --git a/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy9777.groovy b/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy9777.groovy
new file mode 100644
index 0000000000..d4fcd48e48
--- /dev/null
+++ b/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy9777.groovy
@@ -0,0 +1,60 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.codehaus.groovy.tools.stubgenerator
+
+final class Groovy9777 extends StringSourcesStubTestCase {
+
+    @Override
+    Map<String, String> provideSources() {
+        [
+            'A9777.groovy': '''
+                abstract class A9777 {
+                    A9777(Object o) {
+                        this(o.class.name)
+                    }
+                    A9777(Class  c) {
+                        this(c.name)
+                    }
+                    A9777(String s) {
+                    }
+                }
+            ''',
+            'C9777.groovy': '''
+                class C9777 extends A9777 {
+                    C9777() {
+                        super(C9777.class.name) // generates ambiguous "super (null);" in stub
+                    }
+                }
+            ''',
+            'Main.java': '''
+                public class Main {
+                    public static void main(String[] args) {
+                        new C9777();
+                    }
+                }
+            ''',
+        ]
+    }
+
+    @Override
+    void verifyStubs() {
+        def specialCtorCall = (stubJavaSourceFor('C9777') =~ /super\s*\((.+?)\);/)
+        assert specialCtorCall.find() && specialCtorCall.group(1) == '(java.lang.Object)null'
+    }
+}


[groovy] 03/05: GROOVY-6282, GROOVY-10122: stubgen: type of factory in special ctor call

Posted by em...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 548490ef5846e016532898d7da1af91adbb41f02
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Wed Jun 2 16:03:59 2021 -0500

    GROOVY-6282, GROOVY-10122: stubgen: type of factory in special ctor call
---
 .../groovy/tools/javac/JavaStubGenerator.java      | 112 ++++++++++-----------
 src/test/groovy/bugs/Groovy1759_Bug.groovy         |  13 ++-
 src/test/groovy/bugs/Groovy596_Bug.groovy          |  27 +++--
 src/test/groovy/bugs/Groovy7620Bug.groovy          |  12 +--
 src/test/groovy/lang/MapOfClosureTest.groovy       |  36 +++----
 .../{Groovy7482.groovy => Groovy10122.groovy}      |  17 ++--
 .../groovy/tools/stubgenerator/Groovy7482.groovy   |   5 +-
 7 files changed, 104 insertions(+), 118 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java b/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java
index b8551e282e..829e8fd63d 100644
--- a/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java
+++ b/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java
@@ -18,6 +18,7 @@
  */
 package org.codehaus.groovy.tools.javac;
 
+import org.apache.groovy.ast.tools.ExpressionUtils;
 import org.apache.groovy.io.StringBuilderWriter;
 import org.codehaus.groovy.ast.AnnotatedNode;
 import org.codehaus.groovy.ast.AnnotationNode;
@@ -40,6 +41,7 @@ import org.codehaus.groovy.ast.expr.ConstantExpression;
 import org.codehaus.groovy.ast.expr.ConstructorCallExpression;
 import org.codehaus.groovy.ast.expr.Expression;
 import org.codehaus.groovy.ast.expr.ListExpression;
+import org.codehaus.groovy.ast.expr.MethodCallExpression;
 import org.codehaus.groovy.ast.expr.PropertyExpression;
 import org.codehaus.groovy.ast.expr.VariableExpression;
 import org.codehaus.groovy.ast.stmt.BlockStatement;
@@ -390,16 +392,7 @@ public class JavaStubGenerator {
     }
 
     private static boolean sameParameterTypes(final Parameter[] firstParams, final Parameter[] secondParams) {
-        boolean sameParams = firstParams.length == secondParams.length;
-        if (sameParams) {
-            for (int i = 0; i < firstParams.length; i++) {
-                if (!firstParams[i].getType().equals(secondParams[i].getType())) {
-                    sameParams = false;
-                    break;
-                }
-            }
-        }
-        return sameParams;
+        return org.codehaus.groovy.ast.tools.ParameterUtils.parametersEqual(firstParams, secondParams);
     }
 
     private void printConstructors(final PrintWriter out, final ClassNode classNode) {
@@ -503,22 +496,24 @@ public class JavaStubGenerator {
 
     private void printConstructor(PrintWriter out, ClassNode clazz, ConstructorNode constructorNode) {
         printAnnotations(out, constructorNode);
-        // printModifiers(out, constructorNode.getModifiers());
-
         out.print("public "); // temporary hack
+        //printModifiers(out, constructorNode.getModifiers());
+
         String className = clazz.getNameWithoutPackage();
         if (clazz instanceof InnerClassNode)
-            className = className.substring(className.lastIndexOf("$") + 1);
+            className = className.substring(className.lastIndexOf('$') + 1);
         out.println(className);
 
         printParams(out, constructorNode);
 
-        ConstructorCallExpression constrCall = getConstructorCallExpression(constructorNode);
-        if (constrCall == null || !constrCall.isSpecialCall()) {
+        printExceptions(out, constructorNode.getExceptions());
+
+        ConstructorCallExpression ctorCall = getConstructorCallExpression(constructorNode);
+        if (ctorCall == null || !ctorCall.isSpecialCall()) {
             out.println(" {}");
         } else {
             out.println(" {");
-            printSpecialConstructorArgs(out, constructorNode, constrCall);
+            printSpecialConstructorArgs(out, constructorNode, ctorCall);
             out.println("}");
         }
     }
@@ -567,9 +562,9 @@ public class JavaStubGenerator {
 
 
         // if all remaining exceptions are used in the stub we are good
-        outer: for (int i=0; i<superExceptions.length; i++) {
-            ClassNode superExc = superExceptions[i];
-            for (ClassNode stub:stubExceptions) {
+        outer:
+        for (ClassNode superExc : superExceptions) {
+            for (ClassNode stub : stubExceptions) {
                 if (stub.isDerivedFrom(superExc)) continue outer;
             }
             // not found
@@ -579,73 +574,64 @@ public class JavaStubGenerator {
         return true;
     }
 
-    private void printSpecialConstructorArgs(PrintWriter out, ConstructorNode node, ConstructorCallExpression constrCall) {
+    private void printSpecialConstructorArgs(final PrintWriter out, final ConstructorNode ctor, final ConstructorCallExpression ctorCall) {
         // Select a constructor from our class, or super-class which is legal to call,
         // then write out an invoke w/nulls using casts to avoid ambiguous calls
-
-        Parameter[] params = selectAccessibleConstructorFromSuper(node);
+        Parameter[] params = selectAccessibleConstructorFromSuper(ctor);
         if (params != null) {
             out.print("super (");
-
             for (int i = 0, n = params.length; i < n; i += 1) {
                 printDefaultValue(out, params[i].getType());
                 if (i + 1 < n) {
                     out.print(", ");
                 }
             }
-
             out.println(");");
             return;
         }
 
         // Otherwise try the older method based on the constructor's call expression
-        Expression arguments = constrCall.getArguments();
-
-        if (constrCall.isSuperCall()) {
+        Expression arguments = ctorCall.getArguments();
+        if (ctorCall.isSuperCall()) {
             out.print("super(");
         } else {
             out.print("this(");
         }
-
-        // Else try to render some arguments
         if (arguments instanceof ArgumentListExpression) {
-            ArgumentListExpression argumentListExpression = (ArgumentListExpression) arguments;
-            List<Expression> args = argumentListExpression.getExpressions();
-
+            List<Expression> args = ((ArgumentListExpression) arguments).getExpressions();
+            int i = 0, n = args.size();
             for (Expression arg : args) {
                 if (arg instanceof ConstantExpression) {
-                    ConstantExpression expression = (ConstantExpression) arg;
-                    Object o = expression.getValue();
-
-                    if (o instanceof String) {
+                    Object value = ((ConstantExpression) arg).getValue();
+                    if (value instanceof String) {
                         out.print("(String)null");
                     } else {
-                        out.print(expression.getText());
+                        out.print(arg.getText());
                     }
                 } else {
-                    ClassNode type = getConstructorArgumentType(arg, node);
-                    printDefaultValue(out, type);
+                    printDefaultValue(out, getConstructorArgumentType(arg, ctor));
                 }
-
-                if (arg != args.get(args.size() - 1)) {
+                if (++i < n) {
                     out.print(", ");
                 }
             }
         }
-
         out.println(");");
     }
 
-    private static ClassNode getConstructorArgumentType(Expression arg, ConstructorNode node) {
-        if (!(arg instanceof VariableExpression)) return arg.getType();
-        VariableExpression vexp = (VariableExpression) arg;
-        String name = vexp.getName();
-        for (Parameter param : node.getParameters()) {
-            if (param.getName().equals(name)) {
-                return param.getType();
+    private static ClassNode getConstructorArgumentType(final Expression arg, final ConstructorNode ctor) {
+        if (arg instanceof VariableExpression) {
+            return ((VariableExpression) arg).getAccessedVariable().getType();
+        }
+        if (arg instanceof MethodCallExpression) { // GROOVY-10122
+            MethodCallExpression mce = (MethodCallExpression) arg;
+            if (ExpressionUtils.isThisExpression(mce.getObjectExpression())) {
+                MethodNode mn = ctor.getDeclaringClass().tryFindPossibleMethod(mce.getMethodAsString(), mce.getArguments());
+                if (mn != null) return mn.getReturnType();
             }
+            return null;
         }
-        return vexp.getType();
+        return arg.getType();
     }
 
     private void printMethod(PrintWriter out, ClassNode clazz, MethodNode methodNode) {
@@ -671,15 +657,7 @@ public class JavaStubGenerator {
         printParams(out, methodNode);
 
         ClassNode[] exceptions = methodNode.getExceptions();
-        for (int i = 0; i < exceptions.length; i++) {
-            ClassNode exception = exceptions[i];
-            if (i == 0) {
-                out.print("throws ");
-            } else {
-                out.print(", ");
-            }
-            printType(out, exception);
-        }
+        printExceptions(out, exceptions);
 
         if (Traits.isTrait(clazz)) {
             out.println(";");
@@ -716,6 +694,18 @@ public class JavaStubGenerator {
         }
     }
 
+    private void printExceptions(PrintWriter out, ClassNode[] exceptions) {
+        for (int i = 0; i < exceptions.length; i++) {
+            ClassNode exception = exceptions[i];
+            if (i == 0) {
+                out.print("throws ");
+            } else {
+                out.print(", ");
+            }
+            printType(out, exception);
+        }
+    }
+
     private static boolean isAbstract(final MethodNode methodNode) {
         if (isDefaultTraitImpl(methodNode)) {
             return false;
@@ -769,12 +759,12 @@ public class JavaStubGenerator {
     }
 
     private void printDefaultValue(final PrintWriter out, final ClassNode type) {
-        if (!type.equals(ClassHelper.boolean_TYPE)) {
+        if (type != null && !type.equals(ClassHelper.boolean_TYPE)) {
             out.print("(");
             printType(out, type);
             out.print(")");
         }
-        if (ClassHelper.isPrimitiveType(type)) {
+        if (type != null && ClassHelper.isPrimitiveType(type)) {
             if (type.equals(ClassHelper.boolean_TYPE)) {
                 out.print("false");
             } else {
diff --git a/src/test/groovy/bugs/Groovy1759_Bug.groovy b/src/test/groovy/bugs/Groovy1759_Bug.groovy
index 3b146b09f8..14726ff5d2 100644
--- a/src/test/groovy/bugs/Groovy1759_Bug.groovy
+++ b/src/test/groovy/bugs/Groovy1759_Bug.groovy
@@ -16,7 +16,10 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
+package groovy.bugs
+
 class Groovy1759_Bug extends GroovyTestCase {
+
    void testInterception() {
       def benchmarkInterceptor = new BenchmarkInterceptor()
       def proxy = ProxyMetaClass.getInstance(A.class)
@@ -26,14 +29,14 @@ class Groovy1759_Bug extends GroovyTestCase {
          a.a()
          a.b()
       }
-      
+
       def actual = benchmarkInterceptor.statistic().collect{ [ it[0], it[1] ] }
       def expected = [['ctor', 1],['a', 1],['b', 2]]
       assert expected == actual
    }
-}
 
-class A{
-   void a(){ b() }
-   void b(){}
+   static class A {
+       void a() { b() }
+       void b() {     }
+   }
 }
diff --git a/src/test/groovy/bugs/Groovy596_Bug.groovy b/src/test/groovy/bugs/Groovy596_Bug.groovy
index 434bb0ffde..477e29ceb9 100644
--- a/src/test/groovy/bugs/Groovy596_Bug.groovy
+++ b/src/test/groovy/bugs/Groovy596_Bug.groovy
@@ -23,7 +23,6 @@ import java.beans.*
 /**
  *  BeanInfo class usage
  */
-
 class Groovy596_Bug extends GroovyTestCase {
 
     void testMetaClassUsageOfBeanInfoDoesNotConflictWithScriptUsageLeadingToStackOverflow() {
@@ -32,25 +31,25 @@ class Groovy596_Bug extends GroovyTestCase {
         assertNotNull(new C());
         assertNotNull(new D());
     }
-}
 
-class A extends java.beans.SimpleBeanInfo {}
-class B extends A {}
-class C implements java.beans.BeanInfo {
-    public BeanDescriptor getBeanDescriptor() {return null;}
+    static class A extends java.beans.SimpleBeanInfo {}
+    static class B extends A {}
+    static class C implements java.beans.BeanInfo {
+        public BeanDescriptor getBeanDescriptor() {return null;}
 
-    public EventSetDescriptor[] getEventSetDescriptors() {return new EventSetDescriptor[0];}
+        public EventSetDescriptor[] getEventSetDescriptors() {return new EventSetDescriptor[0];}
 
-    public int getDefaultEventIndex() {return 0;}
+        public int getDefaultEventIndex() {return 0;}
 
-    public PropertyDescriptor[] getPropertyDescriptors() {return new PropertyDescriptor[0];}
+        public PropertyDescriptor[] getPropertyDescriptors() {return new PropertyDescriptor[0];}
 
-    public int getDefaultPropertyIndex() {return 0;}
+        public int getDefaultPropertyIndex() {return 0;}
 
-    public MethodDescriptor[] getMethodDescriptors() {return new MethodDescriptor[0];}
+        public MethodDescriptor[] getMethodDescriptors() {return new MethodDescriptor[0];}
 
-    public BeanInfo[] getAdditionalBeanInfo() {return new BeanInfo[0];}
+        public BeanInfo[] getAdditionalBeanInfo() {return new BeanInfo[0];}
 
-    public java.awt.Image getIcon(int iconKind) {return null;}
+        public java.awt.Image getIcon(int iconKind) {return null;}
+    }
+    static class D extends C {}
 }
-class D extends C {}
diff --git a/src/test/groovy/bugs/Groovy7620Bug.groovy b/src/test/groovy/bugs/Groovy7620Bug.groovy
index 44525ef877..ef092a8ad7 100644
--- a/src/test/groovy/bugs/Groovy7620Bug.groovy
+++ b/src/test/groovy/bugs/Groovy7620Bug.groovy
@@ -17,10 +17,10 @@
  * under the License.
  *
  */
-
 package groovy.bugs
 
 class Groovy7620Bug extends GroovyTestCase {
+
     void testShouldSeeThatMethodIsNotImplemented() {
         def msg = shouldFail '''
             abstract class A {
@@ -34,10 +34,7 @@ class Groovy7620Bug extends GroovyTestCase {
             class B extends A {
                static Object foo
             }
-
-            new B().test()
-            '''
-
+        '''
         assert msg.contains("The method 'java.lang.Object getFoo()' is already defined in class 'B'")
     }
 
@@ -50,10 +47,7 @@ class Groovy7620Bug extends GroovyTestCase {
             class D implements C {
                static Object foo
             }
-
-            new B().test()
-            '''
-
+        '''
         assert msg.contains("The method 'java.lang.Object getFoo()' is already defined in class 'D'")
     }
 }
diff --git a/src/test/groovy/lang/MapOfClosureTest.groovy b/src/test/groovy/lang/MapOfClosureTest.groovy
index 653bfcbce2..14b08dd955 100644
--- a/src/test/groovy/lang/MapOfClosureTest.groovy
+++ b/src/test/groovy/lang/MapOfClosureTest.groovy
@@ -89,28 +89,30 @@ class MapOfClosureTest extends GroovyTestCase {
 
         assert ["map foo"] as String[] == c.foo(1, ['a', 'b'], [0.2, 0.3] as Double[])
     }
-}
 
-abstract class A {
-    protected prot() { "prot" }
+    //--------------------------------------------------------------------------
 
-    def pub() { "pub" }
+    abstract static class A {
+        protected prot() { "prot" }
 
-    abstract abstractMethod()
-}
+        def pub() { "pub" }
 
-class B extends A {
-    protected child() { "child" }
+        abstract abstractMethod()
+    }
 
-    def abstractMethod() { "abstract" }
-}
+    static class B extends A {
+        protected child() { "child" }
 
-class C {
-    String[] foo(int a, List b, Double[] c) { ["foo"] as String[] }
-}
+        def abstractMethod() { "abstract" }
+    }
+
+    static class C {
+        String[] foo(int a, List b, Double[] c) { ["foo"] as String[] }
+    }
 
-interface MultiMethodInterface {
-    String methodOne()
+    interface MultiMethodInterface {
+        String methodOne()
 
-    String methodTwo()
-}
\ No newline at end of file
+        String methodTwo()
+    }
+}
diff --git a/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy7482.groovy b/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy10122.groovy
similarity index 78%
copy from src/test/org/codehaus/groovy/tools/stubgenerator/Groovy7482.groovy
copy to src/test/org/codehaus/groovy/tools/stubgenerator/Groovy10122.groovy
index 6bdf7a4afb..9c87fa3c05 100644
--- a/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy7482.groovy
+++ b/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy10122.groovy
@@ -18,38 +18,37 @@
  */
 package org.codehaus.groovy.tools.stubgenerator
 
-final class Groovy7482 extends StringSourcesStubTestCase {
+final class Groovy10122 extends StringSourcesStubTestCase {
 
     @Override
     Map<String, String> provideSources() {
         [
             'A.java': '''
                 public abstract class A {
-                    private Object getProperty(String name) {
-                        return null;
+                    A(Integer i) {
                     }
                 }
             ''',
-
             'C.groovy': '''
                 class C extends A {
+                    C() { super(m()) }
+                    static Integer m() { 42 }
                 }
             ''',
-
             'Main.java': '''
                 public class Main {
                     public static void main(String[] args) {
                         new C();
                     }
                 }
-            '''
+            ''',
         ]
     }
 
     @Override
     void verifyStubs() {
-        String stub = stubJavaSourceFor('C')
-        assert !stub.contains('getProperty')
-        assert !stub.contains('GroovyObject')
+        def stub = stubJavaSourceFor('C')
+        def specialCtorCall = (stub =~ /super\s*\((.*?)\);/)
+        assert specialCtorCall.find() && specialCtorCall.group(1) == '(java.lang.Integer)null'
     }
 }
diff --git a/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy7482.groovy b/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy7482.groovy
index 6bdf7a4afb..5e65f9aa8d 100644
--- a/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy7482.groovy
+++ b/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy7482.groovy
@@ -24,7 +24,7 @@ final class Groovy7482 extends StringSourcesStubTestCase {
     Map<String, String> provideSources() {
         [
             'A.java': '''
-                public abstract class A {
+                abstract class A {
                     private Object getProperty(String name) {
                         return null;
                     }
@@ -49,7 +49,6 @@ final class Groovy7482 extends StringSourcesStubTestCase {
     @Override
     void verifyStubs() {
         String stub = stubJavaSourceFor('C')
-        assert !stub.contains('getProperty')
-        assert !stub.contains('GroovyObject')
+      //assert !stub.contains('getProperty')
     }
 }


[groovy] 04/05: GROOVY-5859, GROOVY-10407: stubgen: write param type arguments (not raw)

Posted by em...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit f9cf0421e1da322a51f953901f2099424262055f
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sun Dec 12 12:30:03 2021 -0600

    GROOVY-5859, GROOVY-10407: stubgen: write param type arguments (not raw)
---
 .../groovy/tools/javac/JavaStubGenerator.java      | 13 +++++----
 .../{Groovy5859Bug.groovy => Groovy10407.groovy}   | 33 +++++++++++++---------
 .../{Groovy5859Bug.groovy => Groovy5859.groovy}    | 30 ++++++++++++--------
 3 files changed, 46 insertions(+), 30 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java b/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java
index 829e8fd63d..03d716af93 100644
--- a/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java
+++ b/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java
@@ -532,11 +532,14 @@ public class JavaStubGenerator {
             Parameter[] normalized = new Parameter[parameters.length];
             for (int i = 0, n = parameters.length; i < n; i += 1) {
                 ClassNode normalizedType = parameters[i].getOriginType();
-                // GROOVY-7306: apply type arguments from declaring type to parameter type
-                normalizedType = correctToGenericsSpec(superTypeGenerics, normalizedType);
-                // workaround for GROOVY-5859: remove generic type info
-                normalizedType = normalizedType.getPlainNodeReference();
-
+                if (superType.getGenericsTypes() == null // GROOVY-10407
+                        && superType.redirect().getGenericsTypes() != null) {
+                    // GROOVY-5859: remove generic type info for raw type
+                    normalizedType = normalizedType.getPlainNodeReference();
+                } else {
+                    // GROOVY-7306: apply type arguments from declaring type to parameter type
+                    normalizedType = correctToGenericsSpec(superTypeGenerics, normalizedType);
+                }
                 normalized[i] = new Parameter(normalizedType, parameters[i].getName());
             }
 
diff --git a/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy5859Bug.groovy b/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy10407.groovy
similarity index 60%
copy from src/test/org/codehaus/groovy/tools/stubgenerator/Groovy5859Bug.groovy
copy to src/test/org/codehaus/groovy/tools/stubgenerator/Groovy10407.groovy
index 9d493912fd..e7d32f4565 100644
--- a/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy5859Bug.groovy
+++ b/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy10407.groovy
@@ -18,24 +18,31 @@
  */
 package org.codehaus.groovy.tools.stubgenerator
 
-class Groovy5859Bug extends StringSourcesStubTestCase {
+final class Groovy10407 extends StringSourcesStubTestCase {
+
     @Override
     Map<String, String> provideSources() {
-        ['TaggedsMap.groovy': '''import org.codehaus.groovy.tools.stubgenerator.Groovy5859Support
-
-class TaggedsMap extends Groovy5859Support {
-
-    TaggedsMap(SortedMap m) {
-        super()
-        putAll (m)
-    }
-}''',
-        'Blah.java': '''public class Blah { TaggedsMap map; }''']
+        [
+            'Pogo.groovy': '''
+                class Foo {
+                    Foo(Map<String, String> map) {
+                    }
+                }
+                class Bar extends Foo {
+                    Bar(Map<String, String> map) {
+                        super(map)
+                    }
+                }
+            ''',
+            'Main.java': '''
+                public class Main { Foo foo; }
+            ''',
+        ]
     }
 
     @Override
     void verifyStubs() {
-        def stubSource = stubJavaSourceFor('TaggedsMap')
-        assert stubSource.contains('super ((java.util.SortedMap)null);')
+        String stub = stubJavaSourceFor('Bar')
+        assert stub.contains('super ((java.util.Map<java.lang.String, java.lang.String>)null);')
     }
 }
diff --git a/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy5859Bug.groovy b/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy5859.groovy
similarity index 61%
rename from src/test/org/codehaus/groovy/tools/stubgenerator/Groovy5859Bug.groovy
rename to src/test/org/codehaus/groovy/tools/stubgenerator/Groovy5859.groovy
index 9d493912fd..08d444e6a0 100644
--- a/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy5859Bug.groovy
+++ b/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy5859.groovy
@@ -18,24 +18,30 @@
  */
 package org.codehaus.groovy.tools.stubgenerator
 
-class Groovy5859Bug extends StringSourcesStubTestCase {
+final class Groovy5859 extends StringSourcesStubTestCase {
+
     @Override
     Map<String, String> provideSources() {
-        ['TaggedsMap.groovy': '''import org.codehaus.groovy.tools.stubgenerator.Groovy5859Support
-
-class TaggedsMap extends Groovy5859Support {
+        [
+            'Pogo.groovy': """
+                import ${this.class.name}Support
 
-    TaggedsMap(SortedMap m) {
-        super()
-        putAll (m)
-    }
-}''',
-        'Blah.java': '''public class Blah { TaggedsMap map; }''']
+                class Pogo extends ${this.class.simpleName}Support/*no type args*/ {
+                    Pogo(SortedMap map) {
+                        super(/*null*/)
+                        putAll(map)
+                    }
+                }
+            """,
+            'Main.java': '''
+                public class Main { Pogo pogo; }
+            '''
+        ]
     }
 
     @Override
     void verifyStubs() {
-        def stubSource = stubJavaSourceFor('TaggedsMap')
-        assert stubSource.contains('super ((java.util.SortedMap)null);')
+        String stub = stubJavaSourceFor('Pogo')
+        assert stub.contains('super ((java.util.SortedMap)null);')
     }
 }