This is an automated email from the ASF dual-hosted git repository.

emilles pushed a commit to branch GROOVY_4_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/GROOVY_4_0_X by this push:
     new 30520bcad2 GROOVY-11565: empty block handling
30520bcad2 is described below

commit 30520bcad25eef6a3f4123a7cb2e3a00e8943c5c
Author: Eric Milles <[email protected]>
AuthorDate: Sat Feb 8 08:58:50 2025 -0600

    GROOVY-11565: empty block handling
    
    4_0_X backport
---
 .../apache/groovy/parser/antlr4/AstBuilder.java    | 53 ++++++----------------
 src/test-resources/core/IfElse_02.groovy           | 32 +++++++++++++
 .../groovy/parser/antlr4/GroovyParserTest.groovy   |  3 +-
 3 files changed, 49 insertions(+), 39 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 1297b6b622..4380f7c02b 100644
--- a/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
+++ b/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
@@ -450,20 +450,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
@@ -484,9 +476,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
@@ -510,12 +500,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);
             }
         }
 
@@ -571,28 +561,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));
 
@@ -4528,16 +4509,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/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 9099bac62f..81b849a2a1 100644
--- a/src/test/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy
+++ b/src/test/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy
@@ -237,7 +237,8 @@ final class GroovyParserTest extends GroovyTestCase {
     }
 
     void "test groovy core - IfElse"() {
-        doTest('core/IfElse_01.groovy', [AssertStatement])
+        doTest('core/IfElse_01.groovy')
+        doTest('core/IfElse_02.groovy')
     }
 
     void "test groovy core - For"() {

Reply via email to