From 59b427e0c6f91b5aca3e75eac37b780bb68ba14d Mon Sep 17 00:00:00 2001 From: Daniel Sun Date: Sat, 15 Jun 2024 10:22:03 +0900 Subject: [PATCH] GROOVY-11055: Support lambda expression as named value --- src/main/antlr/GroovyParser.g4 | 17 +- .../groovy/parser/antlr4/AstBuilder.java | 215 ++---------------- .../parser/antlr4/GroovyParserTest.groovy | 4 + src/test/resources/bugs/GROOVY-11055.groovy | 29 +++ 4 files changed, 61 insertions(+), 204 deletions(-) create mode 100644 src/test/resources/bugs/GROOVY-11055.groovy diff --git a/src/main/antlr/GroovyParser.g4 b/src/main/antlr/GroovyParser.g4 index 0ab2458d..02b3b0ff 100644 --- a/src/main/antlr/GroovyParser.g4 +++ b/src/main/antlr/GroovyParser.g4 @@ -743,6 +743,11 @@ expressionListElement[boolean canSpread] : MUL? expression ; +enhancedExpression + : expression + | standardLambdaExpression + ; + enhancedStatementExpression : statementExpression | standardLambdaExpression @@ -1093,20 +1098,20 @@ options { baseContext = mapEntryList; } ; mapEntry - : mapEntryLabel COLON nls expression - | MUL COLON nls expression + : mapEntryLabel COLON nls enhancedExpression + | MUL COLON nls enhancedExpression ; namedPropertyArg options { baseContext = mapEntry; } - : namedPropertyArgLabel COLON nls expression - | MUL COLON nls expression + : namedPropertyArgLabel COLON nls enhancedExpression + | MUL COLON nls enhancedExpression ; namedArg options { baseContext = mapEntry; } - : namedArgLabel COLON nls expression - | MUL COLON nls expression + : namedArgLabel COLON nls enhancedExpression + | MUL COLON nls enhancedExpression ; mapEntryLabel diff --git a/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java b/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java index 09c3cd37..1109b9ad 100644 --- a/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java +++ b/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java @@ -39,176 +39,6 @@ import org.antlr.v4.runtime.tree.ParseTree; import org.antlr.v4.runtime.tree.TerminalNode; import org.apache.groovy.ast.tools.AnnotatedNodeUtils; -import org.apache.groovy.parser.antlr4.GroovyParser.AdditiveExprAltContext; -import org.apache.groovy.parser.antlr4.GroovyParser.AndExprAltContext; -import org.apache.groovy.parser.antlr4.GroovyParser.AnnotatedQualifiedClassNameContext; -import org.apache.groovy.parser.antlr4.GroovyParser.AnnotationContext; -import org.apache.groovy.parser.antlr4.GroovyParser.AnnotationNameContext; -import org.apache.groovy.parser.antlr4.GroovyParser.AnnotationsOptContext; -import org.apache.groovy.parser.antlr4.GroovyParser.AnonymousInnerClassDeclarationContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ArgumentsContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ArrayInitializerContext; -import org.apache.groovy.parser.antlr4.GroovyParser.AssertStatementContext; -import org.apache.groovy.parser.antlr4.GroovyParser.AssignmentExprAltContext; -import org.apache.groovy.parser.antlr4.GroovyParser.BlockContext; -import org.apache.groovy.parser.antlr4.GroovyParser.BlockStatementContext; -import org.apache.groovy.parser.antlr4.GroovyParser.BlockStatementsContext; -import org.apache.groovy.parser.antlr4.GroovyParser.BlockStatementsOptContext; -import org.apache.groovy.parser.antlr4.GroovyParser.BooleanLiteralAltContext; -import org.apache.groovy.parser.antlr4.GroovyParser.BreakStatementContext; -import org.apache.groovy.parser.antlr4.GroovyParser.BuiltInTypeContext; -import org.apache.groovy.parser.antlr4.GroovyParser.CastExprAltContext; -import org.apache.groovy.parser.antlr4.GroovyParser.CastParExpressionContext; -import org.apache.groovy.parser.antlr4.GroovyParser.CatchClauseContext; -import org.apache.groovy.parser.antlr4.GroovyParser.CatchTypeContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ClassBodyContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ClassBodyDeclarationContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ClassDeclarationContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ClassNameContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ClassOrInterfaceModifierContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ClassOrInterfaceModifiersContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ClassOrInterfaceModifiersOptContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ClassOrInterfaceTypeContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ClassicalForControlContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ClosureContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ClosureOrLambdaExpressionContext; -import org.apache.groovy.parser.antlr4.GroovyParser.CommandArgumentContext; -import org.apache.groovy.parser.antlr4.GroovyParser.CommandExprAltContext; -import org.apache.groovy.parser.antlr4.GroovyParser.CommandExpressionContext; -import org.apache.groovy.parser.antlr4.GroovyParser.CompactConstructorDeclarationContext; -import org.apache.groovy.parser.antlr4.GroovyParser.CompilationUnitContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ConditionalExprAltContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ConditionalStatementContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ContinueStatementContext; -import org.apache.groovy.parser.antlr4.GroovyParser.CreatedNameContext; -import org.apache.groovy.parser.antlr4.GroovyParser.CreatorContext; -import org.apache.groovy.parser.antlr4.GroovyParser.DimContext; -import org.apache.groovy.parser.antlr4.GroovyParser.DoWhileStmtAltContext; -import org.apache.groovy.parser.antlr4.GroovyParser.DynamicMemberNameContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ElementValueArrayInitializerContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ElementValueContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ElementValuePairContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ElementValuePairsContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ElementValuesContext; -import org.apache.groovy.parser.antlr4.GroovyParser.EmptyDimsContext; -import org.apache.groovy.parser.antlr4.GroovyParser.EmptyDimsOptContext; -import org.apache.groovy.parser.antlr4.GroovyParser.EnhancedArgumentListElementContext; -import org.apache.groovy.parser.antlr4.GroovyParser.EnhancedArgumentListInParContext; -import org.apache.groovy.parser.antlr4.GroovyParser.EnhancedForControlContext; -import org.apache.groovy.parser.antlr4.GroovyParser.EnhancedStatementExpressionContext; -import org.apache.groovy.parser.antlr4.GroovyParser.EnumConstantContext; -import org.apache.groovy.parser.antlr4.GroovyParser.EnumConstantsContext; -import org.apache.groovy.parser.antlr4.GroovyParser.EqualityExprAltContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ExclusiveOrExprAltContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ExpressionContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ExpressionInParContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ExpressionListContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ExpressionListElementContext; -import org.apache.groovy.parser.antlr4.GroovyParser.FieldDeclarationContext; -import org.apache.groovy.parser.antlr4.GroovyParser.FinallyBlockContext; -import org.apache.groovy.parser.antlr4.GroovyParser.FloatingPointLiteralAltContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ForControlContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ForInitContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ForStmtAltContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ForUpdateContext; -import org.apache.groovy.parser.antlr4.GroovyParser.FormalParameterContext; -import org.apache.groovy.parser.antlr4.GroovyParser.FormalParameterListContext; -import org.apache.groovy.parser.antlr4.GroovyParser.FormalParametersContext; -import org.apache.groovy.parser.antlr4.GroovyParser.GroovyParserRuleContext; -import org.apache.groovy.parser.antlr4.GroovyParser.GstringContext; -import org.apache.groovy.parser.antlr4.GroovyParser.GstringPathContext; -import org.apache.groovy.parser.antlr4.GroovyParser.GstringValueContext; -import org.apache.groovy.parser.antlr4.GroovyParser.IdentifierContext; -import org.apache.groovy.parser.antlr4.GroovyParser.IdentifierPrmrAltContext; -import org.apache.groovy.parser.antlr4.GroovyParser.IfElseStatementContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ImportDeclarationContext; -import org.apache.groovy.parser.antlr4.GroovyParser.InclusiveOrExprAltContext; -import org.apache.groovy.parser.antlr4.GroovyParser.IndexPropertyArgsContext; -import org.apache.groovy.parser.antlr4.GroovyParser.IntegerLiteralAltContext; -import org.apache.groovy.parser.antlr4.GroovyParser.KeywordsContext; -import org.apache.groovy.parser.antlr4.GroovyParser.LabeledStmtAltContext; -import org.apache.groovy.parser.antlr4.GroovyParser.LambdaBodyContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ListContext; -import org.apache.groovy.parser.antlr4.GroovyParser.LocalVariableDeclarationContext; -import org.apache.groovy.parser.antlr4.GroovyParser.LogicalAndExprAltContext; -import org.apache.groovy.parser.antlr4.GroovyParser.LogicalOrExprAltContext; -import org.apache.groovy.parser.antlr4.GroovyParser.LoopStmtAltContext; -import org.apache.groovy.parser.antlr4.GroovyParser.MapContext; -import org.apache.groovy.parser.antlr4.GroovyParser.MapEntryContext; -import org.apache.groovy.parser.antlr4.GroovyParser.MapEntryLabelContext; -import org.apache.groovy.parser.antlr4.GroovyParser.MapEntryListContext; -import org.apache.groovy.parser.antlr4.GroovyParser.MemberDeclarationContext; -import org.apache.groovy.parser.antlr4.GroovyParser.MethodBodyContext; -import org.apache.groovy.parser.antlr4.GroovyParser.MethodDeclarationContext; -import org.apache.groovy.parser.antlr4.GroovyParser.MethodNameContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ModifierContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ModifiersContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ModifiersOptContext; -import org.apache.groovy.parser.antlr4.GroovyParser.MultipleAssignmentExprAltContext; -import org.apache.groovy.parser.antlr4.GroovyParser.MultiplicativeExprAltContext; -import org.apache.groovy.parser.antlr4.GroovyParser.NamePartContext; -import org.apache.groovy.parser.antlr4.GroovyParser.NamedPropertyArgsContext; -import org.apache.groovy.parser.antlr4.GroovyParser.NewPrmrAltContext; -import org.apache.groovy.parser.antlr4.GroovyParser.NonWildcardTypeArgumentsContext; -import org.apache.groovy.parser.antlr4.GroovyParser.NullLiteralAltContext; -import org.apache.groovy.parser.antlr4.GroovyParser.PackageDeclarationContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ParExpressionContext; -import org.apache.groovy.parser.antlr4.GroovyParser.PathElementContext; -import org.apache.groovy.parser.antlr4.GroovyParser.PathExpressionContext; -import org.apache.groovy.parser.antlr4.GroovyParser.PostfixExpressionContext; -import org.apache.groovy.parser.antlr4.GroovyParser.PowerExprAltContext; -import org.apache.groovy.parser.antlr4.GroovyParser.PrimitiveTypeContext; -import org.apache.groovy.parser.antlr4.GroovyParser.QualifiedClassNameContext; -import org.apache.groovy.parser.antlr4.GroovyParser.QualifiedClassNameListContext; -import org.apache.groovy.parser.antlr4.GroovyParser.QualifiedNameContext; -import org.apache.groovy.parser.antlr4.GroovyParser.QualifiedNameElementContext; -import org.apache.groovy.parser.antlr4.GroovyParser.QualifiedStandardClassNameContext; -import org.apache.groovy.parser.antlr4.GroovyParser.RegexExprAltContext; -import org.apache.groovy.parser.antlr4.GroovyParser.RelationalExprAltContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ResourceContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ResourceListContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ResourcesContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ReturnStmtAltContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ReturnTypeContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ScriptStatementsContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ShiftExprAltContext; -import org.apache.groovy.parser.antlr4.GroovyParser.StandardLambdaExpressionContext; -import org.apache.groovy.parser.antlr4.GroovyParser.StandardLambdaParametersContext; -import org.apache.groovy.parser.antlr4.GroovyParser.StatementContext; -import org.apache.groovy.parser.antlr4.GroovyParser.StringLiteralContext; -import org.apache.groovy.parser.antlr4.GroovyParser.SuperPrmrAltContext; -import org.apache.groovy.parser.antlr4.GroovyParser.SwitchBlockStatementGroupContext; -import org.apache.groovy.parser.antlr4.GroovyParser.SwitchLabelContext; -import org.apache.groovy.parser.antlr4.GroovyParser.SwitchStatementContext; -import org.apache.groovy.parser.antlr4.GroovyParser.SynchronizedStmtAltContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ThisFormalParameterContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ThisPrmrAltContext; -import org.apache.groovy.parser.antlr4.GroovyParser.ThrowStmtAltContext; -import org.apache.groovy.parser.antlr4.GroovyParser.TryCatchStatementContext; -import org.apache.groovy.parser.antlr4.GroovyParser.TypeArgumentContext; -import org.apache.groovy.parser.antlr4.GroovyParser.TypeArgumentsContext; -import org.apache.groovy.parser.antlr4.GroovyParser.TypeArgumentsOrDiamondContext; -import org.apache.groovy.parser.antlr4.GroovyParser.TypeBoundContext; -import org.apache.groovy.parser.antlr4.GroovyParser.TypeContext; -import org.apache.groovy.parser.antlr4.GroovyParser.TypeDeclarationContext; -import org.apache.groovy.parser.antlr4.GroovyParser.TypeListContext; -import org.apache.groovy.parser.antlr4.GroovyParser.TypeNamePairContext; -import org.apache.groovy.parser.antlr4.GroovyParser.TypeNamePairsContext; -import org.apache.groovy.parser.antlr4.GroovyParser.TypeParameterContext; -import org.apache.groovy.parser.antlr4.GroovyParser.TypeParametersContext; -import org.apache.groovy.parser.antlr4.GroovyParser.UnaryAddExprAltContext; -import org.apache.groovy.parser.antlr4.GroovyParser.UnaryNotExprAltContext; -import org.apache.groovy.parser.antlr4.GroovyParser.VariableDeclarationContext; -import org.apache.groovy.parser.antlr4.GroovyParser.VariableDeclaratorContext; -import org.apache.groovy.parser.antlr4.GroovyParser.VariableDeclaratorIdContext; -import org.apache.groovy.parser.antlr4.GroovyParser.VariableDeclaratorsContext; -import org.apache.groovy.parser.antlr4.GroovyParser.VariableInitializerContext; -import org.apache.groovy.parser.antlr4.GroovyParser.VariableInitializersContext; -import org.apache.groovy.parser.antlr4.GroovyParser.VariableModifierContext; -import org.apache.groovy.parser.antlr4.GroovyParser.VariableModifiersContext; -import org.apache.groovy.parser.antlr4.GroovyParser.VariableModifiersOptContext; -import org.apache.groovy.parser.antlr4.GroovyParser.VariableNamesContext; -import org.apache.groovy.parser.antlr4.GroovyParser.WhileStmtAltContext; import org.apache.groovy.parser.antlr4.internal.DescriptiveErrorStrategy; import org.apache.groovy.parser.antlr4.internal.atnmanager.AtnManager; import org.apache.groovy.parser.antlr4.util.StringUtils; @@ -327,33 +157,7 @@ import static org.apache.groovy.parser.antlr4.GroovyLangParser.SwitchExpressionLabelContext; import static org.apache.groovy.parser.antlr4.GroovyLangParser.YieldStatementContext; import static org.apache.groovy.parser.antlr4.GroovyLangParser.YieldStmtAltContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ADD; -import static org.apache.groovy.parser.antlr4.GroovyParser.AS; -import static org.apache.groovy.parser.antlr4.GroovyParser.CASE; -import static org.apache.groovy.parser.antlr4.GroovyParser.DEC; -import static org.apache.groovy.parser.antlr4.GroovyParser.DEF; -import static org.apache.groovy.parser.antlr4.GroovyParser.DEFAULT; -import static org.apache.groovy.parser.antlr4.GroovyParser.FINAL; -import static org.apache.groovy.parser.antlr4.GroovyParser.GE; -import static org.apache.groovy.parser.antlr4.GroovyParser.GT; -import static org.apache.groovy.parser.antlr4.GroovyParser.IN; -import static org.apache.groovy.parser.antlr4.GroovyParser.INC; -import static org.apache.groovy.parser.antlr4.GroovyParser.INSTANCEOF; -import static org.apache.groovy.parser.antlr4.GroovyParser.LE; -import static org.apache.groovy.parser.antlr4.GroovyParser.LT; -import static org.apache.groovy.parser.antlr4.GroovyParser.NON_SEALED; -import static org.apache.groovy.parser.antlr4.GroovyParser.NOT_IN; -import static org.apache.groovy.parser.antlr4.GroovyParser.NOT_INSTANCEOF; -import static org.apache.groovy.parser.antlr4.GroovyParser.PRIVATE; -import static org.apache.groovy.parser.antlr4.GroovyParser.RANGE_EXCLUSIVE_FULL; -import static org.apache.groovy.parser.antlr4.GroovyParser.RANGE_EXCLUSIVE_LEFT; -import static org.apache.groovy.parser.antlr4.GroovyParser.RANGE_EXCLUSIVE_RIGHT; -import static org.apache.groovy.parser.antlr4.GroovyParser.RANGE_INCLUSIVE; -import static org.apache.groovy.parser.antlr4.GroovyParser.SAFE_INDEX; -import static org.apache.groovy.parser.antlr4.GroovyParser.SEALED; -import static org.apache.groovy.parser.antlr4.GroovyParser.STATIC; -import static org.apache.groovy.parser.antlr4.GroovyParser.SUB; -import static org.apache.groovy.parser.antlr4.GroovyParser.VAR; +import static org.apache.groovy.parser.antlr4.GroovyParser.*; import static org.apache.groovy.parser.antlr4.util.PositionConfigureUtils.configureAST; import static org.codehaus.groovy.ast.ClassHelper.isPrimitiveVoid; import static org.codehaus.groovy.ast.tools.GeneralUtils.callX; @@ -2692,6 +2496,21 @@ public Expression visitExpressionInPar(final ExpressionInParContext ctx) { return this.visitEnhancedStatementExpression(ctx.enhancedStatementExpression()); } + @Override + public Expression visitEnhancedExpression(final EnhancedExpressionContext ctx) { + Expression expression; + + if (asBoolean(ctx.expression())) { + expression = (Expression) this.visit(ctx.expression()); + } else if (asBoolean(ctx.standardLambdaExpression())) { + expression = this.visitStandardLambdaExpression(ctx.standardLambdaExpression()); + } else { + throw createParsingFailedException("Unsupported enhanced expression: " + ctx.getText(), ctx); + } + + return configureAST(expression, ctx); + } + @Override public Expression visitEnhancedStatementExpression(final EnhancedStatementExpressionContext ctx) { Expression expression; @@ -3762,7 +3581,7 @@ private List createMapEntryList(final List 'Hello, ' + n, name: 'Daniel') +m(hello: n -> 'Hello, ' + n, hi: n -> 'Hi, ' + n, name: 'Daniel')