From ed4a7a1afae031f8cb3eb245a9539f33f9008390 Mon Sep 17 00:00:00 2001 From: adams85 <31276480+adams85@users.noreply.github.com> Date: Wed, 3 Apr 2024 16:14:51 +0200 Subject: [PATCH] Fix parsing of an "async of" edge case in for loop (#1286) FIX: Properly raise a parse error for invalid `for`/`of` statements using `async` as binding name. --- acorn/src/statement.js | 16 +++++++++++----- test/tests-async-iteration.js | 3 +++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/acorn/src/statement.js b/acorn/src/statement.js index d5e5c6fc8..c5fea3956 100644 --- a/acorn/src/statement.js +++ b/acorn/src/statement.js @@ -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) diff --git a/test/tests-async-iteration.js b/test/tests-async-iteration.js index 4f885c380..2d553bc86 100644 --- a/test/tests-async-iteration.js +++ b/test/tests-async-iteration.js @@ -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})