You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2018/01/12 16:18:08 UTC
groovy git commit: Minor refactoring
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 <su...@apache.org>
Authored: Sat Jan 13 00:18:00 2018 +0800
Committer: sunlan <su...@apache.org>
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;