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 2018/11/20 16:01:39 UTC

groovy git commit: Refine "GROOVY-8887: Support multi-assignment of tuples in STC"

Repository: groovy
Updated Branches:
  refs/heads/master e07eaead6 -> 1fc3b672d


Refine "GROOVY-8887: Support multi-assignment of tuples in STC"


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/1fc3b672
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/1fc3b672
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/1fc3b672

Branch: refs/heads/master
Commit: 1fc3b672da05caea26996f644bd14e524126b4bb
Parents: e07eaea
Author: Daniel Sun <su...@apache.org>
Authored: Wed Nov 21 00:00:34 2018 +0800
Committer: Daniel Sun <su...@apache.org>
Committed: Wed Nov 21 00:00:34 2018 +0800

----------------------------------------------------------------------
 .../stc/StaticTypeCheckingVisitor.java          | 45 +++++++----------
 src/test/groovy/bugs/Groovy8887.groovy          | 52 ++++++++++++++++++--
 2 files changed, 67 insertions(+), 30 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/1fc3b672/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
----------------------------------------------------------------------
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 284fc72..de2abff 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -1124,42 +1124,35 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
         }
 
         ClassNode cn = null;
-        if (rightExpression instanceof MethodCallExpression || rightExpression instanceof VariableExpression) {
-            cn = rightExpression.getType();
+        if (rightExpression instanceof MethodCallExpression || rightExpression instanceof ConstructorCallExpression || rightExpression instanceof VariableExpression) {
+            ClassNode inferredType = getType(rightExpression);
+            cn = null == inferredType ? rightExpression.getType() : inferredType;
         }
 
         if (null == cn) {
             return null;
         }
 
-        Expression listExpression = transformToListExpression(rightExpression, cn);
-        if (listExpression != null) return listExpression;
-
-        return null;
-    }
-
-    private Expression transformToListExpression(Expression expression, ClassNode cn) {
-        if (null != cn && cn.isDerivedFrom(ClassHelper.TUPLE_TYPE)) { // just for performance to check
-            for (int i = 0, n = TUPLE_CLASSES.length; i < n; i++) {
-                Class tcn = TUPLE_CLASSES[i];
-                if (tcn.equals(cn.getTypeClass())) {
-                    ListExpression listExpression = new ListExpression();
-                    GenericsType[] genericsTypes = cn.getGenericsTypes();
-                    for (int j = 0; j < i; j++) {
-                        // the index of element in tuple starts with 1
-                        MethodCallExpression mce = new MethodCallExpression(expression, "getV" + (j + 1), ArgumentListExpression.EMPTY_ARGUMENTS);
-                        ClassNode elementType = null != genericsTypes ? genericsTypes[j].getType() : ClassHelper.OBJECT_TYPE;
-                        mce.setType(elementType);
-                        storeType(mce, elementType);
-                        listExpression.addExpression(mce);
-                    }
+        for (int i = 0, n = TUPLE_CLASSES.length; i < n; i++) {
+            Class tcn = TUPLE_CLASSES[i];
+            if (tcn.equals(cn.getTypeClass())) {
+                ListExpression listExpression = new ListExpression();
+                GenericsType[] genericsTypes = cn.getGenericsTypes();
+                for (int j = 0; j < i; j++) {
+                    // the index of element in tuple starts with 1
+                    MethodCallExpression mce = new MethodCallExpression(rightExpression, "getV" + (j + 1), ArgumentListExpression.EMPTY_ARGUMENTS);
+                    ClassNode elementType = null != genericsTypes ? genericsTypes[j].getType() : ClassHelper.OBJECT_TYPE;
+                    mce.setType(elementType);
+                    storeType(mce, elementType);
+                    listExpression.addExpression(mce);
+                }
 
-                    listExpression.setSourcePosition(expression);
+                listExpression.setSourcePosition(rightExpression);
 
-                    return listExpression;
-                }
+                return listExpression;
             }
         }
+
         return null;
     }
 

http://git-wip-us.apache.org/repos/asf/groovy/blob/1fc3b672/src/test/groovy/bugs/Groovy8887.groovy
----------------------------------------------------------------------
diff --git a/src/test/groovy/bugs/Groovy8887.groovy b/src/test/groovy/bugs/Groovy8887.groovy
index 2c4e80c..2335794 100644
--- a/src/test/groovy/bugs/Groovy8887.groovy
+++ b/src/test/groovy/bugs/Groovy8887.groovy
@@ -22,7 +22,7 @@ class Groovy8887 extends GroovyTestCase {
     void testMultiAssignment() {
         assertScript '''
             @groovy.transform.CompileStatic
-            class TtcTuple {
+            class StcTuple {
                 void multiAssignedByMethodCall() {
                     def (String name, Integer age) = findPersonInfo()
                     
@@ -38,6 +38,44 @@ class Groovy8887 extends GroovyTestCase {
                     assert 35 == age
                 }
                 
+                void multiAssignedByMap1() {
+                    Tuple2<String, Integer> personInfo = new Tuple2<String, Integer>('Daniel', 35)
+                    def (String name, Integer age) = personInfo.map1(e -> "${e}.Sun")
+                    assert 'Daniel.Sun' == name
+                    assert 35 == age
+                }
+                
+                void multiAssignedByMap2() {
+                    Tuple2<String, Integer> personInfo = new Tuple2<String, Integer>('Daniel', 35)
+                    def (String name, Integer age) = personInfo.map2(e -> e - 1)
+                    assert 'Daniel' == name
+                    assert 34 == age
+                }
+                
+                void multiAssignedByFluentMap1() {
+                    def (String name, Integer age) = findPersonInfo().map1(e -> "${e}.Sun")
+                    assert 'Daniel.Sun' == name
+                    assert 35 == age
+                }
+                
+                void multiAssignedByFluentMap2() {
+                    def (String name, Integer age) = findPersonInfo().map2(e -> e - 1)
+                    assert 'Daniel' == name
+                    assert 34 == age
+                }
+                
+                void multiAssignedByFactory() {
+                    def (String name, Integer age) = Tuple.tuple('Daniel', 35)
+                    assert 'Daniel' == name
+                    assert 35 == age
+                }
+                
+                void multiAssignedByConstructor() {
+                    def (String name, Integer age) = new Tuple2<String, Integer>('Daniel', 35)
+                    assert 'Daniel' == name
+                    assert 35 == age
+                }
+                
                 Tuple2<String, Integer> findPersonInfo() {
                     Tuple2<String, Integer> t = new Tuple2<>('Daniel', 35)
                     
@@ -45,9 +83,15 @@ class Groovy8887 extends GroovyTestCase {
                 }
             }
             
-            def tt = new TtcTuple()
-            tt.multiAssignedByMethodCall()
-            tt.multiAssignedByVariableAccess()
+            def st = new StcTuple()
+            st.multiAssignedByMethodCall()
+            st.multiAssignedByVariableAccess()
+            st.multiAssignedByMap1()
+            st.multiAssignedByMap2()
+            st.multiAssignedByFluentMap1()
+            st.multiAssignedByFluentMap2()
+            st.multiAssignedByFactory()
+            st.multiAssignedByConstructor()
         '''
     }
 }