Repository: groovy
Updated Branches:
  refs/heads/native-lambda 7210193eb -> 1296d2f93


Make Lambda extend Closure


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

Branch: refs/heads/native-lambda
Commit: 1296d2f936f3db500cae9ef7655ea9b57e17203d
Parents: 7210193
Author: sunlan <[email protected]>
Authored: Thu Jan 18 10:46:47 2018 +0800
Committer: sunlan <[email protected]>
Committed: Thu Jan 18 10:46:47 2018 +0800

----------------------------------------------------------------------
 src/main/groovy/groovy/lang/Lambda.java         | 32 ++++++++----------
 .../groovy/classgen/asm/ClosureWriter.java      | 35 +++++++++++---------
 .../asm/sc/StaticTypesLambdaWriter.java         | 15 ++++++++-
 3 files changed, 48 insertions(+), 34 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/1296d2f9/src/main/groovy/groovy/lang/Lambda.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/Lambda.java 
b/src/main/groovy/groovy/lang/Lambda.java
index 0b09ef0..82953b0 100644
--- a/src/main/groovy/groovy/lang/Lambda.java
+++ b/src/main/groovy/groovy/lang/Lambda.java
@@ -19,38 +19,34 @@
 
 package groovy.lang;
 
-import java.io.Serializable;
-
 /**
  * Represents any lambda object in Groovy.
  *
  * @since 3.0.0
  */
-public abstract class Lambda<V> extends GroovyObjectSupport implements 
Cloneable, Runnable, GroovyCallable<V>, Serializable {
+public abstract class Lambda<V> extends Closure<V> {
+
+    public Lambda(Object owner, Object thisObject) {
+        super(owner, thisObject);
+    }
+
     /**
-     * When an object implementing interface <code>Runnable</code> is used
-     * to create a thread, starting the thread causes the object's
-     * <code>run</code> method to be called in that separately executing
-     * thread.
-     * <p>
-     * The general contract of the method <code>run</code> is that it may
-     * take any action whatsoever.
+     * Constructor used when the "this" object for the Closure is null.
+     * This is rarely the case in normal Groovy usage.
      *
-     * @see Thread#run()
+     * @param owner the Closure owner
      */
-    @Override
-    public void run() {
-
+    public Lambda(Object owner) {
+        super(owner);
     }
 
     /**
-     * Computes a result, or throws an exception if unable to do so.
+     * Invokes the closure without any parameters, returning any value if 
applicable.
      *
-     * @return computed result
-     * @throws Exception if unable to compute a result
+     * @return the value if applicable or null if there is no return statement 
in the closure
      */
     @Override
-    public V call() throws Exception {
+    public V call() {
         return null;
     }
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/1296d2f9/src/main/java/org/codehaus/groovy/classgen/asm/ClosureWriter.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/ClosureWriter.java 
b/src/main/java/org/codehaus/groovy/classgen/asm/ClosureWriter.java
index 429fe3b..9a4f200 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/ClosureWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/ClosureWriter.java
@@ -248,21 +248,7 @@ public class ClosureWriter {
         }
 
         // let's make the constructor
-        BlockStatement block = new BlockStatement();
-        // this block does not get a source position, because we don't
-        // want this synthetic constructor to show up in corbertura reports
-        VariableExpression outer = new VariableExpression("_outerInstance");
-        outer.setSourcePosition(expression);
-        block.getVariableScope().putReferencedLocalVariable(outer);
-        VariableExpression thisObject = new VariableExpression("_thisObject");
-        thisObject.setSourcePosition(expression);
-        block.getVariableScope().putReferencedLocalVariable(thisObject);
-        TupleExpression conArgs = new TupleExpression(outer, thisObject);
-        block.addStatement(
-                new ExpressionStatement(
-                        new ConstructorCallExpression(
-                                ClassNode.SUPER,
-                                conArgs)));
+        BlockStatement block = createBlockStatementForConstructor(expression);
 
         // let's assign all the parameter fields from the outer context
         for (Parameter param : localVariableParams) {
@@ -305,6 +291,25 @@ public class ClosureWriter {
         return answer;
     }
 
+    protected BlockStatement 
createBlockStatementForConstructor(ClosureExpression expression) {
+        BlockStatement block = new BlockStatement();
+        // this block does not get a source position, because we don't
+        // want this synthetic constructor to show up in corbertura reports
+        VariableExpression outer = new VariableExpression("_outerInstance");
+        outer.setSourcePosition(expression);
+        block.getVariableScope().putReferencedLocalVariable(outer);
+        VariableExpression thisObject = new VariableExpression("_thisObject");
+        thisObject.setSourcePosition(expression);
+        block.getVariableScope().putReferencedLocalVariable(thisObject);
+        TupleExpression conArgs = new TupleExpression(outer, thisObject);
+        block.addStatement(
+                new ExpressionStatement(
+                        new ConstructorCallExpression(
+                                ClassNode.SUPER,
+                                conArgs)));
+        return block;
+    }
+
     private String genClosureClassName() {
         ClassNode classNode = controller.getClassNode();
         ClassNode outerClass = controller.getOutermostClass();

http://git-wip-us.apache.org/repos/asf/groovy/blob/1296d2f9/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 0650684..f7a6261 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
@@ -144,7 +144,10 @@ public class StaticTypesLambdaWriter extends LambdaWriter {
         mv.visitTypeInsn(NEW, lambdaClassInternalName);
         mv.visitInsn(DUP);
 
-        Parameter[] lambdaClassConstructorParameters = Parameter.EMPTY_ARRAY;
+        loadEnclosingClassInstance();
+        loadEnclosingClassInstance();
+
+        Parameter[] lambdaClassConstructorParameters = 
createConstructorParameters();
         mv.visitMethodInsn(INVOKESPECIAL, lambdaClassInternalName, "<init>", 
BytecodeHelper.getMethodDescriptor(ClassHelper.VOID_TYPE, 
lambdaClassConstructorParameters), lambdaClassNode.isInterface());
         controller.getOperandStack().replace(ClassHelper.LAMBDA_TYPE, 
lambdaClassConstructorParameters.length);
     }
@@ -245,11 +248,21 @@ public class StaticTypesLambdaWriter extends LambdaWriter 
{
             answer.setScriptBody(true);
         }
 
+        Parameter[] constructorParameters = createConstructorParameters();
+        answer.addConstructor(ACC_PUBLIC, constructorParameters, 
ClassNode.EMPTY_ARRAY, super.createBlockStatementForConstructor(expression));
+
         addSyntheticLambdaMethodNode(expression, answer);
 
         return answer;
     }
 
+    private Parameter[] createConstructorParameters() {
+        Parameter[] params = new Parameter[2];
+        params[0] = new Parameter(ClassHelper.OBJECT_TYPE, "_outerInstance");
+        params[1] = new Parameter(ClassHelper.OBJECT_TYPE, "_thisObject");
+        return params;
+    }
+
     private String genLambdaClassName() {
         ClassNode classNode = controller.getClassNode();
         ClassNode outerClass = controller.getOutermostClass();

Reply via email to