This is an automated email from the ASF dual-hosted git repository. emilles pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/groovy.git
commit 081fa5016966a3680efa55eb58ad9506797541c9 Author: Eric Milles <[email protected]> AuthorDate: Sat Feb 8 08:58:50 2025 -0600 GROOVY-11565: empty block handling --- .../apache/groovy/parser/antlr4/AstBuilder.java | 260 ++------------------- .../org/codehaus/groovy/ast/stmt/IfStatement.java | 11 +- src/test-resources/core/IfElse_02.groovy | 32 +++ .../groovy/parser/antlr4/GroovyParserTest.groovy | 3 +- 4 files changed, 58 insertions(+), 248 deletions(-) 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 f7799fdadc..c71f363f38 100644 --- a/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java +++ b/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java @@ -39,7 +39,6 @@ import org.antlr.v4.runtime.misc.Interval; import org.antlr.v4.runtime.misc.ParseCancellationException; import org.antlr.v4.runtime.tree.ParseTree; import org.antlr.v4.runtime.tree.TerminalNode; -import org.apache.groovy.parser.antlr4.GroovyParser.DimContext; 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; @@ -152,210 +151,7 @@ import java.util.Optional; import java.util.stream.Collectors; import static groovy.lang.Tuple.tuple; -import static org.apache.groovy.parser.antlr4.GroovyParser.ADD; -import static org.apache.groovy.parser.antlr4.GroovyParser.ARROW; -import static org.apache.groovy.parser.antlr4.GroovyParser.AS; -import static org.apache.groovy.parser.antlr4.GroovyParser.AdditiveExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.AndExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.AnnotatedQualifiedClassNameContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.AnnotationContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.AnnotationNameContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.AnnotationsOptContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.AnonymousInnerClassDeclarationContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ArgumentsContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ArrayInitializerContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.AssertStatementContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.AssignmentExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.BlockContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.BlockStatementContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.BlockStatementsContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.BlockStatementsOptContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.BooleanLiteralAltContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.BreakStatementContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.BuiltInTypeContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.CASE; -import static org.apache.groovy.parser.antlr4.GroovyParser.CastExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.CastParExpressionContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.CatchClauseContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.CatchTypeContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ClassBodyContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ClassBodyDeclarationContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ClassDeclarationContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ClassNameContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ClassOrInterfaceModifierContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ClassOrInterfaceModifiersContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ClassOrInterfaceModifiersOptContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ClassOrInterfaceTypeContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ClassicalForControlContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ClosureContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ClosureOrLambdaExpressionContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.CommandArgumentContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.CommandExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.CommandExpressionContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.CompactConstructorDeclarationContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.CompilationUnitContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ConditionalExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ConditionalStatementContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ContinueStatementContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.CreatedNameContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.CreatorContext; -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.DoWhileStmtAltContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.DynamicMemberNameContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ElementValueArrayInitializerContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ElementValueContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ElementValuePairContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ElementValuePairsContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ElementValuesContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.EmptyDimsContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.EmptyDimsOptContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.EnhancedArgumentListElementContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.EnhancedArgumentListInParContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.EnhancedExpressionContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.EnhancedForControlContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.EnhancedStatementExpressionContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.EnumConstantContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.EnumConstantsContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.EqualityExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ExclusiveOrExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ExpressionContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ExpressionInParContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ExpressionListContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ExpressionListElementContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.FINAL; -import static org.apache.groovy.parser.antlr4.GroovyParser.FieldDeclarationContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.FinallyBlockContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.FloatingPointLiteralAltContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ForControlContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ForInitContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ForStmtAltContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ForUpdateContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.FormalParameterContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.FormalParameterListContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.FormalParametersContext; -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.GroovyParserRuleContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.GstringContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.GstringPathContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.GstringValueContext; -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.IdentifierContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.IdentifierPrmrAltContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.IfElseStatementContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ImplicationExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ImportDeclarationContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.InclusiveOrExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.IndexPropertyArgsContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.IntegerLiteralAltContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.KeywordsContext; -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.LabeledStmtAltContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.LambdaBodyContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ListContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.LocalVariableDeclarationContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.LogicalAndExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.LogicalOrExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.LoopStmtAltContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.MapContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.MapEntryContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.MapEntryLabelContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.MapEntryListContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.MemberDeclarationContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.MethodBodyContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.MethodDeclarationContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.MethodNameContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ModifierContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ModifiersContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ModifiersOptContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.MultipleAssignmentExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.MultiplicativeExprAltContext; -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.NamePartContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.NamedPropertyArgsContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.NewPrmrAltContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.NonWildcardTypeArgumentsContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.NullLiteralAltContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.PRIVATE; -import static org.apache.groovy.parser.antlr4.GroovyParser.PackageDeclarationContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ParExpressionContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.PathElementContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.PathExpressionContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.PostfixExpressionContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.PowerExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.PrimitiveTypeContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.QualifiedClassNameContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.QualifiedClassNameListContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.QualifiedNameContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.QualifiedNameElementContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.QualifiedStandardClassNameContext; -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.RegexExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.RelationalExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ResourceContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ResourceListContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ResourcesContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ReturnStmtAltContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ReturnTypeContext; -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.ScriptStatementsContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ShiftExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.StandardLambdaExpressionContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.StandardLambdaParametersContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.StatementContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.StringLiteralContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.SuperPrmrAltContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.SwitchBlockStatementExpressionGroupContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.SwitchBlockStatementGroupContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.SwitchExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.SwitchExpressionContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.SwitchExpressionLabelContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.SwitchLabelContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.SwitchStatementContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.SynchronizedStmtAltContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ThisFormalParameterContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ThisPrmrAltContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.ThrowStmtAltContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.TryCatchStatementContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.TypeArgumentContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.TypeArgumentsContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.TypeArgumentsOrDiamondContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.TypeBoundContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.TypeContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.TypeDeclarationContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.TypeListContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.TypeNamePairContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.TypeNamePairsContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.TypeParameterContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.TypeParametersContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.UnaryAddExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.UnaryNotExprAltContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.VAR; -import static org.apache.groovy.parser.antlr4.GroovyParser.VariableDeclarationContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.VariableDeclaratorContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.VariableDeclaratorIdContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.VariableDeclaratorsContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.VariableInitializerContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.VariableModifierContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.VariableModifiersContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.VariableModifiersOptContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.VariableNamesContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.WhileStmtAltContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.YieldStatementContext; -import static org.apache.groovy.parser.antlr4.GroovyParser.YieldStmtAltContext; +import static org.apache.groovy.parser.antlr4.GroovyParser.*; import static org.apache.groovy.parser.antlr4.util.PositionConfigureUtils.configureAST; import static org.apache.groovy.parser.antlr4.util.PositionConfigureUtils.configureEndPosition; import static org.codehaus.groovy.ast.tools.GeneralUtils.assignX; @@ -377,6 +173,7 @@ import static org.codehaus.groovy.runtime.DefaultGroovyMethods.last; * Builds the AST from the parse tree generated by Antlr4. */ public class AstBuilder extends GroovyParserBaseVisitor<Object> { + public AstBuilder(final SourceUnit sourceUnit, final boolean groovydocEnabled, final boolean runtimeGroovydocEnabled) { this.sourceUnit = sourceUnit; this.moduleNode = new ModuleNode(sourceUnit); @@ -650,20 +447,12 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> { @Override public IfStatement visitIfElseStatement(final IfElseStatementContext ctx) { Expression conditionExpression = this.visitExpressionInPar(ctx.expressionInPar()); - BooleanExpression booleanExpression = - configureAST( - new BooleanExpression(conditionExpression), conditionExpression); + BooleanExpression booleanExpression = configureAST(new BooleanExpression(conditionExpression), conditionExpression); - Statement ifBlock = - this.unpackStatement( - (Statement) this.visit(ctx.tb)); - Statement elseBlock = - this.unpackStatement( - asBoolean(ctx.ELSE()) - ? (Statement) this.visit(ctx.fb) - : EmptyStatement.INSTANCE); + Statement thenStatement = this.unpackStatement((Statement) this.visit(ctx.tb)) ; + Statement elseStatement = ctx.ELSE() != null ? this.unpackStatement((Statement) this.visit(ctx.fb)) : EmptyStatement.INSTANCE; - return configureAST(new IfStatement(booleanExpression, ifBlock, elseBlock), ctx); + return configureAST(new IfStatement(booleanExpression, thenStatement, elseStatement), ctx); } @Override @@ -684,9 +473,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> { Statement loopBlock = this.unpackStatement((Statement) this.visit(ctx.statement())); - return configureAST( - new ForStatement(controlTuple.getV1(), controlTuple.getV2(), asBoolean(loopBlock) ? loopBlock : EmptyStatement.INSTANCE), - ctx); + return configureAST(new ForStatement(controlTuple.getV1(), controlTuple.getV2(), loopBlock), ctx); } @Override @@ -710,12 +497,12 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> { if (asBoolean(ctx.localVariableDeclaration())) { DeclarationListStatement declarationListStatement = this.visitLocalVariableDeclaration(ctx.localVariableDeclaration()); - List<DeclarationExpression> declarationExpressions = declarationListStatement.getDeclarationExpressions(); + List<? extends Expression> declarationExpressions = declarationListStatement.getDeclarationExpressions(); if (declarationExpressions.size() == 1) { - return configureAST((Expression) declarationExpressions.get(0), ctx); + return configureAST(declarationExpressions.get(0), ctx); } else { - return configureAST(new ClosureListExpression((List) declarationExpressions), ctx); + return configureAST(new ClosureListExpression((List<Expression>) declarationExpressions), ctx); } } @@ -769,28 +556,19 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> { public WhileStatement visitWhileStmtAlt(final WhileStmtAltContext ctx) { Tuple2<BooleanExpression, Statement> conditionAndBlock = createLoopConditionExpressionAndBlock(ctx.expressionInPar(), ctx.statement()); - return configureAST( - new WhileStatement(conditionAndBlock.getV1(), asBoolean(conditionAndBlock.getV2()) ? conditionAndBlock.getV2() : EmptyStatement.INSTANCE), - ctx); + return configureAST(new WhileStatement(conditionAndBlock.getV1(), conditionAndBlock.getV2()), ctx); } @Override public DoWhileStatement visitDoWhileStmtAlt(final DoWhileStmtAltContext ctx) { Tuple2<BooleanExpression, Statement> conditionAndBlock = createLoopConditionExpressionAndBlock(ctx.expressionInPar(), ctx.statement()); - return configureAST( - new DoWhileStatement(conditionAndBlock.getV1(), asBoolean(conditionAndBlock.getV2()) ? conditionAndBlock.getV2() : EmptyStatement.INSTANCE), - ctx); + return configureAST(new DoWhileStatement(conditionAndBlock.getV1(), conditionAndBlock.getV2()), ctx); } private Tuple2<BooleanExpression, Statement> createLoopConditionExpressionAndBlock(final ExpressionInParContext eipc, final StatementContext sc) { Expression conditionExpression = this.visitExpressionInPar(eipc); - - BooleanExpression booleanExpression = - configureAST( - new BooleanExpression(conditionExpression), - conditionExpression - ); + BooleanExpression booleanExpression = configureAST(new BooleanExpression(conditionExpression), conditionExpression); Statement loopBlock = this.unpackStatement((Statement) this.visit(sc)); @@ -4710,16 +4488,12 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> { private Statement unpackStatement(final Statement statement) { if (statement instanceof DeclarationListStatement) { - List<ExpressionStatement> expressionStatementList = ((DeclarationListStatement) statement).getDeclarationStatements(); - - if (1 == expressionStatementList.size()) { - return expressionStatementList.get(0); - } - - return configureAST(this.createBlockStatement(statement), statement); // if DeclarationListStatement contains more than 1 declarations, maybe it's better to create a block to hold them + // if DeclarationListStatement contains more than 1 declarations, maybe it's better to create a block to hold them + List<ExpressionStatement> expressionStatements = ((DeclarationListStatement) statement).getDeclarationStatements(); + return expressionStatements.size() == 1 ? expressionStatements.get(0) : configureAST(this.createBlockStatement(statement), statement); } - return statement; + return Optional.ofNullable(statement).orElse(EmptyStatement.INSTANCE); } BlockStatement createBlockStatement(final Statement... statements) { diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/IfStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/IfStatement.java index 0a9301a314..8165f11825 100644 --- a/src/main/java/org/codehaus/groovy/ast/stmt/IfStatement.java +++ b/src/main/java/org/codehaus/groovy/ast/stmt/IfStatement.java @@ -21,6 +21,9 @@ package org.codehaus.groovy.ast.stmt; import org.codehaus.groovy.ast.GroovyCodeVisitor; import org.codehaus.groovy.ast.expr.BooleanExpression; +import java.util.Objects; +import java.util.Optional; + /** * Represents an if (condition) { ... } else { ... } statement in Groovy. */ @@ -37,15 +40,15 @@ public class IfStatement extends Statement { } public void setBooleanExpression(final BooleanExpression booleanExpression) { - this.booleanExpression = booleanExpression; + this.booleanExpression = Objects.requireNonNull(booleanExpression); } public void setIfBlock(final Statement statement) { - ifBlock = statement; + ifBlock = Objects.requireNonNull(statement); } public void setElseBlock(final Statement statement) { - elseBlock = statement; + elseBlock = Optional.ofNullable(statement).orElse(EmptyStatement.INSTANCE); } //-------------------------------------------------------------------------- @@ -76,7 +79,7 @@ public class IfStatement extends Statement { text.append(getBooleanExpression().getText()); text.append(") "); text.append(thenStmt.getText()); - if (elseStmt != null && !elseStmt.isEmpty()) { + if (!elseStmt.isEmpty()) { if (!(thenStmt instanceof BlockStatement)) { text.append(';'); } diff --git a/src/test-resources/core/IfElse_02.groovy b/src/test-resources/core/IfElse_02.groovy new file mode 100644 index 0000000000..cc4bc00179 --- /dev/null +++ b/src/test-resources/core/IfElse_02.groovy @@ -0,0 +1,32 @@ +/* + * 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. + */ + +// GROOVY-11565: empty block handling + +if (true) ; + +if (true) { } + +if (true) 1 else ; + +if (true) ; else 0 + +if (true) ; else ; + +if (true) {} else {} diff --git a/src/test/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy b/src/test/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy index b5c0594456..73650c0a8d 100644 --- a/src/test/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy +++ b/src/test/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy @@ -254,7 +254,8 @@ final class GroovyParserTest { @Test void 'groovy core - IfElse'() { - doTest('core/IfElse_01.groovy', [AssertStatement]) + doTest('core/IfElse_01.groovy') + doTest('core/IfElse_02.groovy') } void 'groovy core - For'() {
