From 4a84afdc892dcc3a1732b45e5ac65812daa53fae Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Sun, 14 Jul 2019 22:12:08 -0400 Subject: 1353691 - Report SyntaxError when arrow function has await-identifier in async function context. --- .../AsyncFunctions/await-in-arrow-parameters.js | 94 ++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 js/src/tests/ecma_2017/AsyncFunctions/await-in-arrow-parameters.js (limited to 'js/src/tests') diff --git a/js/src/tests/ecma_2017/AsyncFunctions/await-in-arrow-parameters.js b/js/src/tests/ecma_2017/AsyncFunctions/await-in-arrow-parameters.js new file mode 100644 index 0000000000..ebb4ea9dac --- /dev/null +++ b/js/src/tests/ecma_2017/AsyncFunctions/await-in-arrow-parameters.js @@ -0,0 +1,94 @@ +var ieval = eval; +var AsyncFunction = async function(){}.constructor; + +var functionContext = { + Function: { + constructor: Function, + toSourceBody: code => `function f() { ${code} }`, + toSourceParameter: code => `function f(x = ${code}) { }`, + }, + AsyncFunction: { + constructor: AsyncFunction, + toSourceBody: code => `async function f() { ${code} }`, + toSourceParameter: code => `async function f(x = ${code}) { }`, + }, +}; + +function assertSyntaxError(kind, code) { + var {constructor, toSourceBody, toSourceParameter} = functionContext[kind]; + var body = toSourceBody(code); + var parameter = toSourceParameter(code); + + assertThrowsInstanceOf(() => { constructor(code); }, SyntaxError, constructor.name + ":" + code); + assertThrowsInstanceOf(() => { constructor(`x = ${code}`, ""); }, SyntaxError, constructor.name + ":" + code); + + assertThrowsInstanceOf(() => { eval(body); }, SyntaxError, "eval:" + body); + assertThrowsInstanceOf(() => { ieval(body); }, SyntaxError, "indirect eval:" + body); + + assertThrowsInstanceOf(() => { eval(parameter); }, SyntaxError, "eval:" + parameter); + assertThrowsInstanceOf(() => { ieval(parameter); }, SyntaxError, "indirect eval:" + parameter); +} + +function assertNoSyntaxError(kind, code) { + var {constructor, toSourceBody, toSourceParameter} = functionContext[kind]; + var body = toSourceBody(code); + var parameter = toSourceParameter(code); + + constructor(code); + constructor(`x = ${code}`, ""); + + eval(body); + ieval(body); + + eval(parameter); + ieval(parameter); +} + +function assertSyntaxErrorAsync(code) { + assertNoSyntaxError("Function", code); + assertSyntaxError("AsyncFunction", code); +} + +function assertSyntaxErrorBoth(code) { + assertSyntaxError("Function", code); + assertSyntaxError("AsyncFunction", code); +} + + +// Bug 1353691 +// |await| expression is invalid in arrow functions in async-context. +// |await/r/g| first parses as |AwaitExpression RegularExpressionLiteral|, when reparsing the +// arrow function, it is parsed as |IdentRef DIV IdentRef DIV IdentRef|. We need to ensure in this +// case, that we still treat |await| as a keyword and hence throw a SyntaxError. +assertSyntaxErrorAsync("(a = await/r/g) => {}"); +assertSyntaxErrorBoth("async(a = await/r/g) => {}"); + +// Also applies when nesting arrow functions. +assertSyntaxErrorAsync("(a = (b = await/r/g) => {}) => {}"); +assertSyntaxErrorBoth("async(a = (b = await/r/g) => {}) => {}"); +assertSyntaxErrorBoth("(a = async(b = await/r/g) => {}) => {}"); +assertSyntaxErrorBoth("async(a = async(b = await/r/g) => {}) => {}"); + + +// Bug 1355860 +// |await| cannot be used as rest-binding parameter in arrow functions in async-context. +assertSyntaxErrorAsync("(...await) => {}"); +assertSyntaxErrorBoth("async(...await) => {}"); + +assertSyntaxErrorAsync("(a, ...await) => {}"); +assertSyntaxErrorBoth("async(a, ...await) => {}"); + +// Also test nested arrow functions. +assertSyntaxErrorAsync("(a = (...await) => {}) => {}"); +assertSyntaxErrorBoth("(a = async(...await) => {}) => {}"); +assertSyntaxErrorBoth("async(a = (...await) => {}) => {}"); +assertSyntaxErrorBoth("async(a = async(...await) => {}) => {}"); + +assertSyntaxErrorAsync("(a = (b, ...await) => {}) => {}"); +assertSyntaxErrorBoth("(a = async(b, ...await) => {}) => {}"); +assertSyntaxErrorBoth("async(a = (b, ...await) => {}) => {}"); +assertSyntaxErrorBoth("async(a = async(b, ...await) => {}) => {}"); + + +if (typeof reportCompare === "function") + reportCompare(true, true); -- cgit v1.2.3