Skip to content

Commit 4c9c590

Browse files
committed
Don't fail on async comprehension syntax
1 parent e6753cc commit 4c9c590

1 file changed

Lines changed: 24 additions & 8 deletions

File tree

src/core/IronPython/Compiler/Parser.cs

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2340,7 +2340,7 @@ private IReadOnlyList<Node> FinishArgListOrGenExpr() {
23402340

23412341
if (MaybeEat(TokenKind.Assign)) { // Keyword argument
23422342
a = FinishKeywordArgument(e);
2343-
} else if (PeekToken(TokenKind.KeywordFor)) { // Generator expression
2343+
} else if (PeekToken(TokenKind.KeywordFor) || PeekToken(TokenKind.KeywordAsync)) { // Generator expression
23442344
a = ParseGeneratorExpression(e);
23452345
Eat(TokenKind.RightParenthesis);
23462346
a.SetLoc(_globalParent, start, GetEnd());
@@ -2599,7 +2599,7 @@ private Expression FinishTupleOrGenExp() {
25992599
if (MaybeEat(TokenKind.Comma)) {
26002600
// "(" expression "," ...
26012601
ret = FinishExpressionListAsExpr(expr);
2602-
} else if (PeekToken(TokenKind.KeywordFor)) {
2602+
} else if (PeekToken(TokenKind.KeywordFor) || PeekToken(TokenKind.KeywordAsync)) {
26032603
// "(" expression "for" ...
26042604
if (expr is StarredExpression) ReportSyntaxError(expr.StartIndex, expr.EndIndex, "iterable unpacking cannot be used in comprehension");
26052605
ret = ParseGeneratorExpression(expr);
@@ -2634,7 +2634,7 @@ private Expression ParseGeneratorExpression(Expression expr) {
26342634
Statement current = root;
26352635

26362636
for (; ; ) {
2637-
if (PeekToken(TokenKind.KeywordFor)) {
2637+
if (PeekToken(TokenKind.KeywordFor) || PeekToken(TokenKind.KeywordAsync)) {
26382638
current = NestGenExpr(current, ParseGenExprFor());
26392639
} else if (PeekToken(TokenKind.KeywordIf)) {
26402640
current = NestGenExpr(current, ParseGenExprIf());
@@ -2684,6 +2684,14 @@ private static Statement NestGenExpr(Statement current, Statement nested) {
26842684

26852685
// "for" exprlist "in" or_test
26862686
private ForStatement ParseGenExprFor() {
2687+
var isAsync = MaybeEat(TokenKind.KeywordAsync);
2688+
if (isAsync) {
2689+
FunctionDefinition current = CurrentFunction;
2690+
if (current is null || !current.IsAsync) {
2691+
ReportSyntaxError("'asynchronous comprehension outside of an asynchronous function");
2692+
}
2693+
}
2694+
26872695
var start = GetStart();
26882696
Eat(TokenKind.KeywordFor);
26892697
bool trailingComma;
@@ -2754,7 +2762,7 @@ private Expression FinishDictOrSetValue() {
27542762
}
27552763
var expr = ParseStarExpr();
27562764

2757-
if (PeekToken(TokenKind.KeywordFor)) {
2765+
if (PeekToken(TokenKind.KeywordFor) || PeekToken(TokenKind.KeywordAsync)) {
27582766
if (!first) ReportSyntaxError("invalid syntax");
27592767
}
27602768

@@ -2770,7 +2778,7 @@ private Expression FinishDictOrSetValue() {
27702778
}
27712779
Expression e2 = ParseTest();
27722780

2773-
if (PeekToken(TokenKind.KeywordFor)) {
2781+
if (PeekToken(TokenKind.KeywordFor) || PeekToken(TokenKind.KeywordAsync)) {
27742782
if (!first) {
27752783
ReportSyntaxError("invalid syntax");
27762784
}
@@ -2788,7 +2796,7 @@ private Expression FinishDictOrSetValue() {
27882796
first = true;
27892797
}
27902798

2791-
if (PeekToken(TokenKind.KeywordFor)) {
2799+
if (PeekToken(TokenKind.KeywordFor) || PeekToken(TokenKind.KeywordAsync)) {
27922800
if (!first) {
27932801
ReportSyntaxError("invalid syntax");
27942802
}
@@ -2876,7 +2884,7 @@ private ComprehensionIterator[] ParseCompIter() {
28762884
iters.Add(firstFor);
28772885

28782886
while (true) {
2879-
if (PeekToken(TokenKind.KeywordFor)) {
2887+
if (PeekToken(TokenKind.KeywordFor) || PeekToken(TokenKind.KeywordAsync)) {
28802888
iters.Add(ParseCompFor());
28812889
} else if (PeekToken(TokenKind.KeywordIf)) {
28822890
iters.Add(ParseCompIf());
@@ -2890,6 +2898,13 @@ private ComprehensionIterator[] ParseCompIter() {
28902898

28912899
// comp_for: 'for' exprlist 'in' or_test [comp_iter]
28922900
private ComprehensionFor ParseCompFor() {
2901+
var isAsync = MaybeEat(TokenKind.KeywordAsync);
2902+
if (isAsync) {
2903+
FunctionDefinition current = CurrentFunction;
2904+
if (current is null || !current.IsAsync) {
2905+
ReportSyntaxError("'asynchronous comprehension outside of an asynchronous function");
2906+
}
2907+
}
28932908
Eat(TokenKind.KeywordFor);
28942909
var start = GetStart();
28952910
bool trailingComma;
@@ -2934,7 +2949,7 @@ private Expression FinishListValue() {
29342949
// (comp_for | (',' (test|star_expr))* [','] )
29352950

29362951
// comp_for
2937-
if (PeekToken(TokenKind.KeywordFor)) {
2952+
if (PeekToken(TokenKind.KeywordFor) || PeekToken(TokenKind.KeywordAsync)) {
29382953
// although it's calling ParseCompIter(), because the peek token is a FOR it is going to
29392954
// do the right thing.
29402955
if (expr is StarredExpression) ReportSyntaxError(expr.StartIndex, expr.EndIndex, "iterable unpacking cannot be used in comprehension");
@@ -3033,6 +3048,7 @@ private static bool NeverTestToken(Token t) {
30333048
case TokenKind.KeywordFor:
30343049
case TokenKind.KeywordIn:
30353050
case TokenKind.KeywordIf:
3051+
case TokenKind.KeywordAsync:
30363052
return true;
30373053

30383054
default: return false;

0 commit comments

Comments
 (0)