You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2021/03/28 12:51:11 UTC

[groovy] 03/03: GROOVY-7128: STC: support "List list = [1, 2, 3]"

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

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

commit 162e91b8cbc65baa4edac32a7b9089b43cfd1659
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sat Mar 27 17:41:39 2021 -0500

    GROOVY-7128: STC: support "List<Number> list = [1,2,3]"
---
 .../transform/stc/StaticTypeCheckingVisitor.java   | 25 ++++++++++++++++++++--
 .../stc/ArraysAndCollectionsSTCTest.groovy         | 21 ++++++++++++++++++
 2 files changed, 44 insertions(+), 2 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
index 8a7b9b3..7b6bc43 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -4368,11 +4368,11 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
                         || ITERABLE_TYPE.equals(leftRedirect)
                         || Collection_TYPE.equals(leftRedirect)
                         || ArrayList_TYPE.isDerivedFrom(leftRedirect)) { // GROOVY-6912
-                    return GenericsUtils.parameterizeType(right, ArrayList_TYPE.getPlainNodeReference());
+                    return getLiteralResultType(left, right, ArrayList_TYPE); // GROOVY-7128
                 }
                 if (SET_TYPE.equals(leftRedirect)
                         || LinkedHashSet_TYPE.isDerivedFrom(leftRedirect)) { // GROOVY-6912
-                    return GenericsUtils.parameterizeType(right, LinkedHashSet_TYPE.getPlainNodeReference());
+                    return getLiteralResultType(left, right, LinkedHashSet_TYPE); // GROOVY-7128
                 }
             }
 
@@ -4425,6 +4425,27 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
         return null;
     }
 
+    /**
+     * For "{@code List<Type> x = [...]}" or "{@code Set<Type> y = [...]}", etc.
+     * the literal may be composed of sub-types of {@code Type}. In these cases,
+     * {@code ArrayList<Type>} is an appropriate result type for the expression.
+     */
+    private ClassNode getLiteralResultType(final ClassNode targetType, final ClassNode sourceType, final ClassNode baseType) {
+        ClassNode resultType = sourceType.equals(baseType) ? sourceType
+                : GenericsUtils.parameterizeType(sourceType, baseType.getPlainNodeReference());
+
+        if (targetType.getGenericsTypes() != null
+                && !GenericsUtils.buildWildcardType(targetType).isCompatibleWith(resultType)) {
+            GenericsType[] lgt = targetType.getGenericsTypes(), rgt = resultType.getGenericsTypes();
+            if (!lgt[0].isPlaceholder() && !lgt[0].isWildcard() && GenericsUtils.buildWildcardType(
+                    getCombinedBoundType(lgt[0])).isCompatibleWith(getCombinedBoundType(rgt[0]))) {
+                resultType = GenericsUtils.parameterizeType(targetType, baseType.getPlainNodeReference());
+            }
+        }
+
+        return resultType;
+    }
+
     private ClassNode getMathResultType(final int op, final ClassNode leftRedirect, final ClassNode rightRedirect, final String operationName) {
         if (isNumberType(leftRedirect) && isNumberType(rightRedirect)) {
             if (isOperationInGroup(op)) {
diff --git a/src/test/groovy/transform/stc/ArraysAndCollectionsSTCTest.groovy b/src/test/groovy/transform/stc/ArraysAndCollectionsSTCTest.groovy
index 0c7e11a..fa96651 100644
--- a/src/test/groovy/transform/stc/ArraysAndCollectionsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/ArraysAndCollectionsSTCTest.groovy
@@ -720,4 +720,25 @@ class ArraysAndCollectionsSTCTest extends StaticTypeCheckingTestCase {
             Queue<String> queue = []
         ''', 'Cannot assign value of type java.util.List <java.lang.String> to variable of type java.util.Queue <String>'
     }
+
+    // GROOVY-7128
+    void testCollectionTypesInitializedByListLiteral4() {
+        assertScript '''
+            Collection<Number> collection = [1,2,3]
+            assert collection.size() == 3
+            assert collection.last() == 3
+        '''
+
+        assertScript '''
+            List<Number> list = [1,2,3]
+            assert list.size() == 3
+            assert list.last() == 3
+        '''
+
+        assertScript '''
+            Set<Number> set = [1,2,3,3]
+            assert set.size() == 3
+            assert set.last() == 3
+        '''
+    }
 }