Repository: groovy Updated Branches: refs/heads/native-lambda 979cab607 -> 97649f9d1
Generate inner class for native lambda Project: http://git-wip-us.apache.org/repos/asf/groovy/repo Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/97649f9d Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/97649f9d Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/97649f9d Branch: refs/heads/native-lambda Commit: 97649f9d1e3b3a14c68b18891e725d02bd04e6a0 Parents: 979cab6 Author: sunlan <[email protected]> Authored: Fri Jan 12 11:45:15 2018 +0800 Committer: sunlan <[email protected]> Committed: Fri Jan 12 11:45:15 2018 +0800 ---------------------------------------------------------------------- src/main/groovy/groovy/lang/Lambda.java | 56 ++++ .../org/codehaus/groovy/ast/ClassHelper.java | 14 +- .../groovy/classgen/GeneratorContext.java | 14 +- .../groovy/classgen/asm/ClosureWriter.java | 14 +- .../asm/sc/StaticTypesLambdaWriter.java | 63 ++++- .../groovy/runtime/GeneratedLambda.java | 28 ++ src/test/groovy/transform/stc/LambdaTest.groovy | 2 +- .../apache/groovy/parser/antlr4/AstBuilder.java | 273 +------------------ 8 files changed, 177 insertions(+), 287 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/groovy/blob/97649f9d/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 new file mode 100644 index 0000000..0b09ef0 --- /dev/null +++ b/src/main/groovy/groovy/lang/Lambda.java @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +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 { + /** + * 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. + * + * @see Thread#run() + */ + @Override + public void run() { + + } + + /** + * Computes a result, or throws an exception if unable to do so. + * + * @return computed result + * @throws Exception if unable to compute a result + */ + @Override + public V call() throws Exception { + return null; + } +} http://git-wip-us.apache.org/repos/asf/groovy/blob/97649f9d/src/main/java/org/codehaus/groovy/ast/ClassHelper.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/codehaus/groovy/ast/ClassHelper.java b/src/main/java/org/codehaus/groovy/ast/ClassHelper.java index 60eaa47..27bc000 100644 --- a/src/main/java/org/codehaus/groovy/ast/ClassHelper.java +++ b/src/main/java/org/codehaus/groovy/ast/ClassHelper.java @@ -24,11 +24,13 @@ import groovy.lang.GString; import groovy.lang.GroovyInterceptable; import groovy.lang.GroovyObject; import groovy.lang.GroovyObjectSupport; +import groovy.lang.Lambda; import groovy.lang.MetaClass; import groovy.lang.Range; import groovy.lang.Reference; import groovy.lang.Script; import org.codehaus.groovy.runtime.GeneratedClosure; +import org.codehaus.groovy.runtime.GeneratedLambda; import org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport; import org.codehaus.groovy.transform.trait.Traits; import org.codehaus.groovy.util.ManagedConcurrentMap; @@ -58,12 +60,12 @@ public class ClassHelper { private static final Class[] classes = new Class[]{ Object.class, Boolean.TYPE, Character.TYPE, Byte.TYPE, Short.TYPE, Integer.TYPE, Long.TYPE, Double.TYPE, Float.TYPE, Void.TYPE, - Closure.class, GString.class, List.class, Map.class, Range.class, + Closure.class, Lambda.class, GString.class, List.class, Map.class, Range.class, Pattern.class, Script.class, String.class, Boolean.class, Character.class, Byte.class, Short.class, Integer.class, Long.class, Double.class, Float.class, BigDecimal.class, BigInteger.class, Number.class, Void.class, Reference.class, Class.class, MetaClass.class, - Iterator.class, GeneratedClosure.class, GroovyObjectSupport.class + Iterator.class, GeneratedClosure.class, GeneratedLambda.class, GroovyObjectSupport.class }; private static final String[] primitiveClassNames = new String[]{ @@ -73,7 +75,8 @@ public class ClassHelper { public static final ClassNode DYNAMIC_TYPE = makeCached(Object.class), OBJECT_TYPE = DYNAMIC_TYPE, - VOID_TYPE = makeCached(Void.TYPE), CLOSURE_TYPE = makeCached(Closure.class), + VOID_TYPE = makeCached(Void.TYPE), + CLOSURE_TYPE = makeCached(Closure.class), LAMBDA_TYPE = makeCached(Lambda.class), GSTRING_TYPE = makeCached(GString.class), LIST_TYPE = makeWithoutCaching(List.class), MAP_TYPE = makeWithoutCaching(Map.class), RANGE_TYPE = makeCached(Range.class), PATTERN_TYPE = makeCached(Pattern.class), STRING_TYPE = makeCached(String.class), @@ -102,6 +105,7 @@ public class ClassHelper { // uncached constants. CLASS_Type = makeWithoutCaching(Class.class), COMPARABLE_TYPE = makeWithoutCaching(Comparable.class), GENERATED_CLOSURE_Type = makeWithoutCaching(GeneratedClosure.class), + GENERATED_LAMBDA_TYPE = makeWithoutCaching(GeneratedLambda.class), GROOVY_OBJECT_SUPPORT_TYPE = makeWithoutCaching(GroovyObjectSupport.class), GROOVY_OBJECT_TYPE = makeWithoutCaching(GroovyObject.class), GROOVY_INTERCEPTABLE_TYPE = makeWithoutCaching(GroovyInterceptable.class); @@ -110,14 +114,14 @@ public class ClassHelper { OBJECT_TYPE, boolean_TYPE, char_TYPE, byte_TYPE, short_TYPE, int_TYPE, long_TYPE, double_TYPE, float_TYPE, - VOID_TYPE, CLOSURE_TYPE, GSTRING_TYPE, + VOID_TYPE, CLOSURE_TYPE, LAMBDA_TYPE, GSTRING_TYPE, LIST_TYPE, MAP_TYPE, RANGE_TYPE, PATTERN_TYPE, SCRIPT_TYPE, STRING_TYPE, Boolean_TYPE, Character_TYPE, Byte_TYPE, Short_TYPE, Integer_TYPE, Long_TYPE, Double_TYPE, Float_TYPE, BigDecimal_TYPE, BigInteger_TYPE, Number_TYPE, void_WRAPPER_TYPE, REFERENCE_TYPE, CLASS_Type, METACLASS_TYPE, - Iterator_TYPE, GENERATED_CLOSURE_Type, GROOVY_OBJECT_SUPPORT_TYPE, + Iterator_TYPE, GENERATED_CLOSURE_Type, GENERATED_LAMBDA_TYPE, GROOVY_OBJECT_SUPPORT_TYPE, GROOVY_OBJECT_TYPE, GROOVY_INTERCEPTABLE_TYPE, Enum_Type, Annotation_TYPE }; http://git-wip-us.apache.org/repos/asf/groovy/blob/97649f9d/src/main/java/org/codehaus/groovy/classgen/GeneratorContext.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/codehaus/groovy/classgen/GeneratorContext.java b/src/main/java/org/codehaus/groovy/classgen/GeneratorContext.java index 8b8a510..dd318bd 100644 --- a/src/main/java/org/codehaus/groovy/classgen/GeneratorContext.java +++ b/src/main/java/org/codehaus/groovy/classgen/GeneratorContext.java @@ -34,6 +34,7 @@ public class GeneratorContext { private int innerClassIdx = 1; private int closureClassIdx = 1; + private int lambdaClassIdx = 1; private final CompileUnit compileUnit; public GeneratorContext(CompileUnit compileUnit) { @@ -54,6 +55,14 @@ public class GeneratorContext { } public String getNextClosureInnerName(ClassNode owner, ClassNode enclosingClass, MethodNode enclosingMethod) { + return getNextInnerName(owner, enclosingClass, enclosingMethod, "closure"); + } + + public String getNextLambdaInnerName(ClassNode owner, ClassNode enclosingClass, MethodNode enclosingMethod) { + return getNextInnerName(owner, enclosingClass, enclosingMethod, "lambda"); + } + + private String getNextInnerName(ClassNode owner, ClassNode enclosingClass, MethodNode enclosingMethod, String classifier) { String methodName = ""; if (enclosingMethod != null) { methodName = enclosingMethod.getName(); @@ -61,10 +70,11 @@ public class GeneratorContext { if (enclosingClass.isDerivedFrom(ClassHelper.CLOSURE_TYPE)) { methodName = ""; } else { - methodName = "_"+encodeAsValidClassName(methodName); + methodName = "_" + encodeAsValidClassName(methodName); } } - return methodName + "_closure" + closureClassIdx++; + + return methodName + "_" + classifier + closureClassIdx++; } http://git-wip-us.apache.org/repos/asf/groovy/blob/97649f9d/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 af305ba..33ce035 100644 --- a/src/main/java/org/codehaus/groovy/classgen/asm/ClosureWriter.java +++ b/src/main/java/org/codehaus/groovy/classgen/asm/ClosureWriter.java @@ -184,9 +184,8 @@ public class ClosureWriter { protected ClassNode createClosureClass(ClosureExpression expression, int mods) { ClassNode classNode = controller.getClassNode(); ClassNode outerClass = controller.getOutermostClass(); - MethodNode methodNode = controller.getMethodNode(); - String name = classNode.getName() + "$" - + controller.getContext().getNextClosureInnerName(outerClass, classNode, methodNode); // add a more informative name +// MethodNode methodNode = controller.getMethodNode(); + String name = genInnerClassName(); boolean staticMethodOrInStaticClass = controller.isStaticMethod() || classNode.isStaticClass(); Parameter[] parameters = expression.getParameters(); @@ -306,6 +305,15 @@ public class ClosureWriter { return answer; } + protected String genInnerClassName() { + ClassNode classNode = controller.getClassNode(); + ClassNode outerClass = controller.getOutermostClass(); + MethodNode methodNode = controller.getMethodNode(); + + return classNode.getName() + "$" + + controller.getContext().getNextClosureInnerName(outerClass, classNode, methodNode); + } + private static void correctAccessedVariable(final InnerClassNode closureClass, ClosureExpression ce) { CodeVisitorSupport visitor = new CodeVisitorSupport() { @Override http://git-wip-us.apache.org/repos/asf/groovy/blob/97649f9d/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 6feaba5..46cbe15 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 @@ -21,24 +21,28 @@ package org.codehaus.groovy.classgen.asm.sc; import org.codehaus.groovy.ast.ClassHelper; import org.codehaus.groovy.ast.ClassNode; +import org.codehaus.groovy.ast.InnerClassNode; import org.codehaus.groovy.ast.MethodNode; +import org.codehaus.groovy.ast.Parameter; import org.codehaus.groovy.ast.expr.ClosureExpression; +import org.codehaus.groovy.ast.expr.Expression; import org.codehaus.groovy.ast.expr.LambdaExpression; import org.codehaus.groovy.classgen.AsmClassGenerator; 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.objectweb.asm.ClassVisitor; import org.objectweb.asm.Handle; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; -import static org.apache.groovy.parser.antlr4.AstBuilder.LAMBDA_ENCLOSING_CLASSNODE; -import static org.apache.groovy.parser.antlr4.AstBuilder.SYNTHETIC_LAMBDA_METHOD_NODE; import static org.codehaus.groovy.classgen.asm.sc.StaticInvocationWriter.PARAMETER_TYPE; import static org.objectweb.asm.Opcodes.ACC_FINAL; import static org.objectweb.asm.Opcodes.ACC_PUBLIC; @@ -49,13 +53,21 @@ import static org.objectweb.asm.Opcodes.ACC_STATIC; * */ public class StaticTypesLambdaWriter extends LambdaWriter { + public static final String DO_CALL = "doCall"; private StaticTypesClosureWriter staticTypesClosureWriter; private WriterController controller; + private WriterControllerFactory factory; + private final Map<Expression,ClassNode> lambdaClassMap = new HashMap<>(); public StaticTypesLambdaWriter(WriterController wc) { super(wc); this.staticTypesClosureWriter = new StaticTypesClosureWriter(wc); this.controller = wc; + this.factory = new WriterControllerFactory() { + public WriterController makeController(final WriterController normalController) { + return controller; + } + }; } @Override @@ -86,9 +98,8 @@ public class StaticTypesLambdaWriter extends LambdaWriter { ACC_PUBLIC + ACC_FINAL + ACC_STATIC); MethodVisitor mv = controller.getMethodVisitor(); - MethodNode syntheticLambdaMethodNode = expression.getNodeMetaData(SYNTHETIC_LAMBDA_METHOD_NODE); - ClassNode lambdaEnclosingClassNode = expression.getNodeMetaData(LAMBDA_ENCLOSING_CLASSNODE); - + ClassNode lambdaEnclosingClassNode = getOrAddLambdaClass(expression, ACC_PUBLIC); + MethodNode syntheticLambdaMethodNode = lambdaEnclosingClassNode.getMethods(DO_CALL).get(0); String syntheticLambdaMethodDesc = BytecodeHelper.getMethodDescriptor(syntheticLambdaMethodNode); controller.getOperandStack().push(ClassHelper.OBJECT_TYPE); @@ -112,7 +123,49 @@ public class StaticTypesLambdaWriter extends LambdaWriter { false), Type.getType(syntheticLambdaMethodDesc) }); + } + + public ClassNode getOrAddLambdaClass(LambdaExpression expression, int mods) { + ClassNode lambdaClass = lambdaClassMap.get(expression); + if (lambdaClass == null) { + lambdaClass = createLambdaClass(expression, mods); + lambdaClassMap.put(expression, lambdaClass); + controller.getAcg().addInnerClass(lambdaClass); + lambdaClass.addInterface(ClassHelper.GENERATED_LAMBDA_TYPE); + lambdaClass.putNodeMetaData(WriterControllerFactory.class, factory); + } + return lambdaClass; + } + + protected ClassNode createLambdaClass(LambdaExpression expression, int mods) { + ClassNode outerClass = controller.getOutermostClass(); + ClassNode classNode = controller.getClassNode(); + String name = genInnerClassName(); + boolean staticMethodOrInStaticClass = controller.isStaticMethod() || classNode.isStaticClass(); + + InnerClassNode answer = new InnerClassNode(classNode, name, mods, ClassHelper.LAMBDA_TYPE.getPlainNodeReference()); + answer.setEnclosingMethod(controller.getMethodNode()); + answer.setSynthetic(true); + answer.setUsingGenerics(outerClass.isUsingGenerics()); + answer.setSourcePosition(expression); + + if (staticMethodOrInStaticClass) { + answer.setStaticClass(true); + } + if (controller.isInScriptBody()) { + answer.setScriptBody(true); + } + + Parameter[] parameters = expression.getParameters(); + if (parameters == null) { + parameters = Parameter.EMPTY_ARRAY; + } + + MethodNode methodNode = + answer.addMethod(DO_CALL, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_SYNTHETIC, ClassHelper.OBJECT_TYPE, parameters, ClassNode.EMPTY_ARRAY, expression.getCode()); + methodNode.setSourcePosition(expression); + return answer; } @Override http://git-wip-us.apache.org/repos/asf/groovy/blob/97649f9d/src/main/java/org/codehaus/groovy/runtime/GeneratedLambda.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/codehaus/groovy/runtime/GeneratedLambda.java b/src/main/java/org/codehaus/groovy/runtime/GeneratedLambda.java new file mode 100644 index 0000000..0a74b99 --- /dev/null +++ b/src/main/java/org/codehaus/groovy/runtime/GeneratedLambda.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.codehaus.groovy.runtime; + +/** + * Marker interface to identify lambda generated by the groovy compiler. + * For internal use only! + * + * @since 3.0.0 + */ +public interface GeneratedLambda { } http://git-wip-us.apache.org/repos/asf/groovy/blob/97649f9d/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 0ee1ac3..0b9e189 100644 --- a/src/test/groovy/transform/stc/LambdaTest.groovy +++ b/src/test/groovy/transform/stc/LambdaTest.groovy @@ -30,7 +30,7 @@ class LambdaTest extends GroovyTestCase { public class Test1 { public static void main(String[] args) { p1(); - // p2(); +// p2(); // p3(); } http://git-wip-us.apache.org/repos/asf/groovy/blob/97649f9d/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java ---------------------------------------------------------------------- diff --git a/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java b/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java index f808dde..675255b 100644 --- a/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java +++ b/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java @@ -137,212 +137,7 @@ import java.util.logging.Logger; import java.util.stream.Collectors; import java.util.stream.Stream; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ADD; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.AS; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.AdditiveExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.AndExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.AnnotatedQualifiedClassNameContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.AnnotationContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.AnnotationNameContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.AnnotationsOptContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.AnonymousInnerClassDeclarationContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ArgumentsContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ArrayInitializerContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.AssertStatementContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.AssertStmtAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.AssignmentExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.BlockContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.BlockStatementContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.BlockStatementsContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.BlockStatementsOptContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.BooleanLiteralAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.BreakStatementContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.BreakStmtAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.BuiltInTypeContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.CASE; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.CastExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.CastParExpressionContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.CatchClauseContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.CatchTypeContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ClassBodyContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ClassBodyDeclarationContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ClassDeclarationContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ClassNameContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ClassOrInterfaceModifierContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ClassOrInterfaceModifiersContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ClassOrInterfaceModifiersOptContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ClassOrInterfaceTypeContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ClassicalForControlContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ClassifiedModifiersContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ClosureContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ClosurePrmrAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.CommandArgumentContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.CommandExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.CommandExpressionContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.CompilationUnitContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ConditionalExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ConditionalStatementContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ConditionalStmtAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ContinueStatementContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ContinueStmtAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.CreatedNameContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.CreatorContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.DEC; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.DEF; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.DEFAULT; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.DimsContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.DimsOptContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.DoWhileStmtAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.DynamicMemberNameContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ElementValueArrayInitializerContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ElementValueContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ElementValuePairContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ElementValuePairsContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ElementValuesContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.EnhancedArgumentListContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.EnhancedArgumentListElementContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.EnhancedExpressionContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.EnhancedForControlContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.EnhancedStatementExpressionContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.EnumConstantContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.EnumConstantsContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.EqualityExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ExclusiveOrExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ExpressionContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ExpressionInParContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ExpressionListContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ExpressionListElementContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ExpressionStmtAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.FieldDeclarationContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.FinallyBlockContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.FloatingPointLiteralAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ForControlContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ForInitContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ForStmtAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ForUpdateContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.FormalParameterContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.FormalParameterListContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.FormalParametersContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.GE; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.GT; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.GroovyParserRuleContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.GstringContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.GstringPathContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.GstringPrmrAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.GstringValueContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.IN; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.INC; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.INSTANCEOF; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.IdentifierContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.IdentifierPrmrAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.IfElseStatementContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ImportDeclarationContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ImportStmtAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.InclusiveOrExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.IndexPropertyArgsContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.IntegerLiteralAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.KeywordsContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.LE; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.LT; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.LabeledStmtAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.LambdaBodyContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.LambdaPrmrAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ListContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ListPrmrAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.LiteralPrmrAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.LocalVariableDeclarationContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.LocalVariableDeclarationStmtAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.LogicalAndExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.LogicalOrExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.LoopStmtAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.MapContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.MapEntryContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.MapEntryLabelContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.MapEntryListContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.MapPrmrAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.MemberDeclarationContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.MethodBodyContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.MethodDeclarationContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.MethodDeclarationStmtAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.MethodNameContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ModifierContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ModifiersContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ModifiersOptContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.MultipleAssignmentExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.MultiplicativeExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.NOT_IN; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.NOT_INSTANCEOF; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.NamePartContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.NamedPropertyArgsContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.NewPrmrAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.NonWildcardTypeArgumentsContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.NormalExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.NullLiteralAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.PRIVATE; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.PackageDeclarationContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ParExpressionContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ParenPrmrAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.PathElementContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.PathExpressionContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.PostfixExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.PostfixExpressionContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.PowerExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.PrimitiveTypeContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.QualifiedClassNameContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.QualifiedClassNameListContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.QualifiedNameContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.QualifiedStandardClassNameContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.RegexExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.RelationalExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ResourceContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ResourceListContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ResourcesContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ReturnStmtAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ReturnTypeContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.STATIC; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.SUB; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ShiftExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.StandardLambdaExpressionContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.StandardLambdaParametersContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.StatementsContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.StringLiteralAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.StringLiteralContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.SuperPrmrAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.SwitchBlockStatementGroupContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.SwitchLabelContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.SwitchStatementContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.SynchronizedStmtAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ThisFormalParameterContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ThisPrmrAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.ThrowStmtAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.TryCatchStatementContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.TryCatchStmtAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.TypeArgumentContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.TypeArgumentsContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.TypeArgumentsOrDiamondContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.TypeBoundContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.TypeContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.TypeDeclarationContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.TypeDeclarationStmtAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.TypeListContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.TypeNamePairContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.TypeNamePairsContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.TypeParameterContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.TypeParametersContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.TypePrmrAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.UnaryAddExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.UnaryNotExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.VariableDeclarationContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.VariableDeclaratorContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.VariableDeclaratorIdContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.VariableDeclaratorsContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.VariableInitializerContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.VariableInitializersContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.VariableModifierContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.VariableModifiersContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.VariableModifiersOptContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.VariableNamesContext; -import static org.apache.groovy.parser.antlr4.GroovyLangParser.WhileStmtAltContext; +import static org.apache.groovy.parser.antlr4.GroovyLangParser.*; import static org.apache.groovy.parser.antlr4.util.PositionConfigureUtils.configureAST; import static org.codehaus.groovy.runtime.DefaultGroovyMethods.asBoolean; import static org.codehaus.groovy.runtime.DefaultGroovyMethods.last; @@ -354,7 +149,6 @@ import static org.codehaus.groovy.runtime.DefaultGroovyMethods.last; * Created on 2016/08/14 */ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements GroovyParserVisitor<Object> { - public AstBuilder(SourceUnit sourceUnit) { this.sourceUnit = sourceUnit; this.moduleNode = new ModuleNode(sourceUnit); @@ -1266,49 +1060,9 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov this.visitClassBodyDeclaration(e); }); - genSyntheticLambdaMethodNode(classNode); - return null; } - private void genSyntheticLambdaMethodNode(ClassNode classNode) { - if (null == classNode) { - classNode = moduleNode.getScriptClassDummy(); - } - - if (null == classNode) { - return; - } - - List<LambdaExpression> lambdaExpressionList = lambdaExpressionRegistry.get(classNode); - - if (null == lambdaExpressionList) { - return; - } - - for (LambdaExpression lambdaExpression : lambdaExpressionList) { - String syntheticLambdaMethodNodeName = createSyntheticLambdaMethodNodeName(); - - Parameter[] parameters = lambdaExpression.getParameters(); - if (parameters == null) { - parameters = Parameter.EMPTY_ARRAY; - } - - MethodNode methodNode = - classNode.addMethod(syntheticLambdaMethodNodeName, Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC | Opcodes.ACC_SYNTHETIC, ClassHelper.OBJECT_TYPE, parameters, ClassNode.EMPTY_ARRAY, lambdaExpression.getCode()); - - lambdaExpression.putNodeMetaData(SYNTHETIC_LAMBDA_METHOD_NODE, methodNode); - lambdaExpression.putNodeMetaData(LAMBDA_ENCLOSING_CLASSNODE, classNode); - - configureAST(methodNode, lambdaExpression); - } - } - - private int syntheticLambdaMethodNodeCount = 0; - private String createSyntheticLambdaMethodNodeName() { - return "lambda$" + syntheticLambdaMethodNodeCount++; - } - @Override public List<FieldNode> visitEnumConstants(EnumConstantsContext ctx) { ClassNode classNode = ctx.getNodeMetaData(CLASS_DECLARATION_CLASS_NODE); @@ -3620,26 +3374,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov @Override public LambdaExpression visitStandardLambdaExpression(StandardLambdaExpressionContext ctx) { - LambdaExpression lambdaExpression = configureAST(this.createLambda(ctx.standardLambdaParameters(), ctx.lambdaBody()), ctx); - - registerLambdaExpression(lambdaExpression); - - return lambdaExpression; - } - - private void registerLambdaExpression(LambdaExpression lambdaExpression) { - ClassNode classNode = classNodeStack.peek(); - - if (null == classNode) { - classNode = moduleNode.getScriptClassDummy(); - } - - List<LambdaExpression> lambdaExpressionList = lambdaExpressionRegistry.get(classNode); - if (null == lambdaExpressionList) { - lambdaExpressionList = new LinkedList<>(); - lambdaExpressionRegistry.put(classNode, lambdaExpressionList); - } - lambdaExpressionList.add(lambdaExpression); + return configureAST(this.createLambda(ctx.standardLambdaParameters(), ctx.lambdaBody()), ctx); } private LambdaExpression createLambda(StandardLambdaParametersContext standardLambdaParametersContext, LambdaBodyContext lambdaBodyContext) { @@ -4547,7 +4282,6 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov scriptClassNode.setLastLineNumber(lastStatement.getLastLineNumber()); } - genSyntheticLambdaMethodNode(scriptClassNode); } private boolean isTrue(NodeMetaDataHandler nodeMetaDataHandler, String key) { @@ -4713,7 +4447,6 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov private final List<ClassNode> classNodeList = new LinkedList<>(); private final Deque<ClassNode> classNodeStack = new ArrayDeque<>(); private final Deque<List<InnerClassNode>> anonymousInnerClassesDefinedInMethodStack = new ArrayDeque<>(); - private final Map<ClassNode, List<LambdaExpression>> lambdaExpressionRegistry = new LinkedHashMap<>(); private int anonymousInnerClassCounter = 1; private Tuple2<GroovyParserRuleContext, Exception> numberFormatError; @@ -4772,6 +4505,4 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov private static final String FLOATING_POINT_LITERAL_TEXT = "_FLOATING_POINT_LITERAL_TEXT"; private static final String CLASS_NAME = "_CLASS_NAME"; - public static final String LAMBDA_ENCLOSING_CLASSNODE = "_LAMBDA_ENCLOSING_CLASSNODE"; - public static final String SYNTHETIC_LAMBDA_METHOD_NODE = "_SYNTHETIC_LAMBDA_METHOD_NODE"; }
