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:41 UTC

[groovy] branch master updated (b29512397d -> 78276ce051)

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

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


    from b29512397d GROOVY-10697: @ToString throws an NPE for POJO with null field
     new fe84544d0b GROOVY-10699: STC: resolve type arguments from closure/lambda parameters
     new 78276ce051 GROOVY-10701: null-safe `findSAM`, `isSAMType` and `isClosureWithType`

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../java/org/codehaus/groovy/ast/ClassHelper.java   |  1 +
 .../transform/stc/StaticTypeCheckingSupport.java    |  2 +-
 .../transform/stc/StaticTypeCheckingVisitor.java    |  7 ++++++-
 .../groovy/transform/stc/GenericsSTCTest.groovy     | 21 +++++++++++++++++++++
 .../transform/stc/TernaryOperatorSTCTest.groovy     | 18 ++++++++++++++++++
 5 files changed, 47 insertions(+), 2 deletions(-)


[groovy] 02/02: GROOVY-10701: null-safe `findSAM`, `isSAMType` and `isClosureWithType`

Posted by em...@apache.org.
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 '''


[groovy] 01/02: GROOVY-10699: STC: resolve type arguments from closure/lambda parameters

Posted by em...@apache.org.
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 fe84544d0b238e738e4e7f4db4de0cb8fa43e9be
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Fri Jul 22 09:37:03 2022 -0500

    GROOVY-10699: STC: resolve type arguments from closure/lambda parameters
---
 .../transform/stc/StaticTypeCheckingSupport.java    |  2 +-
 .../groovy/transform/stc/GenericsSTCTest.groovy     | 21 +++++++++++++++++++++
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
index 18093b95f5..8a826212cc 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -1712,7 +1712,7 @@ public abstract class StaticTypeCheckingSupport {
      * Should the target not have any generics this method does nothing.
      */
     static void extractGenericsConnections(final Map<GenericsTypeName, GenericsType> connections, final ClassNode type, final ClassNode target) {
-        if (target == null || target == type || !isUsingGenericsOrIsArrayUsingGenerics(target)) return;
+        if (target == null || target == type || (!target.isGenericsPlaceHolder() && !isUsingGenericsOrIsArrayUsingGenerics(target))) return;
         if (type == null || type == UNKNOWN_PARAMETER_TYPE) return;
 
         if (target.isGenericsPlaceHolder()) {
diff --git a/src/test/groovy/transform/stc/GenericsSTCTest.groovy b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
index dd92c842a4..b61d831a71 100644
--- a/src/test/groovy/transform/stc/GenericsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
@@ -3774,6 +3774,27 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
         '''
     }
 
+    // GROOVY-10699
+    void testReturnTypeInferenceWithClosure4() {
+        for (type in ['Function<T,T>', 'UnaryOperator<T>']) {
+            assertScript """import java.util.function.*
+
+                <T> T m($type x) {
+                    x.apply(null)
+                }
+
+                void test() {
+                    // the only type witness for T is the lambda parameter
+                    @ASTTest(phase=INSTRUCTION_SELECTION, value={
+                        assert node.getNodeMetaData(INFERRED_TYPE) == Double_TYPE
+                    })
+                    def x = m( (Double d) -> d ) // Expected type Object for lambda parameter: d
+                }
+                test()
+            """
+        }
+    }
+
     // GROOVY-6129
     void testShouldNotThrowNPE() {
         assertScript '''