fix: Allow toplevel await when option true and correctly mark await keyword as unexpected (#9371)

This commit is contained in:
Daniel Tschinder 2019-01-22 14:56:30 -08:00 committed by GitHub
parent 93e1b5e612
commit 8bc9f9a05f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 165 additions and 18 deletions

View File

@ -453,16 +453,19 @@ export default class StatementParser extends ExpressionParser {
this.next(); this.next();
this.state.labels.push(loopLabel); this.state.labels.push(loopLabel);
let forAwait = false; let awaitAt = -1;
if (this.state.inAsync && this.isContextual("await")) { if (
forAwait = true; (this.state.inAsync ||
this.next(); (!this.state.inFunction && this.options.allowAwaitOutsideFunction)) &&
this.eatContextual("await")
) {
awaitAt = this.state.lastTokStart;
} }
this.expect(tt.parenL); this.expect(tt.parenL);
if (this.match(tt.semi)) { if (this.match(tt.semi)) {
if (forAwait) { if (awaitAt > -1) {
this.unexpected(); this.unexpected(awaitAt);
} }
return this.parseFor(node, null); return this.parseFor(node, null);
} }
@ -487,12 +490,12 @@ export default class StatementParser extends ExpressionParser {
if (this.state.strict && isForInInitializer) { if (this.state.strict && isForInInitializer) {
this.raise(this.state.start, "for-in initializer in strict mode"); this.raise(this.state.start, "for-in initializer in strict mode");
} else if (isForInInitializer || !declaration.init) { } else if (isForInInitializer || !declaration.init) {
return this.parseForIn(node, init, forAwait); return this.parseForIn(node, init, awaitAt);
} }
} }
} }
if (forAwait) { if (awaitAt > -1) {
this.unexpected(); this.unexpected(awaitAt);
} }
return this.parseFor(node, init); return this.parseFor(node, init);
} }
@ -505,12 +508,12 @@ export default class StatementParser extends ExpressionParser {
: "for-in statement"; : "for-in statement";
this.toAssignable(init, undefined, description); this.toAssignable(init, undefined, description);
this.checkLVal(init, undefined, undefined, description); this.checkLVal(init, undefined, undefined, description);
return this.parseForIn(node, init, forAwait); return this.parseForIn(node, init, awaitAt);
} else if (refShorthandDefaultPos.start) { } else if (refShorthandDefaultPos.start) {
this.unexpected(refShorthandDefaultPos.start); this.unexpected(refShorthandDefaultPos.start);
} }
if (forAwait) { if (awaitAt > -1) {
this.unexpected(); this.unexpected(awaitAt);
} }
return this.parseFor(node, init); return this.parseFor(node, init);
} }
@ -872,16 +875,16 @@ export default class StatementParser extends ExpressionParser {
parseForIn( parseForIn(
node: N.ForInOf, node: N.ForInOf,
init: N.VariableDeclaration, init: N.VariableDeclaration,
forAwait: boolean, awaitAt: number,
): N.ForInOf { ): N.ForInOf {
const type = this.match(tt._in) ? "ForInStatement" : "ForOfStatement"; const type = this.match(tt._in) ? "ForInStatement" : "ForOfStatement";
if (forAwait) { if (awaitAt > -1) {
this.eatContextual("of"); this.eatContextual("of");
} else { } else {
this.next(); this.next();
} }
if (type === "ForOfStatement") { if (type === "ForOfStatement") {
node.await = !!forAwait; node.await = awaitAt > -1;
} }
node.left = init; node.left = init;
node.right = this.parseExpression(); node.right = this.parseExpression();

View File

@ -0,0 +1 @@
for await (const i of imports) {}

View File

@ -0,0 +1,3 @@
{
"throws": "Unexpected token, expected \"(\" (1:4)"
}

View File

@ -0,0 +1 @@
for await (const i of imports) {}

View File

@ -0,0 +1,3 @@
{
"allowAwaitOutsideFunction": true
}

View File

@ -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": []
}
}

View File

@ -1,3 +1,3 @@
{ {
"throws": "Unexpected token (2:13)" "throws": "Unexpected token (2:6)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "Unexpected token (2:22)" "throws": "Unexpected token (2:6)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "Unexpected token (2:18)" "throws": "Unexpected token (2:6)"
} }