1 // Copyright (C) 2016 the V8 project authors. All rights reserved.
2 // This code is governed by the BSD license found in the LICENSE file.
4 // This test requires ENABLE_ES2017_ASYNCFUNCTION_SYNTAX to be enabled at build time.
7 function testSyntax(script) {
11 if (error instanceof SyntaxError)
12 throw new Error("Bad error: " + String(error) + "\n evaluating `" + script + "`");
16 function testSyntaxError(script, message) {
24 throw new Error("Expected syntax error not thrown\n evaluating `" + script + "`");
26 if (typeof message === "string" && String(error) !== message)
27 throw new Error("Bad error: " + String(error) + "\n evaluating `" + script + "`");
30 (function testTopLevelAsyncAwaitSyntaxSloppyMode() {
31 testSyntax(`var asyncFn = async function() { await 1; };`);
32 testSyntax(`var asyncFn = async function withName() { await 1; };`);
33 testSyntax(`var asyncFn = async () => await 'test';`);
34 testSyntax(`var asyncFn = async x => await x + 'test';`);
35 testSyntax(`async function asyncFn() { await 1; }`);
36 testSyntax(`var O = { async method() { await 1; } };`);
37 testSyntax(`var O = { async ['meth' + 'od']() { await 1; } };`);
38 testSyntax(`var O = { async 'method'() { await 1; } };`);
39 testSyntax(`var O = { async 0() { await 1; } };`);
40 testSyntax(`class C { async method() { await 1; } };`);
41 testSyntax(`class C { async ['meth' + 'od']() { await 1; } };`);
42 testSyntax(`class C { async 'method'() { await 1; } };`);
43 testSyntax(`class C { async 0() { await 1; } };`);
44 testSyntax(`var asyncFn = async({ foo = 1 }) => foo;`);
45 testSyntax(`var asyncFn = async({ foo = 1 } = {}) => foo;`);
46 testSyntax(`function* g() { var f = async(yield); }`);
47 testSyntax(`function* g() { var f = async(x = yield); }`);
50 (function testTopLevelAsyncAwaitSyntaxStrictMode() {
51 testSyntax(`"use strict"; var asyncFn = async function() { await 1; };`);
52 testSyntax(`"use strict"; var asyncFn = async function withName() { await 1; };`);
53 testSyntax(`"use strict"; var asyncFn = async () => await 'test';`);
54 testSyntax(`"use strict"; var asyncFn = async x => await x + 'test';`);
55 testSyntax(`"use strict"; async function asyncFn() { await 1; }`);
56 testSyntax(`"use strict"; var O = { async method() { await 1; } };`);
57 testSyntax(`"use strict"; var O = { async ['meth' + 'od']() { await 1; } };`);
58 testSyntax(`"use strict"; var O = { async 'method'() { await 1; } };`);
59 testSyntax(`"use strict"; var O = { async 0() { await 1; } };`);
60 testSyntax(`"use strict"; class C { async method() { await 1; } };`);
61 testSyntax(`"use strict"; class C { async ['meth' + 'od']() { await 1; } };`);
62 testSyntax(`"use strict"; class C { async 'method'() { await 1; } };`);
63 testSyntax(`"use strict"; class C { async 0() { await 1; } };`);
64 testSyntax(`"use strict"; var asyncFn = async({ foo = 1 }) => foo;`);
65 testSyntax(`"use strict"; var asyncFn = async({ foo = 1 } = {}) => foo;`);
66 testSyntax(`"use strict"; function* g() { var f = async(yield); }`);
67 testSyntax(`"use strict"; function* g() { var f = async(x = yield); }`);
70 (function testNestedAsyncAwaitSyntax() {
72 { prefix: "function outerFunction() { ", suffix: " }" },
73 { prefix: "function* outerGenerator() { ", suffix: " }" },
74 { prefix: "var outerFuncExpr = function() { ", suffix: " };" },
75 { prefix: "var outerGenExpr = function*() { ", suffix: " };" },
76 { prefix: "var outerObject = { outerMethod() { ", suffix: " } };" },
77 { prefix: "var outerObject = { *outerGenMethod() { ", suffix: " } };" },
78 { prefix: "var outerClassExpr = class C { outerMethod() { ", suffix: " } };" },
79 { prefix: "var outerClassExpr = class C { *outerGenMethod() { ", suffix: " } };" },
80 { prefix: "var outerClassExpr = class C { static outerStaticMethod() { ", suffix: " } };" },
81 { prefix: "var outerClassExpr = class C { static *outerStaticGenMethod() { ", suffix: " } };" },
82 { prefix: "class outerClass { outerMethod() { ", suffix: " } };" },
83 { prefix: "class outerClass { *outerGenMethod() { ", suffix: " } };" },
84 { prefix: "class outerClass { static outerStaticMethod() { ", suffix: " } };" },
85 { prefix: "class outerClass { static *outerStaticGenMethod() { ", suffix: " } };" },
86 { prefix: "var outerArrow = () => { ", suffix: " };" },
87 { prefix: "async function outerAsyncFunction() { ", suffix: " }" },
88 { prefix: "var outerAsyncFuncExpr = async function() { ", suffix: " };" },
89 { prefix: "var outerAsyncArrowFunc = async () => { ", suffix: " };" },
90 { prefix: "var outerObject = { async outerAsyncMethod() { ", suffix: " } };" },
91 { prefix: "var outerClassExpr = class C { async outerAsyncMethod() { ", suffix: " } };" },
92 { prefix: "var outerClassExpr = class C { static async outerStaticAsyncMethod() { ", suffix: " } };" },
93 { prefix: "class outerClass { async outerAsyncMethod() { ", suffix: " } };" },
94 { prefix: "class outerClass { static async outerStaticAsyncMethod() { ", suffix: " } };" },
98 `var async = 1; return async;`,
99 `let async = 1; return async;`,
100 `const async = 1; return async;`,
101 `function async() {} return async();`,
102 `var async = async => async; return async();`,
103 `function foo() { var await = 1; return await; }`,
104 `function foo(await) { return await; }`,
105 `function* foo() { var await = 1; return await; }`,
106 `function* foo(await) { return await; }`,
107 `var f = () => { var await = 1; return await; }`,
108 `var O = { method() { var await = 1; return await; } };`,
109 `var O = { method(await) { return await; } };`,
110 `var O = { *method() { var await = 1; return await; } };`,
111 `var O = { *method(await) { return await; } };`,
113 `(function await() {})`,
116 for (let context of contextData) {
117 for (let test of testData) {
118 let script = context.prefix + test + context.suffix;
120 testSyntax(`"use strict"; ${script}`);
126 (function testTopLevelAsyncAwaitSyntaxSloppyMode() {
127 testSyntaxError(`var asyncFn = async function await() {}`);
128 testSyntaxError(`var asyncFn = async () => var await = 'test';`);
129 testSyntaxError(`var asyncFn = async () => { var await = 'test'; };`);
130 testSyntaxError(`var asyncFn = async await => await + 'test'`);
131 testSyntaxError(`var asyncFn = async function(await) {}`);
132 testSyntaxError(`var asyncFn = async function withName(await) {}`);
133 testSyntaxError(`var asyncFn = async (await) => 'test';`);
134 testSyntaxError(`async function asyncFunctionDeclaration(await) {}`);
136 // FIXME: MethodDefinitions do not apply StrictFormalParameters restrictions
137 // in sloppy mode (https://bugs.webkit.org/show_bug.cgi?id=161408)
138 //testSyntaxError(`var outerObject = { async method(a, a) {} }`);
139 //testSyntaxError(`var outerObject = { async ['meth' + 'od'](a, a) {} }`);
140 //testSyntaxError(`var outerObject = { async 'method'(a, a) {} }`);
141 //testSyntaxError(`var outerObject = { async 0(a, a) {} }`);
143 testSyntaxError(`var asyncArrowFn = async() => await;`);
145 testSyntaxError(`var asyncFn = async function*() {}`);
146 testSyntaxError(`async function* asyncGenerator() {}`);
147 testSyntaxError(`var O = { *async asyncGeneratorMethod() {} };`);
148 testSyntaxError(`var O = { async *asyncGeneratorMethod() {} };`);
149 testSyntaxError(`var O = { async asyncGeneratorMethod*() {} };`);
151 testSyntaxError(`var asyncFn = async function(x = await 1) { return x; }`);
152 testSyntaxError(`async function f(x = await 1) { return x; }`);
153 testSyntaxError(`var f = async(x = await 1) => x;`);
154 testSyntaxError(`var O = { async method(x = await 1) { return x; } };`);
156 testSyntaxError(`function* outerGenerator() { var asyncArrowFn = async yield => 1; }`);
157 testSyntaxError(`function* outerGenerator() { var asyncArrowFn = async(yield) => 1; }`);
158 testSyntaxError(`function* outerGenerator() { var asyncArrowFn = async(x = yield) => 1; }`);
159 testSyntaxError(`function* outerGenerator() { var asyncArrowFn = async({x = yield}) => 1; }`);
161 testSyntaxError(`class C { async constructor() {} }`);
162 testSyntaxError(`class C {}; class C2 extends C { async constructor() {} }`);
163 testSyntaxError(`class C { static async prototype() {} }`);
164 testSyntaxError(`class C {}; class C2 extends C { static async prototype() {} }`);
166 testSyntaxError(`var f = async() => ((async(x = await 1) => x)();`);
168 // Henrique Ferreiro's bug (tm)
169 testSyntaxError(`(async function foo1() { } foo2 => 1)`);
170 testSyntaxError(`(async function foo3() { } () => 1)`);
171 testSyntaxError(`(async function foo4() { } => 1)`);
172 testSyntaxError(`(async function() { } foo5 => 1)`);
173 testSyntaxError(`(async function() { } () => 1)`);
174 testSyntaxError(`(async function() { } => 1)`);
175 testSyntaxError(`(async.foo6 => 1)`);
176 testSyntaxError(`(async.foo7 foo8 => 1)`);
177 testSyntaxError(`(async.foo9 () => 1)`);
178 testSyntaxError(`(async().foo10 => 1)`);
179 testSyntaxError(`(async().foo11 foo12 => 1)`);
180 testSyntaxError(`(async().foo13 () => 1)`);
181 testSyntaxError(`(async['foo14'] => 1)`);
182 testSyntaxError(`(async['foo15'] foo16 => 1)`);
183 testSyntaxError(`(async['foo17'] () => 1)`);
184 testSyntaxError(`(async()['foo18'] => 1)`);
185 testSyntaxError(`(async()['foo19'] foo20 => 1)`);
186 testSyntaxError(`(async()['foo21'] () => 1`);
187 testSyntaxError("(async`foo22` => 1)");
188 testSyntaxError("(async`foo23` foo24 => 1)");
189 testSyntaxError("(async`foo25` () => 1)");
190 testSyntaxError("(async`foo26`.bar27 => 1)");
191 testSyntaxError("(async`foo28`.bar29 foo30 => 1)");
192 testSyntaxError("(async`foo31`.bar32 () => 1)");
194 // assert that errors are still thrown for calls that may have been async functions
195 testSyntaxError(`function async() {}
196 async({ foo33 = 1 })`);
199 (function testTopLevelAsyncAwaitSyntaxStrictMode() {
200 testSyntaxError(`"use strict"; var asyncFn = async function await() {}`);
201 testSyntaxError(`"use strict"; var asyncFn = async () => var await = 'test';`);
202 testSyntaxError(`"use strict"; var asyncFn = async () => { var await = 'test'; };`);
203 testSyntaxError(`"use strict"; var asyncFn = async await => await + 'test'`);
204 testSyntaxError(`"use strict"; var asyncFn = async function(await) {}`);
205 testSyntaxError(`"use strict"; var asyncFn = async function withName(await) {}`);
206 testSyntaxError(`"use strict"; var asyncFn = async (await) => 'test';`);
207 testSyntaxError(`"use strict"; async function asyncFunctionDeclaration(await) {}`);
209 testSyntaxError(`"use strict"; var outerObject = { async method(a, a) {} }`);
210 testSyntaxError(`"use strict"; var outerObject = { async ['meth' + 'od'](a, a) {} }`);
211 testSyntaxError(`"use strict"; var outerObject = { async 'method'(a, a) {} }`);
212 testSyntaxError(`"use strict"; var outerObject = { async 0(a, a) {} }`);
214 testSyntaxError(`"use strict"; var asyncArrowFn = async() => await;`);
216 testSyntaxError(`"use strict"; var asyncFn = async function*() {}`);
217 testSyntaxError(`"use strict"; async function* asyncGenerator() {}`);
218 testSyntaxError(`"use strict"; var O = { *async asyncGeneratorMethod() {} };`);
219 testSyntaxError(`"use strict"; var O = { async *asyncGeneratorMethod() {} };`);
220 testSyntaxError(`"use strict"; var O = { async asyncGeneratorMethod*() {} };`);
222 testSyntaxError(`"use strict"; var asyncFn = async function(x = await 1) { return x; }`);
223 testSyntaxError(`"use strict"; async function f(x = await 1) { return x; }`);
224 testSyntaxError(`"use strict"; var f = async(x = await 1) => x;`);
225 testSyntaxError(`"use strict"; var O = { async method(x = await 1) { return x; } };`);
227 testSyntaxError(`"use strict"; function* outerGenerator() { var asyncArrowFn = async yield => 1; }`);
228 testSyntaxError(`"use strict"; function* outerGenerator() { var asyncArrowFn = async(yield) => 1; }`);
229 testSyntaxError(`"use strict"; function* outerGenerator() { var asyncArrowFn = async(x = yield) => 1; }`);
230 testSyntaxError(`"use strict"; function* outerGenerator() { var asyncArrowFn = async({x = yield}) => 1; }`);
232 testSyntaxError(`"use strict"; class C { async constructor() {} }`);
233 testSyntaxError(`"use strict"; class C {}; class C2 extends C { async constructor() {} }`);
234 testSyntaxError(`"use strict"; class C { static async prototype() {} }`);
235 testSyntaxError(`"use strict"; class C {}; class C2 extends C { static async prototype() {} }`);
237 testSyntaxError(`"use strict"; var f = async() => ((async(x = await 1) => x)();`);
239 // Henrique Ferreiro's bug (tm)
240 testSyntaxError(`"use strict"; (async function foo1() { } foo2 => 1)`);
241 testSyntaxError(`"use strict"; (async function foo3() { } () => 1)`);
242 testSyntaxError(`"use strict"; (async function foo4() { } => 1)`);
243 testSyntaxError(`"use strict"; (async function() { } foo5 => 1)`);
244 testSyntaxError(`"use strict"; (async function() { } () => 1)`);
245 testSyntaxError(`"use strict"; (async function() { } => 1)`);
246 testSyntaxError(`"use strict"; (async.foo6 => 1)`);
247 testSyntaxError(`"use strict"; (async.foo7 foo8 => 1)`);
248 testSyntaxError(`"use strict"; (async.foo9 () => 1)`);
249 testSyntaxError(`"use strict"; (async().foo10 => 1)`);
250 testSyntaxError(`"use strict"; (async().foo11 foo12 => 1)`);
251 testSyntaxError(`"use strict"; (async().foo13 () => 1)`);
252 testSyntaxError(`"use strict"; (async['foo14'] => 1)`);
253 testSyntaxError(`"use strict"; (async['foo15'] foo16 => 1)`);
254 testSyntaxError(`"use strict"; (async['foo17'] () => 1)`);
255 testSyntaxError(`"use strict"; (async()['foo18'] => 1)`);
256 testSyntaxError(`"use strict"; (async()['foo19'] foo20 => 1)`);
257 testSyntaxError(`"use strict"; (async()['foo21'] () => 1)`);
258 testSyntaxError('"use strict"; (async`foo22` => 1)');
259 testSyntaxError('"use strict"; (async`foo23` foo24 => 1)');
260 testSyntaxError('"use strict"; (async`foo25` () => 1)');
261 testSyntaxError('"use strict"; (async`foo26`.bar27 => 1)');
262 testSyntaxError('"use strict"; (async`foo28`.bar29 foo30 => 1)');
263 testSyntaxError('"use strict"; (async`foo31`.bar32 () => 1)');
265 // assert that errors are still thrown for calls that may have been async functions
266 testSyntaxError(`"use strict"; function async() {}
267 async({ foo33 = 1 })`);
269 testSyntaxError(`"use strict"; var O = { async method(eval) {} }`);
270 testSyntaxError(`"use strict"; var O = { async ['meth' + 'od'](eval) {} }`);
271 testSyntaxError(`"use strict"; var O = { async 'method'(eval) {} }`);
272 testSyntaxError(`"use strict"; var O = { async 0(eval) {} }`);
274 testSyntaxError(`"use strict"; var O = { async method(arguments) {} }`);
275 testSyntaxError(`"use strict"; var O = { async ['meth' + 'od'](arguments) {} }`);
276 testSyntaxError(`"use strict"; var O = { async 'method'(arguments) {} }`);
277 testSyntaxError(`"use strict"; var O = { async 0(arguments) {} }`);
279 testSyntaxError(`"use strict"; var O = { async method(dupe, dupe) {} }`);