diff --git a/packages/babel-parser/src/parser/statement.js b/packages/babel-parser/src/parser/statement.js index 1ef98a1f87..48578310a0 100644 --- a/packages/babel-parser/src/parser/statement.js +++ b/packages/babel-parser/src/parser/statement.js @@ -453,16 +453,19 @@ export default class StatementParser extends ExpressionParser { this.next(); this.state.labels.push(loopLabel); - let forAwait = false; - if (this.state.inAsync && this.isContextual("await")) { - forAwait = true; - this.next(); + let awaitAt = -1; + if ( + (this.state.inAsync || + (!this.state.inFunction && this.options.allowAwaitOutsideFunction)) && + this.eatContextual("await") + ) { + awaitAt = this.state.lastTokStart; } this.expect(tt.parenL); if (this.match(tt.semi)) { - if (forAwait) { - this.unexpected(); + if (awaitAt > -1) { + this.unexpected(awaitAt); } return this.parseFor(node, null); } @@ -487,12 +490,12 @@ export default class StatementParser extends ExpressionParser { if (this.state.strict && isForInInitializer) { this.raise(this.state.start, "for-in initializer in strict mode"); } else if (isForInInitializer || !declaration.init) { - return this.parseForIn(node, init, forAwait); + return this.parseForIn(node, init, awaitAt); } } } - if (forAwait) { - this.unexpected(); + if (awaitAt > -1) { + this.unexpected(awaitAt); } return this.parseFor(node, init); } @@ -505,12 +508,12 @@ export default class StatementParser extends ExpressionParser { : "for-in statement"; this.toAssignable(init, undefined, description); this.checkLVal(init, undefined, undefined, description); - return this.parseForIn(node, init, forAwait); + return this.parseForIn(node, init, awaitAt); } else if (refShorthandDefaultPos.start) { this.unexpected(refShorthandDefaultPos.start); } - if (forAwait) { - this.unexpected(); + if (awaitAt > -1) { + this.unexpected(awaitAt); } return this.parseFor(node, init); } @@ -872,16 +875,16 @@ export default class StatementParser extends ExpressionParser { parseForIn( node: N.ForInOf, init: N.VariableDeclaration, - forAwait: boolean, + awaitAt: number, ): N.ForInOf { const type = this.match(tt._in) ? "ForInStatement" : "ForOfStatement"; - if (forAwait) { + if (awaitAt > -1) { this.eatContextual("of"); } else { this.next(); } if (type === "ForOfStatement") { - node.await = !!forAwait; + node.await = awaitAt > -1; } node.left = init; node.right = this.parseExpression(); diff --git a/packages/babel-parser/test/fixtures/core/opts/allowAwaitOutsideFunction-false/input.js b/packages/babel-parser/test/fixtures/core/opts/allowAwaitOutsideFunction-false/input.js new file mode 100644 index 0000000000..3e4ef35fdb --- /dev/null +++ b/packages/babel-parser/test/fixtures/core/opts/allowAwaitOutsideFunction-false/input.js @@ -0,0 +1 @@ +for await (const i of imports) {} diff --git a/packages/babel-parser/test/fixtures/core/opts/allowAwaitOutsideFunction-false/options.json b/packages/babel-parser/test/fixtures/core/opts/allowAwaitOutsideFunction-false/options.json new file mode 100644 index 0000000000..01bcb0a20e --- /dev/null +++ b/packages/babel-parser/test/fixtures/core/opts/allowAwaitOutsideFunction-false/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Unexpected token, expected \"(\" (1:4)" +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/core/opts/allowAwaitOutsideFunction-true/input.js b/packages/babel-parser/test/fixtures/core/opts/allowAwaitOutsideFunction-true/input.js new file mode 100644 index 0000000000..3e4ef35fdb --- /dev/null +++ b/packages/babel-parser/test/fixtures/core/opts/allowAwaitOutsideFunction-true/input.js @@ -0,0 +1 @@ +for await (const i of imports) {} diff --git a/packages/babel-parser/test/fixtures/core/opts/allowAwaitOutsideFunction-true/options.json b/packages/babel-parser/test/fixtures/core/opts/allowAwaitOutsideFunction-true/options.json new file mode 100644 index 0000000000..40360d582b --- /dev/null +++ b/packages/babel-parser/test/fixtures/core/opts/allowAwaitOutsideFunction-true/options.json @@ -0,0 +1,3 @@ +{ + "allowAwaitOutsideFunction": true +} diff --git a/packages/babel-parser/test/fixtures/core/opts/allowAwaitOutsideFunction-true/output.json b/packages/babel-parser/test/fixtures/core/opts/allowAwaitOutsideFunction-true/output.json new file mode 100644 index 0000000000..259b3ffcf4 --- /dev/null +++ b/packages/babel-parser/test/fixtures/core/opts/allowAwaitOutsideFunction-true/output.json @@ -0,0 +1,136 @@ +{ + "type": "File", + "start": 0, + "end": 33, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 33 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 33, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 33 + } + }, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ForOfStatement", + "start": 0, + "end": 33, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 33 + } + }, + "await": true, + "left": { + "type": "VariableDeclaration", + "start": 11, + "end": 18, + "loc": { + "start": { + "line": 1, + "column": 11 + }, + "end": { + "line": 1, + "column": 18 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 17, + "end": 18, + "loc": { + "start": { + "line": 1, + "column": 17 + }, + "end": { + "line": 1, + "column": 18 + } + }, + "id": { + "type": "Identifier", + "start": 17, + "end": 18, + "loc": { + "start": { + "line": 1, + "column": 17 + }, + "end": { + "line": 1, + "column": 18 + }, + "identifierName": "i" + }, + "name": "i" + }, + "init": null + } + ], + "kind": "const" + }, + "right": { + "type": "Identifier", + "start": 22, + "end": 29, + "loc": { + "start": { + "line": 1, + "column": 22 + }, + "end": { + "line": 1, + "column": 29 + }, + "identifierName": "imports" + }, + "name": "imports" + }, + "body": { + "type": "BlockStatement", + "start": 31, + "end": 33, + "loc": { + "start": { + "line": 1, + "column": 31 + }, + "end": { + "line": 1, + "column": 33 + } + }, + "body": [], + "directives": [] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/es2018/async-generators/for-await-no-semi-1/options.json b/packages/babel-parser/test/fixtures/es2018/async-generators/for-await-no-semi-1/options.json index f45f06d72e..9660494a29 100644 --- a/packages/babel-parser/test/fixtures/es2018/async-generators/for-await-no-semi-1/options.json +++ b/packages/babel-parser/test/fixtures/es2018/async-generators/for-await-no-semi-1/options.json @@ -1,3 +1,3 @@ { - "throws": "Unexpected token (2:13)" + "throws": "Unexpected token (2:6)" } diff --git a/packages/babel-parser/test/fixtures/es2018/async-generators/for-await-no-semi-2/options.json b/packages/babel-parser/test/fixtures/es2018/async-generators/for-await-no-semi-2/options.json index c2c8f56374..9660494a29 100644 --- a/packages/babel-parser/test/fixtures/es2018/async-generators/for-await-no-semi-2/options.json +++ b/packages/babel-parser/test/fixtures/es2018/async-generators/for-await-no-semi-2/options.json @@ -1,3 +1,3 @@ { - "throws": "Unexpected token (2:22)" + "throws": "Unexpected token (2:6)" } diff --git a/packages/babel-parser/test/fixtures/es2018/async-generators/for-await-no-semi-3/options.json b/packages/babel-parser/test/fixtures/es2018/async-generators/for-await-no-semi-3/options.json index ae405ee221..9660494a29 100644 --- a/packages/babel-parser/test/fixtures/es2018/async-generators/for-await-no-semi-3/options.json +++ b/packages/babel-parser/test/fixtures/es2018/async-generators/for-await-no-semi-3/options.json @@ -1,3 +1,3 @@ { - "throws": "Unexpected token (2:18)" + "throws": "Unexpected token (2:6)" }