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/09/21 20:51:45 UTC

[groovy] branch master updated: GROOVY-10220, GROOVY-10235: STC: merge LHS and RHS type info : unchecked

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


The following commit(s) were added to refs/heads/master by this push:
     new f1c912b  GROOVY-10220, GROOVY-10235: STC: merge LHS and RHS type info : unchecked
f1c912b is described below

commit f1c912b53b94684c75539449d72a5bfb605cc7c1
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Tue Sep 21 15:36:59 2021 -0500

    GROOVY-10220, GROOVY-10235: STC: merge LHS and RHS type info : unchecked
    
      Set<XX> view = ConcurrentHashMap.newKeySet() // KeySetView<XX,Boolean>
      // key type inferred from assignment target and value type from source
---
 .../transform/stc/StaticTypeCheckingVisitor.java   | 12 +++++++--
 .../stc/ArraysAndCollectionsSTCTest.groovy         |  4 +--
 .../groovy/transform/stc/GenericsSTCTest.groovy    | 31 ++++++++++++++++++++++
 3 files changed, 43 insertions(+), 4 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 9782980..9dda68f 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -855,11 +855,19 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
                     // List<Type> list = new LinkedList()
                     // Iterable<Type> iter = new LinkedList()
                     // Collection<Type> coll = Collections.emptyList()
+                    // Collection<Type> view = ConcurrentHashMap.newKeySet()
 
                     // the inferred type of the binary expression is the type of the RHS
                     // "completed" with generics type information available from the LHS
-                    if (!resultType.isGenericsPlaceHolder()) // plain reference drops placeholder
-                        resultType = GenericsUtils.parameterizeType(lType, resultType.getPlainNodeReference());
+                    if (lType.equals(resultType)) {
+                        if (!lType.isGenericsPlaceHolder()) resultType = lType;
+                    } else { // GROOVY-10235, et al.
+                        Map<GenericsTypeName, GenericsType> gt = new HashMap<>();
+                        extractGenericsConnections(gt, resultType, resultType.redirect());
+                        extractGenericsConnections(gt, lType, ClassHelper.getNextSuperClass(resultType, lType));
+
+                        resultType = applyGenericsContext(gt, resultType.redirect());
+                    }
                 }
 
                 ClassNode originType = getOriginalDeclarationType(leftExpression);
diff --git a/src/test/groovy/transform/stc/ArraysAndCollectionsSTCTest.groovy b/src/test/groovy/transform/stc/ArraysAndCollectionsSTCTest.groovy
index a9385ea..e425ab7 100644
--- a/src/test/groovy/transform/stc/ArraysAndCollectionsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/ArraysAndCollectionsSTCTest.groovy
@@ -904,11 +904,11 @@ class ArraysAndCollectionsSTCTest extends StaticTypeCheckingTestCase {
 
         shouldFailWithMessages '''
             Deque<String> deque = []
-        ''', 'Cannot assign value of type java.util.List<java.lang.String> to variable of type java.util.Deque<java.lang.String>'
+        ''', 'Cannot assign value of type java.util.List<E> to variable of type java.util.Deque<java.lang.String>'
 
         shouldFailWithMessages '''
             Queue<String> queue = []
-        ''', 'Cannot assign value of type java.util.List<java.lang.String> to variable of type java.util.Queue<java.lang.String>'
+        ''', 'Cannot assign value of type java.util.List<E> to variable of type java.util.Queue<java.lang.String>'
     }
 
     // GROOVY-7128
diff --git a/src/test/groovy/transform/stc/GenericsSTCTest.groovy b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
index 690680a..2e5d630 100644
--- a/src/test/groovy/transform/stc/GenericsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
@@ -2116,6 +2116,37 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
         '''
     }
 
+    // GROOVY-10220
+    void testCompatibleArgumentsForPlaceholders3() {
+        assertScript '''
+            class C<S, T extends Number> {
+            }
+            class D<T> {
+                C<? extends T, Integer> f
+                D(C<? extends T, Integer> p) {
+                    f = p
+                }
+            }
+
+            assert new D<String>(null).f == null
+        '''
+    }
+
+    // GROOVY-10235
+    void testCompatibleArgumentsForPlaceholders4() {
+        assertScript '''
+            import static java.util.concurrent.ConcurrentHashMap.newKeySet
+
+            void accept(Collection<Integer> integers) {
+                assert integers
+            }
+
+            Set<Integer> integers = newKeySet()
+            integers.add(42)
+            accept(integers)
+        '''
+    }
+
     void testIncompatibleArgumentsForPlaceholders1() {
         shouldFailWithMessages '''
             def <T extends Number> T test(T one, T two) { }