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

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


The following commit(s) were added to refs/heads/GROOVY-9381 by this push:
     new 646eb6fb18 GROOVY-9381: Support async/await like ES7(grammar)
646eb6fb18 is described below

commit 646eb6fb1868b7c51fa3a872506b9a10a12c0f60
Author: Daniel Sun <[email protected]>
AuthorDate: Sun Oct 26 23:30:16 2025 +0900

    GROOVY-9381: Support async/await like ES7(grammar)
---
 src/antlr/GroovyLexer.g4                           |   3 +
 src/antlr/GroovyParser.g4                          |   8 +
 .../apache/groovy/parser/antlr4/AstBuilder.java    | 225 ++++++++++++++++++++-
 .../groovy/parser/antlr4/ModifierManager.java      |   3 +-
 .../java/org/codehaus/groovy/ast/ModifierNode.java |   4 +-
 src/test-resources/core/AsyncAwait_01x.groovy      |  29 +++
 .../util/concurrent/async/AsyncHelperTest.groovy   | 198 +++++++++---------
 .../groovy/parser/antlr4/GroovyParserTest.groovy   |   5 +
 8 files changed, 372 insertions(+), 103 deletions(-)

diff --git a/src/antlr/GroovyLexer.g4 b/src/antlr/GroovyLexer.g4
index 79ddf78dbd..cc9eb54377 100644
--- a/src/antlr/GroovyLexer.g4
+++ b/src/antlr/GroovyLexer.g4
@@ -406,7 +406,9 @@ BuiltInPrimitiveType
     ;
 
 ABSTRACT      : 'abstract';
+ASYNC         : 'async';
 ASSERT        : 'assert';
+AWAIT         : 'await';
 
 fragment
 BOOLEAN       : 'boolean';
@@ -485,6 +487,7 @@ VOLATILE      : 'volatile';
 WHILE         : 'while';
 YIELD         : 'yield';
 
+
 // ยง3.10.1 Integer Literals
 
 IntegerLiteral
diff --git a/src/antlr/GroovyParser.g4 b/src/antlr/GroovyParser.g4
index b41faad333..fd315dfd91 100644
--- a/src/antlr/GroovyParser.g4
+++ b/src/antlr/GroovyParser.g4
@@ -130,6 +130,7 @@ modifier
     :   classOrInterfaceModifier
     |   m=(   NATIVE
           |   SYNCHRONIZED
+          |   ASYNC
           |   TRANSIENT
           |   VOLATILE
           |   DEF
@@ -776,6 +777,9 @@ expression
     // must come before postfixExpression to resolve the ambiguities between 
casting and call on parentheses expression, e.g. (int)(1 / 2)
     :   castParExpression castOperandExpression                                
             #castExprAlt
 
+    // await expression
+    |   AWAIT nls expression                                                   
             #awaitExprAlt
+
     // qualified names, array expressions, method invocation, post inc/dec
     |   postfixExpression                                                      
             #postfixExprAlt
 
@@ -1226,6 +1230,8 @@ identifier
     :   Identifier
     |   CapitalizedIdentifier
     |   AS
+    |   ASYNC
+    |   AWAIT
     |   IN
     |   PERMITS
     |   RECORD
@@ -1243,7 +1249,9 @@ builtInType
 keywords
     :   ABSTRACT
     |   AS
+    |   ASYNC
     |   ASSERT
+    |   AWAIT
     |   BREAK
     |   CASE
     |   CATCH
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 74d8c062e3..c96fe153f5 100644
--- a/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
+++ b/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
@@ -20,11 +20,13 @@ package org.apache.groovy.parser.antlr4;
 
 import groovy.lang.Tuple2;
 import groovy.lang.Tuple3;
+import groovy.transform.Async;
 import groovy.transform.CompileStatic;
 import groovy.transform.NonSealed;
 import groovy.transform.Sealed;
 import groovy.transform.Trait;
 import groovy.transform.TupleConstructor;
+import groovy.util.concurrent.async.AsyncHelper;
 import org.antlr.v4.runtime.ANTLRErrorListener;
 import org.antlr.v4.runtime.CharStream;
 import org.antlr.v4.runtime.CharStreams;
@@ -39,6 +41,7 @@ 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.AwaitExprAltContext;
 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;
@@ -97,6 +100,7 @@ import org.codehaus.groovy.ast.expr.PropertyExpression;
 import org.codehaus.groovy.ast.expr.RangeExpression;
 import org.codehaus.groovy.ast.expr.SpreadExpression;
 import org.codehaus.groovy.ast.expr.SpreadMapExpression;
+import org.codehaus.groovy.ast.expr.StaticMethodCallExpression;
 import org.codehaus.groovy.ast.expr.TernaryExpression;
 import org.codehaus.groovy.ast.expr.TupleExpression;
 import org.codehaus.groovy.ast.expr.UnaryMinusExpression;
@@ -151,9 +155,214 @@ import java.util.function.Function;
 import java.util.stream.Collectors;
 
 import static groovy.lang.Tuple.tuple;
-import static org.apache.groovy.parser.antlr4.GroovyParser.*;
+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.ASYNC;
+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.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.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.IndexVariableContext;
+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.MatchingTypeContext;
+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.OriginalForControlContext;
+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.ReferenceTypeContext;
+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.util.PositionConfigureUtils.configureAST;
 import static 
org.apache.groovy.parser.antlr4.util.PositionConfigureUtils.configureEndPosition;
+import static org.codehaus.groovy.ast.ClassHelper.make;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.assignX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.block;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.callThisX;
@@ -1758,6 +1967,11 @@ public class AstBuilder extends 
GroovyParserBaseVisitor<Object> {
             methodNode.getVariableScope().setInStaticContext(true);
         }
 
+        if (modifierManager.containsAny(ASYNC)) {
+            AnnotationNode asyncAnnotationNode = 
makeAnnotationNode(Async.class);
+            methodNode.addAnnotation(asyncAnnotationNode);
+        }
+
         configureAST(methodNode, ctx);
 
         validateMethodDeclaration(ctx, methodNode, modifierManager, classNode);
@@ -2944,6 +3158,13 @@ public class AstBuilder extends 
GroovyParserBaseVisitor<Object> {
         return configureAST(cast, ctx);
     }
 
+    @Override
+    public Expression visitAwaitExprAlt(AwaitExprAltContext ctx) {
+        Expression expr = (Expression) this.visit(ctx.expression());
+        StaticMethodCallExpression awaitMethodCallExpression = 
callX(ASYNC_HELPER_TYPE, "await", expr);
+        return configureAST(awaitMethodCallExpression, ctx);
+    }
+
     @Override
     public BinaryExpression visitPowerExprAlt(final PowerExprAltContext ctx) {
         return this.createBinaryExpression(ctx.left, ctx.op, ctx.right, ctx);
@@ -4795,6 +5016,8 @@ public class AstBuilder extends 
GroovyParserBaseVisitor<Object> {
 
     private Tuple2<GroovyParserRuleContext, Exception> numberFormatError;
 
+    private static final ClassNode ASYNC_HELPER_TYPE = make(AsyncHelper.class);
+
     private int visitingClosureCount;
     private int visitingLoopStatementCount;
     private int visitingSwitchStatementCount;
diff --git a/src/main/java/org/apache/groovy/parser/antlr4/ModifierManager.java 
b/src/main/java/org/apache/groovy/parser/antlr4/ModifierManager.java
index 4d86449b8d..c4a903a55f 100644
--- a/src/main/java/org/apache/groovy/parser/antlr4/ModifierManager.java
+++ b/src/main/java/org/apache/groovy/parser/antlr4/ModifierManager.java
@@ -41,13 +41,14 @@ import static 
org.apache.groovy.parser.antlr4.GroovyLangParser.FINAL;
 import static org.apache.groovy.parser.antlr4.GroovyLangParser.NATIVE;
 import static org.apache.groovy.parser.antlr4.GroovyLangParser.STATIC;
 import static org.apache.groovy.parser.antlr4.GroovyLangParser.VOLATILE;
+import static org.apache.groovy.parser.antlr4.GroovyLangParser.ASYNC;
 
 /**
  * Process modifiers for AST nodes
  */
 class ModifierManager {
     private static final Map<Class, List<Integer>> INVALID_MODIFIERS_MAP = 
Maps.of(
-            ConstructorNode.class, Arrays.asList(STATIC, FINAL, ABSTRACT, 
NATIVE),
+            ConstructorNode.class, Arrays.asList(STATIC, FINAL, ABSTRACT, 
NATIVE, ASYNC),
             MethodNode.class, Arrays.asList(VOLATILE/*, TRANSIENT*/) // 
Transient is left open for properties for legacy reasons but should be removed 
before ClassCompletionVerifier runs (CLASSGEN)
     );
     private AstBuilder astBuilder;
diff --git a/src/main/java/org/codehaus/groovy/ast/ModifierNode.java 
b/src/main/java/org/codehaus/groovy/ast/ModifierNode.java
index e76e1b4849..83f86e98fb 100644
--- a/src/main/java/org/codehaus/groovy/ast/ModifierNode.java
+++ b/src/main/java/org/codehaus/groovy/ast/ModifierNode.java
@@ -27,6 +27,7 @@ import java.util.Objects;
 import static org.apache.groovy.parser.antlr4.GroovyParser.ABSTRACT;
 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.ASYNC;
 import static org.apache.groovy.parser.antlr4.GroovyParser.FINAL;
 import static org.apache.groovy.parser.antlr4.GroovyParser.NATIVE;
 import static org.apache.groovy.parser.antlr4.GroovyParser.NON_SEALED;
@@ -72,7 +73,8 @@ public class ModifierNode extends ASTNode {
             NON_SEALED, 0,
             FINAL, Opcodes.ACC_FINAL,
             STRICTFP, Opcodes.ACC_STRICT,
-            DEFAULT, 0 // no flag for specifying a default method in the JVM 
spec, hence no ACC_DEFAULT flag in ASM
+            DEFAULT, 0, // no flag for specifying a default method in the JVM 
spec, hence no ACC_DEFAULT flag in ASM
+            ASYNC, 0 // a virtual modifier with no corresponding JVM flag
     );
 
     public ModifierNode(Integer type) {
diff --git a/src/test-resources/core/AsyncAwait_01x.groovy 
b/src/test-resources/core/AsyncAwait_01x.groovy
new file mode 100644
index 0000000000..1bcbf169c8
--- /dev/null
+++ b/src/test-resources/core/AsyncAwait_01x.groovy
@@ -0,0 +1,29 @@
+/*
+ *  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.
+ */
+async fetchData() {
+    return 1
+}
+
+async processData() {
+    def data = await fetchData()
+    return data + 2
+}
+
+def result = await processData() // TODO should we support top-level await?
+assert result == 3
diff --git 
a/src/test/groovy/groovy/util/concurrent/async/AsyncHelperTest.groovy 
b/src/test/groovy/groovy/util/concurrent/async/AsyncHelperTest.groovy
index 20a288ad42..44a06b489e 100644
--- a/src/test/groovy/groovy/util/concurrent/async/AsyncHelperTest.groovy
+++ b/src/test/groovy/groovy/util/concurrent/async/AsyncHelperTest.groovy
@@ -32,8 +32,6 @@ import java.util.concurrent.TimeUnit
 import java.util.concurrent.atomic.AtomicInteger
 import java.util.concurrent.atomic.AtomicReference
 
-import static groovy.util.concurrent.async.AsyncHelper.async
-import static groovy.util.concurrent.async.AsyncHelper.await
 import static org.junit.jupiter.api.Assertions.assertEquals
 import static org.junit.jupiter.api.Assertions.assertFalse
 import static org.junit.jupiter.api.Assertions.assertNotNull
@@ -52,50 +50,50 @@ class AsyncHelperTest {
         @Test
         @DisplayName("should execute simple async operation")
         void testSimpleAsync() {
-            Promise<Integer> promise = async(() -> 42)
-            Integer result = await(promise)
+            Promise<Integer> promise = AsyncHelper.async(() -> 42)
+            Integer result = AsyncHelper.await(promise)
             assertEquals(42, result)
         }
 
         @Test
         @DisplayName("should execute async operation with string")
         void testAsyncWithString() {
-            Promise<String> promise = async(() -> "Hello, Async!")
-            String result = await(promise)
+            Promise<String> promise = AsyncHelper.async(() -> "Hello, Async!")
+            String result = AsyncHelper.await(promise)
             assertEquals("Hello, Async!", result)
         }
 
         @Test
         @DisplayName("should handle async operation returning null")
         void testAsyncReturningNull() {
-            Promise<Object> promise = async(() -> null)
-            Object result = await(promise)
+            Promise<Object> promise = AsyncHelper.async(() -> null)
+            Object result = AsyncHelper.await(promise)
             assertNull(result)
         }
 
         @Test
         @DisplayName("should execute multiple async operations")
         void testMultipleAsyncOperations() {
-            Promise<Integer> p1 = async(() -> 10)
-            Promise<Integer> p2 = async(() -> 20)
-            Promise<Integer> p3 = async(() -> 30)
+            Promise<Integer> p1 = AsyncHelper.async(() -> 10)
+            Promise<Integer> p2 = AsyncHelper.async(() -> 20)
+            Promise<Integer> p3 = AsyncHelper.async(() -> 30)
 
-            assertEquals(10, await(p1))
-            assertEquals(20, await(p2))
-            assertEquals(30, await(p3))
+            assertEquals(10, AsyncHelper.await(p1))
+            assertEquals(20, AsyncHelper.await(p2))
+            assertEquals(30, AsyncHelper.await(p3))
         }
 
         @Test
         @DisplayName("should handle computation in async")
         void testAsyncComputation() {
-            Promise<Integer> promise = async(() -> {
+            Promise<Integer> promise = AsyncHelper.async(() -> {
                 int sum = 0
                 for (int i = 1; i <= 100; i++) {
                     sum += i
                 }
                 return sum
             })
-            assertEquals(5050, await(promise))
+            assertEquals(5050, AsyncHelper.await(promise))
         }
     }
 
@@ -117,12 +115,12 @@ class AsyncHelperTest {
             customExecutor = Executors.newSingleThreadExecutor()
             AtomicReference<String> threadName = new AtomicReference<>()
 
-            Promise<Integer> promise = async(() -> {
+            Promise<Integer> promise = AsyncHelper.async(() -> {
                 threadName.set(Thread.currentThread().getName())
                 return 100
             }, customExecutor)
 
-            assertEquals(100, await(promise))
+            assertEquals(100, AsyncHelper.await(promise))
             assertNotNull(threadName.get())
         }
 
@@ -131,11 +129,11 @@ class AsyncHelperTest {
         void testMultipleOperationsWithCustomExecutor() {
             customExecutor = Executors.newFixedThreadPool(2)
 
-            Promise<Integer> p1 = async(() -> 1, customExecutor)
-            Promise<Integer> p2 = async(() -> 2, customExecutor)
-            Promise<Integer> p3 = async(() -> 3, customExecutor)
+            Promise<Integer> p1 = AsyncHelper.async(() -> 1, customExecutor)
+            Promise<Integer> p2 = AsyncHelper.async(() -> 2, customExecutor)
+            Promise<Integer> p3 = AsyncHelper.async(() -> 3, customExecutor)
 
-            assertEquals(6, await(p1) + await(p2) + await(p3))
+            assertEquals(6, AsyncHelper.await(p1) + AsyncHelper.await(p2) + 
AsyncHelper.await(p3))
         }
 
         @Test
@@ -146,12 +144,12 @@ class AsyncHelperTest {
 
             for (int i = 0; i < 10; i++) {
                 final int value = i
-                promises.add(async(() -> value * 2, customExecutor))
+                promises.add(AsyncHelper.async(() -> value * 2, 
customExecutor))
             }
 
             int sum = 0
             for (Promise<Integer> p : promises) {
-                sum += await(p)
+                sum += AsyncHelper.await(p)
             }
             assertEquals(90, sum)
         }
@@ -164,24 +162,24 @@ class AsyncHelperTest {
         @Test
         @DisplayName("should chain async operations like Promise.then()")
         void testChainedAsync() {
-            Promise<Integer> result = async(() -> 10)
+            Promise<Integer> result = AsyncHelper.async(() -> 10)
                 .thenApply(n -> n * 2)
                 .thenApply(n -> n + 5)
 
-            assertEquals(25, await(result))
+            assertEquals(25, AsyncHelper.await(result))
         }
 
         @Test
         @DisplayName("should handle sequential async operations")
         void testSequentialAsync() {
-            Promise<String> step1 = async(() -> "Step1")
-            String result1 = await(step1)
+            Promise<String> step1 = AsyncHelper.async(() -> "Step1")
+            String result1 = AsyncHelper.await(step1)
 
-            Promise<String> step2 = async(() -> result1 + "-Step2")
-            String result2 = await(step2)
+            Promise<String> step2 = AsyncHelper.async(() -> result1 + "-Step2")
+            String result2 = AsyncHelper.await(step2)
 
-            Promise<String> step3 = async(() -> result2 + "-Step3")
-            String result3 = await(step3)
+            Promise<String> step3 = AsyncHelper.async(() -> result2 + "-Step3")
+            String result3 = AsyncHelper.await(step3)
 
             assertEquals("Step1-Step2-Step3", result3)
         }
@@ -190,45 +188,45 @@ class AsyncHelperTest {
         @DisplayName("should handle parallel async operations like 
Promise.all()")
         @Timeout(2)
         void testParallelAsync() {
-            Promise<Integer> p1 = async(() -> {
+            Promise<Integer> p1 = AsyncHelper.async(() -> {
                 sleep(100)
                 return 1
             })
 
-            Promise<Integer> p2 = async(() -> {
+            Promise<Integer> p2 = AsyncHelper.async(() -> {
                 sleep(100)
                 return 2
             })
 
-            Promise<Integer> p3 = async(() -> {
+            Promise<Integer> p3 = AsyncHelper.async(() -> {
                 sleep(100)
                 return 3
             })
 
             Promise<Void> all = SimplePromise.allOf(p1, p2, p3)
-            await(all)
+            AsyncHelper.await(all)
 
-            assertEquals(1, await(p1))
-            assertEquals(2, await(p2))
-            assertEquals(3, await(p3))
+            assertEquals(1, AsyncHelper.await(p1))
+            assertEquals(2, AsyncHelper.await(p2))
+            assertEquals(3, AsyncHelper.await(p3))
         }
 
         @Test
         @DisplayName("should handle race conditions like Promise.race()")
         @Timeout(1)
         void testAsyncRace() {
-            Promise<String> slow = async(() -> {
+            Promise<String> slow = AsyncHelper.async(() -> {
                 sleep(500)
                 return "slow"
             })
 
-            Promise<String> fast = async(() -> {
+            Promise<String> fast = AsyncHelper.async(() -> {
                 sleep(50)
                 return "fast"
             })
 
             Promise<Object> winner = SimplePromise.anyOf(fast, slow)
-            String result = await(winner)
+            String result = AsyncHelper.await(winner)
 
             assertEquals("fast", result)
         }
@@ -236,7 +234,7 @@ class AsyncHelperTest {
         @Test
         @DisplayName("should handle async/await with exception handling")
         void testAsyncWithExceptionHandling() {
-            Promise<Integer> promise = async(() -> {
+            Promise<Integer> promise = AsyncHelper.async(() -> {
                 throw new RuntimeException("Simulated error")
             })
 
@@ -245,13 +243,13 @@ class AsyncHelperTest {
                 return -1
             })
 
-            assertEquals(-1, await(recovered))
+            assertEquals(-1, AsyncHelper.await(recovered))
         }
 
         @Test
         @DisplayName("should handle async/await with data transformation 
pipeline")
         void testAsyncDataPipeline() {
-            Promise<? extends List<Integer>> result = async(() -> List.of(1, 
2, 3, 4, 5))
+            Promise<? extends List<Integer>> result = AsyncHelper.async(() -> 
List.of(1, 2, 3, 4, 5))
                 .thenApply(list -> {
                     List<Integer> doubled = new ArrayList<>()
                     for (Integer n : list) {
@@ -270,18 +268,18 @@ class AsyncHelperTest {
                 })
 
             List<Integer> expected = List.of(6, 8, 10)
-            assertEquals(expected, await(result))
+            assertEquals(expected, AsyncHelper.await(result))
         }
 
         @Test
         @DisplayName("should handle nested async operations")
         void testNestedAsync() {
-            Promise<Integer> outer = async(() -> {
-                Promise<Integer> inner = async(() -> 5)
-                return await(inner) * 2
+            Promise<Integer> outer = AsyncHelper.async(() -> {
+                Promise<Integer> inner = AsyncHelper.async(() -> 5)
+                return AsyncHelper.await(inner) * 2
             })
 
-            assertEquals(10, await(outer))
+            assertEquals(10, AsyncHelper.await(outer))
         }
     }
 
@@ -294,7 +292,7 @@ class AsyncHelperTest {
         void testAsyncRetryPattern() {
             AtomicInteger attempts = new AtomicInteger(0)
 
-            Promise<String> result = async(() -> {
+            Promise<String> result = AsyncHelper.async(() -> {
                 int count = attempts.incrementAndGet()
                 if (count < 3) {
                     throw new RuntimeException("Not ready yet")
@@ -302,13 +300,13 @@ class AsyncHelperTest {
                 return "Success after " + count + " attempts"
             }).exceptionallyCompose(ex -> {
                 sleep(50)
-                return async(() -> {
+                return AsyncHelper.async(() -> {
                     int count = attempts.incrementAndGet()
                     return "Success after " + count + " attempts"
                 })
             })
 
-            String finalResult = await(result)
+            String finalResult = AsyncHelper.await(result)
             assertTrue(finalResult.contains("Success"))
             assertTrue(attempts.get() >= 2)
         }
@@ -317,7 +315,7 @@ class AsyncHelperTest {
         @DisplayName("should handle async timeout pattern")
         @Timeout(1)
         void testAsyncTimeoutPattern() throws Exception {
-            Promise<String> slowTask = async(() -> {
+            Promise<String> slowTask = AsyncHelper.async(() -> {
                 sleep(5000)
                 return "completed"
             })
@@ -337,12 +335,12 @@ class AsyncHelperTest {
             List<Promise<Integer>> squarePromises = new ArrayList<>()
             for (Integer n : numbers) {
                 def tmpN = n
-                squarePromises.add(async(() -> tmpN * tmpN))
+                squarePromises.add(AsyncHelper.async(() -> tmpN * tmpN))
             }
 
             int total = 0
             for (Promise<Integer> p : squarePromises) {
-                total += await(p)
+                total += AsyncHelper.await(p)
             }
 
             assertEquals(55, total)
@@ -351,24 +349,24 @@ class AsyncHelperTest {
         @Test
         @DisplayName("should handle async combine operations")
         void testAsyncCombine() {
-            Promise<Integer> p1 = async(() -> 10)
-            Promise<Integer> p2 = async(() -> 20)
+            Promise<Integer> p1 = AsyncHelper.async(() -> 10)
+            Promise<Integer> p2 = AsyncHelper.async(() -> 20)
 
             Promise<Integer> combined = p1.thenCombine(p2, Integer::sum)
 
-            assertEquals(30, await(combined))
+            assertEquals(30, AsyncHelper.await(combined))
         }
 
         @Test
         @DisplayName("should handle async compose operations")
         void testAsyncCompose() {
-            Promise<Integer> initial = async(() -> 5)
+            Promise<Integer> initial = AsyncHelper.async(() -> 5)
 
             Promise<Integer> composed = initial.thenCompose(n ->
-                async(() -> n * 3)
+                AsyncHelper.async(() -> n * 3)
             )
 
-            assertEquals(15, await(composed))
+            assertEquals(15, AsyncHelper.await(composed))
         }
     }
 
@@ -379,7 +377,7 @@ class AsyncHelperTest {
         @Test
         @DisplayName("should simulate API call with data transformation")
         void testSimulateApiCall() {
-            Promise<String> apiCall = async(() -> {
+            Promise<String> apiCall = AsyncHelper.async(() -> {
                 sleep(50)
                 return "{\"userId\":1,\"name\":\"John\"}"
             })
@@ -388,7 +386,7 @@ class AsyncHelperTest {
                 json.replace("John", "Jane")
             )
 
-            String result = await(transformed)
+            String result = AsyncHelper.await(transformed)
             assertTrue(result.contains("Jane"))
             assertFalse(result.contains("John"))
         }
@@ -397,17 +395,17 @@ class AsyncHelperTest {
         @DisplayName("should handle multiple parallel API calls")
         @Timeout(1)
         void testMultipleParallelApiCalls() {
-            Promise<String> userApi = async(() -> {
+            Promise<String> userApi = AsyncHelper.async(() -> {
                 sleep(100)
                 return "User data"
             })
 
-            Promise<String> orderApi = async(() -> {
+            Promise<String> orderApi = AsyncHelper.async(() -> {
                 sleep(100)
                 return "Order data"
             })
 
-            Promise<String> productApi = async(() -> {
+            Promise<String> productApi = AsyncHelper.async(() -> {
                 sleep(100)
                 return "Product data"
             })
@@ -415,7 +413,7 @@ class AsyncHelperTest {
             Promise<String> combined = userApi.thenCombine(orderApi, (u, o) -> 
u + ", " + o)
                 .thenCombine(productApi, (uo, p) -> uo + ", " + p)
 
-            String result = await(combined)
+            String result = AsyncHelper.await(combined)
             assertEquals("User data, Order data, Product data", result)
         }
 
@@ -425,7 +423,7 @@ class AsyncHelperTest {
             AtomicReference<String> cache = new AtomicReference<>()
             AtomicInteger fetchCount = new AtomicInteger(0)
 
-            Promise<String> getCachedData = async(() -> {
+            Promise<String> getCachedData = AsyncHelper.async(() -> {
                 if (cache.get() != null) {
                     return cache.get()
                 }
@@ -436,12 +434,12 @@ class AsyncHelperTest {
                 return data
             })
 
-            String firstCall = await(getCachedData)
+            String firstCall = AsyncHelper.await(getCachedData)
             assertEquals("Fresh data", firstCall)
             assertEquals(1, fetchCount.get())
 
-            Promise<String> secondCall = async(() -> cache.get())
-            assertEquals("Fresh data", await(secondCall))
+            Promise<String> secondCall = AsyncHelper.async(() -> cache.get())
+            assertEquals("Fresh data", AsyncHelper.await(secondCall))
             assertEquals(1, fetchCount.get())
         }
 
@@ -455,7 +453,7 @@ class AsyncHelperTest {
             List<Promise<Void>> tasks = new ArrayList<>()
             for (Integer item : queue) {
                 def tmp = item
-                tasks.add(async(() -> {
+                tasks.add(AsyncHelper.async(() -> {
                     sleep(50)
                     processed.addAndGet(tmp)
                     return
@@ -463,7 +461,7 @@ class AsyncHelperTest {
             }
 
             Promise<Void> allProcessed = SimplePromise.allOf(tasks as 
Promise[])
-            await(allProcessed)
+            AsyncHelper.await(allProcessed)
 
             assertEquals(150, processed.get())
         }
@@ -473,15 +471,15 @@ class AsyncHelperTest {
         void testAsyncBatchProcessing() {
             List<Integer> batch = List.of(1, 2, 3, 4, 5)
 
-            Promise<Integer> batchSum = async(() -> {
+            Promise<Integer> batchSum = AsyncHelper.async(() -> {
                 int sum = 0
                 for (Integer item : batch) {
-                    sum += await(async(() -> item * 2))
+                    sum += AsyncHelper.await(AsyncHelper.async(() -> item * 2))
                 }
                 return sum
             })
 
-            assertEquals(30, await(batchSum))
+            assertEquals(30, AsyncHelper.await(batchSum))
         }
     }
 
@@ -492,28 +490,28 @@ class AsyncHelperTest {
         @Test
         @DisplayName("should propagate exceptions in async chain")
         void testExceptionPropagation() {
-            Promise<Integer> promise = async(() -> 10)
+            Promise<Integer> promise = AsyncHelper.async(() -> 10)
                 .thenApply(n -> {
                     throw new RuntimeException("Chain error")
                 })
 
-            assertThrows(AwaitException.class, () -> await(promise))
+            assertThrows(AwaitException.class, () -> 
AsyncHelper.await(promise))
         }
 
         @Test
         @DisplayName("should handle exception in async operation")
         void testAsyncException() {
-            Promise<Integer> promise = async(() -> {
+            Promise<Integer> promise = AsyncHelper.async(() -> {
                 throw new IllegalStateException("Async error")
             })
 
-            assertThrows(AwaitException.class, () -> await(promise))
+            assertThrows(AwaitException.class, () -> 
AsyncHelper.await(promise))
         }
 
         @Test
         @DisplayName("should recover from exception with fallback")
         void testExceptionRecovery() {
-            Promise<Object> promise = async(() -> {
+            Promise<Object> promise = AsyncHelper.async(() -> {
                 throw new RuntimeException("Error")
             }).handle((result, ex) -> {
                 if (ex != null) {
@@ -522,31 +520,31 @@ class AsyncHelperTest {
                 return result
             })
 
-            assertEquals("Fallback value", await(promise))
+            assertEquals("Fallback value", AsyncHelper.await(promise))
         }
 
         @Test
         @DisplayName("should handle exception with exceptionally")
         void testExceptionallyHandler() {
-            Promise<Integer> promise = async(() -> {
+            Promise<Integer> promise = AsyncHelper.async(() -> {
                 throw new RuntimeException("Error")
             }).exceptionally(ex -> {
                 assertTrue(ex.getCause() instanceof RuntimeException)
                 return 999
             })
 
-            assertEquals(999, await(promise))
+            assertEquals(999, AsyncHelper.await(promise))
         }
 
         @Test
         @DisplayName("should handle null pointer exception")
         void testNullPointerException() {
-            Promise<String> promise = async(() -> {
+            Promise<String> promise = AsyncHelper.async(() -> {
                 String s = null
                 return s.length() + ""
             })
 
-            assertThrows(AwaitException.class, () -> await(promise))
+            assertThrows(AwaitException.class, () -> 
AsyncHelper.await(promise))
         }
     }
 
@@ -562,7 +560,7 @@ class AsyncHelperTest {
             CountDownLatch latch = new CountDownLatch(100)
 
             for (int i = 0; i < 100; i++) {
-                async(() -> {
+                AsyncHelper.async(() -> {
                     counter.incrementAndGet()
                     latch.countDown()
                     return null
@@ -580,14 +578,14 @@ class AsyncHelperTest {
 
             List<Promise<Void>> promises = new ArrayList<>()
             for (int i = 0; i < 10; i++) {
-                promises.add(async(() -> {
+                promises.add(AsyncHelper.async(() -> {
                     shared.incrementAndGet()
                     return
                 }))
             }
 
             for (Promise<Void> p : promises) {
-                await(p)
+                AsyncHelper.await(p)
             }
 
             assertEquals(10, shared.get())
@@ -601,38 +599,38 @@ class AsyncHelperTest {
         @Test
         @DisplayName("should handle empty result")
         void testEmptyResult() {
-            Promise<Void> promise = async(() -> null)
-            assertNull(await(promise))
+            Promise<Void> promise = AsyncHelper.async(() -> null)
+            assertNull(AsyncHelper.await(promise))
         }
 
         @Test
         @DisplayName("should handle boolean results")
         void testBooleanResults() {
-            Promise<Boolean> truePromise = async(() -> true)
-            Promise<Boolean> falsePromise = async(() -> false)
+            Promise<Boolean> truePromise = AsyncHelper.async(() -> true)
+            Promise<Boolean> falsePromise = AsyncHelper.async(() -> false)
 
-            assertTrue(await(truePromise))
-            assertFalse(await(falsePromise))
+            assertTrue(AsyncHelper.await(truePromise))
+            assertFalse(AsyncHelper.await(falsePromise))
         }
 
         @Test
         @DisplayName("should handle long running tasks")
         @Timeout(2)
         void testLongRunningTask() {
-            Promise<String> promise = async(() -> {
+            Promise<String> promise = AsyncHelper.async(() -> {
                 sleep(500)
                 return "Long task completed"
             })
 
-            assertEquals("Long task completed", await(promise))
+            assertEquals("Long task completed", AsyncHelper.await(promise))
         }
 
         @Test
         @DisplayName("should handle immediate completion")
         void testImmediateCompletion() {
             long start = System.currentTimeMillis()
-            Promise<String> promise = async(() -> "Immediate")
-            String result = await(promise)
+            Promise<String> promise = AsyncHelper.async(() -> "Immediate")
+            String result = AsyncHelper.await(promise)
             long duration = System.currentTimeMillis() - start
 
             assertEquals("Immediate", result)
diff --git 
a/src/test/groovy/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy 
b/src/test/groovy/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy
index 60973387db..35fd8fb3b5 100644
--- a/src/test/groovy/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy
+++ b/src/test/groovy/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy
@@ -345,6 +345,11 @@ final class GroovyParserTest {
         doTest('core/Label_01.groovy')
     }
 
+    @Test
+    void 'groovy core - async-await'() {
+        doRunAndTestAntlr4('core/AsyncAwait_01x.groovy')
+    }
+
     @Test
     void 'groovy core - LocalVariableDeclaration'() {
         doTest('core/LocalVariableDeclaration_01.groovy', [Token]) // [class 
org.codehaus.groovy.syntax.Token][startLine]:: 9 != 8

Reply via email to