Repository: groovy
Updated Branches:
  refs/heads/native-lambda 5965c5c07 -> d53fb4f8a


Support nested native lambda


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/d53fb4f8
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/d53fb4f8
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/d53fb4f8

Branch: refs/heads/native-lambda
Commit: d53fb4f8a4d07811243f77c36980d153a9a23037
Parents: 5965c5c
Author: sunlan <sun...@apache.org>
Authored: Fri Jan 26 16:59:26 2018 +0800
Committer: sunlan <sun...@apache.org>
Committed: Fri Jan 26 16:59:26 2018 +0800

----------------------------------------------------------------------
 .../asm/sc/StaticTypesLambdaWriter.java         | 16 ++--
 src/test/groovy/transform/stc/LambdaTest.groovy | 81 +++++++++++++++++++-
 2 files changed, 88 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/d53fb4f8/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesLambdaWriter.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesLambdaWriter.java
 
b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesLambdaWriter.java
index 121c8f6..899fd45 100644
--- 
a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesLambdaWriter.java
+++ 
b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesLambdaWriter.java
@@ -107,7 +107,7 @@ public class StaticTypesLambdaWriter extends LambdaWriter {
 
         ClassNode classNode = controller.getClassNode();
         boolean isInterface = classNode.isInterface();
-        ClassNode lambdaClassNode = getOrAddLambdaClass(expression, ACC_PUBLIC 
| (isInterface ? ACC_STATIC : 0));
+        ClassNode lambdaClassNode = getOrAddLambdaClass(expression, ACC_PUBLIC 
| (isInterface ? ACC_STATIC : 0), abstractMethodNode);
         MethodNode syntheticLambdaMethodNode = 
lambdaClassNode.getMethods(DO_CALL).get(0);
 
         newGroovyLambdaInstanceAndLoad(lambdaClassNode, 
syntheticLambdaMethodNode);
@@ -259,10 +259,10 @@ public class StaticTypesLambdaWriter extends LambdaWriter 
{
         return parameterType.redirect().isInterface() && 
!parameterType.redirect().getAnnotations(ClassHelper.FunctionalInterface_Type).isEmpty();
     }
 
-    public ClassNode getOrAddLambdaClass(LambdaExpression expression, int 
mods) {
+    public ClassNode getOrAddLambdaClass(LambdaExpression expression, int 
mods, MethodNode abstractMethodNode) {
         ClassNode lambdaClass = lambdaClassMap.get(expression);
         if (lambdaClass == null) {
-            lambdaClass = createLambdaClass(expression, mods);
+            lambdaClass = createLambdaClass(expression, mods, 
abstractMethodNode);
             lambdaClassMap.put(expression, lambdaClass);
             controller.getAcg().addInnerClass(lambdaClass);
             lambdaClass.addInterface(ClassHelper.GENERATED_LAMBDA_TYPE);
@@ -271,7 +271,7 @@ public class StaticTypesLambdaWriter extends LambdaWriter {
         return lambdaClass;
     }
 
-    protected ClassNode createLambdaClass(LambdaExpression expression, int 
mods) {
+    protected ClassNode createLambdaClass(LambdaExpression expression, int 
mods, MethodNode abstractMethodNode) {
         ClassNode outerClass = controller.getOutermostClass();
         ClassNode classNode = controller.getClassNode();
         String name = genLambdaClassName();
@@ -290,7 +290,7 @@ public class StaticTypesLambdaWriter extends LambdaWriter {
             answer.setScriptBody(true);
         }
 
-        MethodNode syntheticLambdaMethodNode = 
addSyntheticLambdaMethodNode(expression, answer);
+        MethodNode syntheticLambdaMethodNode = 
addSyntheticLambdaMethodNode(expression, answer, abstractMethodNode);
         Parameter[] localVariableParameters = 
syntheticLambdaMethodNode.getNodeMetaData(LAMBDA_SHARED_VARIABLES);
 
         addFieldsAndGettersForLocalVariables(answer, localVariableParameters);
@@ -312,9 +312,9 @@ public class StaticTypesLambdaWriter extends LambdaWriter {
                 + controller.getContext().getNextLambdaInnerName(outerClass, 
classNode, methodNode);
     }
 
-    private MethodNode addSyntheticLambdaMethodNode(LambdaExpression 
expression, InnerClassNode answer) {
+    private MethodNode addSyntheticLambdaMethodNode(LambdaExpression 
expression, InnerClassNode answer, MethodNode abstractMethodNode) {
         Parameter[] parametersWithExactType = 
createParametersWithExactType(expression); // expression.getParameters();
-        ClassNode returnType = 
expression.getNodeMetaData(StaticTypesMarker.INFERRED_RETURN_TYPE); 
//abstractMethodNode.getReturnType();
+//        ClassNode returnType = 
expression.getNodeMetaData(StaticTypesMarker.INFERRED_RETURN_TYPE); 
//abstractMethodNode.getReturnType();
         Parameter[] localVariableParameters = 
getLambdaSharedVariables(expression);
         removeInitialValues(localVariableParameters);
 
@@ -325,7 +325,7 @@ public class StaticTypesLambdaWriter extends LambdaWriter {
                 answer.addMethod(
                         DO_CALL,
                         Opcodes.ACC_PUBLIC,
-                        returnType,
+                        abstractMethodNode.getReturnType() 
/*ClassHelper.OBJECT_TYPE*/ /*returnType*/,
                         methodParameterList.toArray(Parameter.EMPTY_ARRAY),
                         ClassNode.EMPTY_ARRAY,
                         expression.getCode()

http://git-wip-us.apache.org/repos/asf/groovy/blob/d53fb4f8/src/test/groovy/transform/stc/LambdaTest.groovy
----------------------------------------------------------------------
diff --git a/src/test/groovy/transform/stc/LambdaTest.groovy 
b/src/test/groovy/transform/stc/LambdaTest.groovy
index 7f28151..212ec11 100644
--- a/src/test/groovy/transform/stc/LambdaTest.groovy
+++ b/src/test/groovy/transform/stc/LambdaTest.groovy
@@ -485,7 +485,7 @@ TestScript0.groovy: 14: [Static type checking] - Cannot 
find matching method jav
             }
         
             public static void p() {
-                Function<Integer, String> f = (Integer e) -> 'a' + e
+                Function<Integer, String> f = (Integer e) -> 'a' + e // STC 
can not infer the type of `e`, so we have to specify the type `Integer` by 
ourselves
                 assert ['a1', 'a2', 'a3'] == [1, 2, 
3].stream().map(f).collect(Collectors.toList())
             }
         }
@@ -520,4 +520,83 @@ TestScript0.groovy: 14: [Static type checking] - Cannot 
find matching method jav
         
         '''
     }
+
+    void testFunctionWithNestedLambda() {
+        assertScript '''
+        import groovy.transform.CompileStatic
+        import java.util.stream.Collectors
+        import java.util.stream.Stream
+        
+        @CompileStatic
+        public class Test1 {
+            public static void main(String[] args) {
+                p()
+            }
+        
+            public static void p() {
+                [1, 2].stream().forEach(e -> {
+                    def list = ['a', 'b'].stream().map(f -> f + e).toList()
+                    if (1 == e) {
+                        assert ['a1', 'b1'] == list
+                    } else if (2 == e) {
+                        assert ['a2', 'b2'] == list
+                    }
+                })
+                
+            }
+        }
+        '''
+    }
+
+    void testFunctionWithNestedLambda2() {
+        assertScript '''
+        import groovy.transform.CompileStatic
+        import java.util.stream.Collectors
+        import java.util.stream.Stream
+        
+        @CompileStatic
+        public class Test1 {
+            public static void main(String[] args) {
+                p()
+            }
+        
+            public static void p() {
+                def list = ['a', 'b'].stream()
+                .map(e -> {
+                    [1, 2].stream().map(f -> e + f).toList()
+                }).toList()
+                
+                assert ['a1', 'a2'] == list[0]
+                assert ['b1', 'b2'] == list[1]
+            }
+        }
+        '''
+    }
+
+    void testFunctionWithNestedLambda3() {
+        assertScript '''
+        import groovy.transform.CompileStatic
+        import java.util.stream.Collectors
+        import java.util.stream.Stream
+        import java.util.function.Function
+        
+        @CompileStatic
+        public class Test1 {
+            public static void main(String[] args) {
+                p()
+            }
+        
+            public static void p() {
+                def list = ['a', 'b'].stream()
+                .map(e -> {
+                    Function<Integer, String> x = (Integer f) -> e + f
+                    [1, 2].stream().map(x).toList()
+                }).toList()
+                
+                assert ['a1', 'a2'] == list[0]
+                assert ['b1', 'b2'] == list[1]
+            }
+        }
+        '''
+    }
 }

Reply via email to