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 2022/07/26 14:22:11 UTC

[groovy] 02/05: GROOVY-10271, GROOVY-10272: STC: process closure in ternary expression

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

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

commit 5145aa4ae8d5ee9c0e04e16d3c0b8dcbad5e591f
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Thu May 19 12:28:46 2022 -0500

    GROOVY-10271, GROOVY-10272: STC: process closure in ternary expression
    
    4_0_X backport
---
 .../transform/stc/StaticTypeCheckingVisitor.java   | 23 +++++++++++++++++-----
 .../transform/stc/TernaryOperatorSTCTest.groovy    |  6 +++---
 2 files changed, 21 insertions(+), 8 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 7569f9683e..a38c74f094 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -4205,12 +4205,10 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
         }
         Expression trueExpression = expression.getTrueExpression();
         ClassNode typeOfTrue = findCurrentInstanceOfClass(trueExpression, null);
-        trueExpression.visit(this);
-        if (typeOfTrue == null) typeOfTrue = getType(trueExpression);
+        typeOfTrue = Optional.ofNullable(typeOfTrue).orElse(visitValueExpression(trueExpression));
         typeCheckingContext.popTemporaryTypeInfo(); // instanceof doesn't apply to false branch
         Expression falseExpression = expression.getFalseExpression();
-        falseExpression.visit(this);
-        ClassNode typeOfFalse = getType(falseExpression);
+        ClassNode typeOfFalse = visitValueExpression(falseExpression);
 
         ClassNode resultType;
         if (isNullConstant(trueExpression) && isNullConstant(falseExpression)) { // GROOVY-5523
@@ -4230,6 +4228,18 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
         popAssignmentTracking(oldTracker);
     }
 
+    /**
+     * @param expr true or false branch of ternary expression
+     * @return the inferred type of {@code expr}
+     */
+    private ClassNode visitValueExpression(final Expression expr) {
+        if (expr instanceof ClosureExpression) {
+            applyTargetType(checkForTargetType(expr, null), expr);
+        }
+        expr.visit(this);
+        return getType(expr);
+    }
+
     /**
      * @param expr true or false branch of ternary expression
      * @param type the inferred type of {@code expr}
@@ -4255,11 +4265,14 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
              targetType = enclosingMethod.getReturnType();
         }
 
+        if (expr instanceof ClosureExpression) { // GROOVY-10271, GROOVY-10272
+            return isSAMType(targetType) ? targetType : sourceType;
+        }
+
         if (expr instanceof ConstructorCallExpression) { // GROOVY-9972, GROOVY-9983
             // GROOVY-10114: type parameter(s) could be inferred from call arguments
             if (targetType == null) targetType = sourceType.getPlainNodeReference();
             inferDiamondType((ConstructorCallExpression) expr, targetType);
-            return sourceType;
         }
 
         if (targetType == null) return sourceType;
diff --git a/src/test/groovy/transform/stc/TernaryOperatorSTCTest.groovy b/src/test/groovy/transform/stc/TernaryOperatorSTCTest.groovy
index 3b975d2c4c..61deb89ff1 100644
--- a/src/test/groovy/transform/stc/TernaryOperatorSTCTest.groovy
+++ b/src/test/groovy/transform/stc/TernaryOperatorSTCTest.groovy
@@ -166,7 +166,7 @@ class TernaryOperatorSTCTest extends StaticTypeCheckingTestCase {
         '''
     }
 
-    @NotYetImplemented // GROOVY-10271
+    // GROOVY-10271
     void testFunctionalInterfaceTarget1() {
         for (flag in ['true', 'false']) {
             assertScript """import java.util.function.Supplier
@@ -179,7 +179,7 @@ class TernaryOperatorSTCTest extends StaticTypeCheckingTestCase {
         }
     }
 
-    @NotYetImplemented // GROOVY-10272
+    // GROOVY-10272
     void testFunctionalInterfaceTarget2() {
         assertScript '''
             import java.util.function.Function
@@ -235,7 +235,7 @@ class TernaryOperatorSTCTest extends StaticTypeCheckingTestCase {
     }
 
     // GROOVY-10358
-    void testCommonInterface() {
+    void testCommonInterface1() {
         assertScript '''
             interface I {
                 int m(int i)