From 2fa19846353a97e33676e819e9ba4f7104aaad3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Tue, 6 Nov 2018 08:30:06 +0100 Subject: [PATCH] Fix await in function name and parameters (#7727) * Disallow await in function parameters * Fix await as function name * Update test whitelists --- .../babel-parser/src/parser/expression.js | 98 ++++++--- packages/babel-parser/src/parser/statement.js | 13 +- packages/babel-parser/src/tokenizer/state.js | 10 +- .../input.js | 3 + .../options.json | 3 + .../input.js | 1 + .../output.json | 86 ++++++++ .../input.js | 1 + .../options.json | 3 + .../input.js | 3 + .../options.json | 3 + .../input.js | 3 + .../output.json | 158 ++++++++++++++ .../input.js | 3 + .../output.json | 189 ++++++++++++++++ .../input.js | 3 + .../options.json | 3 + .../input.js | 3 + .../output.json | 204 ++++++++++++++++++ .../input.js | 1 + .../options.json | 3 + .../input.js | 3 + .../options.json | 3 + .../input.js | 3 + .../options.json | 3 + .../input.js | 3 + .../options.json | 3 + .../await-inside-parameters/input.js | 1 + .../await-inside-parameters/options.json | 3 + .../input.js | 3 + .../output.json | 174 +++++++++++++++ scripts/tests/flow/flow_tests_whitelist.txt | 1 + scripts/tests/test262/test262_whitelist.txt | 20 +- 33 files changed, 963 insertions(+), 51 deletions(-) create mode 100644 packages/babylon/test/fixtures/es2015/yield/parameter-default-inside-arrow-inside-generator-6/input.js create mode 100644 packages/babylon/test/fixtures/es2015/yield/parameter-default-inside-arrow-inside-generator-6/options.json create mode 100644 packages/babylon/test/fixtures/es2017/async-functions/await-async-function-declaration-name/input.js create mode 100644 packages/babylon/test/fixtures/es2017/async-functions/await-async-function-declaration-name/output.json create mode 100644 packages/babylon/test/fixtures/es2017/async-functions/await-async-function-expression-name/input.js create mode 100644 packages/babylon/test/fixtures/es2017/async-functions/await-async-function-expression-name/options.json create mode 100644 packages/babylon/test/fixtures/es2017/async-functions/await-function-declaration-name-inside-async-function/input.js create mode 100644 packages/babylon/test/fixtures/es2017/async-functions/await-function-declaration-name-inside-async-function/options.json create mode 100644 packages/babylon/test/fixtures/es2017/async-functions/await-function-expression-name-inside-async-function/input.js create mode 100644 packages/babylon/test/fixtures/es2017/async-functions/await-function-expression-name-inside-async-function/output.json create mode 100644 packages/babylon/test/fixtures/es2017/async-functions/await-identifier-inside-parameters-of-nested-function/input.js create mode 100644 packages/babylon/test/fixtures/es2017/async-functions/await-identifier-inside-parameters-of-nested-function/output.json create mode 100644 packages/babylon/test/fixtures/es2017/async-functions/await-inside-arguments-of-async-call-inside-parameters-of-async-arrow-function/input.js create mode 100644 packages/babylon/test/fixtures/es2017/async-functions/await-inside-arguments-of-async-call-inside-parameters-of-async-arrow-function/options.json create mode 100644 packages/babylon/test/fixtures/es2017/async-functions/await-inside-arguments-of-async-function-call/input.js create mode 100644 packages/babylon/test/fixtures/es2017/async-functions/await-inside-arguments-of-async-function-call/output.json create mode 100644 packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters-of-async-arrow-function/input.js create mode 100644 packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters-of-async-arrow-function/options.json create mode 100644 packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters-of-nested-arrow-function/input.js create mode 100644 packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters-of-nested-arrow-function/options.json create mode 100644 packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters-of-nested-async-arrow-function/input.js create mode 100644 packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters-of-nested-async-arrow-function/options.json create mode 100644 packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters-of-nested-function/input.js create mode 100644 packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters-of-nested-function/options.json create mode 100644 packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters/input.js create mode 100644 packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters/options.json create mode 100644 packages/babylon/test/fixtures/es2017/async-functions/await-inside-parenthesized-assign/input.js create mode 100644 packages/babylon/test/fixtures/es2017/async-functions/await-inside-parenthesized-assign/output.json diff --git a/packages/babel-parser/src/parser/expression.js b/packages/babel-parser/src/parser/expression.js index e16dc4e124c3..b51cdcef5d79 100644 --- a/packages/babel-parser/src/parser/expression.js +++ b/packages/babel-parser/src/parser/expression.js @@ -522,10 +522,15 @@ export default class ExpressionParser extends LValParser { } return this.finishNode(node, "MemberExpression"); } else if (!noCalls && this.match(tt.parenL)) { + const oldMaybeInArrowParameters = this.state.maybeInArrowParameters; + const oldYOAIPAP = this.state.yieldOrAwaitInPossibleArrowParameters; + this.state.maybeInArrowParameters = true; + this.state.yieldOrAwaitInPossibleArrowParameters = null; + const possibleAsync = this.atPossibleAsync(base); this.next(); - const node = this.startNodeAt(startPos, startLoc); + let node = this.startNodeAt(startPos, startLoc); node.callee = base; // TODO: Clean up/merge this into `this.state` or a class like acorn's @@ -554,13 +559,22 @@ export default class ExpressionParser extends LValParser { ); } - return this.parseAsyncArrowFromCallExpression( + node = this.parseAsyncArrowFromCallExpression( this.startNodeAt(startPos, startLoc), node, ); + this.state.yieldOrAwaitInPossibleArrowParameters = oldYOAIPAP; } else { this.toReferencedList(node.arguments); + + // We keep the old value if it isn't null, for cases like + // (x = async(yield)) => {} + this.state.yieldOrAwaitInPossibleArrowParameters = + this.state.yieldOrAwaitInPossibleArrowParameters || oldYOAIPAP; } + + this.state.maybeInArrowParameters = oldMaybeInArrowParameters; + return node; } else if (this.match(tt.backQuote)) { return this.parseTaggedTemplateExpression( @@ -685,11 +699,8 @@ export default class ExpressionParser extends LValParser { node: N.ArrowFunctionExpression, call: N.CallExpression, ): N.ArrowFunctionExpression { - const oldYield = this.state.yieldInPossibleArrowParameters; - this.state.yieldInPossibleArrowParameters = null; this.expect(tt.arrow); this.parseArrowExpression(node, call.arguments, true); - this.state.yieldInPossibleArrowParameters = oldYield; return node; } @@ -800,21 +811,24 @@ export default class ExpressionParser extends LValParser { id.name === "async" && this.match(tt.name) ) { - const oldYield = this.state.yieldInPossibleArrowParameters; - this.state.yieldInPossibleArrowParameters = null; + const oldYOAIPAP = this.state.yieldOrAwaitInPossibleArrowParameters; + const oldInAsync = this.state.inAsync; + this.state.yieldOrAwaitInPossibleArrowParameters = null; + this.state.inAsync = true; const params = [this.parseIdentifier()]; this.expect(tt.arrow); // let foo = async bar => {}; this.parseArrowExpression(node, params, true); - this.state.yieldInPossibleArrowParameters = oldYield; + this.state.yieldOrAwaitInPossibleArrowParameters = oldYOAIPAP; + this.state.inAsync = oldInAsync; return node; } if (canBeArrow && !this.canInsertSemicolon() && this.eat(tt.arrow)) { - const oldYield = this.state.yieldInPossibleArrowParameters; - this.state.yieldInPossibleArrowParameters = null; + const oldYOAIPAP = this.state.yieldOrAwaitInPossibleArrowParameters; + this.state.yieldOrAwaitInPossibleArrowParameters = null; this.parseArrowExpression(node, [id]); - this.state.yieldInPossibleArrowParameters = oldYield; + this.state.yieldOrAwaitInPossibleArrowParameters = oldYOAIPAP; return node; } @@ -1049,9 +1063,9 @@ export default class ExpressionParser extends LValParser { this.expect(tt.parenL); const oldMaybeInArrowParameters = this.state.maybeInArrowParameters; - const oldYield = this.state.yieldInPossibleArrowParameters; + const oldYOAIPAP = this.state.yieldOrAwaitInPossibleArrowParameters; this.state.maybeInArrowParameters = true; - this.state.yieldInPossibleArrowParameters = null; + this.state.yieldOrAwaitInPossibleArrowParameters = null; const innerStartPos = this.state.start; const innerStartLoc = this.state.startLoc; @@ -1124,11 +1138,14 @@ export default class ExpressionParser extends LValParser { } this.parseArrowExpression(arrowNode, exprList); - this.state.yieldInPossibleArrowParameters = oldYield; + this.state.yieldOrAwaitInPossibleArrowParameters = oldYOAIPAP; return arrowNode; } - this.state.yieldInPossibleArrowParameters = oldYield; + // We keep the old value if it isn't null, for cases like + // (x = (yield)) => {} + this.state.yieldOrAwaitInPossibleArrowParameters = + this.state.yieldOrAwaitInPossibleArrowParameters || oldYOAIPAP; if (!exprList.length) { this.unexpected(this.state.lastTokStart); @@ -1620,9 +1637,11 @@ export default class ExpressionParser extends LValParser { ): T { const oldInFunc = this.state.inFunction; const oldInMethod = this.state.inMethod; + const oldInAsync = this.state.inAsync; const oldInGenerator = this.state.inGenerator; this.state.inFunction = true; this.state.inMethod = node.kind || true; + this.state.inAsync = isAsync; this.state.inGenerator = isGenerator; this.initFunction(node, isAsync); @@ -1633,6 +1652,7 @@ export default class ExpressionParser extends LValParser { this.state.inFunction = oldInFunc; this.state.inMethod = oldInMethod; + this.state.inAsync = oldInAsync; this.state.inGenerator = oldInGenerator; return node; @@ -1648,12 +1668,21 @@ export default class ExpressionParser extends LValParser { ): N.ArrowFunctionExpression { // if we got there, it's no more "yield in possible arrow parameters"; // it's just "yield in arrow parameters" - if (this.state.yieldInPossibleArrowParameters) { - this.raise( - this.state.yieldInPossibleArrowParameters.start, - "yield is not allowed in the parameters of an arrow function" + - " inside a generator", - ); + const yOAIPAP = this.state.yieldOrAwaitInPossibleArrowParameters; + if (yOAIPAP) { + if (yOAIPAP.type === "YieldExpression") { + this.raise( + yOAIPAP.start, + "yield is not allowed in the parameters of an arrow function" + + " inside a generator", + ); + } else { + this.raise( + yOAIPAP.start, + "await is not allowed in the parameters of an arrow function" + + " inside an async function", + ); + } } const oldInFunc = this.state.inFunction; @@ -1661,11 +1690,14 @@ export default class ExpressionParser extends LValParser { this.initFunction(node, isAsync); if (params) this.setArrowFunctionParameters(node, params); + const oldInAsync = this.state.inAsync; const oldInGenerator = this.state.inGenerator; const oldMaybeInArrowParameters = this.state.maybeInArrowParameters; + this.state.inAsync = true; this.state.inGenerator = false; this.state.maybeInArrowParameters = false; this.parseFunctionBody(node, true); + this.state.inAsync = oldInAsync; this.state.inGenerator = oldInGenerator; this.state.inFunction = oldInFunc; this.state.maybeInArrowParameters = oldMaybeInArrowParameters; @@ -1713,9 +1745,7 @@ export default class ExpressionParser extends LValParser { const isExpression = allowExpression && !this.match(tt.braceL); const oldInParameters = this.state.inParameters; - const oldInAsync = this.state.inAsync; this.state.inParameters = false; - this.state.inAsync = node.async; if (isExpression) { node.body = this.parseMaybeAssign(); @@ -1733,7 +1763,6 @@ export default class ExpressionParser extends LValParser { this.state.inGenerator = oldInGen; this.state.labels = oldLabels; } - this.state.inAsync = oldInAsync; this.checkFunctionNameAndParams(node, allowExpression); this.state.inParameters = oldInParameters; @@ -1910,12 +1939,27 @@ export default class ExpressionParser extends LValParser { ) { this.unexpected(); } + if (this.state.inParameters) { + this.raise( + node.start, + "await is not allowed in async function parameters", + ); + } if (this.match(tt.star)) { this.raise( node.start, "await* has been removed from the async functions proposal. Use Promise.all() instead.", ); } + if ( + this.state.maybeInArrowParameters && + // We only set yieldOrAwaitInPossibleArrowParameters if we haven't already + // found a possible invalid AwaitExpression. + !this.state.yieldOrAwaitInPossibleArrowParameters + ) { + this.state.yieldOrAwaitInPossibleArrowParameters = node; + } + node.argument = this.parseMaybeUnary(); return this.finishNode(node, "AwaitExpression"); } @@ -1930,11 +1974,11 @@ export default class ExpressionParser extends LValParser { } if ( this.state.maybeInArrowParameters && - // We only set yieldInPossibleArrowParameters if we haven't already + // We only set yieldOrAwaitInPossibleArrowParameters if we haven't already // found a possible invalid YieldExpression. - !this.state.yieldInPossibleArrowParameters + !this.state.yieldOrAwaitInPossibleArrowParameters ) { - this.state.yieldInPossibleArrowParameters = node; + this.state.yieldOrAwaitInPossibleArrowParameters = node; } this.next(); diff --git a/packages/babel-parser/src/parser/statement.js b/packages/babel-parser/src/parser/statement.js index 475d6dab3d91..b19cd78f1bd3 100644 --- a/packages/babel-parser/src/parser/statement.js +++ b/packages/babel-parser/src/parser/statement.js @@ -842,6 +842,7 @@ export default class StatementParser extends ExpressionParser { ): T { const oldInFunc = this.state.inFunction; const oldInMethod = this.state.inMethod; + const oldInAsync = this.state.inAsync; const oldInGenerator = this.state.inGenerator; const oldInClassProperty = this.state.inClassProperty; this.state.inFunction = true; @@ -872,11 +873,18 @@ export default class StatementParser extends ExpressionParser { // valid because yield is parsed as if it was outside the generator. // Therefore, this.state.inGenerator is set before or after parsing the // function id according to the "isStatement" parameter. - if (!isStatement) this.state.inGenerator = node.generator; + // The same applies to await & async functions. + if (!isStatement) { + this.state.inAsync = isAsync; + this.state.inGenerator = node.generator; + } if (this.match(tt.name) || this.match(tt._yield)) { node.id = this.parseBindingIdentifier(); } - if (isStatement) this.state.inGenerator = node.generator; + if (isStatement) { + this.state.inAsync = isAsync; + this.state.inGenerator = node.generator; + } this.parseFunctionParams(node); this.parseFunctionBodyAndFinish( @@ -887,6 +895,7 @@ export default class StatementParser extends ExpressionParser { this.state.inFunction = oldInFunc; this.state.inMethod = oldInMethod; + this.state.inAsync = oldInAsync; this.state.inGenerator = oldInGenerator; this.state.inClassProperty = oldInClassProperty; diff --git a/packages/babel-parser/src/tokenizer/state.js b/packages/babel-parser/src/tokenizer/state.js index 364ceec96d32..1c08d1ce6522 100644 --- a/packages/babel-parser/src/tokenizer/state.js +++ b/packages/babel-parser/src/tokenizer/state.js @@ -39,7 +39,7 @@ export default class State { this.decoratorStack = [[]]; - this.yieldInPossibleArrowParameters = null; + this.yieldOrAwaitInPossibleArrowParameters = null; this.tokens = []; @@ -126,10 +126,10 @@ export default class State { // where @foo belongs to the outer class and @bar to the inner decoratorStack: Array>; - // The first yield expression inside parenthesized expressions and arrow - // function parameters. It is used to disallow yield in arrow function - // parameters. - yieldInPossibleArrowParameters: ?N.YieldExpression; + // The first yield or await expression inside parenthesized expressions + // and arrow function parameters. It is used to disallow yield and await in + // arrow function parameters. + yieldOrAwaitInPossibleArrowParameters: ?N.YieldExpression; // Token store. tokens: Array; diff --git a/packages/babylon/test/fixtures/es2015/yield/parameter-default-inside-arrow-inside-generator-6/input.js b/packages/babylon/test/fixtures/es2015/yield/parameter-default-inside-arrow-inside-generator-6/input.js new file mode 100644 index 000000000000..896d8fcb5cf9 --- /dev/null +++ b/packages/babylon/test/fixtures/es2015/yield/parameter-default-inside-arrow-inside-generator-6/input.js @@ -0,0 +1,3 @@ +function* fn() { + (x = (yield)) => {}; +} \ No newline at end of file diff --git a/packages/babylon/test/fixtures/es2015/yield/parameter-default-inside-arrow-inside-generator-6/options.json b/packages/babylon/test/fixtures/es2015/yield/parameter-default-inside-arrow-inside-generator-6/options.json new file mode 100644 index 000000000000..816f0c4579af --- /dev/null +++ b/packages/babylon/test/fixtures/es2015/yield/parameter-default-inside-arrow-inside-generator-6/options.json @@ -0,0 +1,3 @@ +{ + "throws": "yield is not allowed in the parameters of an arrow function inside a generator (2:8)" +} \ No newline at end of file diff --git a/packages/babylon/test/fixtures/es2017/async-functions/await-async-function-declaration-name/input.js b/packages/babylon/test/fixtures/es2017/async-functions/await-async-function-declaration-name/input.js new file mode 100644 index 000000000000..60b70d4a68e9 --- /dev/null +++ b/packages/babylon/test/fixtures/es2017/async-functions/await-async-function-declaration-name/input.js @@ -0,0 +1 @@ +async function await() {} \ No newline at end of file diff --git a/packages/babylon/test/fixtures/es2017/async-functions/await-async-function-declaration-name/output.json b/packages/babylon/test/fixtures/es2017/async-functions/await-async-function-declaration-name/output.json new file mode 100644 index 000000000000..0cde29d7f404 --- /dev/null +++ b/packages/babylon/test/fixtures/es2017/async-functions/await-async-function-declaration-name/output.json @@ -0,0 +1,86 @@ +{ + "type": "File", + "start": 0, + "end": 25, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 25 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 25, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 25 + } + }, + "sourceType": "script", + "body": [ + { + "type": "FunctionDeclaration", + "start": 0, + "end": 25, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 25 + } + }, + "id": { + "type": "Identifier", + "start": 15, + "end": 20, + "loc": { + "start": { + "line": 1, + "column": 15 + }, + "end": { + "line": 1, + "column": 20 + }, + "identifierName": "await" + }, + "name": "await" + }, + "generator": false, + "async": true, + "params": [], + "body": { + "type": "BlockStatement", + "start": 23, + "end": 25, + "loc": { + "start": { + "line": 1, + "column": 23 + }, + "end": { + "line": 1, + "column": 25 + } + }, + "body": [], + "directives": [] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babylon/test/fixtures/es2017/async-functions/await-async-function-expression-name/input.js b/packages/babylon/test/fixtures/es2017/async-functions/await-async-function-expression-name/input.js new file mode 100644 index 000000000000..5102f04c3f84 --- /dev/null +++ b/packages/babylon/test/fixtures/es2017/async-functions/await-async-function-expression-name/input.js @@ -0,0 +1 @@ +(async function await() {}); \ No newline at end of file diff --git a/packages/babylon/test/fixtures/es2017/async-functions/await-async-function-expression-name/options.json b/packages/babylon/test/fixtures/es2017/async-functions/await-async-function-expression-name/options.json new file mode 100644 index 000000000000..848e79b9dbca --- /dev/null +++ b/packages/babylon/test/fixtures/es2017/async-functions/await-async-function-expression-name/options.json @@ -0,0 +1,3 @@ +{ + "throws": "invalid use of await inside of an async function (1:16)" +} \ No newline at end of file diff --git a/packages/babylon/test/fixtures/es2017/async-functions/await-function-declaration-name-inside-async-function/input.js b/packages/babylon/test/fixtures/es2017/async-functions/await-function-declaration-name-inside-async-function/input.js new file mode 100644 index 000000000000..1df99191e510 --- /dev/null +++ b/packages/babylon/test/fixtures/es2017/async-functions/await-function-declaration-name-inside-async-function/input.js @@ -0,0 +1,3 @@ +async function foo() { + function await() {} +} \ No newline at end of file diff --git a/packages/babylon/test/fixtures/es2017/async-functions/await-function-declaration-name-inside-async-function/options.json b/packages/babylon/test/fixtures/es2017/async-functions/await-function-declaration-name-inside-async-function/options.json new file mode 100644 index 000000000000..e2abd7d95537 --- /dev/null +++ b/packages/babylon/test/fixtures/es2017/async-functions/await-function-declaration-name-inside-async-function/options.json @@ -0,0 +1,3 @@ +{ + "throws": "invalid use of await inside of an async function (2:11)" +} \ No newline at end of file diff --git a/packages/babylon/test/fixtures/es2017/async-functions/await-function-expression-name-inside-async-function/input.js b/packages/babylon/test/fixtures/es2017/async-functions/await-function-expression-name-inside-async-function/input.js new file mode 100644 index 000000000000..97183151654b --- /dev/null +++ b/packages/babylon/test/fixtures/es2017/async-functions/await-function-expression-name-inside-async-function/input.js @@ -0,0 +1,3 @@ +async function fn() { + (function await() {}); +} \ No newline at end of file diff --git a/packages/babylon/test/fixtures/es2017/async-functions/await-function-expression-name-inside-async-function/output.json b/packages/babylon/test/fixtures/es2017/async-functions/await-function-expression-name-inside-async-function/output.json new file mode 100644 index 000000000000..5711b91c540d --- /dev/null +++ b/packages/babylon/test/fixtures/es2017/async-functions/await-function-expression-name-inside-async-function/output.json @@ -0,0 +1,158 @@ +{ + "type": "File", + "start": 0, + "end": 48, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 48, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "sourceType": "script", + "body": [ + { + "type": "FunctionDeclaration", + "start": 0, + "end": 48, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "id": { + "type": "Identifier", + "start": 15, + "end": 17, + "loc": { + "start": { + "line": 1, + "column": 15 + }, + "end": { + "line": 1, + "column": 17 + }, + "identifierName": "fn" + }, + "name": "fn" + }, + "generator": false, + "async": true, + "params": [], + "body": { + "type": "BlockStatement", + "start": 20, + "end": 48, + "loc": { + "start": { + "line": 1, + "column": 20 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 24, + "end": 46, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 2, + "column": 24 + } + }, + "expression": { + "type": "FunctionExpression", + "start": 25, + "end": 44, + "loc": { + "start": { + "line": 2, + "column": 3 + }, + "end": { + "line": 2, + "column": 22 + } + }, + "id": { + "type": "Identifier", + "start": 34, + "end": 39, + "loc": { + "start": { + "line": 2, + "column": 12 + }, + "end": { + "line": 2, + "column": 17 + }, + "identifierName": "await" + }, + "name": "await" + }, + "generator": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start": 42, + "end": 44, + "loc": { + "start": { + "line": 2, + "column": 20 + }, + "end": { + "line": 2, + "column": 22 + } + }, + "body": [], + "directives": [] + }, + "extra": { + "parenthesized": true, + "parenStart": 24 + } + } + } + ], + "directives": [] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babylon/test/fixtures/es2017/async-functions/await-identifier-inside-parameters-of-nested-function/input.js b/packages/babylon/test/fixtures/es2017/async-functions/await-identifier-inside-parameters-of-nested-function/input.js new file mode 100644 index 000000000000..ec2205553408 --- /dev/null +++ b/packages/babylon/test/fixtures/es2017/async-functions/await-identifier-inside-parameters-of-nested-function/input.js @@ -0,0 +1,3 @@ +async function fn() { + function g(x = await) {} +} \ No newline at end of file diff --git a/packages/babylon/test/fixtures/es2017/async-functions/await-identifier-inside-parameters-of-nested-function/output.json b/packages/babylon/test/fixtures/es2017/async-functions/await-identifier-inside-parameters-of-nested-function/output.json new file mode 100644 index 000000000000..dd5611dc6ea3 --- /dev/null +++ b/packages/babylon/test/fixtures/es2017/async-functions/await-identifier-inside-parameters-of-nested-function/output.json @@ -0,0 +1,189 @@ +{ + "type": "File", + "start": 0, + "end": 50, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 50, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "sourceType": "script", + "body": [ + { + "type": "FunctionDeclaration", + "start": 0, + "end": 50, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "id": { + "type": "Identifier", + "start": 15, + "end": 17, + "loc": { + "start": { + "line": 1, + "column": 15 + }, + "end": { + "line": 1, + "column": 17 + }, + "identifierName": "fn" + }, + "name": "fn" + }, + "generator": false, + "async": true, + "params": [], + "body": { + "type": "BlockStatement", + "start": 20, + "end": 50, + "loc": { + "start": { + "line": 1, + "column": 20 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "body": [ + { + "type": "FunctionDeclaration", + "start": 24, + "end": 48, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 2, + "column": 26 + } + }, + "id": { + "type": "Identifier", + "start": 33, + "end": 34, + "loc": { + "start": { + "line": 2, + "column": 11 + }, + "end": { + "line": 2, + "column": 12 + }, + "identifierName": "g" + }, + "name": "g" + }, + "generator": false, + "async": false, + "params": [ + { + "type": "AssignmentPattern", + "start": 35, + "end": 44, + "loc": { + "start": { + "line": 2, + "column": 13 + }, + "end": { + "line": 2, + "column": 22 + } + }, + "left": { + "type": "Identifier", + "start": 35, + "end": 36, + "loc": { + "start": { + "line": 2, + "column": 13 + }, + "end": { + "line": 2, + "column": 14 + }, + "identifierName": "x" + }, + "name": "x" + }, + "right": { + "type": "Identifier", + "start": 39, + "end": 44, + "loc": { + "start": { + "line": 2, + "column": 17 + }, + "end": { + "line": 2, + "column": 22 + }, + "identifierName": "await" + }, + "name": "await" + } + } + ], + "body": { + "type": "BlockStatement", + "start": 46, + "end": 48, + "loc": { + "start": { + "line": 2, + "column": 24 + }, + "end": { + "line": 2, + "column": 26 + } + }, + "body": [], + "directives": [] + } + } + ], + "directives": [] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babylon/test/fixtures/es2017/async-functions/await-inside-arguments-of-async-call-inside-parameters-of-async-arrow-function/input.js b/packages/babylon/test/fixtures/es2017/async-functions/await-inside-arguments-of-async-call-inside-parameters-of-async-arrow-function/input.js new file mode 100644 index 000000000000..b27b79ef4ae1 --- /dev/null +++ b/packages/babylon/test/fixtures/es2017/async-functions/await-inside-arguments-of-async-call-inside-parameters-of-async-arrow-function/input.js @@ -0,0 +1,3 @@ +async function fn() { + async (x = async(y = await 2)) => {}; +} \ No newline at end of file diff --git a/packages/babylon/test/fixtures/es2017/async-functions/await-inside-arguments-of-async-call-inside-parameters-of-async-arrow-function/options.json b/packages/babylon/test/fixtures/es2017/async-functions/await-inside-arguments-of-async-call-inside-parameters-of-async-arrow-function/options.json new file mode 100644 index 000000000000..662a80c579c4 --- /dev/null +++ b/packages/babylon/test/fixtures/es2017/async-functions/await-inside-arguments-of-async-call-inside-parameters-of-async-arrow-function/options.json @@ -0,0 +1,3 @@ +{ + "throws": "await is not allowed in the parameters of an arrow function inside an async function (2:23)" +} \ No newline at end of file diff --git a/packages/babylon/test/fixtures/es2017/async-functions/await-inside-arguments-of-async-function-call/input.js b/packages/babylon/test/fixtures/es2017/async-functions/await-inside-arguments-of-async-function-call/input.js new file mode 100644 index 000000000000..d41288f1156b --- /dev/null +++ b/packages/babylon/test/fixtures/es2017/async-functions/await-inside-arguments-of-async-function-call/input.js @@ -0,0 +1,3 @@ +async function fn() { + async(x = await 2); +} \ No newline at end of file diff --git a/packages/babylon/test/fixtures/es2017/async-functions/await-inside-arguments-of-async-function-call/output.json b/packages/babylon/test/fixtures/es2017/async-functions/await-inside-arguments-of-async-function-call/output.json new file mode 100644 index 000000000000..6095dda3069b --- /dev/null +++ b/packages/babylon/test/fixtures/es2017/async-functions/await-inside-arguments-of-async-function-call/output.json @@ -0,0 +1,204 @@ +{ + "type": "File", + "start": 0, + "end": 45, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 45, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "sourceType": "script", + "body": [ + { + "type": "FunctionDeclaration", + "start": 0, + "end": 45, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "id": { + "type": "Identifier", + "start": 15, + "end": 17, + "loc": { + "start": { + "line": 1, + "column": 15 + }, + "end": { + "line": 1, + "column": 17 + }, + "identifierName": "fn" + }, + "name": "fn" + }, + "generator": false, + "async": true, + "params": [], + "body": { + "type": "BlockStatement", + "start": 20, + "end": 45, + "loc": { + "start": { + "line": 1, + "column": 20 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 24, + "end": 43, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 2, + "column": 21 + } + }, + "expression": { + "type": "CallExpression", + "start": 24, + "end": 42, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 2, + "column": 20 + } + }, + "callee": { + "type": "Identifier", + "start": 24, + "end": 29, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 2, + "column": 7 + }, + "identifierName": "async" + }, + "name": "async" + }, + "arguments": [ + { + "type": "AssignmentExpression", + "start": 30, + "end": 41, + "loc": { + "start": { + "line": 2, + "column": 8 + }, + "end": { + "line": 2, + "column": 19 + } + }, + "operator": "=", + "left": { + "type": "Identifier", + "start": 30, + "end": 31, + "loc": { + "start": { + "line": 2, + "column": 8 + }, + "end": { + "line": 2, + "column": 9 + }, + "identifierName": "x" + }, + "name": "x" + }, + "right": { + "type": "AwaitExpression", + "start": 34, + "end": 41, + "loc": { + "start": { + "line": 2, + "column": 12 + }, + "end": { + "line": 2, + "column": 19 + } + }, + "argument": { + "type": "NumericLiteral", + "start": 40, + "end": 41, + "loc": { + "start": { + "line": 2, + "column": 18 + }, + "end": { + "line": 2, + "column": 19 + } + }, + "extra": { + "rawValue": 2, + "raw": "2" + }, + "value": 2 + } + } + } + ] + } + } + ], + "directives": [] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters-of-async-arrow-function/input.js b/packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters-of-async-arrow-function/input.js new file mode 100644 index 000000000000..f137977faf1d --- /dev/null +++ b/packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters-of-async-arrow-function/input.js @@ -0,0 +1 @@ +async (x = await 2) => {}; \ No newline at end of file diff --git a/packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters-of-async-arrow-function/options.json b/packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters-of-async-arrow-function/options.json new file mode 100644 index 000000000000..a38149bc650b --- /dev/null +++ b/packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters-of-async-arrow-function/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Unexpected token, expected \",\" (1:17)" +} \ No newline at end of file diff --git a/packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters-of-nested-arrow-function/input.js b/packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters-of-nested-arrow-function/input.js new file mode 100644 index 000000000000..39aea232a5ce --- /dev/null +++ b/packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters-of-nested-arrow-function/input.js @@ -0,0 +1,3 @@ +async function fn() { + (x = await 2) => {}; +} \ No newline at end of file diff --git a/packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters-of-nested-arrow-function/options.json b/packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters-of-nested-arrow-function/options.json new file mode 100644 index 000000000000..779503d21709 --- /dev/null +++ b/packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters-of-nested-arrow-function/options.json @@ -0,0 +1,3 @@ +{ + "throws": "await is not allowed in the parameters of an arrow function inside an async function (2:7)" +} \ No newline at end of file diff --git a/packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters-of-nested-async-arrow-function/input.js b/packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters-of-nested-async-arrow-function/input.js new file mode 100644 index 000000000000..7571a193f836 --- /dev/null +++ b/packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters-of-nested-async-arrow-function/input.js @@ -0,0 +1,3 @@ +async function fn() { + async (x = await 2) => {}; +} \ No newline at end of file diff --git a/packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters-of-nested-async-arrow-function/options.json b/packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters-of-nested-async-arrow-function/options.json new file mode 100644 index 000000000000..52eda98537e7 --- /dev/null +++ b/packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters-of-nested-async-arrow-function/options.json @@ -0,0 +1,3 @@ +{ + "throws": "await is not allowed in the parameters of an arrow function inside an async function (2:13)" +} \ No newline at end of file diff --git a/packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters-of-nested-function/input.js b/packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters-of-nested-function/input.js new file mode 100644 index 000000000000..f9a4ebddb333 --- /dev/null +++ b/packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters-of-nested-function/input.js @@ -0,0 +1,3 @@ +async function foo() { + function bar(x = await 2) {} +} \ No newline at end of file diff --git a/packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters-of-nested-function/options.json b/packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters-of-nested-function/options.json new file mode 100644 index 000000000000..7d80be8b1e9e --- /dev/null +++ b/packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters-of-nested-function/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Unexpected token, expected \",\" (2:25)" +} \ No newline at end of file diff --git a/packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters/input.js b/packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters/input.js new file mode 100644 index 000000000000..52459e1a27a6 --- /dev/null +++ b/packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters/input.js @@ -0,0 +1 @@ +async function fn(x = await 2) {} \ No newline at end of file diff --git a/packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters/options.json b/packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters/options.json new file mode 100644 index 000000000000..1a6e14706ad1 --- /dev/null +++ b/packages/babylon/test/fixtures/es2017/async-functions/await-inside-parameters/options.json @@ -0,0 +1,3 @@ +{ + "throws": "await is not allowed in async function parameters (1:22)" +} \ No newline at end of file diff --git a/packages/babylon/test/fixtures/es2017/async-functions/await-inside-parenthesized-assign/input.js b/packages/babylon/test/fixtures/es2017/async-functions/await-inside-parenthesized-assign/input.js new file mode 100644 index 000000000000..fd46caa54ce3 --- /dev/null +++ b/packages/babylon/test/fixtures/es2017/async-functions/await-inside-parenthesized-assign/input.js @@ -0,0 +1,3 @@ +async function fn() { + (x = await 2); +} \ No newline at end of file diff --git a/packages/babylon/test/fixtures/es2017/async-functions/await-inside-parenthesized-assign/output.json b/packages/babylon/test/fixtures/es2017/async-functions/await-inside-parenthesized-assign/output.json new file mode 100644 index 000000000000..b9ed763bd7f1 --- /dev/null +++ b/packages/babylon/test/fixtures/es2017/async-functions/await-inside-parenthesized-assign/output.json @@ -0,0 +1,174 @@ +{ + "type": "File", + "start": 0, + "end": 40, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 40, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "sourceType": "script", + "body": [ + { + "type": "FunctionDeclaration", + "start": 0, + "end": 40, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "id": { + "type": "Identifier", + "start": 15, + "end": 17, + "loc": { + "start": { + "line": 1, + "column": 15 + }, + "end": { + "line": 1, + "column": 17 + }, + "identifierName": "fn" + }, + "name": "fn" + }, + "generator": false, + "async": true, + "params": [], + "body": { + "type": "BlockStatement", + "start": 20, + "end": 40, + "loc": { + "start": { + "line": 1, + "column": 20 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 24, + "end": 38, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 2, + "column": 16 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 25, + "end": 36, + "loc": { + "start": { + "line": 2, + "column": 3 + }, + "end": { + "line": 2, + "column": 14 + } + }, + "operator": "=", + "left": { + "type": "Identifier", + "start": 25, + "end": 26, + "loc": { + "start": { + "line": 2, + "column": 3 + }, + "end": { + "line": 2, + "column": 4 + }, + "identifierName": "x" + }, + "name": "x" + }, + "right": { + "type": "AwaitExpression", + "start": 29, + "end": 36, + "loc": { + "start": { + "line": 2, + "column": 7 + }, + "end": { + "line": 2, + "column": 14 + } + }, + "argument": { + "type": "NumericLiteral", + "start": 35, + "end": 36, + "loc": { + "start": { + "line": 2, + "column": 13 + }, + "end": { + "line": 2, + "column": 14 + } + }, + "extra": { + "rawValue": 2, + "raw": "2" + }, + "value": 2 + } + }, + "extra": { + "parenthesized": true, + "parenStart": 24 + } + } + } + ], + "directives": [] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/scripts/tests/flow/flow_tests_whitelist.txt b/scripts/tests/flow/flow_tests_whitelist.txt index 7bb740ee78d6..520eaaebf693 100644 --- a/scripts/tests/flow/flow_tests_whitelist.txt +++ b/scripts/tests/flow/flow_tests_whitelist.txt @@ -11,6 +11,7 @@ JSX_invalid/migrated_0000.js arrow_function_invalid/migrated_0002.js async_await/async_generic_method.js +async_await/migrated_0007.js async_await/migrated_0020.js async_await/migrated_0024.js async_await/migrated_0027.js diff --git a/scripts/tests/test262/test262_whitelist.txt b/scripts/tests/test262/test262_whitelist.txt index e24e628223f1..52ea231a5f85 100644 --- a/scripts/tests/test262/test262_whitelist.txt +++ b/scripts/tests/test262/test262_whitelist.txt @@ -326,10 +326,6 @@ language/expressions/function/dflt-params-duplicates.js(default) language/expressions/generators/dflt-params-duplicates.js(default) language/expressions/object/method-definition/early-errors-object-method-async-lineterminator.js(default) language/expressions/object/method-definition/early-errors-object-method-async-lineterminator.js(strict mode) -language/expressions/object/method-definition/early-errors-object-method-await-in-formals-default.js(default) -language/expressions/object/method-definition/early-errors-object-method-await-in-formals-default.js(strict mode) -language/expressions/object/method-definition/early-errors-object-method-await-in-formals.js(default) -language/expressions/object/method-definition/early-errors-object-method-await-in-formals.js(strict mode) language/expressions/object/method-definition/early-errors-object-method-duplicate-parameters.js(default) language/expressions/object/method-definition/gen-meth-dflt-params-duplicates.js(default) language/expressions/object/method-definition/generator-param-redecl-const.js(default) @@ -395,18 +391,10 @@ language/module-code/parse-err-hoist-lex-fun.js(strict mode) language/module-code/parse-err-hoist-lex-gen.js(default) language/module-code/parse-err-hoist-lex-gen.js(strict mode) language/statements/async-function/dflt-params-duplicates.js(default) -language/statements/async-function/early-errors-declaration-await-in-formals-default.js(default) -language/statements/async-function/early-errors-declaration-await-in-formals-default.js(strict mode) -language/statements/async-function/early-errors-declaration-await-in-formals.js(default) -language/statements/async-function/early-errors-declaration-await-in-formals.js(strict mode) language/statements/async-function/early-errors-declaration-formals-body-duplicate.js(default) language/statements/async-function/early-errors-declaration-formals-body-duplicate.js(strict mode) language/statements/class/async-meth-escaped-async.js(default) language/statements/class/async-meth-escaped-async.js(strict mode) -language/statements/class/definition/early-errors-class-method-await-in-formals-default.js(default) -language/statements/class/definition/early-errors-class-method-await-in-formals-default.js(strict mode) -language/statements/class/definition/early-errors-class-method-await-in-formals.js(default) -language/statements/class/definition/early-errors-class-method-await-in-formals.js(strict mode) language/statements/class/strict-mode/with.js(default) language/statements/class/syntax/early-errors/class-definition-evaluation-block-duplicate-binding.js(default) language/statements/class/syntax/early-errors/class-definition-evaluation-block-duplicate-binding.js(strict mode) @@ -1573,14 +1561,10 @@ language/statements/class/fields-same-line-method-private-field-usage.js(strict language/statements/class/fields-wrapped-in-sc-private-field-usage.js(default) language/statements/class/fields-wrapped-in-sc-private-field-usage.js(strict mode) language/expressions/async-generator/dflt-params-duplicates.js(default) -language/expressions/async-generator/early-errors-expression-await-as-function-binding-identifier.js(default) -language/expressions/async-generator/early-errors-expression-await-as-function-binding-identifier.js(strict mode) language/expressions/async-generator/early-errors-expression-formals-body-duplicate-const.js(default) language/expressions/async-generator/early-errors-expression-formals-body-duplicate-const.js(strict mode) language/expressions/async-generator/early-errors-expression-formals-body-duplicate-let.js(default) language/expressions/async-generator/early-errors-expression-formals-body-duplicate-let.js(strict mode) -language/expressions/async-generator/early-errors-expression-formals-contains-await.js(default) -language/expressions/async-generator/early-errors-expression-formals-contains-await.js(strict mode) language/expressions/async-generator/named-dflt-params-duplicates.js(default) language/statements/async-generator/dflt-params-duplicates.js(default) language/statements/class/async-gen-meth-escaped-async.js(default) @@ -1669,4 +1653,6 @@ language/statements/switch/syntax/redeclaration/generator-declaration-attempt-to language/statements/switch/syntax/redeclaration/let-declaration-attempt-to-redeclare-with-async-generator-declaration.js(default) language/statements/switch/syntax/redeclaration/let-declaration-attempt-to-redeclare-with-async-generator-declaration.js(strict mode) language/statements/switch/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-async-generator-declaration.js(default) -language/statements/switch/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-async-generator-declaration.js(strict mode) \ No newline at end of file +language/statements/switch/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-async-generator-declaration.js(strict mode) +language/expressions/dynamic-import/assignment-expression/await-identifier.js(default) +language/expressions/dynamic-import/assignment-expression/await-identifier.js(strict mode) \ No newline at end of file