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

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


The following commit(s) were added to refs/heads/master by this push:
     new 60d58bd79b GROOVY-11601: restore support for expression list in `for` 
statement
60d58bd79b is described below

commit 60d58bd79b6db7d046b08d7f5ef787e15a173389
Author: Eric Milles <[email protected]>
AuthorDate: Fri Sep 5 12:05:41 2025 -0500

    GROOVY-11601: restore support for expression list in `for` statement
    
    revert commit 7f6720b17cd81ba62f82a71d6353963ac31fc7d4
---
 src/antlr/GroovyParser.g4                            |  1 +
 .../org/apache/groovy/parser/antlr4/AstBuilder.java  | 13 +++++++++++--
 src/test/groovy/groovy/ForLoopTest.groovy            | 20 +++++++++++++++++---
 3 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/src/antlr/GroovyParser.g4 b/src/antlr/GroovyParser.g4
index 18c08b5f44..b41faad333 100644
--- a/src/antlr/GroovyParser.g4
+++ b/src/antlr/GroovyParser.g4
@@ -704,6 +704,7 @@ originalForControl
 
 forInit
     :   localVariableDeclaration
+    |   expressionList[false]
     ;
 
 forUpdate
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 c8daa1b606..74d8c062e3 100644
--- a/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
+++ b/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
@@ -545,6 +545,10 @@ public class AstBuilder extends 
GroovyParserBaseVisitor<Object> {
             }
         }
 
+        if (asBoolean(ctx.expressionList())) {
+            return this.translateExpressionList(ctx.expressionList());
+        }
+
         throw createParsingFailedException("Unsupported for init: " + 
ctx.getText(), ctx);
     }
 
@@ -554,9 +558,14 @@ public class AstBuilder extends 
GroovyParserBaseVisitor<Object> {
             return EmptyExpression.INSTANCE;
         }
 
-        var expressionList = this.visitExpressionList(ctx.expressionList());
+        return this.translateExpressionList(ctx.expressionList());
+    }
+
+    private Expression translateExpressionList(final ExpressionListContext 
ctx) {
+        List<Expression> expressionList = this.visitExpressionList(ctx);
+
         if (expressionList.size() == 1) {
-            return configureAST(expressionList.get(0), ctx); // one Expression
+            return configureAST(expressionList.get(0), ctx);
         } else {
             return configureAST(new ClosureListExpression(expressionList), 
ctx);
         }
diff --git a/src/test/groovy/groovy/ForLoopTest.groovy 
b/src/test/groovy/groovy/ForLoopTest.groovy
index ee795e97eb..05fb76a253 100644
--- a/src/test/groovy/groovy/ForLoopTest.groovy
+++ b/src/test/groovy/groovy/ForLoopTest.groovy
@@ -157,14 +157,19 @@ final class ForLoopTest {
 
     @Test
     void testClassicFor() {
+        for (x = 0; x < 10; x += 2) {
+        }
+        assert x == 10
+
+        x = 0
         for (int i = 0; i < 10; i++) {
-            x++
+            x += 1
         }
         assert x == 10
 
-        def list = [1, 2]
         x = 0
-        for (Iterator i = list.iterator(); i.hasNext();) {
+        def list = [1, 2]
+        for (Iterator i = list.iterator(); i.hasNext(); ) {
             x += i.next()
         }
         assert x == 3
@@ -214,6 +219,15 @@ final class ForLoopTest {
         assert result == 7 // 1 + 2 + 4
     }
 
+    // GROOVY-11601
+    void testClassicForWithMultiAssignment2() {
+        int foo, bar, baz = 0
+        for (foo = 1, bar = 2; foo < 10; foo += 1, bar += 2) {
+            baz += bar
+        }
+        assert baz == (2 + 4 + 6 + 8 + 10 + 12 + 14 + 16 + 18)
+    }
+
     @Test
     void testClassicForWithEmptyInitializer() {
         def i = 0

Reply via email to