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 2021/12/12 19:09:49 UTC

[groovy] branch master updated (ce24e8f -> b23f1e1)

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

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


    from ce24e8f  GROOVY-9391: Cannot cast or coerce `super`
     new 1494490  GROOVY-5859, GROOVY-10407: stubgen: write param type arguments (not raw)
     new b23f1e1  GROOVY-7300: drop dead code and refactor `StaticCompilationTransformer`

The 2 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/classgen/asm/InvocationWriter.java      |  2 +-
 .../classgen/asm/sc/StaticInvocationWriter.java    | 14 ----
 .../groovy/tools/javac/JavaStubGenerator.java      | 14 ++--
 .../PropertyExpressionTransformer.java             | 56 +++++++++++++
 .../transformers/StaticCompilationTransformer.java | 55 +++++--------
 .../VariableExpressionTransformer.java             | 92 +++++++++++++---------
 .../{Groovy10299.groovy => Groovy10407.groovy}     | 24 +++---
 .../{Groovy5859Bug.groovy => Groovy5859.groovy}    | 30 ++++---
 8 files changed, 170 insertions(+), 117 deletions(-)
 create mode 100644 src/main/java/org/codehaus/groovy/transform/sc/transformers/PropertyExpressionTransformer.java
 copy src/test/org/codehaus/groovy/tools/stubgenerator/{Groovy10299.groovy => Groovy10407.groovy} (70%)
 rename src/test/org/codehaus/groovy/tools/stubgenerator/{Groovy5859Bug.groovy => Groovy5859.groovy} (61%)

[groovy] 02/02: GROOVY-7300: drop dead code and refactor `StaticCompilationTransformer`

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

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

commit b23f1e1c822ae60e34cef25a6fbdd24b911a40a4
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sun Dec 12 13:09:38 2021 -0600

    GROOVY-7300: drop dead code and refactor `StaticCompilationTransformer`
---
 .../groovy/classgen/asm/InvocationWriter.java      |  2 +-
 .../classgen/asm/sc/StaticInvocationWriter.java    | 14 ----
 .../PropertyExpressionTransformer.java             | 56 +++++++++++++
 .../transformers/StaticCompilationTransformer.java | 55 +++++--------
 .../VariableExpressionTransformer.java             | 92 +++++++++++++---------
 5 files changed, 131 insertions(+), 88 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/InvocationWriter.java b/src/main/java/org/codehaus/groovy/classgen/asm/InvocationWriter.java
index 9181b6b..05e0007 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/InvocationWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/InvocationWriter.java
@@ -110,7 +110,7 @@ public class InvocationWriter {
 
     public void makeCall(final Expression origin, final Expression receiver, final Expression message, final Expression arguments, final MethodCallerMultiAdapter adapter, boolean safe, final boolean spreadSafe, boolean implicitThis) {
         ClassNode sender;
-        if (isSuperExpression(receiver) || isThisExpression(receiver) && !implicitThis) {
+        if (isSuperExpression(receiver) || (isThisExpression(receiver) && !implicitThis)) {
             // GROOVY-6045, GROOVY-8693, et al.
             sender = controller.getThisType();
             implicitThis = false;
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java
index 5c72843..6fee1be 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java
@@ -125,20 +125,6 @@ public class StaticInvocationWriter extends InvocationWriter {
     }
 
     @Override
-    protected boolean makeDirectCall(final Expression origin, final Expression receiver, final Expression message, final Expression arguments, final MethodCallerMultiAdapter adapter, final boolean implicitThis, final boolean containsSpreadExpression) {
-        if (origin instanceof MethodCallExpression && isSuperExpression(receiver)) {
-            MethodCallExpression mce = (MethodCallExpression) origin;
-            if (mce.getMethodTarget() == null && !controller.getCompileStack().isLHS()) { // GROOVY-7300
-                ClassNode owner = receiver.getNodeMetaData(StaticCompilationMetadataKeys.PROPERTY_OWNER);
-                if (owner != null) {
-                    mce.setMethodTarget(owner.getDeclaredMethod(mce.getMethodAsString(), Parameter.EMPTY_ARRAY));
-                }
-            }
-        }
-        return super.makeDirectCall(origin, receiver, message, arguments, adapter, implicitThis, containsSpreadExpression);
-    }
-
-    @Override
     public void writeInvokeMethod(final MethodCallExpression call) {
         MethodCallExpression old = currentCall;
         currentCall = call;
diff --git a/src/main/java/org/codehaus/groovy/transform/sc/transformers/PropertyExpressionTransformer.java b/src/main/java/org/codehaus/groovy/transform/sc/transformers/PropertyExpressionTransformer.java
new file mode 100644
index 0000000..bc3d3aa
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/transform/sc/transformers/PropertyExpressionTransformer.java
@@ -0,0 +1,56 @@
+/*
+ *  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.transform.sc.transformers;
+
+import org.codehaus.groovy.ast.MethodNode;
+import org.codehaus.groovy.ast.expr.Expression;
+import org.codehaus.groovy.ast.expr.MethodCallExpression;
+import org.codehaus.groovy.ast.expr.PropertyExpression;
+import org.codehaus.groovy.transform.stc.StaticTypesMarker;
+
+import static org.apache.groovy.ast.tools.ExpressionUtils.isThisOrSuper;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.callX;
+
+class PropertyExpressionTransformer {
+
+    private final StaticCompilationTransformer scTransformer;
+
+    PropertyExpressionTransformer(final StaticCompilationTransformer scTransformer) {
+        this.scTransformer = scTransformer;
+    }
+
+    Expression transformPropertyExpression(final PropertyExpression pe) {
+        if (isThisOrSuper(pe.getObjectExpression())) { // TODO: all obj exp
+            MethodNode dmct = pe.getNodeMetaData(StaticTypesMarker.DIRECT_METHOD_CALL_TARGET);
+            // NOTE: BinaryExpressionTransformer handles the setter
+            if (dmct != null && dmct.getParameters().length == 0) {
+                MethodCallExpression mce = callX(scTransformer.transform(pe.getObjectExpression()), dmct.getName());
+                mce.setImplicitThis(pe.isImplicitThis());
+                mce.setSpreadSafe(pe.isSpreadSafe());
+                mce.setMethodTarget(dmct);
+                mce.setSourcePosition(pe);
+                mce.copyNodeMetaData(pe);
+                mce.setSafe(pe.isSafe());
+                return mce;
+            }
+        }
+
+        return scTransformer.superTransform(pe);
+    }
+}
diff --git a/src/main/java/org/codehaus/groovy/transform/sc/transformers/StaticCompilationTransformer.java b/src/main/java/org/codehaus/groovy/transform/sc/transformers/StaticCompilationTransformer.java
index 0a8f8a7..1b8e6fc 100644
--- a/src/main/java/org/codehaus/groovy/transform/sc/transformers/StaticCompilationTransformer.java
+++ b/src/main/java/org/codehaus/groovy/transform/sc/transformers/StaticCompilationTransformer.java
@@ -42,13 +42,10 @@ import org.codehaus.groovy.control.SourceUnit;
 import org.codehaus.groovy.runtime.ScriptBytecodeAdapter;
 import org.codehaus.groovy.syntax.Types;
 import org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor;
-import org.codehaus.groovy.transform.stc.StaticTypesMarker;
 
 import java.util.Iterator;
 import java.util.Map;
 
-import static org.apache.groovy.ast.tools.ExpressionUtils.isSuperExpression;
-
 /**
  * Some expressions use symbols as aliases to method calls (&lt;&lt;, +=, ...). In static compilation,
  * if such a method call is found, we transform the original binary expression into a method
@@ -75,12 +72,13 @@ public class StaticCompilationTransformer extends ClassCodeExpressionTransformer
 
     // various helpers in order to avoid a potential very big class
     private final StaticMethodCallExpressionTransformer staticMethodCallExpressionTransformer = new StaticMethodCallExpressionTransformer(this);
-    private final ConstructorCallTransformer constructorCallTransformer = new ConstructorCallTransformer(this);
     private final MethodCallExpressionTransformer methodCallExpressionTransformer = new MethodCallExpressionTransformer(this);
-    private final BinaryExpressionTransformer binaryExpressionTransformer = new BinaryExpressionTransformer(this);
+    private final ConstructorCallTransformer constructorCallTransformer = new ConstructorCallTransformer(this);
+    private final PropertyExpressionTransformer propertyExpressionTransformer = new PropertyExpressionTransformer(this);
+    private final VariableExpressionTransformer variableExpressionTransformer = new VariableExpressionTransformer();
     private final ClosureExpressionTransformer closureExpressionTransformer = new ClosureExpressionTransformer(this);
     private final BooleanExpressionTransformer booleanExpressionTransformer = new BooleanExpressionTransformer(this);
-    private final VariableExpressionTransformer variableExpressionTransformer = new VariableExpressionTransformer();
+    private final BinaryExpressionTransformer binaryExpressionTransformer = new BinaryExpressionTransformer(this);
     private final RangeExpressionTransformer rangeExpressionTransformer = new RangeExpressionTransformer(this);
     private final ListExpressionTransformer listExpressionTransformer = new ListExpressionTransformer(this);
     private final CastExpressionOptimizer castExpressionTransformer = new CastExpressionOptimizer(this);
@@ -110,53 +108,38 @@ public class StaticCompilationTransformer extends ClassCodeExpressionTransformer
 
     @Override
     public Expression transform(final Expression expr) {
-        if (expr instanceof BinaryExpression) {
-            return binaryExpressionTransformer.transformBinaryExpression((BinaryExpression) expr);
+        if (expr instanceof StaticMethodCallExpression) {
+            return staticMethodCallExpressionTransformer.transformStaticMethodCallExpression((StaticMethodCallExpression) expr);
         }
-        if (expr instanceof ClosureExpression) {
-            return closureExpressionTransformer.transformClosureExpression((ClosureExpression) expr);
+        if (expr instanceof MethodCallExpression) {
+            return methodCallExpressionTransformer.transformMethodCallExpression((MethodCallExpression) expr);
         }
         if (expr instanceof ConstructorCallExpression) {
             return constructorCallTransformer.transformConstructorCall((ConstructorCallExpression) expr);
         }
-        if (expr instanceof MethodCallExpression) {
-            return methodCallExpressionTransformer.transformMethodCallExpression((MethodCallExpression) expr);
+        if (expr instanceof PropertyExpression) {
+            return propertyExpressionTransformer.transformPropertyExpression((PropertyExpression) expr);
         }
-        if (expr instanceof StaticMethodCallExpression) {
-            return staticMethodCallExpressionTransformer.transformStaticMethodCallExpression((StaticMethodCallExpression) expr);
+        if (expr instanceof VariableExpression) {
+            return variableExpressionTransformer.transformVariableExpression((VariableExpression) expr);
+        }
+        if (expr instanceof ClosureExpression) {
+            return closureExpressionTransformer.transformClosureExpression((ClosureExpression) expr);
         }
         if (expr instanceof BooleanExpression) {
             return booleanExpressionTransformer.transformBooleanExpression((BooleanExpression) expr);
         }
-        if (expr instanceof VariableExpression) {
-            return variableExpressionTransformer.transformVariableExpression((VariableExpression) expr);
-        }
-        if (expr instanceof PropertyExpression && isSuperExpression(((PropertyExpression) expr).getObjectExpression())) { // TODO: all obj exp
-            // TODO: delegate to propertyExpressionTransformer.transformPropertyExpression((PropertyExpression) expr);
-            MethodNode dmct = expr.getNodeMetaData(StaticTypesMarker.DIRECT_METHOD_CALL_TARGET);
-            // NOTE: BinaryExpressionTransformer handles the setter
-            if (dmct != null && dmct.getParameters().length == 0) {
-                PropertyExpression pe = (PropertyExpression) expr;
-
-                MethodCallExpression mce = new MethodCallExpression(transform(pe.getObjectExpression()), dmct.getName(), MethodCallExpression.NO_ARGUMENTS);
-                mce.setImplicitThis(pe.isImplicitThis());
-                mce.setSpreadSafe(pe.isSpreadSafe());
-                mce.setType(dmct.getReturnType());
-                mce.setMethodTarget(dmct);
-                mce.setSourcePosition(pe);
-                mce.copyNodeMetaData(pe);
-                mce.setSafe(pe.isSafe());
-                return mce;
-            }
+        if (expr instanceof BinaryExpression) {
+            return binaryExpressionTransformer.transformBinaryExpression((BinaryExpression) expr);
         }
         if (expr instanceof RangeExpression) {
-            return rangeExpressionTransformer.transformRangeExpression(((RangeExpression) expr));
+            return rangeExpressionTransformer.transformRangeExpression((RangeExpression) expr);
         }
         if (expr instanceof ListExpression) {
             return listExpressionTransformer.transformListExpression((ListExpression) expr);
         }
         if (expr instanceof CastExpression) {
-            return castExpressionTransformer.transformCastExpression(((CastExpression) expr));
+            return castExpressionTransformer.transformCastExpression((CastExpression) expr);
         }
         return super.transform(expr);
     }
diff --git a/src/main/java/org/codehaus/groovy/transform/sc/transformers/VariableExpressionTransformer.java b/src/main/java/org/codehaus/groovy/transform/sc/transformers/VariableExpressionTransformer.java
index 978fcec..d1c3fd7 100644
--- a/src/main/java/org/codehaus/groovy/transform/sc/transformers/VariableExpressionTransformer.java
+++ b/src/main/java/org/codehaus/groovy/transform/sc/transformers/VariableExpressionTransformer.java
@@ -20,73 +20,91 @@ package org.codehaus.groovy.transform.sc.transformers;
 
 import org.codehaus.groovy.ast.ClassNode;
 import org.codehaus.groovy.ast.FieldNode;
+import org.codehaus.groovy.ast.MethodNode;
 import org.codehaus.groovy.ast.expr.Expression;
+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.transform.sc.StaticCompilationMetadataKeys;
 import org.codehaus.groovy.transform.stc.StaticTypesMarker;
 
+import static org.codehaus.groovy.ast.tools.GeneralUtils.callThisX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.classX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.propX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.thisPropX;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.varX;
 
-/**
- * Transformer for VariableExpression the bytecode backend wouldn't be able to
- * handle otherwise.
- */
-public class VariableExpressionTransformer {
+class VariableExpressionTransformer {
 
-    public Expression transformVariableExpression(final VariableExpression expr) {
-        Expression trn = tryTransformDelegateToProperty(expr);
-        if (trn == null) {
-            trn = tryTransformPrivateFieldAccess(expr);
+    Expression transformVariableExpression(final VariableExpression ve) {
+        Expression xe = tryTransformImplicitReceiver(ve);
+        if (xe == null) {
+            xe = tryTransformPrivateFieldAccess(ve);
+        }
+        if (xe == null) {
+            xe = tryTransformDirectMethodTarget(ve);
+        }
+        if (xe != null) {
+            return xe;
         }
-        return trn != null ? trn : expr;
+        return ve;
     }
 
-    private static Expression tryTransformDelegateToProperty(final VariableExpression expr) {
+    private static Expression tryTransformImplicitReceiver(final VariableExpression ve) {
         // we need to transform variable expressions that go to a delegate
         // to a property expression, as ACG would lose the information in
         // processClassVariable before it reaches any makeCall, that could handle it
-        Object val = expr.getNodeMetaData(StaticTypesMarker.IMPLICIT_RECEIVER);
-        if (val == null || val.equals(expr.getName())) return null;
+        Object val = ve.getNodeMetaData(StaticTypesMarker.IMPLICIT_RECEIVER);
+        if (val == null || val.equals(ve.getName())) return null;
 
         // TODO: handle the owner and delegate cases better for nested scenarios and potentially remove the need for the implicit this case
-        Expression receiver = varX("owner".equals(val) ? (String) val : "delegate".equals(val) ? (String) val : "this");
-        // GROOVY-9136 -- object expression should not overlap source range of property; property stands in for original variable expression
-        receiver.setLineNumber(expr.getLineNumber());
-        receiver.setColumnNumber(expr.getColumnNumber());
+        Expression receiver = new VariableExpression("owner".equals(val) ? (String) val : "delegate".equals(val) ? (String) val : "this");
+        // GROOVY-9136: object expression should not overlap source range of property; property stands in for original variable expression
+        receiver.setColumnNumber(ve.getColumnNumber());
+        receiver.setLineNumber(ve.getLineNumber());
 
-        PropertyExpression pexp = propX(receiver, expr.getName());
-        pexp.getProperty().setSourcePosition(expr);
-        pexp.copyNodeMetaData(expr);
-        pexp.setImplicitThis(true);
+        PropertyExpression pe = propX(receiver, ve.getName());
+        pe.getProperty().setSourcePosition(ve);
+        pe.setImplicitThis(true);
+        pe.copyNodeMetaData(ve);
 
-        ClassNode owner = expr.getNodeMetaData(StaticCompilationMetadataKeys.PROPERTY_OWNER);
+        ClassNode owner = ve.getNodeMetaData(StaticCompilationMetadataKeys.PROPERTY_OWNER);
         if (owner != null) {
             receiver.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, owner);
             receiver.putNodeMetaData(StaticTypesMarker.IMPLICIT_RECEIVER, val);
         }
-        pexp.removeNodeMetaData(StaticTypesMarker.IMPLICIT_RECEIVER);
+        pe.removeNodeMetaData(StaticTypesMarker.IMPLICIT_RECEIVER);
 
-        return pexp;
+        return pe;
     }
 
-    private static Expression tryTransformPrivateFieldAccess(final VariableExpression expr) {
-        FieldNode field = expr.getNodeMetaData(StaticTypesMarker.PV_FIELDS_ACCESS);
+    private static Expression tryTransformPrivateFieldAccess(final VariableExpression ve) {
+        FieldNode field = ve.getNodeMetaData(StaticTypesMarker.PV_FIELDS_ACCESS);
         if (field == null) {
-            field = expr.getNodeMetaData(StaticTypesMarker.PV_FIELDS_MUTATION);
+            field = ve.getNodeMetaData(StaticTypesMarker.PV_FIELDS_MUTATION);
         }
-        if (field != null) {
-            // access to a private field from a section of code that normally doesn't have access to it, like a closure or an inner class
-            PropertyExpression pexp = !field.isStatic() ? thisPropX(true, expr.getName()) : propX(classX(field.getDeclaringClass()), expr.getName());
-            // store the declaring class so that the class writer knows that it will have to call a bridge method
-            pexp.getObjectExpression().putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, field.getDeclaringClass());
-            pexp.putNodeMetaData(StaticTypesMarker.DECLARATION_INFERRED_TYPE, field.getOriginType());
-            pexp.getProperty().setSourcePosition(expr);
-            return pexp;
+        if (field == null) {
+            return null;
         }
-        return null;
+
+        // access to a private field from a section of code that normally doesn't have access to it, like a closure block or an inner class
+        PropertyExpression pe = !field.isStatic() ? thisPropX(true, ve.getName()) : propX(classX(field.getDeclaringClass()), ve.getName());
+        // store the declaring class so that the class writer knows that it will have to call a bridge method
+        pe.getObjectExpression().putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, field.getDeclaringClass());
+        pe.putNodeMetaData(StaticTypesMarker.DECLARATION_INFERRED_TYPE, field.getOriginType());
+        pe.getProperty().setSourcePosition(ve);
+        return pe;
+    }
+
+    private static Expression tryTransformDirectMethodTarget(final VariableExpression ve) {
+        MethodNode dmct = ve.getNodeMetaData(StaticTypesMarker.DIRECT_METHOD_CALL_TARGET);
+        // NOTE: BinaryExpressionTransformer handles the setter
+        if (dmct == null || dmct.getParameters().length != 0) {
+            return null;
+        }
+
+        MethodCallExpression mce = callThisX(dmct.getName());
+        mce.getMethod().setSourcePosition(ve);
+        mce.setMethodTarget(dmct);
+        return mce;
     }
 }

[groovy] 01/02: 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 master
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 149449039672008a196528c2afa3cc53ab98462f
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      | 14 +++++----
 .../{Groovy5859Bug.groovy => Groovy10407.groovy}   | 33 +++++++++++++---------
 .../{Groovy5859Bug.groovy => Groovy5859.groovy}    | 30 ++++++++++++--------
 3 files changed, 47 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 06fc1a0..b4e04f3 100644
--- a/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java
+++ b/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java
@@ -57,6 +57,7 @@ import org.objectweb.asm.Opcodes;
 
 import javax.tools.FileObject;
 import javax.tools.JavaFileObject;
+
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
@@ -587,11 +588,14 @@ public class JavaStubGenerator {
             Parameter[] parameters = target.getParameters();
             Parameter[] normalized = Arrays.stream(parameters).map(parameter -> {
                 ClassNode normalizedType = parameter.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);
+                }
                 return new Parameter(normalizedType, parameter.getName());
             }).toArray(Parameter[]::new);
 
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 9d49391..e7d32f4 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 9d49391..08d444e 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);')
     }
 }