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/07/15 16:34:41 UTC

[groovy] branch GROOVY_4_0_X updated: GROOVY-10651, GROOVY-10671: wildcard implicit bounding (binary)

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 aecb643dd8 GROOVY-10651, GROOVY-10671: wildcard implicit bounding (binary)
aecb643dd8 is described below

commit aecb643dd8ad0e343651915fa0fddb9645f82bec
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Fri Jul 15 10:58:11 2022 -0500

    GROOVY-10651, GROOVY-10671: wildcard implicit bounding (binary)
---
 .../groovy/ast/decompiled/TypeSignatureParser.java | 16 +++++++++++-
 .../codehaus/groovy/ast/tools/GenericsUtils.java   | 29 ++--------------------
 2 files changed, 17 insertions(+), 28 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/ast/decompiled/TypeSignatureParser.java b/src/main/java/org/codehaus/groovy/ast/decompiled/TypeSignatureParser.java
index 2a7b1a50eb..fd9b38e9c3 100644
--- a/src/main/java/org/codehaus/groovy/ast/decompiled/TypeSignatureParser.java
+++ b/src/main/java/org/codehaus/groovy/ast/decompiled/TypeSignatureParser.java
@@ -115,7 +115,21 @@ abstract class TypeSignatureParser extends SignatureVisitor {
             finished(baseType);
         } else {
             ClassNode parameterizedType = baseType.getPlainNodeReference();
-            if (!arguments.isEmpty()) { // else GROOVY-10234: no type arguments -> raw type
+            if (arguments.isEmpty()) {
+                // GROOVY-10234: no type arguments -> raw type
+            } else {
+                try {
+                    // GROOVY-10153, GROOVY-10651, GROOVY-10671: "?" or "? super T" (see ResolveVisitor#resolveWildcardBounding)
+                    for (int i = 0, n = arguments.size(); i < n; i += 1) { GenericsType argument = arguments.get(i);
+                    if (!argument.isWildcard() || argument.getUpperBounds() != null) continue; //
+                    ClassNode[] implicitBounds = baseType.getGenericsTypes()[i].getUpperBounds();
+                    if (implicitBounds != null && !ClassHelper.isObjectType(implicitBounds[0])) {
+                        argument.getType().setRedirect(implicitBounds[0]); // bound is not Object
+                    }
+                    }
+                } catch (StackOverflowError ignore) {
+                    // TODO: self-referential type parameter
+                }
                 parameterizedType.setGenericsTypes(arguments.toArray(GenericsType.EMPTY_ARRAY));
             }
             finished(parameterizedType);
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 143300ee35..2cbb5ced6c 100644
--- a/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java
+++ b/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java
@@ -128,31 +128,12 @@ public class GenericsUtils {
         return generics;
     }
 
-    /**
-     * Generates a wildcard generic type with implicit upper and optional lower
-     * bounds. The result provides "?" or "? super T" (no "extends") semantics.
-     */
-    private static GenericsType boundWildcardType(final ClassNode implicit, final ClassNode lower) {
-        ClassNode base = ClassHelper.makeWithoutCaching("?");
-        base.setGenericsPlaceHolder(true);
-        base.setRedirect(implicit);
-
-        GenericsType gt = new GenericsType(base, null, lower);
-        gt.setPlaceholder(false);
-        gt.setWildcard(true);
-        return gt;
-    }
-
     /**
      * Generates a wildcard generic type in order to be used for checks against
      * class nodes. See {@link GenericsType#isCompatibleWith(ClassNode)}.
-     *
-     * @param types the type(s) to be used as the wildcard's upper bound
      */
-    public static GenericsType buildWildcardType(final ClassNode... types) {
-        ClassNode base = ClassHelper.makeWithoutCaching("?");
-
-        GenericsType gt = new GenericsType(base, types, null);
+    public static GenericsType buildWildcardType(final ClassNode... upperBounds) {
+        GenericsType gt = new GenericsType(ClassHelper.makeWithoutCaching("?"), upperBounds, null);
         gt.setWildcard(true);
         return gt;
     }
@@ -209,12 +190,6 @@ public class GenericsUtils {
             if (rgt.isPlaceholder()) { // type parameter
                 GenericsType typeArgument = genericsTypes[i];
                 placeholders.computeIfAbsent(new GenericsType.GenericsTypeName(rgt.getName()), x -> {
-                    if (typeArgument.isWildcard() && typeArgument.getUpperBounds() == null) {
-                        ClassNode[] implicitBounds = rgt.getUpperBounds();//GROOVY-10651,GROOVY-10671
-                        if (implicitBounds != null && !ClassHelper.isObjectType(implicitBounds[0])) {
-                            return boundWildcardType(implicitBounds[0],typeArgument.getLowerBound());
-                        }
-                    }
                     typeArguments.add(typeArgument);
                     return typeArgument;
                 });