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/05/09 15:13:26 UTC

[groovy] branch master updated: GROOVY-8202: STC: void doesn't factor into closure return type inference

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 1def253  GROOVY-8202: STC: void doesn't factor into closure return type inference
1def253 is described below

commit 1def25301b42132f0fce82f2f524aa09c53835d4
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sun May 9 09:55:14 2021 -0500

    GROOVY-8202: STC: void doesn't factor into closure return type inference
---
 .../transform/stc/StaticTypeCheckingVisitor.java   |  2 +-
 .../groovy/transform/stc/ClosuresSTCTest.groovy    | 93 +++++++++++++++++-----
 2 files changed, 74 insertions(+), 21 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 3e910c2..84746a6 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -2209,7 +2209,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
                 && STRING_TYPE.equals(getInferredReturnType(enclosingClosure.getClosureExpression()))) {
             // GROOVY-9971: convert GString to String at the point of return
             enclosingClosure.addReturnType(STRING_TYPE);
-        } else {
+        } else if (!VOID_TYPE.equals(returnType)) {
             enclosingClosure.addReturnType(returnType);
         }
     }
diff --git a/src/test/groovy/transform/stc/ClosuresSTCTest.groovy b/src/test/groovy/transform/stc/ClosuresSTCTest.groovy
index 81ed63d..2f76ca7 100644
--- a/src/test/groovy/transform/stc/ClosuresSTCTest.groovy
+++ b/src/test/groovy/transform/stc/ClosuresSTCTest.groovy
@@ -131,9 +131,38 @@ class ClosuresSTCTest extends StaticTypeCheckingTestCase {
         'Possible loss of precision from long to byte'
     }
 
-    // GROOVY-8427
+    // GROOVY-9907
     void testClosureReturnTypeInference4() {
         assertScript '''
+            Integer foo(x) {
+                if (x instanceof Integer) {
+                    def bar = { -> return x }
+                    return bar.call()
+                }
+                return 0
+            }
+            assert foo(1) == 1
+        '''
+    }
+
+    // GROOVY-9971
+    void testClosureReturnTypeInference5() {
+        assertScript '''
+            def m(Closure<String> c) {
+                c.call()
+            }
+            final x = 123
+            Closure<String> c = { -> "x=$x" }
+            String type = c.call().class.name
+            assert type == 'java.lang.String'
+            type = (m { -> "x=$x" }).class.name
+            assert type == 'java.lang.String' // not GStringImpl
+        '''
+    }
+
+    // GROOVY-8427
+    void testClosureReturnTypeInference6() {
+        assertScript '''
             import java.util.function.Consumer
 
             class C {
@@ -153,32 +182,56 @@ class ClosuresSTCTest extends StaticTypeCheckingTestCase {
         '''
     }
 
-    // GROOVY-9907
-    void testClosureReturnTypeInference5() {
+    // GROOVY-8202
+    void testClosureReturnTypeInference7() {
         assertScript '''
-            Integer foo(x) {
-                if (x instanceof Integer) {
-                    def bar = { -> return x }
-                    return bar.call()
+            void proc() {
+            }
+            String test0(flag) {
+              if (flag) {
+                'foo'
+              } else {
+                proc()
+              }
+            }
+            String test1(flag) {
+              Closure<String> c = { ->
+                if (flag) {
+                  'bar'
+                } else {
+                  proc()
+                  null
                 }
-                return 0
+              }
+              c.call()
             }
-            assert foo(1) == 1
+            String test2(flag) {
+              Closure<String> c = { -> // Cannot assign Closure<Object> to Closure<String>
+                if (flag) {
+                  'baz'
+                } else {
+                  proc()
+                }
+              }
+              c.call()
+            }
+
+            assert test0(true) == 'foo'
+            assert test1(true) == 'bar'
+            assert test2(true) == 'baz'
+            assert test0(false) == null
+            assert test1(false) == null
+            assert test2(false) == null
         '''
-    }
 
-    // GROOVY-9971
-    void testClosureReturnTypeInference6() {
         assertScript '''
-            def m(Closure<String> c) {
-                c.call()
+            Closure<Void> c = { flag ->
+                if (flag) {
+                    print 'true'
+                } else {
+                    print 'false'
+                }
             }
-            final x = 123
-            Closure<String> c = { -> "x=$x" }
-            String type = c.call().class.name
-            assert type == 'java.lang.String'
-            type = (m { -> "x=$x" }).class.name
-            assert type == 'java.lang.String' // not GStringImpl
         '''
     }