Skip to content

Commit

Permalink
Fix parsing of an "async of" edge case in for loop (#1286)
Browse files Browse the repository at this point in the history
FIX: Properly raise a parse error for invalid `for`/`of` statements using `async` as binding name.
  • Loading branch information
adams85 committed Apr 3, 2024
1 parent 9a5ecbc commit ed4a7a1
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 5 deletions.
16 changes: 11 additions & 5 deletions acorn/src/statement.js
Original file line number Diff line number Diff line change
Expand Up @@ -235,13 +235,19 @@ pp.parseForStatement = function(node) {
return this.parseFor(node, init)
}
let startsWithLet = this.isContextual("let"), isForOf = false
let containsEsc = this.containsEsc
let refDestructuringErrors = new DestructuringErrors
let init = this.parseExpression(awaitAt > -1 ? "await" : true, refDestructuringErrors)
let initPos = this.start
let init = awaitAt > -1
? this.parseExprSubscripts(refDestructuringErrors, "await")
: this.parseExpression(true, refDestructuringErrors)
if (this.type === tt._in || (isForOf = this.options.ecmaVersion >= 6 && this.isContextual("of"))) {
if (this.options.ecmaVersion >= 9) {
if (this.type === tt._in) {
if (awaitAt > -1) this.unexpected(awaitAt)
} else node.await = awaitAt > -1
if (awaitAt > -1) { // implies `ecmaVersion >= 9` (see declaration of awaitAt)
if (this.type === tt._in) this.unexpected(awaitAt)
node.await = true
} else if (isForOf && this.options.ecmaVersion >= 8) {
if (init.start === initPos && !containsEsc && init.type === "Identifier" && init.name === "async") this.unexpected()
else if (this.options.ecmaVersion >= 9) node.await = false
}
if (startsWithLet && isForOf) this.raise(init.start, "The left-hand side of a for-of loop may not start with 'let'.")
this.toAssignable(init, false, refDestructuringErrors)
Expand Down
3 changes: 3 additions & 0 deletions test/tests-async-iteration.js
Original file line number Diff line number Diff line change
Expand Up @@ -1998,3 +1998,6 @@ test("async () => { for await (async of []); }", {}, {ecmaVersion: 9})
test("for (async of => {}; i < 10; ++i) {}", {}, {ecmaVersion: 9})
testFail("for (async of [1]) {}", "Unexpected token (1:14)", {ecmaVersion: 9})

testFail("async () => { for (async\nof []); }", "Unexpected token (2:0)", {ecmaVersion: 9})
testFail("async () => { for (async of\n[]); }", "Unexpected token (2:0)", {ecmaVersion: 9})
test("for ((async) of [7]);", {}, {ecmaVersion: 9})

0 comments on commit ed4a7a1

Please sign in to comment.