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/09 16:01:59 UTC

[groovy] branch master updated: GROOVY-10217: STC: consider instanceof flow-type for binary expr LHS

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 fd14d18  GROOVY-10217: STC: consider instanceof flow-type for binary expr LHS
fd14d18 is described below

commit fd14d189e51049ad28bb9084c6b62baacaa3c525
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Thu Sep 9 10:45:40 2021 -0500

    GROOVY-10217: STC: consider instanceof flow-type for binary expr LHS
---
 .../transform/stc/StaticTypeCheckingVisitor.java   | 22 +++++++++++-----------
 src/test/groovy/transform/stc/BugsSTCTest.groovy   |  2 +-
 .../transform/stc/TypeInferenceSTCTest.groovy      | 14 ++++++++++++++
 3 files changed, 26 insertions(+), 12 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 d1058ca..9b84a13 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -587,10 +587,6 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
         final Variable accessedVariable = vexp.getAccessedVariable();
         final TypeCheckingContext.EnclosingClosure enclosingClosure = typeCheckingContext.getEnclosingClosure();
 
-        if (accessedVariable == null) {
-            return;
-        }
-
         if (accessedVariable instanceof DynamicVariable) {
             // a dynamic variable is either a closure property, a class member referenced from a closure, or an undeclared variable
 
@@ -657,18 +653,18 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
                     }
                 }
             }
-        } else {
+        } else if (accessedVariable != null) {
             VariableExpression localVariable;
             if (accessedVariable instanceof Parameter) {
-                Parameter parameter = (Parameter) accessedVariable;
-                localVariable = new ParameterVariableExpression(parameter);
+                Parameter prm = (Parameter) accessedVariable;
+                localVariable = new ParameterVariableExpression(prm);
             } else {
                 localVariable = (VariableExpression) accessedVariable;
             }
 
             ClassNode inferredType = localVariable.getNodeMetaData(INFERRED_TYPE);
             inferredType = getInferredTypeFromTempInfo(localVariable, inferredType);
-            if (inferredType != null && !isObjectType(inferredType)) {
+            if (inferredType != null && !isObjectType(inferredType) && !inferredType.equals(accessedVariable.getType())) {
                 vexp.putNodeMetaData(INFERRED_RETURN_TYPE, inferredType);
             }
         }
@@ -685,7 +681,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
         if (vexp == VariableExpression.THIS_EXPRESSION) return true;
         if (!vexp.isThisExpression()) return false;
         // GROOVY-6904, GROOVY-9422: non-static inner class constructor call sets type
-        storeType(vexp, !OBJECT_TYPE.equals(vexp.getType()) ? vexp.getType() : makeThis());
+        storeType(vexp, !isObjectType(vexp.getType()) ? vexp.getType() : makeThis());
         return true;
     }
 
@@ -776,7 +772,11 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
                 lType = getType(leftExpression);
             } else {
                 if (op != ASSIGN && op != ELVIS_EQUAL) {
-                    lType = getType(leftExpression);
+                    if (leftExpression instanceof VariableExpression && hasInferredReturnType(leftExpression)) {
+                        lType = getInferredReturnType(leftExpression);
+                    } else {
+                        lType = getType(leftExpression);
+                    }
                 } else {
                     lType = getOriginalDeclarationType(leftExpression);
 
@@ -5020,7 +5020,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
                 return fieldType;
             }
             if (variable != vexp && variable instanceof VariableExpression) {
-                return getType((Expression) variable);
+                return getType((VariableExpression) variable);
             }
             if (variable instanceof Parameter) {
                 Parameter parameter = (Parameter) variable;
diff --git a/src/test/groovy/transform/stc/BugsSTCTest.groovy b/src/test/groovy/transform/stc/BugsSTCTest.groovy
index a1ec9df..0781a77 100644
--- a/src/test/groovy/transform/stc/BugsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/BugsSTCTest.groovy
@@ -100,7 +100,7 @@ class BugsSTCTest extends StaticTypeCheckingTestCase {
                     x()
                 }
             }
-        ''', 'Cannot find matching method T#x'
+        ''', 'Cannot find matching method <UnionType:C+T>#x'
     }
 
     // GROOVY-10102
diff --git a/src/test/groovy/transform/stc/TypeInferenceSTCTest.groovy b/src/test/groovy/transform/stc/TypeInferenceSTCTest.groovy
index bd812b3..b5645e0 100644
--- a/src/test/groovy/transform/stc/TypeInferenceSTCTest.groovy
+++ b/src/test/groovy/transform/stc/TypeInferenceSTCTest.groovy
@@ -487,6 +487,20 @@ class TypeInferenceSTCTest extends StaticTypeCheckingTestCase {
         '''
     }
 
+    // GROOVY-10217
+    void testInstanceOfThenSubscriptOperator() {
+        assertScript '''
+            void test(Object o) {
+                if (o instanceof List) {
+                    assert o[0] == 1
+                    def x = (List) o
+                    assert x[0] == 1
+                }
+            }
+            test([1])
+        '''
+    }
+
     void testShouldNotFailWithWith() {
         assertScript '''
             class A {