Repository: groovy
Updated Branches:
  refs/heads/native-lambda 4172bd764 -> 083089fc3


Minor refactoring


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

Branch: refs/heads/native-lambda
Commit: 083089fc35405379c4a4f27fa1d3123eb396dc67
Parents: 4172bd7
Author: sunlan <[email protected]>
Authored: Sat Jan 13 00:18:00 2018 +0800
Committer: sunlan <[email protected]>
Committed: Sat Jan 13 00:18:00 2018 +0800

----------------------------------------------------------------------
 .../asm/sc/StaticTypesLambdaWriter.java         | 123 +++++++++++--------
 src/test/groovy/transform/stc/LambdaTest.groovy |  17 +++
 2 files changed, 86 insertions(+), 54 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/083089fc/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 c847c33..bdf10d8 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
@@ -31,8 +31,8 @@ import org.codehaus.groovy.classgen.asm.BytecodeHelper;
 import org.codehaus.groovy.classgen.asm.LambdaWriter;
 import org.codehaus.groovy.classgen.asm.WriterController;
 import org.codehaus.groovy.classgen.asm.WriterControllerFactory;
+import org.codehaus.groovy.transform.stc.StaticTypesMarker;
 import org.objectweb.asm.Handle;
-import org.objectweb.asm.MethodVisitor;
 import org.objectweb.asm.Opcodes;
 import org.objectweb.asm.Type;
 
@@ -77,50 +77,61 @@ public class StaticTypesLambdaWriter extends LambdaWriter {
                         .collect(Collectors.toList());
 
         if (!(isFunctionInterface(parameterType) && 
abstractMethodNodeList.size() == 1)) {
+            // if the parameter type is not real FunctionInterface, generate 
the default bytecode, which is actually a closure
             super.writeLambda(expression);
             return;
         }
 
         MethodNode abstractMethodNode = abstractMethodNodeList.get(0);
-        String abstractMethodName = abstractMethodNode.getName();
-        String abstractMethodDesc = "()L" + 
parameterType.redirect().getPackageName().replace('.', '/') + "/" + 
parameterType.redirect().getNameWithoutPackage() + ";";
+        String abstractMethodDesc = createMethodDescriptor(abstractMethodNode);
 
-
-        MethodVisitor mv = controller.getMethodVisitor();
-        ClassNode lambdaEnclosingClassNode = getOrAddLambdaClass(expression, 
ACC_PUBLIC, abstractMethodNode);
-        MethodNode syntheticLambdaMethodNode = 
lambdaEnclosingClassNode.getMethods(DO_CALL).get(0);
+        ClassNode lambdaClassNode = getOrAddLambdaClass(expression, 
ACC_PUBLIC);
+        MethodNode syntheticLambdaMethodNode = 
lambdaClassNode.getMethods(DO_CALL).get(0);
         String syntheticLambdaMethodWithExactTypeDesc = 
BytecodeHelper.getMethodDescriptor(syntheticLambdaMethodNode);
-        String syntheticLambdaMethodDesc =
-                BytecodeHelper.getMethodDescriptor(
-                        abstractMethodNode.getReturnType().getTypeClass(),
-                        Arrays.stream(abstractMethodNode.getParameters())
-                                .map(e -> e.getType().getTypeClass())
-                                .toArray(Class[]::new)
-                );
-
-        controller.getOperandStack().push(ClassHelper.OBJECT_TYPE);
-
-        mv.visitInvokeDynamicInsn(
-                abstractMethodName,
-                abstractMethodDesc,
+
+        controller.getOperandStack().push(parameterType.redirect());
+        controller.getMethodVisitor().visitInvokeDynamicInsn(
+                abstractMethodNode.getName(),
+                createAbstractMethodDesc(parameterType),
+                createBootstrapMethod(),
+                createBootstrapMethodArguments(abstractMethodDesc, 
lambdaClassNode, syntheticLambdaMethodNode, 
syntheticLambdaMethodWithExactTypeDesc)
+        );
+    }
+
+    private String createAbstractMethodDesc(ClassNode parameterType) {
+        return "()L" + parameterType.redirect().getPackageName().replace('.', 
'/') + "/" + parameterType.redirect().getNameWithoutPackage() + ";";
+    }
+
+    private Handle createBootstrapMethod() {
+        return new Handle(
+                Opcodes.H_INVOKESTATIC,
+                "java/lang/invoke/LambdaMetafactory",
+                "metafactory",
+                
"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;",
+                false
+        );
+    }
+
+    private Object[] createBootstrapMethodArguments(String abstractMethodDesc, 
ClassNode lambdaClassNode, MethodNode syntheticLambdaMethodNode, String 
syntheticLambdaMethodWithExactTypeDesc) {
+        return new Object[]{
+                Type.getType(abstractMethodDesc),
                 new Handle(
                         Opcodes.H_INVOKESTATIC,
-                        "java/lang/invoke/LambdaMetafactory",
-                        "metafactory",
-                        
"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;",
+                        lambdaClassNode.getName(),
+                        syntheticLambdaMethodNode.getName(),
+                        syntheticLambdaMethodWithExactTypeDesc,
                         false
                 ),
-                new Object[]{
-                        Type.getType(syntheticLambdaMethodDesc),
-                        new Handle(
-                                Opcodes.H_INVOKESTATIC,
-                                lambdaEnclosingClassNode.getName(),
-                                syntheticLambdaMethodNode.getName(),
-                                syntheticLambdaMethodWithExactTypeDesc,
-                                false
-                        ),
-                        Type.getType(syntheticLambdaMethodWithExactTypeDesc)
-                }
+                Type.getType(syntheticLambdaMethodWithExactTypeDesc)
+        };
+    }
+
+    private String createMethodDescriptor(MethodNode abstractMethodNode) {
+        return BytecodeHelper.getMethodDescriptor(
+                abstractMethodNode.getReturnType().getTypeClass(),
+                Arrays.stream(abstractMethodNode.getParameters())
+                        .map(e -> e.getType().getTypeClass())
+                        .toArray(Class[]::new)
         );
     }
 
@@ -128,10 +139,10 @@ public class StaticTypesLambdaWriter extends LambdaWriter 
{
         return parameterType.redirect().isInterface() && 
!parameterType.redirect().getAnnotations(ClassHelper.FunctionalInterface_Type).isEmpty();
     }
 
-    public ClassNode getOrAddLambdaClass(LambdaExpression expression, int 
mods, MethodNode abstractMethodNode) {
+    public ClassNode getOrAddLambdaClass(LambdaExpression expression, int 
mods) {
         ClassNode lambdaClass = lambdaClassMap.get(expression);
         if (lambdaClass == null) {
-            lambdaClass = createLambdaClass(expression, mods, 
abstractMethodNode);
+            lambdaClass = createLambdaClass(expression, mods);
             lambdaClassMap.put(expression, lambdaClass);
             controller.getAcg().addInnerClass(lambdaClass);
             lambdaClass.addInterface(ClassHelper.GENERATED_LAMBDA_TYPE);
@@ -140,7 +151,7 @@ public class StaticTypesLambdaWriter extends LambdaWriter {
         return lambdaClass;
     }
 
-    protected ClassNode createLambdaClass(LambdaExpression expression, int 
mods, MethodNode abstractMethodNode) {
+    protected ClassNode createLambdaClass(LambdaExpression expression, int 
mods) {
         ClassNode outerClass = controller.getOutermostClass();
         ClassNode classNode = controller.getClassNode();
         String name = genLambdaClassName();
@@ -159,13 +170,27 @@ public class StaticTypesLambdaWriter extends LambdaWriter 
{
             answer.setScriptBody(true);
         }
 
+        addSyntheticLambdaMethodNode(expression, answer);
+
+        return answer;
+    }
+
+    private String genLambdaClassName() {
+        ClassNode classNode = controller.getClassNode();
+        ClassNode outerClass = controller.getOutermostClass();
+        MethodNode methodNode = controller.getMethodNode();
+
+        return classNode.getName() + "$"
+                + controller.getContext().getNextLambdaInnerName(outerClass, 
classNode, methodNode);
+    }
+
+    private void addSyntheticLambdaMethodNode(LambdaExpression expression, 
InnerClassNode answer) {
         Parameter[] parametersWithExactType = 
createParametersWithExactType(expression); // expression.getParameters();
+        ClassNode returnType = 
expression.getNodeMetaData(StaticTypesMarker.INFERRED_RETURN_TYPE); 
//abstractMethodNode.getReturnType();
 
         MethodNode methodNode =
-                answer.addMethod(DO_CALL, Opcodes.ACC_PUBLIC | 
Opcodes.ACC_STATIC | Opcodes.ACC_SYNTHETIC, abstractMethodNode.getReturnType(), 
parametersWithExactType, ClassNode.EMPTY_ARRAY, expression.getCode());
+                answer.addMethod(DO_CALL, Opcodes.ACC_PUBLIC | 
Opcodes.ACC_STATIC | Opcodes.ACC_SYNTHETIC, returnType, 
parametersWithExactType, ClassNode.EMPTY_ARRAY, expression.getCode());
         methodNode.setSourcePosition(expression);
-
-        return answer;
     }
 
     private Parameter[] createParametersWithExactType(LambdaExpression 
expression) {
@@ -174,13 +199,12 @@ public class StaticTypesLambdaWriter extends LambdaWriter 
{
             parameters = Parameter.EMPTY_ARRAY;
         }
 
-        ClassNode[] blockParameterTypes = 
expression.getNodeMetaData(org.codehaus.groovy.transform.stc.StaticTypesMarker.CLOSURE_ARGUMENTS);
-//        Parameter[] parametersWithExactType = new 
Parameter[parameters.length];
-
         for (int i = 0; i < parameters.length; i++) {
-            parameters[i].setType(blockParameterTypes[i]);
-            parameters[i].setOriginType(blockParameterTypes[i]);
+            ClassNode inferredType = 
parameters[i].getNodeMetaData(StaticTypesMarker.INFERRED_TYPE);
+            parameters[i].setType(inferredType);
+            parameters[i].setOriginType(inferredType);
         }
+
         return parameters;
     }
 
@@ -188,13 +212,4 @@ public class StaticTypesLambdaWriter extends LambdaWriter {
     protected ClassNode createClosureClass(final ClosureExpression expression, 
final int mods) {
         return staticTypesClosureWriter.createClosureClass(expression, mods);
     }
-
-    private String genLambdaClassName() {
-        ClassNode classNode = controller.getClassNode();
-        ClassNode outerClass = controller.getOutermostClass();
-        MethodNode methodNode = controller.getMethodNode();
-
-        return classNode.getName() + "$"
-                + controller.getContext().getNextLambdaInnerName(outerClass, 
classNode, methodNode);
-    }
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/083089fc/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 db4aa36..700f9cd 100644
--- a/src/test/groovy/transform/stc/LambdaTest.groovy
+++ b/src/test/groovy/transform/stc/LambdaTest.groovy
@@ -39,6 +39,23 @@ class LambdaTest extends GroovyTestCase {
         '''
     }
 
+    /*
+    void testFunction2() {
+        assertScript '''
+        import groovy.transform.CompileStatic
+        import java.util.stream.Collectors
+        import java.util.stream.Stream
+        
+        @CompileStatic
+        void p() {
+            assert [2, 3, 4] == Stream.of(1, 2, 3).map(e -> e.plus 
1).collect(Collectors.toList());
+        }
+        
+        p()
+        '''
+    }
+    */
+
     void testBinaryOperator() {
         if (true) return;
 

Reply via email to