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 <[email protected]> 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)
