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 72c7914  GROOVY-10308: STC: variable flow type: do not use 
`INFERRED_RETURN_TYPE`
72c7914 is described below

commit 72c791402fef8181b218aad74b379dc3272829c7
Author: Eric Milles <[email protected]>
AuthorDate: Sat Oct 23 18:57:43 2021 -0500

    GROOVY-10308: STC: variable flow type: do not use `INFERRED_RETURN_TYPE`
---
 .../transform/stc/StaticTypeCheckingVisitor.java   | 64 +++++-----------------
 .../transform/stc/TypeInferenceSTCTest.groovy      | 41 ++++++++++++--
 .../{Groovy7333Bug.groovy => Groovy7333.groovy}    |  4 +-
 3 files changed, 51 insertions(+), 58 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 ef4eee2..b0e15ba 100644
--- 
a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ 
b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -641,7 +641,7 @@ public class StaticTypeCheckingVisitor extends 
ClassCodeVisitorSupport {
                 // GROOVY-9454
                 ClassNode inferredType = getInferredTypeFromTempInfo(vexp, 
null);
                 if (inferredType != null && !isObjectType(inferredType)) {
-                    vexp.putNodeMetaData(INFERRED_RETURN_TYPE, inferredType);
+                    vexp.putNodeMetaData(INFERRED_TYPE, inferredType);
                 } else {
                     storeType(vexp, getType(vexp));
                 }
@@ -673,7 +673,7 @@ public class StaticTypeCheckingVisitor extends 
ClassCodeVisitorSupport {
             ClassNode inferredType = 
localVariable.getNodeMetaData(INFERRED_TYPE);
             inferredType = getInferredTypeFromTempInfo(localVariable, 
inferredType);
             if (inferredType != null && !isObjectType(inferredType) && 
!inferredType.equals(accessedVariable.getType())) {
-                vexp.putNodeMetaData(INFERRED_RETURN_TYPE, inferredType);
+                vexp.putNodeMetaData(INFERRED_TYPE, inferredType);
             }
         }
     }
@@ -780,11 +780,7 @@ public class StaticTypeCheckingVisitor extends 
ClassCodeVisitorSupport {
                 lType = getType(leftExpression);
             } else {
                 if (op != ASSIGN && op != ELVIS_EQUAL) {
-                    if (leftExpression instanceof VariableExpression && 
hasInferredReturnType(leftExpression)) {
-                        lType = getInferredReturnType(leftExpression);
-                    } else {
-                        lType = getType(leftExpression);
-                    }
+                    lType = getType(leftExpression);
                 } else {
                     lType = getOriginalDeclarationType(leftExpression);
 
@@ -1321,23 +1317,17 @@ public class StaticTypeCheckingVisitor extends 
ClassCodeVisitorSupport {
         // TODO: need errors for write-only too!
         if (addedReadOnlyPropertyError(leftExpression)) return;
 
-        ClassNode rTypeInferred, rTypeWrapped; // check for instanceof and 
spreading
-        if (rightExpression instanceof VariableExpression && 
hasInferredReturnType(rightExpression) && 
assignmentExpression.getOperation().getType() == ASSIGN) {
-            rTypeInferred = getInferredReturnType(rightExpression);
-        } else {
-            rTypeInferred = rightExpressionType;
-        }
-        rTypeWrapped = adjustTypeForSpreading(rTypeInferred, leftExpression);
+        ClassNode rTypeWrapped = adjustTypeForSpreading(rightExpressionType, 
leftExpression);
 
         if (!checkCompatibleAssignmentTypes(leftExpressionType, rTypeWrapped, 
rightExpression)) {
-            if (!extension.handleIncompatibleAssignment(leftExpressionType, 
rTypeInferred, assignmentExpression)) {
-                addAssignmentError(leftExpressionType, rTypeInferred, 
rightExpression);
+            if (!extension.handleIncompatibleAssignment(leftExpressionType, 
rightExpressionType, assignmentExpression)) {
+                addAssignmentError(leftExpressionType, rightExpressionType, 
rightExpression);
             }
         } else {
             ClassNode lTypeRedirect = leftExpressionType.redirect();
-            addPrecisionErrors(lTypeRedirect, leftExpressionType, 
rTypeInferred, rightExpression);
+            addPrecisionErrors(lTypeRedirect, leftExpressionType, 
rightExpressionType, rightExpression);
             if (rightExpression instanceof ListExpression) {
-                addListAssignmentConstructorErrors(lTypeRedirect, 
leftExpressionType, rTypeInferred, rightExpression, assignmentExpression);
+                addListAssignmentConstructorErrors(lTypeRedirect, 
leftExpressionType, rightExpressionType, rightExpression, assignmentExpression);
             } else if (rightExpression instanceof MapExpression) {
                 addMapAssignmentConstructorErrors(lTypeRedirect, 
leftExpression, rightExpression);
             }
@@ -1954,12 +1944,7 @@ public class StaticTypeCheckingVisitor extends 
ClassCodeVisitorSupport {
             super.visitForLoop(forLoop);
         } else {
             collectionExpression.visit(this);
-            ClassNode collectionType;
-            if (collectionExpression instanceof VariableExpression && 
hasInferredReturnType(collectionExpression)) {
-                collectionType = getInferredReturnType(collectionExpression);
-            } else {
-                collectionType = getType(collectionExpression);
-            }
+            ClassNode collectionType = getType(collectionExpression);
             ClassNode forLoopVariableType = forLoop.getVariableType();
             ClassNode componentType;
             if (isWrapperCharacter(getWrapper(forLoopVariableType)) && 
isStringType(collectionType)) {
@@ -2203,12 +2188,7 @@ public class StaticTypeCheckingVisitor extends 
ClassCodeVisitorSupport {
 
     protected ClassNode checkReturnType(final ReturnStatement statement) {
         Expression expression = statement.getExpression();
-        ClassNode type;
-        if (expression instanceof VariableExpression && 
hasInferredReturnType(expression)) {
-            type = getInferredReturnType(expression);
-        } else {
-            type = getType(expression);
-        }
+        ClassNode type = getType(expression);
         if (typeCheckingContext.getEnclosingClosure() != null) {
             ClassNode inferredReturnType = 
getInferredReturnType(typeCheckingContext.getEnclosingClosure().getClosureExpression());
             // GROOVY-9995: return ctor call with diamond operator
@@ -3316,18 +3296,11 @@ public class StaticTypeCheckingVisitor extends 
ClassCodeVisitorSupport {
         objectExpression.visit(this);
         call.getMethod().visit(this);
 
-        ClassNode receiver;
-        if (objectExpression instanceof VariableExpression && 
hasInferredReturnType(objectExpression)) {
-            receiver = getInferredReturnType(objectExpression);
-        } else {
-            receiver = getType(objectExpression);
-        }
-        // if it's a spread operator call, then make sure receiver is array or 
collection
-        if (call.isSpreadSafe()) {
+        ClassNode receiver = getType(objectExpression);
+        if (call.isSpreadSafe()) { // make sure receiver is array or 
collection then check element type
             if (!receiver.isArray() && 
!implementsInterfaceOrIsSubclassOf(receiver, Collection_TYPE)) {
                 addStaticTypeError("Spread operator can only be used on 
collection types", objectExpression);
             } else {
-                // type check call as if it was made on component type
                 ClassNode componentType = inferComponentType(receiver, 
int_TYPE);
                 MethodCallExpression subcall = callX(castX(componentType, 
EmptyExpression.INSTANCE), name, call.getArguments());
                 subcall.setLineNumber(call.getLineNumber()); 
subcall.setColumnNumber(call.getColumnNumber());
@@ -3751,11 +3724,7 @@ public class StaticTypeCheckingVisitor extends 
ClassCodeVisitorSupport {
 
         visitClosureExpression(closure);
 
-        if (getInferredReturnType(closure) != null) {
-            return getInferredReturnType(closure);
-        }
-
-        return null;
+        return getInferredReturnType(closure);
     }
 
     /**
@@ -4206,7 +4175,7 @@ public class StaticTypeCheckingVisitor extends 
ClassCodeVisitorSupport {
      * @param type the inferred type of {@code expr}
      */
     private ClassNode checkForTargetType(final Expression expr, final 
ClassNode type) {
-        ClassNode sourceType = (hasInferredReturnType(expr) ? 
getInferredReturnType(expr) : type);
+        ClassNode sourceType = 
Optional.ofNullable(getInferredReturnType(expr)).orElse(type);
 
         ClassNode targetType = null;
         MethodNode enclosingMethod = typeCheckingContext.getEnclosingMethod();
@@ -4281,11 +4250,6 @@ public class StaticTypeCheckingVisitor extends 
ClassCodeVisitorSupport {
         return expr instanceof MapExpression && ((MapExpression) 
expr).getMapEntryExpressions().isEmpty();
     }
 
-    private static boolean hasInferredReturnType(final Expression expression) {
-        ClassNode type = expression.getNodeMetaData(INFERRED_RETURN_TYPE);
-        return type != null && !type.getName().equals(ClassHelper.OBJECT);
-    }
-
     @Override
     public void visitTryCatchFinally(final TryCatchStatement statement) {
         List<CatchStatement> catchStatements = statement.getCatchStatements();
diff --git a/src/test/groovy/transform/stc/TypeInferenceSTCTest.groovy 
b/src/test/groovy/transform/stc/TypeInferenceSTCTest.groovy
index 3e7cff4..0c596f6 100644
--- a/src/test/groovy/transform/stc/TypeInferenceSTCTest.groovy
+++ b/src/test/groovy/transform/stc/TypeInferenceSTCTest.groovy
@@ -18,6 +18,7 @@
  */
 package groovy.transform.stc
 
+import groovy.test.NotYetImplemented
 import org.codehaus.groovy.ast.ClassHelper
 import org.codehaus.groovy.ast.ClassNode
 import org.codehaus.groovy.ast.MethodNode
@@ -614,7 +615,7 @@ class TypeInferenceSTCTest extends 
StaticTypeCheckingTestCase {
         '''
     }
 
-   void testCallMethodInWithContextAndShadowing() {
+    void testCallMethodInWithContextAndShadowing() {
        // make sure that the method which is found in 'with' is actually the 
one from class A
        // which returns a String
        assertScript '''
@@ -774,11 +775,38 @@ class TypeInferenceSTCTest extends 
StaticTypeCheckingTestCase {
     }
 
     void testFlowTypingWithStringVariable() {
-        // as anything can be assigned to a string, flow typing engine
-        // could "erase" the type of the original variable although is must not
         assertScript '''
-            String str = new Object() // type checker will not complain, 
anything assignable to a String
-            str.toUpperCase() // should not complain
+            String s = new Object() // anything assignable to String
+            s.toUpperCase()
+        '''
+    }
+
+    @NotYetImplemented // GROOVY-10294
+    void testFlowTypingWithNullAssignment() {
+        assertScript '''
+            class C {
+            }
+            C test() {
+                def x = new C()
+                if (false) {
+                    x = null
+                }
+                x
+            }
+            assert test() != null
+        '''
+    }
+
+    // GROOVY-10308
+    void testFlowTypingWithNullAssignment2() {
+        assertScript '''
+            class C<T> {
+                T p
+            }
+            def x = { -> new C<String>() }
+            def y = x()
+            def z = y.p // false positive: field access error
+            y = null
         '''
     }
 
@@ -870,7 +898,8 @@ class TypeInferenceSTCTest extends 
StaticTypeCheckingTestCase {
         '''
     }
 
-    void testGroovy6215() {
+    // GROOVY-6215
+    void testSwitchCaseAnalysis2() {
         assertScript '''
             def processNumber(int x) {
                 def value = getValueForNumber(x)
diff --git 
a/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy7333Bug.groovy 
b/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy7333.groovy
similarity index 94%
rename from 
src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy7333Bug.groovy
rename to src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy7333.groovy
index 0916e27..2a7a962 100644
--- a/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy7333Bug.groovy
+++ b/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy7333.groovy
@@ -21,7 +21,7 @@ package org.codehaus.groovy.classgen.asm.sc.bugs
 import groovy.transform.stc.StaticTypeCheckingTestCase
 import org.codehaus.groovy.classgen.asm.sc.StaticCompilationTestSupport
 
-final class Groovy7333Bug extends StaticTypeCheckingTestCase implements 
StaticCompilationTestSupport {
+final class Groovy7333 extends StaticTypeCheckingTestCase implements 
StaticCompilationTestSupport {
 
     // GROOVY-7333
     void testIncorrectInstanceOfInference1() {
@@ -49,7 +49,7 @@ final class Groovy7333Bug extends StaticTypeCheckingTestCase 
implements StaticCo
             void test(A a) {
                 if (a instanceof B) {
                     @ASTTest(phase=INSTRUCTION_SELECTION, value={
-                        def type = 
node.rightExpression.getNodeMetaData(INFERRED_RETURN_TYPE)
+                        def type = 
node.rightExpression.getNodeMetaData(INFERRED_TYPE)
                         assert type.text == 'B' // not '<UnionType:A+B>'
                     })
                     def x = a

Reply via email to