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 2020/04/23 10:53:37 UTC

[groovy] branch GROOVY_3_0_X updated (4db12da -> 0839294)

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

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


    from 4db12da  fix typo
     new fb81c6e  GROOVY-9518: STC: type check constructor arguments like method call args
     new 0839294  GROOVY-9517: use inferred right expression type for array checks

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:
 .../transform/stc/StaticTypeCheckingVisitor.java   | 53 ++++++++++++----------
 .../stc/ArraysAndCollectionsSTCTest.groovy         | 45 ++++++++++++------
 .../stc/ClosureParamTypeInferenceSTCTest.groovy    | 37 ++++++++++++++-
 3 files changed, 96 insertions(+), 39 deletions(-)


[groovy] 02/02: GROOVY-9517: use inferred right expression type for array checks

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

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

commit 08392944821ea875e2166f6eda50d78bcd347e7b
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Wed Apr 22 10:41:01 2020 -0500

    GROOVY-9517: use inferred right expression type for array checks
    
    (cherry picked from commit 48ec228c651d3febfc47bee12ea9de1820cc9721)
---
 .../transform/stc/StaticTypeCheckingVisitor.java   | 37 +++++++++---------
 .../stc/ArraysAndCollectionsSTCTest.groovy         | 45 +++++++++++++++-------
 2 files changed, 49 insertions(+), 33 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 f33fb0c..09584b5 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -1175,30 +1175,29 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
         return true;
     }
 
-    private void addPrecisionErrors(final ClassNode leftRedirect, final ClassNode lhsType, final ClassNode inferredrhsType, final Expression rightExpression) {
-        if (isNumberType(leftRedirect) && isNumberType(inferredrhsType)) {
-            if (checkPossibleLossOfPrecision(leftRedirect, inferredrhsType, rightExpression)) {
-                addStaticTypeError("Possible loss of precision from " + inferredrhsType + " to " + leftRedirect, rightExpression);
-                return;
+    private void addPrecisionErrors(final ClassNode leftRedirect, final ClassNode lhsType, final ClassNode rhsType, final Expression rightExpression) {
+        if (isNumberType(leftRedirect)) {
+            if (isNumberType(rhsType) && checkPossibleLossOfPrecision(leftRedirect, rhsType, rightExpression)) {
+                addStaticTypeError("Possible loss of precision from " + rhsType.toString(false) + " to " + lhsType.toString(false), rightExpression);
             }
+            return;
         }
-        // if left type is array, we should check the right component types
-        if (!lhsType.isArray()) return;
-        ClassNode leftComponentType = lhsType.getComponentType();
-        ClassNode rightRedirect = rightExpression.getType().redirect();
-        if (rightRedirect.isArray()) {
-            ClassNode rightComponentType = rightRedirect.getComponentType();
-            if (!checkCompatibleAssignmentTypes(leftComponentType, rightComponentType)) {
-                addStaticTypeError("Cannot assign value of type " + rightComponentType.toString(false) + " into array of type " + lhsType.toString(false), rightExpression);
-            }
-        } else if (rightExpression instanceof ListExpression) {
-            for (Expression element : ((ListExpression) rightExpression).getExpressions()) {
-                ClassNode rightComponentType = this.getType(element);
-                if (!checkCompatibleAssignmentTypes(leftComponentType, rightComponentType)
-                        && !(isNullConstant(element) && !isPrimitiveType(leftComponentType))) {
+        if (!leftRedirect.isArray()) return;
+        // left type is an array, check the right component types
+        if (rightExpression instanceof ListExpression) {
+            ClassNode leftComponentType = leftRedirect.getComponentType();
+            for (Expression expression : ((ListExpression) rightExpression).getExpressions()) {
+                ClassNode rightComponentType = getType(expression);
+                if (!checkCompatibleAssignmentTypes(leftComponentType, rightComponentType) && !(isNullConstant(expression) && !isPrimitiveType(leftComponentType))) {
                     addStaticTypeError("Cannot assign value of type " + rightComponentType.toString(false) + " into array of type " + lhsType.toString(false), rightExpression);
                 }
             }
+        } else if (rhsType.redirect().isArray()) {
+            ClassNode leftComponentType = leftRedirect.getComponentType();
+            ClassNode rightComponentType = rhsType.redirect().getComponentType();
+            if (!checkCompatibleAssignmentTypes(leftComponentType, rightComponentType)) {
+                addStaticTypeError("Cannot assign value of type " + rightComponentType.toString(false) + " into array of type " + lhsType.toString(false), rightExpression);
+            }
         }
     }
 
diff --git a/src/test/groovy/transform/stc/ArraysAndCollectionsSTCTest.groovy b/src/test/groovy/transform/stc/ArraysAndCollectionsSTCTest.groovy
index 9152b2d..d841ed5 100644
--- a/src/test/groovy/transform/stc/ArraysAndCollectionsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/ArraysAndCollectionsSTCTest.groovy
@@ -91,6 +91,7 @@ class ArraysAndCollectionsSTCTest extends StaticTypeCheckingTestCase {
             for (int i in arr) { }
         ''', 'Cannot loop with element of type int with collection of type java.lang.String[]'
     }
+
     void testJava5StyleForLoopWithArray() {
         assertScript '''
             String[] arr = ['1','2','3']
@@ -321,6 +322,20 @@ class ArraysAndCollectionsSTCTest extends StaticTypeCheckingTestCase {
         ''', 'Cannot assign value of type Foo[] to variable of type FooAnother'
     }
 
+    // GROOVY-9517
+    void testShouldAllowArrayAssignment() {
+        assertScript '''
+            void test(File directory) {
+                File[] files = directory.listFiles()
+                files = files?.sort { it.name }
+                for (file in files) {
+                    // ...
+                }
+            }
+            println 'works'
+        '''
+    }
+
     void testListPlusEquals() {
         assertScript '''
             List<String> list = ['a','b']
@@ -334,7 +349,7 @@ class ArraysAndCollectionsSTCTest extends StaticTypeCheckingTestCase {
             assert list == ['a','b','c']
         '''
     }
-    
+
     void testObjectArrayGet() {
         assertScript '''
             Object[] arr = [new Object()]
@@ -478,18 +493,21 @@ class ArraysAndCollectionsSTCTest extends StaticTypeCheckingTestCase {
     // GROOVY-5793
     void testShouldNotForceAsTypeWhenListOfNullAssignedToArray() {
         assertScript '''
-        Integer[] m() {
-          Integer[] arr = [ null, null ]
-        }
-        assert m().length == 2
+            Integer[] m() {
+                Integer[] array = [ null, null ]
+                return array
+            }
+            assert m().length == 2
         '''
     }
+
     void testShouldNotForceAsTypeWhenListOfNullAssignedToArrayUnlessPrimitive() {
         shouldFailWithMessages '''
-        int[] m() {
-          int[] arr = [ null, null ]
-        }
-        ''', 'into array of type'
+            int[] m() {
+                int[] array = [ null, null ]
+                return array
+            }
+        ''', 'Cannot assign value of type java.lang.Object into array of type int[]'
     }
 
     // GROOVY-6131
@@ -512,7 +530,7 @@ class ArraysAndCollectionsSTCTest extends StaticTypeCheckingTestCase {
             assert AR.'key'[0] == ['val1']
         """
     }
-    
+
     // GROOVY-6311
     void testSetSpread() {
         assertScript """
@@ -525,7 +543,7 @@ class ArraysAndCollectionsSTCTest extends StaticTypeCheckingTestCase {
             assert res[0].contains('def')
         """
     }
-    
+
     // GROOVY-6241
     void testAsImmutable() {
         assertScript """
@@ -535,7 +553,7 @@ class ArraysAndCollectionsSTCTest extends StaticTypeCheckingTestCase {
             Map<String, Integer> immutableMap = [foo: 123, bar: 456].asImmutable()
         """
     }
-    
+
     // GROOVY-6350
     void testListPlusList() {
         assertScript """
@@ -566,8 +584,7 @@ class ArraysAndCollectionsSTCTest extends StaticTypeCheckingTestCase {
                 Set<Foo> foos = [new Foo(name: 'pls'), new Foo(name: 'bar')].toSet()
                 foos*.name
             }
-            assert meth().toSet() == ['pls', 'bar'].toSet()            
+            assert meth().toSet() == ['pls', 'bar'].toSet()
         '''
     }
 }
-


[groovy] 01/02: GROOVY-9518: STC: type check constructor arguments like method call args

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

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

commit fb81c6e726b96d39464c85446dc914b250d3ae10
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Tue Apr 21 10:33:49 2020 -0500

    GROOVY-9518: STC: type check constructor arguments like method call args
    
    (cherry picked from commit b7ad32403f902f1ab9dc5964aab0420bfe6b8193)
---
 .../transform/stc/StaticTypeCheckingVisitor.java   | 16 +++++++---
 .../stc/ClosureParamTypeInferenceSTCTest.groovy    | 37 +++++++++++++++++++++-
 2 files changed, 47 insertions(+), 6 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 fec7971..f33fb0c 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -2185,18 +2185,21 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
 
     @Override
     public void visitConstructorCallExpression(final ConstructorCallExpression call) {
-        super.visitConstructorCallExpression(call);
         if (extension.beforeMethodCall(call)) {
             extension.afterMethodCall(call);
             return;
         }
-        ClassNode receiver = call.isThisCall() ? typeCheckingContext.getEnclosingClassNode() :
-                call.isSuperCall() ? typeCheckingContext.getEnclosingClassNode().getSuperClass() : call.getType();
+        ClassNode receiver = call.getType();
+        if (call.isThisCall()) {
+            receiver = typeCheckingContext.getEnclosingClassNode();
+        } else if (call.isSuperCall()) {
+            receiver = typeCheckingContext.getEnclosingClassNode().getSuperClass();
+        }
         Expression arguments = call.getArguments();
-
         ArgumentListExpression argumentList = InvocationWriter.makeArgumentList(arguments);
 
         checkForbiddenSpreadArgument(argumentList);
+        visitMethodCallArguments(receiver, argumentList, false, null);
 
         ClassNode[] args = getArgumentTypes(argumentList);
         if (args.length > 0 &&
@@ -2226,7 +2229,10 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
             } else {
                 typeCheckMethodsWithGenericsOrFail(receiver, args, node, call);
             }
-            if (node != null) storeTargetMethod(call, node);
+            if (node != null) {
+                storeTargetMethod(call, node);
+                visitMethodCallArguments(receiver, argumentList, true, node);
+            }
         }
 
         // GROOVY-9327: check for AIC in STC method with non-STC enclosing class
diff --git a/src/test/groovy/transform/stc/ClosureParamTypeInferenceSTCTest.groovy b/src/test/groovy/transform/stc/ClosureParamTypeInferenceSTCTest.groovy
index 3539e25..373b11f 100644
--- a/src/test/groovy/transform/stc/ClosureParamTypeInferenceSTCTest.groovy
+++ b/src/test/groovy/transform/stc/ClosureParamTypeInferenceSTCTest.groovy
@@ -545,7 +545,7 @@ import groovy.transform.stc.ClosureParams
             assert sum == 110
         '''
     }
-    
+
     void testInferenceForDGM_upto() {
         assertScript '''
             BigDecimal sum = 0
@@ -1340,4 +1340,39 @@ method()
             assert foo() == ['FEE', 'FO']
         '''
     }
+
+    void testGroovy9518() {
+        assertScript '''
+            class C {
+                C(String s, Comparable<List<Integer>> c) {
+                }
+            }
+
+            new C('blah', { list -> list.get(0) })
+        '''
+    }
+
+    void testGroovy9518a() {
+        assertScript '''
+            class C {
+                C(String s, Comparable<List<Integer>> c) {
+                }
+            }
+
+            new C('blah', { it.get(0) })
+        '''
+    }
+
+    void testGroovy9518b() {
+        assertScript '''
+            import groovy.transform.stc.*
+
+            class C {
+                C(String s, @ClosureParams(value=SimpleType, options='java.util.List') Closure<Integer> c) {
+                }
+            }
+
+            new C('blah', { list -> list.get(0) })
+        '''
+    }
 }