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();
