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

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


The following commit(s) were added to refs/heads/GROOVY_3_0_X by this push:
     new 7c62395  GROOVY-10033, GROOVY-10046, GROOVY-10047: refs for ctor and 
static calls
7c62395 is described below

commit 7c6239554227201c86211006bd5193b138ab7889
Author: Eric Milles <[email protected]>
AuthorDate: Wed Apr 21 11:57:04 2021 -0500

    GROOVY-10033, GROOVY-10046, GROOVY-10047: refs for ctor and static calls
    
    Conflicts:
        
src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesMethodReferenceExpressionWriter.java
        src/test/groovy/transform/stc/MethodReferenceTest.groovy
---
 .../java/org/codehaus/groovy/ast/ClassHelper.java  |   2 +-
 ...StaticTypesMethodReferenceExpressionWriter.java | 123 ++++++-------
 .../asm/sc/StaticTypesWriterController.java        |   8 +-
 .../transform/stc/StaticTypeCheckingVisitor.java   |  26 ++-
 .../transform/stc/MethodReferenceTest.groovy       | 202 ++++++++++++++++-----
 5 files changed, 222 insertions(+), 139 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/ast/ClassHelper.java 
b/src/main/java/org/codehaus/groovy/ast/ClassHelper.java
index 17bcc8d..413ac68 100644
--- a/src/main/java/org/codehaus/groovy/ast/ClassHelper.java
+++ b/src/main/java/org/codehaus/groovy/ast/ClassHelper.java
@@ -418,7 +418,7 @@ public class ClassHelper {
     public static boolean isFunctionalInterface(final ClassNode type) {
         // Functional interface must be an interface at first, or the 
following exception will occur:
         // java.lang.invoke.LambdaConversionException: Functional interface 
SamCallable is not an interface
-        return type.isInterface() && isSAMType(type);
+        return type != null && type.isInterface() && isSAMType(type);
     }
 
     /**
diff --git 
a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesMethodReferenceExpressionWriter.java
 
b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesMethodReferenceExpressionWriter.java
index ebbfdb9..14af6ba 100644
--- 
a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesMethodReferenceExpressionWriter.java
+++ 
b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesMethodReferenceExpressionWriter.java
@@ -20,10 +20,7 @@ package org.codehaus.groovy.classgen.asm.sc;
 
 import groovy.lang.Tuple;
 import groovy.lang.Tuple2;
-import groovy.transform.CompileStatic;
-import groovy.transform.Generated;
 import org.codehaus.groovy.ast.ASTNode;
-import org.codehaus.groovy.ast.AnnotationNode;
 import org.codehaus.groovy.ast.ClassHelper;
 import org.codehaus.groovy.ast.ClassNode;
 import org.codehaus.groovy.ast.MethodNode;
@@ -31,17 +28,17 @@ import org.codehaus.groovy.ast.Parameter;
 import org.codehaus.groovy.ast.expr.ArgumentListExpression;
 import org.codehaus.groovy.ast.expr.ArrayExpression;
 import org.codehaus.groovy.ast.expr.ClassExpression;
-import org.codehaus.groovy.ast.expr.ConstantExpression;
 import org.codehaus.groovy.ast.expr.Expression;
+import org.codehaus.groovy.ast.expr.MethodCallExpression;
 import org.codehaus.groovy.ast.expr.MethodReferenceExpression;
 import org.codehaus.groovy.ast.tools.GeneralUtils;
 import org.codehaus.groovy.classgen.asm.BytecodeHelper;
 import org.codehaus.groovy.classgen.asm.MethodReferenceExpressionWriter;
 import org.codehaus.groovy.classgen.asm.WriterController;
-import org.codehaus.groovy.runtime.ArrayTypeUtils;
 import org.codehaus.groovy.syntax.RuntimeParserException;
+import org.codehaus.groovy.transform.sc.StaticCompilationMetadataKeys;
 import org.codehaus.groovy.transform.stc.ExtensionMethodNode;
-import org.objectweb.asm.MethodVisitor;
+import org.codehaus.groovy.transform.stc.StaticTypesMarker;
 import org.objectweb.asm.Opcodes;
 
 import java.util.Arrays;
@@ -49,27 +46,25 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.stream.Collectors;
 
+import static org.apache.groovy.ast.tools.ClassNodeUtils.addGeneratedMethod;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.args;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.block;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.callX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.classX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.ctorX;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.nullX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.returnS;
 import static 
org.codehaus.groovy.ast.tools.ParameterUtils.parametersCompatible;
 import static 
org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.filterMethodsByVisibility;
 import static 
org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.findDGMMethodsForClassNode;
 import static 
org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.isAssignableTo;
-import static 
org.codehaus.groovy.transform.stc.StaticTypesMarker.CLOSURE_ARGUMENTS;
 
 /**
- * Writer responsible for generating method reference in statically compiled 
mode.
+ * Generates bytecode for method reference expressions in statically-compiled 
code.
  *
  * @since 3.0.0
  */
 public class StaticTypesMethodReferenceExpressionWriter extends 
MethodReferenceExpressionWriter implements AbstractFunctionalInterfaceWriter {
-    private static final String METHODREF_EXPR_INSTANCE = 
"__METHODREF_EXPR_INSTANCE";
-    private static final ClassNode GENERATED_TYPE = 
ClassHelper.make(Generated.class);
-    private static final ClassNode COMPILE_STATIC_TYPE = 
ClassHelper.make(CompileStatic.class);
 
     public StaticTypesMethodReferenceExpressionWriter(WriterController 
controller) {
         super(controller);
@@ -103,7 +98,7 @@ public class StaticTypesMethodReferenceExpressionWriter 
extends MethodReferenceE
         ClassNode typeOrTargetRefType = isClassExpression ? 
typeOrTargetRef.getType()
                 : controller.getTypeChooser().resolveType(typeOrTargetRef, 
classNode);
 
-        ClassNode[] methodReferenceParamTypes = 
methodReferenceExpression.getNodeMetaData(CLOSURE_ARGUMENTS);
+        ClassNode[] methodReferenceParamTypes = 
methodReferenceExpression.getNodeMetaData(StaticTypesMarker.CLOSURE_ARGUMENTS);
         Parameter[] parametersWithExactType = 
createParametersWithExactType(abstractMethodNode, methodReferenceParamTypes);
 
         String methodRefName = 
methodReferenceExpression.getMethodName().getText();
@@ -127,33 +122,30 @@ public class StaticTypesMethodReferenceExpressionWriter 
extends MethodReferenceE
                 methodRefMethod = addSyntheticMethodForDGSM(methodRefMethod);
             }
 
-            ClassExpression classExpression = new 
ClassExpression(methodRefMethod.getDeclaringClass());
+            typeOrTargetRefType = methodRefMethod.getDeclaringClass();
+            ClassExpression classExpression = classX(typeOrTargetRefType);
             classExpression.setSourcePosition(typeOrTargetRef);
             typeOrTargetRef = classExpression;
-            typeOrTargetRefType = typeOrTargetRef.getType();
+            isClassExpression = true;
         }
 
         methodRefMethod.putNodeMetaData(ORIGINAL_PARAMETERS_WITH_EXACT_TYPE, 
parametersWithExactType);
-        MethodVisitor mv = controller.getMethodVisitor();
 
-        boolean isClassExpr = isClassExpr(typeOrTargetRef);
-        if (!isClassExpr) {
+        if (!isClassExpression) {
             if (isConstructorReference) {
-                // TODO move the checking code to the Parrot parser
+                // TODO: move the checking code to the Parrot parser
                 addFatalError("Constructor reference must be className::new", 
methodReferenceExpression);
             } else if (methodRefMethod.isStatic()) {
                 ClassExpression classExpression = classX(typeOrTargetRefType);
                 classExpression.setSourcePosition(typeOrTargetRef);
                 typeOrTargetRef = classExpression;
-                isClassExpr = true;
-            }
-
-            if (!isClassExpr) {
+                isClassExpression = true;
+            } else {
                 typeOrTargetRef.visit(controller.getAcg());
             }
         }
 
-        mv.visitInvokeDynamicInsn(
+        controller.getMethodVisitor().visitInvokeDynamicInsn(
                 abstractMethodNode.getName(),
                 createAbstractMethodDesc(functionalInterfaceType, 
typeOrTargetRef),
                 createBootstrapMethod(isInterface, false),
@@ -164,7 +156,7 @@ public class StaticTypesMethodReferenceExpressionWriter 
extends MethodReferenceE
                         methodRefMethod, false)
         );
 
-        if (isClassExpr) {
+        if (isClassExpression) {
             controller.getOperandStack().push(redirect);
         } else {
             controller.getOperandStack().replace(redirect, 1);
@@ -194,55 +186,53 @@ public class StaticTypesMethodReferenceExpressionWriter 
extends MethodReferenceE
     private MethodNode addSyntheticMethodForDGSM(MethodNode mn) {
         Parameter[] parameters = removeFirstParameter(mn.getParameters());
         ArgumentListExpression args = args(parameters);
-        args.getExpressions().add(0, ConstantExpression.NULL);
+        args.getExpressions().add(0, nullX());
+
+        MethodCallExpression returnValue = 
callX(classX(mn.getDeclaringClass()), mn.getName(), args);
+        
returnValue.putNodeMetaData(StaticTypesMarker.DIRECT_METHOD_CALL_TARGET, mn);
+        returnValue.setMethodTarget(mn);
 
-        MethodNode syntheticMethodNode = 
controller.getClassNode().addSyntheticMethod(
-                "dgsm$$" + 
mn.getParameters()[0].getType().getName().replace(".", "$") + "$$" + 
mn.getName(),
+        MethodNode delegateMethod = 
addGeneratedMethod(controller.getClassNode(),
+                "dgsm$$" + 
mn.getParameters()[0].getType().getName().replace('.', '$') + "$$" + 
mn.getName(),
                 Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL | 
Opcodes.ACC_SYNTHETIC,
                 mn.getReturnType(),
                 parameters,
                 ClassNode.EMPTY_ARRAY,
-                block(
-                        returnS(
-                                callX(new 
ClassExpression(mn.getDeclaringClass()), mn.getName(), args)
-                        )
-                )
+                block(returnS(returnValue))
         );
 
-        syntheticMethodNode.addAnnotation(new AnnotationNode(GENERATED_TYPE));
-        syntheticMethodNode.addAnnotation(new 
AnnotationNode(COMPILE_STATIC_TYPE));
+        
delegateMethod.putNodeMetaData(StaticCompilationMetadataKeys.STATIC_COMPILE_NODE,
 Boolean.TRUE);
 
-        return syntheticMethodNode;
+        return delegateMethod;
     }
 
     private MethodNode addSyntheticMethodForConstructorReference(String 
syntheticMethodName, ClassNode returnType, Parameter[] parametersWithExactType) 
{
         ArgumentListExpression ctorArgs = args(parametersWithExactType);
 
-        MethodNode syntheticMethodNode = 
controller.getClassNode().addSyntheticMethod(
+        Expression returnValue;
+        if (returnType.isArray()) {
+            returnValue = new ArrayExpression(
+                    returnType.getComponentType(),
+                    null, ctorArgs.getExpressions());
+        } else {
+            returnValue = ctorX(returnType, ctorArgs);
+        }
+
+        MethodNode delegateMethod = 
addGeneratedMethod(controller.getClassNode(),
                 syntheticMethodName,
                 Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL | 
Opcodes.ACC_SYNTHETIC,
                 returnType,
                 parametersWithExactType,
                 ClassNode.EMPTY_ARRAY,
-                block(
-                        returnS(
-                                returnType.isArray()
-                                        ?
-                                        new ArrayExpression(
-                                                
ClassHelper.make(ArrayTypeUtils.elementType(returnType.getTypeClass())),
-                                                null,
-                                                ctorArgs.getExpressions()
-                                        )
-                                        :
-                                        ctorX(returnType, ctorArgs)
-                        )
-                )
+                block(returnS(returnValue))
         );
 
-        syntheticMethodNode.addAnnotation(new AnnotationNode(GENERATED_TYPE));
-        syntheticMethodNode.addAnnotation(new 
AnnotationNode(COMPILE_STATIC_TYPE));
+        // TODO: if StaticTypesMarker.DIRECT_METHOD_CALL_TARGET or
+        // OptimizingStatementWriter.StatementMeta.class metadatas
+        // can bet set for the ctorX above, then this can be TRUE:
+        
delegateMethod.putNodeMetaData(StaticCompilationMetadataKeys.STATIC_COMPILE_NODE,
 Boolean.FALSE);
 
-        return syntheticMethodNode;
+        return delegateMethod;
     }
 
     private String genSyntheticMethodNameForConstructorReference() {
@@ -261,7 +251,7 @@ public class StaticTypesMethodReferenceExpressionWriter 
extends MethodReferenceE
         List<Parameter> methodReferenceSharedVariableList = new LinkedList<>();
 
         if (!(methodRef instanceof ClassExpression)) {
-            prependParameter(methodReferenceSharedVariableList, 
METHODREF_EXPR_INSTANCE,
+            prependParameter(methodReferenceSharedVariableList, 
"__METHODREF_EXPR_INSTANCE",
                 controller.getTypeChooser().resolveType(methodRef, 
controller.getClassNode()));
         }
 
@@ -269,29 +259,22 @@ public class StaticTypesMethodReferenceExpressionWriter 
extends MethodReferenceE
     }
 
     private Parameter[] createParametersWithExactType(MethodNode 
abstractMethodNode, ClassNode[] inferredParameterTypes) {
-        Parameter[] originalParameters = abstractMethodNode.getParameters();
-
         // We MUST clone the parameters to avoid impacting the original 
parameter type of SAM
-        Parameter[] parameters = GeneralUtils.cloneParams(originalParameters);
+        Parameter[] parameters = 
GeneralUtils.cloneParams(abstractMethodNode.getParameters());
         if (parameters == null) {
             parameters = Parameter.EMPTY_ARRAY;
         }
-
-        for (int i = 0; i < parameters.length; i++) {
-            Parameter parameter = parameters[i];
-            ClassNode parameterType = parameter.getType();
-            ClassNode inferredType = inferredParameterTypes[i];
-
-            if (null == inferredType) {
-                continue;
+        if (inferredParameterTypes != null) {
+            for (int i = 0, n = parameters.length; i < n; i += 1) {
+                ClassNode inferredParamType = inferredParameterTypes[i];
+                if (inferredParamType == null) continue;
+                Parameter parameter = parameters[i];
+
+                ClassNode type = convertParameterType(parameter.getType(), 
inferredParamType);
+                parameter.setOriginType(type);
+                parameter.setType(type);
             }
-
-            ClassNode type = convertParameterType(parameterType, inferredType);
-
-            parameter.setType(type);
-            parameter.setOriginType(type);
         }
-
         return parameters;
     }
 
diff --git 
a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesWriterController.java
 
b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesWriterController.java
index 25bd2a0..8aa352c 100644
--- 
a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesWriterController.java
+++ 
b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesWriterController.java
@@ -100,10 +100,8 @@ public class StaticTypesWriterController extends 
DelegatingController {
             node = classNode.getOuterClass();
         }
 
-        boolean isStaticCompileNode = 
classNode.getNodeMetaData(StaticCompilationMetadataKeys.STATIC_COMPILE_NODE) != 
null;
-        isInStaticallyCheckedMethod =
-                mn != null && 
(StaticCompilationVisitor.isStaticallyCompiled(node)
-                                || 
implementsGeneratedClosureOrGeneratedLambdaInterface && isStaticCompileNode);
+        isInStaticallyCheckedMethod = mn != null && 
(StaticCompilationVisitor.isStaticallyCompiled(node)
+                || implementsGeneratedClosureOrGeneratedLambdaInterface && 
Boolean.TRUE.equals(classNode.getNodeMetaData(StaticCompilationMetadataKeys.STATIC_COMPILE_NODE)));
     }
 
     @Override
@@ -121,7 +119,7 @@ public class StaticTypesWriterController extends 
DelegatingController {
     @Override
     public CallSiteWriter getCallSiteWriter() {
         MethodNode methodNode = getMethodNode();
-        if (methodNode !=null && 
methodNode.getNodeMetaData(StaticTypesMarker.DYNAMIC_RESOLUTION)==Boolean.TRUE) 
{
+        if (methodNode != null && 
Boolean.TRUE.equals(methodNode.getNodeMetaData(StaticTypesMarker.DYNAMIC_RESOLUTION)))
 {
             return super.getCallSiteWriter();
         }
         if (isInStaticallyCheckedMethod) {
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 897e5ba..ed0c92c 100644
--- 
a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ 
b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -2724,6 +2724,9 @@ public class StaticTypeCheckingVisitor extends 
ClassCodeVisitorSupport {
         if (nExpressions > 0 && expressions.get(0) instanceof MapExpression && 
params.length > 0) {
             checkNamedParamsAnnotation(params[0], (MapExpression) 
expressions.get(0));
         }
+        if (visitClosures) {
+            inferMethodReferenceType(receiver, arguments, selectedMethod);
+        }
     }
 
     private void checkNamedParamsAnnotation(final Parameter param, final 
MapExpression args) {
@@ -3564,8 +3567,6 @@ public class StaticTypeCheckingVisitor extends 
ClassCodeVisitorSupport {
                     }
                 }
             }
-
-            inferMethodReferenceType(call, receiver, argumentList);
         } finally {
             typeCheckingContext.popEnclosingMethodCall();
             extension.afterMethodCall(call);
@@ -3583,28 +3584,23 @@ public class StaticTypeCheckingVisitor extends 
ClassCodeVisitorSupport {
         return Closure.OWNER_FIRST;
     }
 
-    private void inferMethodReferenceType(final MethodCallExpression call, 
final ClassNode receiver, final ArgumentListExpression argumentList) {
-        if (call == null) return;
+    private void inferMethodReferenceType(final ClassNode receiver, final 
ArgumentListExpression argumentList, final MethodNode selectedMethod) {
         if (receiver == null) return;
         if (argumentList == null) return;
+        if (selectedMethod == null) return;
 
-        List<Expression> argumentExpressionList = 
argumentList.getExpressions();
-        if (argumentExpressionList == null) return;
-
-        boolean noMethodReferenceParams = 
argumentExpressionList.stream().noneMatch(e -> e instanceof 
MethodReferenceExpression);
-        if (noMethodReferenceParams) {
+        List<Expression> argumentExpressions = argumentList.getExpressions();
+        if (argumentExpressions == null || argumentExpressions.stream()
+                .noneMatch(e -> e instanceof MethodReferenceExpression)) {
             return;
         }
 
-        MethodNode selectedMethod = 
call.getNodeMetaData(DIRECT_METHOD_CALL_TARGET);
-        if (selectedMethod == null) return;
-
         Parameter[] parameters = selectedMethod.getParameters();
 
         List<Integer> methodReferenceParamIndexList = new LinkedList<>();
         List<Expression> newArgumentExpressionList = new LinkedList<>();
-        for (int i = 0, n = argumentExpressionList.size(); i < n; i++) {
-            Expression argumentExpression = argumentExpressionList.get(i);
+        for (int i = 0, n = argumentExpressions.size(); i < n; i += 1) {
+            Expression argumentExpression = argumentExpressions.get(i);
             if (!(argumentExpression instanceof MethodReferenceExpression)) {
                 newArgumentExpressionList.add(argumentExpression);
                 continue;
@@ -3630,7 +3626,7 @@ public class StaticTypeCheckingVisitor extends 
ClassCodeVisitorSupport {
         for (Integer methodReferenceParamIndex : 
methodReferenceParamIndexList) {
             LambdaExpression lambdaExpression = (LambdaExpression) 
newArgumentExpressionList.get(methodReferenceParamIndex);
             ClassNode[] argumentTypes = 
lambdaExpression.getNodeMetaData(CLOSURE_ARGUMENTS);
-            
argumentExpressionList.get(methodReferenceParamIndex).putNodeMetaData(CLOSURE_ARGUMENTS,
 argumentTypes);
+            
argumentExpressions.get(methodReferenceParamIndex).putNodeMetaData(CLOSURE_ARGUMENTS,
 argumentTypes);
         }
     }
 
diff --git a/src/test/groovy/transform/stc/MethodReferenceTest.groovy 
b/src/test/groovy/transform/stc/MethodReferenceTest.groovy
index 4e00072..4ff62ab 100644
--- a/src/test/groovy/transform/stc/MethodReferenceTest.groovy
+++ b/src/test/groovy/transform/stc/MethodReferenceTest.groovy
@@ -44,21 +44,55 @@ class MethodReferenceTest extends GroovyTestCase {
             @groovy.transform.CompileStatic
             void p() {
                 def result = [1, 2, 
3].stream().map(Integer::toString).collect(Collectors.toList())
-                assert result ['1', '2', '3']
+                assert result == ['1', '2', '3']
             }
 
             p()
         '''
     }
 
-    // class::instanceMethod
+    // class::instanceMethod -- GROOVY-10047
     void testFunctionCI3() {
+        assertScript '''
+            import java.util.function.Function
+            import static java.util.stream.Collectors.toMap
+
+            @groovy.transform.CompileStatic
+            void p() {
+                List<String> list = ['a','bc','def']
+                Function<String,String> self = str -> str // help for toMap
+                def map = list.stream().collect(toMap(self, String::length))
+                assert map == [a: 1, bc: 2, 'def': 3]
+            }
+
+            p()
+        '''
+
+        assertScript '''
+            import java.util.function.Function
+            import static java.util.stream.Collectors.toMap
+
+            @groovy.transform.CompileStatic
+            void p() {
+                List<String> list = ['a','bc','def']
+                // TODO: inference for T in toMap(Function<? super T,...>, 
Function<? super T,...>)
+                def map = 
list.stream().collect(toMap(Function.<String>identity(), String::length))
+                assert map == [a: 1, bc: 2, 'def': 3]
+            }
+
+            p()
+        '''
+    }
+
+    // class::instanceMethod
+    void testFunctionCI4() {
         def err = shouldFail '''
-            import java.util.stream.Collectors
+            import static java.util.stream.Collectors.toList
 
             @groovy.transform.CompileStatic
             void p() {
-                def result = [1, 2, 
3].stream().map(String::toString).collect(Collectors.toList())
+                def result = [1, 2, 
3].stream().map(String::toString).collect(toList())
+                assert result == ["1", "2", "3"]
             }
 
             p()
@@ -68,10 +102,10 @@ class MethodReferenceTest extends GroovyTestCase {
     }
 
     // class::instanceMethod -- GROOVY-9814
-    void testFunctionCI4() {
+    void testFunctionCI5() {
         assertScript '''
             import java.util.function.*
-            import groovy.transform.CompileStatic
+            import groovy.transform.*
 
             @CompileStatic
             class One { String id }
@@ -79,7 +113,7 @@ class MethodReferenceTest extends GroovyTestCase {
             @CompileStatic
             class Two extends One { }
 
-            @CompileStatic 
@groovy.transform.Immutable(knownImmutableClasses=[Function])
+            @CompileStatic @Immutable(knownImmutableClasses=[Function])
             class FunctionHolder<T> {
                 Function<T, ?> extractor
 
@@ -122,41 +156,6 @@ class MethodReferenceTest extends GroovyTestCase {
         '''
     }
 
-    // class::staticMethod
-    void testFunctionCS() {
-        assertScript '''
-            import groovy.transform.CompileStatic
-            import java.util.stream.Collectors
-            @CompileStatic
-            void p() {
-                def result = [1, -2, 
3].stream().map(Math::abs).collect(Collectors.toList())
-                assert [1, 2, 3] == result
-            }
-            p()
-        '''
-    }
-
-    // class::staticMethod -- GROOVY-9799
-    void testFunctionCS2() {
-        assertScript '''
-            class C {
-                String x
-            }
-            class D {
-                String x
-                static D from(C c) {
-                    new D(x: c.x)
-                }
-            }
-            @groovy.transform.CompileStatic
-            def test(C c) {
-                Optional.of(c).map(D::from).get()
-            }
-            def d = test(new C(x: 'x'))
-            assert d.x == 'x'
-        '''
-    }
-
     // instance::instanceMethod
     void testBinaryOperatorII() {
         assertScript '''
@@ -316,30 +315,137 @@ class MethodReferenceTest extends GroovyTestCase {
     }
 
     // arrayClass::new
-    void testIntFunctionCN() {
+    void testFunctionCN() {
         assertScript '''
             @groovy.transform.CompileStatic
             void p() {
-                assert new Integer[] { 1, 2, 3 } == [1, 2, 
3].stream().toArray(Integer[]::new)
+                def result = [1, 2, 3].stream().toArray(Integer[]::new)
+                assert result == new Integer[] { 1, 2, 3 }
             }
 
             p()
-
         '''
     }
 
     // class::new
-    void testFunctionCN() {
+    void testFunctionCN2() {
         assertScript '''
-            import java.util.stream.Collectors
+            import static java.util.stream.Collectors.toList
+
+            @groovy.transform.CompileStatic
+            void p() {
+                def result = ["1", "2", 
"3"].stream().map(Integer::new).collect(toList())
+                assert result == [1, 2, 3]
+            }
+
+            p()
+        '''
+    }
+
+    // class::new -- GROOVY-10033
+    void testFunctionCN3() {
+        assertScript '''
+            import java.util.function.Function
+
+            @groovy.transform.CompileStatic
+            class C {
+                C(Function<String,Integer> f) {
+                    def i = f.apply('42')
+                    assert i == 42
+                }
+                static test() {
+                    new C(Integer::new)
+                }
+            }
+            C.test()
+        '''
+    }
+
+    // class::new -- GROOVY-10033
+    void testFunctionCN4() {
+        assertScript '''
+            import java.util.function.Function
+
+            class A {
+                A(Function<A,B> f) {
+                    B b = f.apply(this)
+                    assert b instanceof X.Y
+                }
+            }
+            class B {
+                B(A a) {
+                    assert a != null
+                }
+            }
+            @groovy.transform.CompileStatic
+            class X extends A {
+              public X() {
+                super(Y::new)
+              }
+              private static class Y extends B {
+                Y(A a) {
+                  super(a)
+                }
+              }
+            }
+
+            new X()
+        '''
+    }
+
+    // class::staticMethod
+    void testFunctionCS() {
+        assertScript '''
+            import static java.util.stream.Collectors.toList
 
             @groovy.transform.CompileStatic
             void p() {
-                assert [1, 2, 3] == ["1", "2", 
"3"].stream().map(Integer::new).collect(Collectors.toList())
+                def result = [1, -2, 
3].stream().map(Math::abs).collect(toList())
+                assert [1, 2, 3] == result
             }
 
             p()
+        '''
+    }
+
+    // class::staticMethod
+    void testFunctionCS2() {
+        assertScript '''
+            import java.util.function.Function
+            import static java.util.stream.Collectors.toMap
+
+            @groovy.transform.CompileStatic
+            void p() {
+                List<String> list = ['x','y','z']
+                def map = list.stream().collect(toMap(Function.identity(), 
Collections::singletonList))
+                assert map == [x: ['x'], y: ['y'], z: ['z']]
+            }
+
+            p()
+        '''
+    }
+
+    // class::staticMethod -- GROOVY-9799
+    void testFunctionCS3() {
+        assertScript '''
+            class C {
+                String x
+            }
 
+            class D {
+                String x
+                static D from(C c) {
+                    new D(x: c.x)
+                }
+            }
+
+            @groovy.transform.CompileStatic
+            def test(C c) {
+                Optional.of(c).map(D::from).get()
+            }
+
+            def d = test(new C(x: 'x'))
+            assert d.x == 'x'
         '''
     }
 

Reply via email to