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/22 16:21:43 UTC
[groovy] 02/02: GROOVY-10701: null-safe `findSAM`, `isSAMType` and `isClosureWithType`
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
commit 78276ce051e50193c5a18d80c44febaf17ab17fd
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Fri Jul 22 11:11:43 2022 -0500
GROOVY-10701: null-safe `findSAM`, `isSAMType` and `isClosureWithType`
---
src/main/java/org/codehaus/groovy/ast/ClassHelper.java | 1 +
.../transform/stc/StaticTypeCheckingVisitor.java | 7 ++++++-
.../groovy/transform/stc/TernaryOperatorSTCTest.groovy | 18 ++++++++++++++++++
3 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/src/main/java/org/codehaus/groovy/ast/ClassHelper.java b/src/main/java/org/codehaus/groovy/ast/ClassHelper.java
index e190ffcfb3..d4daf9face 100644
--- a/src/main/java/org/codehaus/groovy/ast/ClassHelper.java
+++ b/src/main/java/org/codehaus/groovy/ast/ClassHelper.java
@@ -560,6 +560,7 @@ public class ClassHelper {
* @return the method node if type is a SAM type, null otherwise
*/
public static MethodNode findSAM(final ClassNode type) {
+ if (type == null) return null;
if (type.isInterface()) {
MethodNode sam = null;
for (MethodNode mn : type.getAbstractMethods()) {
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 0b26ae18c9..11e12da0ff 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -1072,7 +1072,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
}
private static boolean isClosureWithType(final ClassNode type) {
- return type.equals(CLOSURE_TYPE) && Optional.ofNullable(type.getGenericsTypes()).filter(gts -> gts != null && gts.length == 1).isPresent();
+ return CLOSURE_TYPE.equals(type) && Optional.ofNullable(type.getGenericsTypes()).filter(gts -> gts != null && gts.length == 1).isPresent();
}
private static boolean isCompoundAssignment(final Expression exp) {
@@ -4265,11 +4265,16 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
private ClassNode checkForTargetType(final Expression expr, final ClassNode type) {
ClassNode targetType = null;
MethodNode enclosingMethod = typeCheckingContext.getEnclosingMethod();
+ MethodCall enclosingMethodCall = (MethodCall)typeCheckingContext.getEnclosingMethodCall();
BinaryExpression enclosingExpression = typeCheckingContext.getEnclosingBinaryExpression();
if (enclosingExpression != null
&& isAssignment(enclosingExpression.getOperation().getType())
&& isTypeSource(expr, enclosingExpression.getRightExpression())) {
targetType = getDeclaredOrInferredType(enclosingExpression.getLeftExpression());
+ } else if (enclosingMethodCall != null
+ && InvocationWriter.makeArgumentList(enclosingMethodCall.getArguments())
+ .getExpressions().stream().anyMatch(arg -> isTypeSource(expr, arg))) {
+ // TODO: locate method target parameter
} else if (enclosingMethod != null
&& !enclosingMethod.isAbstract()
&& !enclosingMethod.isVoidMethod()
diff --git a/src/test/groovy/transform/stc/TernaryOperatorSTCTest.groovy b/src/test/groovy/transform/stc/TernaryOperatorSTCTest.groovy
index 92b708e40c..40dd80722e 100644
--- a/src/test/groovy/transform/stc/TernaryOperatorSTCTest.groovy
+++ b/src/test/groovy/transform/stc/TernaryOperatorSTCTest.groovy
@@ -197,6 +197,24 @@ class TernaryOperatorSTCTest extends StaticTypeCheckingTestCase {
'''
}
+ // GROOVY-10701
+ void testFunctionalInterfaceTarget3() {
+ for (type in ['Function<T,T>', 'UnaryOperator<T>']) {
+ assertScript """import java.util.function.*
+
+ def <T> T m1($type x) {
+ x.apply(null)
+ }
+ double m2(double d) {
+ Math.PI
+ }
+
+ def result = m1(true ? (Double d) -> 42.0d : this::m2)
+ assert result == 42.0d
+ """
+ }
+ }
+
// GROOVY-10357
void testAbstractMethodDefault() {
assertScript '''