Rolling out r214038 and r213697: Crashes when using computed properties with rest...
[WebKit-https.git] / LayoutTests / js / script-tests / parser-syntax-check.js
1 description(
2 "This test checks that the following expressions or statements are valid ECMASCRIPT code or should throw parse error"
3 );
4
5 function testFailed(msg) {
6     description(msg);
7     throw new Error("Bad!");
8 }
9
10 function runTest(_a, expectSyntaxError)
11 {
12     var error;
13
14     if (typeof _a != "string")
15         testFailed("runTest expects string argument: " + _a);
16     try {
17         eval(_a);
18     } catch (e) {
19         error = e;
20     }
21
22     if (expectSyntaxError) {
23         if (error && error instanceof SyntaxError)
24             testPassed(`Invalid: "${_a}". Produced the following syntax error: "${error.toString()}"`);
25         else if (error)
26             testFailed('Invalid: "' + _a + '" should throw SyntaxError but got ' + (error.name || error));
27         else
28             testFailed('Invalid: "' + _a + '" but did not throw');
29     } else {
30         if (!error)
31             testPassed('Valid:   "' + _a + '"');
32         else if (!(error instanceof SyntaxError))
33             testPassed('Valid:   "' + _a + '" with ' + (error.name || error));
34         else
35             testFailed('Valid:   "' + _a + '" should NOT throw but got ' + (error.name || error));
36     }
37 }
38
39 function valid(_a)
40 {
41     // Test both the grammar and the syntax checker
42     runTest(_a, false);
43     runTest("function f() { " + _a + " }", false);
44 }
45
46 function onlyValidGlobally(_a)
47 {
48     runTest(_a, false);
49     runTest("function f() { " + _a + " }", true);
50 }
51
52 function onlyInvalidGlobally(_a)
53 {
54     runTest(_a, true);
55     runTest("function f() { " + _a + " }", false);
56 }
57
58 function invalid(_a)
59 {
60     // Test both the grammar and the syntax checker
61     runTest(_a, true);
62     runTest("function f() { " + _a + " }", true);
63 }
64
65 // known issue:
66 //   some statements requires statement as argument, and
67 //   it seems the End-Of-File terminator is converted to semicolon
68 //      "a:[EOF]" is not parse error, while "{ a: }" is parse error
69 //      "if (a)[EOF]" is not parse error, while "{ if (a) }" is parse error
70 // known issues of bison parser:
71 //   accepts: 'function f() { return 6 + }' (only inside a function declaration)
72 //   some comma expressions: see reparsing-semicolon-insertion.js
73
74 debug  ("Unary operators and member access");
75
76 valid  ("");
77 invalid("(a");
78 invalid("a[5");
79 invalid("a[5 + 6");
80 invalid("a.");
81 invalid("()");
82 invalid("a.'l'");
83 valid  ("a: +~!new a");
84 invalid("new -a");
85 valid  ("new (-1)")
86 valid  ("a: b: c: new f(x++)++")
87 valid  ("(a)++");
88 valid  ("(1--).x");
89 invalid("a-- ++");
90 invalid("(a:) --b");
91 valid  ("++ -- ++ a");
92 valid  ("++ new new a ++");
93 valid  ("delete void 0");
94 invalid("delete the void");
95 invalid("(a++");
96 valid  ("++a--");
97 valid  ("++((a))--");
98 valid  ("(a.x++)++");
99 invalid("1: null");
100 invalid("+-!~");
101 invalid("+-!~((");
102 invalid("a)");
103 invalid("a]");
104 invalid(".l");
105 invalid("1.l");
106 valid  ("1 .l");
107
108 debug ("Octal numbers");
109
110 valid  ("'use strict'; 0");
111 valid  ("0");
112 invalid("'use strict'; 00");
113 valid  ("00");
114 invalid("'use strict'; 08");
115 valid  ("08");
116 invalid("'use strict'; 09");
117 valid  ("09");
118
119 debug  ("Binary and conditional operators");
120
121 valid  ("a + + typeof this");
122 invalid("a + * b");
123 invalid("a ? b");
124 invalid("a ? b :");
125 invalid("%a");
126 invalid("a-");
127 valid  ("a = b ? b = c : d = e");
128 valid  ("s: a[1].l ? b.l['s'] ? c++ : d : true");
129 valid  ("a ? b + 1 ? c + 3 * d.l : d[5][6] : e");
130 valid  ("a in b instanceof delete -c");
131 invalid("a in instanceof b.l");
132 valid  ("- - true % 5");
133 invalid("- false = 3");
134 valid  ("a: b: c: (1 + null) = 3");
135 valid  ("a[2] = b.l += c /= 4 * 7 ^ !6");
136 invalid("a + typeof b += c in d");
137 invalid("typeof a &= typeof b");
138 valid  ("a: ((typeof (a))) >>>= a || b.l && c");
139 valid  ("a: b: c[a /= f[a %= b]].l[c[x] = 7] -= a ? b <<= f : g");
140 valid  ("-void+x['y'].l == x.l != 5 - f[7]");
141
142 debug  ("Function calls (and new with arguments)");
143
144 valid  ("a()()()");
145 valid  ("s: l: a[2](4 == 6, 5 = 6)(f[4], 6)");
146 valid  ("s: eval(a.apply(), b.call(c[5] - f[7]))");
147 invalid("a(");
148 invalid("a(5");
149 invalid("a(5,");
150 valid("a(5,)");
151 invalid("a(5,6");
152 valid  ("a(b[7], c <d> e.l, new a() > b)");
153 invalid("a(b[5)");
154 invalid("a(b.)");
155 valid  ("~new new a(1)(i++)(c[l])");
156 invalid("a(*a)");
157 valid  ("((((a))((b)()).l))()");
158 valid  ("(a)[b + (c) / (d())].l--");
159 valid  ("new (5)");
160 invalid("new a(5");
161 valid  ("new (f + 5)(6, (g)() - 'l'() - true(false))");
162 invalid("a(.length)");
163
164 debug  ("function declaration and expression");
165
166 valid  ("function f() {}");
167 valid  ("function f(a,b) {}");
168 invalid("function () {}");
169 invalid("function f(a b) {}");
170 valid("function f(a,) {}");
171 invalid("function f(a,");
172 invalid("function f(a, 1) {}");
173 valid  ("function g(arguments, eval) {}");
174 valid  ("function f() {} + function g() {}");
175 invalid("(function a{})");
176 invalid("(function this(){})");
177 valid  ("(delete new function f(){} + function(a,b){}(5)(6))");
178 valid  ("6 - function (m) { function g() {} }");
179 invalid("function l() {");
180 invalid("function l++(){}");
181
182 debug  ("Array and object literal, comma operator");
183
184 // Note these are tested elsewhere, no need to repeat those tests here
185 valid  ("[] in [5,6] * [,5,] / [,,5,,] || [a,] && new [,b] % [,,]");
186 invalid("[5,");
187 invalid("[,");
188 invalid("(a,)");
189 valid  ("1 + {get get(){}, set set(a){}, get1:4, set1:get-set, }");
190 invalid("1 + {a");
191 invalid("1 + {a:");
192 invalid("1 + {get l(");
193 invalid(",a");
194 valid  ("(4,(5,a(3,4))),f[4,a-6]");
195 invalid("(,f)");
196 invalid("a,,b");
197 invalid("a ? b, c : d");
198
199 debug  ("simple statements");
200
201 valid  ("{ }");
202 invalid("{ { }");
203 valid  ("{ ; ; ; }");
204 valid  ("a: { ; }");
205 invalid("{ a: }");
206 valid  ("{} f; { 6 + f() }");
207 valid  ("{ a[5],6; {} ++b-new (-5)() } c().l++");
208 valid  ("{ l1: l2: l3: { this } a = 32 ; { i++ ; { { { } } ++i } } }");
209 valid  ("if (a) ;");
210 invalid("{ if (a) }");
211 invalid("if a {}");
212 invalid("if (a");
213 invalid("if (a { }");
214 valid  ("x: s: if (a) ; else b");
215 invalid("else {}");
216 valid  ("if (a) if (b) y; else {} else ;");
217 invalid("if (a) {} else x; else");
218 invalid("if (a) { else }");
219 valid  ("if (a.l + new b()) 4 + 5 - f()");
220 valid  ("if (a) with (x) ; else with (y) ;");
221 invalid("with a.b { }");
222 valid  ("while (a() - new b) ;");
223 invalid("while a {}");
224 valid  ("do ; while(0) i++"); // Is this REALLY valid? (Firefox also accepts this)
225 valid  ("do if (a) x; else y; while(z)");
226 invalid("do g; while 4");
227 invalid("do g; while ((4)");
228 valid  ("{ { do do do ; while(0) while(0) while(0) } }");
229 valid  ("do while (0) if (a) {} else y; while(0)");
230 valid  ("if (a) while (b) if (c) with(d) {} else e; else f");
231 invalid("break ; break your_limits ; continue ; continue living ; debugger");
232 invalid("debugger X");
233 invalid("break 0.2");
234 invalid("continue a++");
235 invalid("continue (my_friend)");
236 valid  ("while (1) break");
237 valid  ("do if (a) with (b) continue; else debugger; while (false)");
238 invalid("do if (a) while (false) else debugger");
239 invalid("while if (a) ;");
240 valid  ("if (a) function f() {} else function g() {}");
241 invalid("if (a()) while(0) function f() {} else function g() {}");
242 invalid("if (a()) function f() { else function g() }");
243 invalid("if (a) if (b) ; else function f {}");
244 invalid("if (a) if (b) ; else function (){}");
245 valid  ("throw a");
246 valid  ("throw a + b in void c");
247 invalid("throw");
248
249 debug  ("var and const statements");
250
251 valid  ("var a, b = null");
252 valid  ("const a = 5, b = 10, c = 20");
253 invalid("var");
254 invalid("var = 7");
255 invalid("var c (6)");
256 valid  ("if (a) var a,b; else { const b = 1, c = 2; }");
257 invalid("if (a) var a,b; else { const b, c }");
258 invalid("var 5 = 6");
259 valid  ("while (0) var a, b, c=6, d, e, f=5*6, g=f*h, h");
260 invalid("var a = if (b) { c }");
261 invalid("var a = var b");
262 invalid("const a = b += c, a, a, a = (b - f())");
263 invalid("var a %= b | 5");
264 invalid("var (a) = 5");
265 invalid("var a = (4, b = 6");
266 invalid("const 'l' = 3");
267 invalid("var var = 3");
268 valid  ("var varr = 3 in 1");
269 valid  ("const  a = void 7 - typeof 8, b = 8");
270 invalid("const a, a, a = void 7 - typeof 8, a = 8");
271 valid  ("const x_x = 6 /= 7 ? e : f");
272 invalid("var a = ?");
273 invalid("const a = *7");
274 invalid("var a = :)");
275 valid  ("var a = a in b in c instanceof d");
276 invalid("var a = b ? c, b");
277 invalid("const a = b : c");
278 valid("const a = 7; eval(''); a++");
279 valid("const a = 7; eval(''); a--");
280 valid("const a = 7; with({}) a++");
281 valid("const a = 7; with({}) a--");
282 valid("const a = 7; eval(''); a+=1");
283 valid("const a = 7; eval(''); a-=1");
284 valid("const a = 7; with({}) a+=1");
285 valid("const a = 7; with({}) a-=1");
286 valid("const a = 7; eval(''); a=1");
287 valid("const a = 7; eval(''); a=1");
288 valid("const a = 7; with({}) a=1");
289 valid("const a = 7; with({}) a=1");
290
291
292 debug  ("for statement");
293
294 valid  ("for ( ; ; ) { break }");
295 valid  ("for ( a ; ; ) { break }");
296 valid  ("for ( ; a ; ) { break }");
297 valid  ("for ( ; ; a ) { break }");
298 valid  ("for ( a ; a ; ) break");
299 valid  ("for ( a ; ; a ) break");
300 valid  ("for ( ; a ; a ) break");
301 invalid("for () { }");
302 invalid("for ( a ) { }");
303 invalid("for ( ; ) ;");
304 invalid("for a ; b ; c { }");
305 invalid("for (a ; { }");
306 invalid("for ( a ; ) ;");
307 invalid("for ( ; a ) break");
308 valid  ("for (var a, b ; ; ) { break } ");
309 valid  ("for (var a = b, b = a ; ; ) break");
310 valid  ("for (var a = b, c, d, b = a ; x in b ; ) { break }");
311 valid  ("for (var a = b, c, d ; ; 1 in a()) break");
312 invalid("for ( ; var a ; ) break");
313 invalid("for (const x; ; ) break");
314 invalid("for (const x = 20, y; ; ) break");
315 valid  ("for (const x = 20; ; ) break");
316 valid  ("for (const x of []) break");
317 valid  ("for (const x in {}) break");
318 invalid("for (const x = 20, x = 30; ; ) { const x = 20; break; }");
319 valid  ("for (const x = 20; ; ) { const x = 20; break; }");
320 valid  ("for (const x of []) { const x = 20; break; }");
321 valid  ("for (const x in {}) { const x = 20; break; }");
322 invalid("for (const let = 10; ; ) { break; }");
323 invalid("for (const let in {}) { break; }");
324 invalid("for (const let of []) { break; }");
325 invalid("for (let let = 10; ; ) { break; }");
326 invalid("for (let let in {}) { break; }");
327 invalid("for (let let of []) { break; }");
328 invalid("for ( %a ; ; ) { }");
329 valid  ("for (a in b) break");
330 valid  ("for (a() in b) break");
331 valid  ("for (a().l[4] in b) break");
332 valid  ("for (new a in b in c in d) break");
333 valid  ("for (new new new a in b) break");
334 invalid("for (delete new a() in b) break");
335 invalid("for (a * a in b) break");
336 valid  ("for ((a * a) in b) break");
337 invalid("for (a++ in b) break");
338 valid  ("for ((a++) in b) break");
339 invalid("for (++a in b) break");
340 valid  ("for ((++a) in b) break");
341 invalid("for (a, b in c) break");
342 invalid("for (a,b in c ;;) break");
343 valid  ("for (a,(b in c) ;;) break");
344 valid  ("for ((a, b) in c) break");
345 invalid("for (a ? b : c in c) break");
346 valid  ("for ((a ? b : c) in c) break");
347 valid  ("for (var a in b in c) break");
348 valid("for (var a = 5 += 6 in b) break");
349 valid("for (var a = foo('should be hit') in b) break");
350 invalid("for (var a += 5 in b) break");
351 invalid("for (var a = in b) break");
352 invalid("for (var a, b in b) break");
353 invalid("for (var a = -6, b in b) break");
354 invalid("for (var a, b = 8 in b) break");
355 valid("for (var a = (b in c) in d) break");
356 invalid("for (var a = (b in c in d) break");
357 invalid("for (var (a) in b) { }");
358 valid  ("for (var a = 7, b = c < d >= d ; f()[6]++ ; --i()[1]++ ) {}");
359 invalid("for (var {a} = 20 in b) { }");
360 invalid("for (var {a} = 20 of b) { }");
361 invalid("for (var {a} = 20 in b) { }");
362 valid("for (var i = 20 in b) { }");
363 invalid("for (var i = 20 of b) { }");
364 invalid("for (var {i} = 20 of b) { }");
365 invalid("for (var [i] = 20 of b) { }");
366 invalid("for (let [i] = 20 of b) { }");
367 invalid("for (const [i] = 20 of b) { }");
368 invalid("for (const i = 20 of b) { }");
369 invalid("for (let i = 20 of b) { }");
370 invalid("for (let i = 20 in b) { }");
371 invalid("for (const i = 20 in b) { }");
372 invalid("for (const {i} = 20 in b) { }");
373 invalid("for (let {i} = 20 in b) { }");
374
375 debug  ("try statement");
376
377 invalid("try { break } catch(e) {}");
378 valid  ("try {} finally { c++ }");
379 valid  ("try { with (x) { } } catch(e) {} finally { if (a) ; }");
380 invalid("try {}");
381 invalid("catch(e) {}");
382 invalid("finally {}");
383 invalid("try a; catch(e) {}");
384 invalid("try {} catch(e) a()");
385 invalid("try {} finally a()");
386 invalid("try {} catch(e)");
387 invalid("try {} finally");
388 invalid("try {} finally {} catch(e) {}");
389 invalid("try {} catch (...) {}");
390 invalid("try {} catch {}");
391 valid  ("if (a) try {} finally {} else b;");
392 valid  ("if (--a()) do with(1) try {} catch(ke) { f() ; g() } while (a in b) else {}");
393 invalid("if (a) try {} else b; catch (e) { }");
394 invalid("try { finally {}");
395
396 debug  ("switch statement");
397
398 valid  ("switch (a) {}");
399 invalid("switch () {}");
400 invalid("case 5:");
401 invalid("default:");
402 invalid("switch (a) b;");
403 invalid("switch (a) case 3: b;");
404 valid  ("switch (f()) { case 5 * f(): default: case '6' - 9: ++i }");
405 invalid("switch (true) { default: case 6: default: }");
406 invalid("switch (l) { f(); }");
407 invalid("switch (l) { case 1: ; a: case 5: }");
408 valid  ("switch (g() - h[5].l) { case 1 + 6: a: b: c: ++f }");
409 invalid("switch (g) { case 1: a: }");
410 invalid("switch (g) { case 1: a: default: }");
411 invalid("switch g { case 1: l() }");
412 invalid("switch (g) { case 1:");
413 valid  ("switch (l) { case a = b ? c : d : }");
414 valid  ("switch (sw) { case a ? b - 7[1] ? [c,,] : d = 6 : { } : }");
415 invalid("switch (l) { case b ? c : }");
416 valid  ("switch (l) { case 1: a: with(g) switch (g) { case 2: default: } default: }");
417 invalid("switch (4 - ) { }");
418 invalid("switch (l) { default case: 5; }");
419
420 invalid("L: L: ;");
421 invalid("L: L1: L: ;");
422 invalid("L: L1: L2: L3: L4: L: ;");
423
424 invalid("for(var a,b 'this shouldn\'t be allowed' false ; ) ;");
425 invalid("for(var a,b '");
426
427 valid("function __proto__(){}")
428 valid("(function __proto__(){})")
429 valid("'use strict'; function __proto__(){}")
430 valid("'use strict'; (function __proto__(){})")
431
432 valid("'use strict'; function f1(a) { function f2(b) { return b; } return f2(a); } f1(5);")
433 valid("'use strict'; function f1(a) { function f2(b) { function f3(c) { return c; } return f3(b); } return f2(a); } f1(5);")
434 valid("'use strict'; function f1(a) { if (a) { function f2(b) { return b; } return f2(a); } else return a; } f1(5);")
435 valid("'use strict'; function f1(a) { function f2(b) { if (b) { function f3(c) { return c; } return f3(b); } else return b; } return f2(a); } f1(5);")
436 valid("'use strict'; function f1(a) {}; function f1(a) {};")
437 invalid("'use strict'; { function f1(a) {}; function f1(a) {}; }")
438 invalid("'use strict'; { let f1; function f1(a) {}; }")
439 invalid("'use strict'; { function f1(a) {}; let f1; }")
440 invalid("'use strict'; let f1; function f1(a) {};")
441 invalid("'use strict'; function f1(a) {}; let f1; ")
442 invalid("let f1; function f1(a) {};")
443 valid("function foo() { let f1; { function f1(a) {}; } }")
444 valid("function foo() { { function f1(a) {}; } let f1; }")
445 valid("function foo() { { function foo() { }; function foo() { } } }")
446 invalid("function foo() { 'use strict'; { function foo() { }; function foo() { } } }")
447 invalid("function foo() { let f1; function f1(a) {}; }")
448 invalid("let f1; function f1(a) {};")
449 invalid("{ function f1(a) {}; let f1; }")
450 invalid("{ function f1(a) {}; const f1 = 25; }")
451 invalid("{ function f1(a) {}; class f1{}; }")
452 invalid("function foo() { { let bar; function bar() { } } }")
453 invalid("function foo() { { function bar() { }; let bar; } }")
454 invalid("function foo() { { const bar; function bar() { } } }")
455 invalid("function foo() { { function bar() { }; const bar; } }")
456 invalid("function foo() { { class bar{}; function bar() { } } }")
457 invalid("function foo() { { function bar() { }; class bar{}; } }")
458 valid("switch('foo') { case 1: function foo() {}; break; case 2: function foo() {}; break; }")
459 invalid("switch('foo') { case 1: let foo; function foo() {}; break; case 2: function foo() {}; break; }")
460 invalid("switch('foo') { case 1: function foo() {}; let foo; break; case 2: function foo() {}; break; }")
461 invalid("switch('foo') { case 1: function foo() {}; const foo = 25; break; case 2: function foo() {}; break; }")
462 invalid("switch('foo') { case 1: function foo() {}; class foo {} ; break; case 2: function foo() {}; break; }")
463 invalid("switch('foo') { case 1: function foo() {}; break; case 2: function foo() {}; break; case 3: let foo; }")
464 valid("function foo() { switch('foo') { case 1: function foo() {}; break; case 2: function foo() {}; break; case 3: { let foo; } } }")
465 invalid("'use strict'; switch('foo') { case 1: function foo() {}; break; case 2: function foo() {}; break; }");
466 invalid("'use strict'; switch('foo') { case 1: function foo() {}; break; case 2: let foo; break; }");
467 invalid("'use strict'; switch('foo') { case 1: let foo; break; case 2: function foo() {}; break; }");
468 valid("'use strict'; switch('foo') { case 1: { let foo; break; } case 2: function foo() {}; break; }");
469 valid("'use strict'; switch('foo') { case 1: { function foo() { }; break; } case 2: function foo() {}; break; }");
470 invalid("'use strict'; if (true) function foo() { }; ");
471 valid("if (true) function foo() { }; ");
472 valid(" let foo; if (true) function foo() { };");
473 valid("function baz() { let foo; if (true) function foo() { }; }");
474 valid("if (true) function foo() { }; let foo;");
475 valid("{ if (true) function foo() { }; } let foo;");
476 invalid("let foo; while (false) function foo() { }; ");
477 invalid("let foo;  { while (false) function foo() { }; } ");
478 invalid("while (false) function foo() { }; let foo;");
479 invalid("let foo; while (false) label: function foo() { }; ");
480 invalid("while (false) label: function foo() { }; let foo;");
481 invalid("'use strict'; while (false) function foo() { }; ");
482 invalid("'use strict'; if (false) function foo() { }; ");
483 invalid("'use strict'; do function foo() { } while (false); ");
484 invalid("while (false) function foo() { }; ");
485 valid("if (false) function foo() { }; ");
486 invalid("do function foo() { } while (false); ");
487 invalid("if (cond) label: function foo() { }");
488 invalid("while (true) { while (true) function bar() { } }");
489 invalid("with ({}) function bar() { }");
490 valid("function bar() { label: function baz() { } }");
491 valid("function bar() { let: function baz() { } }");
492 invalid("function bar() { 'use strict'; let: function baz() { } }");
493 valid("function bar() { yield: function baz() { } }");
494 valid("function bar() { label: label2: function baz() { } }");
495 valid("function bar() { label: label2: label3: function baz() { } }");
496 invalid("function bar() { label: label2: label weird: function baz() { } }");
497 valid("function bar() { label: label2: label3: function baz() { } }");
498 invalid("function bar() { 'use strict'; label: label2: label 3: function baz() { } }");
499 invalid("function bar() { if (cond) label: function foo() { } }");
500 invalid("function bar() { while (cond) label: function foo() { } }");
501 valid("label: function foo() { }");
502 valid("let: function foo() { }");
503 valid("yield: function foo() { }");
504 valid("yield: let: function foo() { }");
505 invalid("'use strict'; yield: let: function foo() { }");
506
507 valid("var str = \"'use strict'; function f1(a) { function f2(b) { return b; } return f2(a); } return f1(arguments[0]);\"; var foo = new Function(str); foo(5);")
508 valid("var str = \"'use strict'; function f1(a) { function f2(b) { function f3(c) { return c; } return f3(b); } return f2(a); } return f1(arguments[0]);\"; var foo = new Function(str); foo(5);")
509 valid("var str = \"'use strict'; function f1(a) { if (a) { function f2(b) { return b; } return f2(a); } else return a; } return f1(arguments[0]);\"; var foo = new Function(str); foo(5);")
510 valid("var str = \"'use strict'; function f1(a) { function f2(b) { if (b) { function f3(c) { return c; } return f3(b); } else return b; } return f2(a); } return f1(arguments[0]);\"; var foo = new Function(str); foo(5);")
511
512 valid("if (0) $foo; ")
513 valid("if (0) _foo; ")
514 valid("if (0) foo$; ")
515 valid("if (0) foo_; ")
516 valid("if (0) obj.$foo; ")
517 valid("if (0) obj._foo; ")
518 valid("if (0) obj.foo$; ")
519 valid("if (0) obj.foo_; ")
520 valid("if (0) obj.foo\\u03bb; ")
521 valid("if (0) new a(b+c).d = 5");
522 valid("if (0) new a(b+c) = 5");
523 valid("([1 || 1].a = 1)");
524 valid("({a: 1 || 1}.a = 1)");
525
526 invalid("var a.b = c");
527 invalid("var a.b;");
528
529 valid("for (of of of){}")
530 valid("for (of; of; of){}")
531 valid("for (var of of of){}")
532 valid("for (var of; of; of){}")
533 invalid("for (var of.of of of){}")
534 invalid("for (var of[of] of of){}")
535 valid("for (of.of of of){}")
536 valid("for (of[of] of of){}")
537 valid("for (var [of] of of){}")
538 valid("for (var {of} of of){}")
539 valid("for (of in of){}")
540 valid("for (var of in of){}")
541 invalid("for (var of.of in of){}")
542 valid("for (of.of in of){}")
543 valid("for (of[of] in of){}")
544 invalid("for (var of[of] in of){}")
545 valid("for (var [of] in of){}")
546 valid("for (var {of} in of){}")
547 valid("for ([of] in of){}")
548 valid("for ({of} in of){}")
549 invalid("for (var of = x of of){}")
550 invalid("for (var {of} = x of of){}")
551 invalid("for (var [of] = x of of){}")
552
553
554 invalid("for (of of of of){}")
555 invalid("for (of of; of; of){}")
556 invalid("for (of of []; of; of){}")
557 invalid("for (of of){}")
558 invalid("for (var of of){}")
559 invalid("for (of of in of){}")
560 invalid("for (of in){}")
561 invalid("for (var of in){}")
562
563 debug("spread operator and destructuring")
564 valid("foo(...bar)")
565 valid("o.foo(...bar)")
566 valid("o[foo](...bar)")
567 valid("new foo(...bar)")
568 valid("new o.foo(...bar)")
569 valid("new o[foo](...bar)")
570 invalid("foo(...)")
571 invalid("o.foo(...)")
572 invalid("o[foo](...)")
573 invalid("foo(bar...)")
574 invalid("o.foo(bar...)")
575 invalid("o[foo](bar...)")
576 valid("foo(a,...bar)")
577 valid("o.foo(a,...bar)")
578 valid("o[foo](a,...bar)")
579 valid("foo(...bar, a)")
580 valid("o.foo(...bar, a)")
581 valid("o[foo](...bar, a)")
582 valid("[...bar]")
583 valid("[a, ...bar]")
584 valid("[...bar, a]")
585 valid("[...bar,,,,]")
586 valid("[,,,,...bar]")
587 valid("({1: x})")
588 valid("({1: x}=1)")
589 valid("({1: x}=null)")
590 valid("({1: x})")
591 valid("({1: x}=1)")
592 valid("({1: x}=null)")
593 valid("({a: b}=null)")
594 valid("'use strict'; ({1: x})")
595 valid("'use strict'; ({1: x}=1)")
596 valid("'use strict'; ({1: x}=null)")
597 valid("'use strict'; ({a: b}=null)")
598 valid("var {1:x}=1")
599 valid("var {x}=1")
600 valid("var {x, y}=1")
601 valid("var [x]=1")
602 valid("var [x, y]=1")
603 valid("[x]=1")
604 valid("var [x]=1")
605 valid("({[x]: 1})")
606 valid("delete ({a}=1)")
607 valid("delete ({a:a}=1)")
608 valid("({a}=1)()")
609 valid("({a:a}=1)()")
610 valid("({a}=1)=1")
611 valid("({a:a}=1)=1")
612 valid("({a}=1=1)")
613 valid("({a:a}=1=1)")
614 invalid("var {x}")
615 invalid("var {x, y}")
616 invalid("var {x} = 20, {x, y}")
617 invalid("var {foo:bar, bar:baz}")
618 invalid("var [x]")
619 invalid("var [x, y]")
620 invalid("var [x] = [], [x, y]")
621 valid("({get x(){}})")
622 valid("({set x(x){}})")
623 invalid("({get x(a){}})")
624 invalid("({get x(a,b){}})")
625 invalid("({set x(){}})")
626 invalid("({set x(a,b){}})")
627 valid("({get [x](){}})")
628 invalid("({get [x (){}})")
629 invalid("({set [x](){}})")
630 valid("({set [x](x){}})")
631 invalid("({set [x (x){}})")
632 valid("({set foo(x) { } })");
633 valid("({set foo(x) { 'use strict'; } })");
634 invalid("({set foo(x = 20) { 'use strict'; } })");
635 invalid("({set foo({x}) { 'use strict'; } })");
636 invalid("({set foo([x]) { 'use strict'; } })");
637 invalid("({set foo(...x) {} })");
638 valid("class Foo { set v(z) { } }");
639 valid("class Foo { set v(z) { 'use strict'; } }");
640 invalid("class Foo { set v(z = 50) { 'use strict'; } }");
641 invalid("class Foo { set v({z}) { 'use strict'; } }");
642 invalid("class Foo { set v([z]) { 'use strict'; } }");
643 invalid("class Foo { set v(...z) { } }");
644 invalid("class foo { set y([x, y, x]) { } }");
645 invalid("class foo { set y([x, y, {x}]) { } }");
646 invalid("class foo { set y({x, x}) { } }");
647 invalid("class foo { set y({x, field: {x}}) { } }");
648 valid("class foo { set y({x, field: {xx}}) { } }");
649 invalid("({[...x]: 1})")
650 invalid("function f({a, a}) {}");
651 invalid("function f({a}, a) {}");
652 invalid("function f([b, b]) {}");
653 invalid("function f([b], b) {}");
654 invalid("function f({a: {b}}, b) {}");
655 valid("function f(a, b = 20) {}");
656 valid("function f(a = 20, b = a) {}");
657 valid("function f({a = 20} = {a: 40}, b = a) {}");
658 valid("function f([a,b,c] = [1,2,3]) {}");
659 invalid("function f(a, a=20) {}");
660 invalid("function f({a} = 20, a=20) {}");
661 invalid("function f([a,b,a] = [1,2,3]) {}");
662 invalid("function f([a,b,c] = [1,2,3], a) {}");
663 invalid("function f([a,b,c] = [1,2,3], {a}) {}");
664 valid("( function(){ return this || eval('this'); }().x = 'y' )");
665 invalid("function(){ return this || eval('this'); }().x = 'y'");
666 invalid("1 % +");
667 invalid("1 % -");
668 invalid("1 % typeof");
669 invalid("1 % void");
670 invalid("1 % !");
671 invalid("1 % ~");
672 invalid("1 % delete");
673 invalid("1 % ++");
674 invalid("1 % --");
675 invalid("1 % \n++");
676 invalid("1 % \n--");
677 invalid('let {w} = (foo-=()), {} = ("a" ^= "b");');
678 invalid('const {w} = (foo-=()), {} = ("a" ^= "b");');
679 invalid('var {w} = (foo-=()), {} = ("a" ^= "b");');
680 invalid('let {w} = ();');
681 invalid('let {w} = 1234abc;');
682 invalid('const {w} = 1234abc;');
683 invalid('var {w} = 1234abc;');
684 invalid("var [...x = 20] = 20;");
685 invalid("var [...[...x = 20]] = 20;");
686 valid("var [...x] = 20;");
687 valid("var [...[...x]] = 20;");
688 valid("var [...[...{x}]] = 20;");
689 valid("var [...[x = 20, ...y]] = 20;");
690 valid("var [...[{x} = 20, ...y]] = 20;");
691 valid("var {x: [y, ...[...[...{z: [...z]}]]]} = 20");
692 valid("var {x: [y, {z: {z: [...z]}}]} = 20");
693 invalid("var [...y, ...z] = 20");
694 invalid("var [...{...y}] = 20");
695
696 debug("Rest parameter");
697 valid("function foo(...a) { }");
698 valid("function foo(a, ...b) { }");
699 valid("function foo(a = 20, ...b) { }");
700 valid("function foo(a, b, c, d, e, f, g, ...h) { }");
701 invalid("function foo(a, ...b, c) { }")
702 invalid("function foo(a, ...b, ) { }")
703 invalid("function foo(a, ...[b], ) { }")
704 invalid("function foo(a, ...{b}, ) { }")
705 invalid("function foo(a, ...a) { }");
706 invalid("function foo(...a, ...b) { }");
707 invalid("function foo(...b, ...b) { }");
708 invalid("function foo(...b  ...b) { }");
709 invalid("function foo(a, a, ...b) { }");
710 invalid("function foo(a, ...{b} = 20) { }");
711 invalid("function foo(a, ...b = 20) { }");
712 valid("function foo(...{b}) { }");
713 valid("function foo(...[b]) { }");
714 invalid("function foo(...123) { }");
715 invalid("function foo(...123abc) { }");
716 valid("function foo(...abc123) { }");
717 valid("function foo(...let) { }");
718 invalid("'use strict'; function foo(...let) { }");
719 invalid("'use strict'; function foo(...[let]) { }");
720 valid("function foo(...yield) { }");
721 invalid("'use strict'; function foo(...yield) { }");
722 invalid("function foo(...if) { }");
723 valid("let x = (...a) => { }");
724 valid("let x = (a, ...b) => { }");
725 valid("let x = (a = 20, ...b) => { }");
726 invalid("let x = (a = 20, ...b, ...c) => { }");
727 valid("let x = (a = 20, ...[...b]) => { }");
728 valid("let x = (a = 20, ...[...[b = 40]]) => { }");
729 valid("let x = (a = 20, ...{b}) => { }");
730 invalid("let x = (a = 20, ...{...b}) => { }");
731 invalid("let x = (a = 20, ...{124}) => { }");
732
733 debug("non-simple parameter list")
734 invalid("function foo(...restParam) { 'use strict'; }");
735 invalid("function foo(...restParam) { 'a'; 'use strict'; }");
736 invalid("function foo({x}) { 'use strict'; }");
737 invalid("function foo({x}) { 'a'; 'use strict'; }");
738 invalid("function foo(a = 20) { 'use strict'; }");
739 invalid("function foo(a = 20) { 'a'; 'use strict'; }");
740 invalid("function foo({a} = 20) { 'use strict'; }");
741 invalid("function foo({a} = 20) { 'a'; 'use strict'; }");
742 invalid("function foo([a]) { 'use strict'; }");
743 invalid("function foo([a]) { 'a'; 'use strict'; }");
744 invalid("function foo(foo, bar, a = 25) { 'use strict'; }");
745 invalid("function foo(foo, bar, a = 25) { 'a'; 'use strict'; }");
746 invalid("function foo(foo, bar, baz, ...rest) { 'use strict'; }");
747 invalid("function foo(foo, bar, baz, ...rest) { 'a'; 'use strict'; }");
748 invalid("function foo(a = function() { }) { 'use strict'; a(); }");
749 invalid("function foo(a = function() { }) { 'a'; 'use strict'; a(); }");
750 invalid("let foo = (...restParam) => { 'use strict'; }");
751 invalid("let foo = (...restParam) => { 'a'; 'use strict'; }");
752 invalid("let foo = ({x}) => { 'use strict'; }");
753 invalid("let foo = ({x}) => { 'a'; 'use strict'; }");
754 invalid("let foo = (a = 20) => { 'use strict'; }");
755 invalid("let foo = (a = 20) => { 'a'; 'use strict'; }");
756 invalid("let foo = ({a} = 20) => { 'use strict'; }");
757 invalid("let foo = ({a} = 20) => { 'a'; 'use strict'; }");
758 invalid("let foo = ([a]) => { 'use strict'; }");
759 invalid("let foo = ([a]) => { 'a'; 'use strict'; }");
760 invalid("let foo = (foo, bar, a = 25) => { 'use strict'; }");
761 invalid("let foo = (foo, bar, a = 25) => { 'a'; 'use strict'; }");
762 invalid("let foo = (foo, bar, baz, ...rest) => { 'use strict'; }");
763 invalid("let foo = (foo, bar, baz, ...rest) => { 'a'; 'use strict'; }");
764 invalid("let foo = (a = function() { }) => { 'use strict'; a(); }");
765 invalid("let foo = (a = function() { }) => { 'a'; 'use strict'; a(); }");
766 valid("function outer() { 'use strict'; function foo(...restParam) {  } }");
767 valid("function outer() { 'use strict'; function foo(a,b,c,...restParam) {  } }");
768 valid("function outer() { 'use strict'; function foo(a = 20,b,c,...restParam) {  } }");
769 valid("function outer() { 'use strict'; function foo(a = 20,{b},c,...restParam) {  } }");
770 valid("function outer() { 'use strict'; function foo(a = 20,{b},[c] = 5,...restParam) {  } }");
771 valid("function outer() { 'use strict'; function foo(a = 20) {  } }");
772 valid("function outer() { 'use strict'; function foo(a,b,c,{d} = 20) {  } }");
773 invalid("function outer() { 'use strict'; function foo(...restParam) { 'use strict';  } }");
774 invalid("function outer() { 'use strict'; function foo(a,b,c,...restParam) {  'use strict'; } }");
775 invalid("function outer() { 'use strict'; function foo(a = 20,b,c,...restParam) {  'use strict'; } }");
776 invalid("function outer() { 'use strict'; function foo(a = 20,{b},c,...restParam) { 'use strict'; } }");
777 invalid("function outer() { 'use strict'; function foo(a = 20,{b},[c] = 5,...restParam) { 'use strict'; } }");
778 invalid("function outer() { 'use strict'; function foo(a = 20) {  'use strict';} }");
779 invalid("function outer() { 'use strict'; function foo(a,b,c,{d} = 20) { 'use strict'; } }");
780
781 debug("Arrow function");
782 valid("var x = (x) => x;");
783 valid("var x = (x, y, z) => x;");
784 valid("var x = ({x}, [y], z) => x;");
785 valid("var x = ({x = 30}, [y], z) => x;");
786 valid("var x = (x = 20) => x;");
787 valid("var x = ([x] = 20, y) => x;");
788 valid("var x = ([x = 20] = 20) => x;");
789 valid("var x = foo => x;");
790 valid("var x = foo => x => x => x => x;");
791 valid("var x = foo => x => (x = 20) => (x = 20) => x;");
792 valid("var x = foo => x => x => x => {x};");
793 valid("var x = ([x = 25]) => x => x => ({x} = {});");
794 invalid("var x = foo => x => x => {x} => x;");
795 invalid("var x = {x} = 20 => x;");
796 invalid("var x = [x] = 20 => x;");
797 invalid("var x = [x = 25] = 20 => x;");
798 invalid("var x = ([x = 25]) =>;");
799 invalid("var x = ([x = 25]) => x =>;");
800 invalid("var x = ([x = 25]) => x => x =>;");
801 invalid("var x = ([x = 25]) => x => x => {;");
802 invalid("var x ==> x;");
803 invalid("var x = x ==> x;");
804 valid("foo((x) => x)");
805 valid("foo((x, y, z) => x)");
806 valid("foo(({x}, [y], z) => x)");
807 valid("foo(({x = 30}, [y], z) => x)");
808 valid("foo((x = 20) => x)");
809 valid("foo(([x] = 20, y) => x)");
810 valid("foo(([x = 20] = 20) => x)");
811 valid("foo(foo => x)");
812 valid("foo(foo => x => x => x => x)");
813 valid("foo(foo => x => (x = 20) => (x = 20) => x)");
814 valid("foo(foo => x => x => x => {x})");
815 valid("foo(([x = 25]) => x => x => ({x} = {}))");
816 invalid("foo(foo => x => x => {x} => x)");
817 invalid("foo({x} = 20 => x)");
818 invalid("foo([x] = 20 => x)");
819 invalid("foo([x = 25] = 20 => x)");
820 invalid("foo(([x = 25]) =>)");
821 invalid("foo(([x = 25]) => x =>)");
822 invalid("foo(([x = 25]) => x => x =>)");
823 invalid("foo(([x = 25]) => x => x => {)");
824 invalid("foo(x ==> x)");
825 invalid("foo(x = x ==> x)");
826 valid("var f = cond ? ()=>20 : ()=>20");
827 valid("var f = cond ? (x)=>{x} : ()=>20");
828 valid("var f = cond ? (x)=>x : ()=>{2}");
829 valid("var f = cond ? (x)=>x : x=>2");
830 valid("var f = cond ? x=>x : x=>2");
831 valid("var f = cond ? x=>x*2 : x=>2");
832 valid("var f = cond ? x=>x.foo : x=>2");
833 valid("var f = cond ? x=>x.foo : x=>x + x + x + x + x + x + x");
834 valid("var f = cond ? x=>{x.foo } : x=>x + x + x + x + x + x + (x =>x) ");
835 valid("var f = (x) => x => (x) => ({y}) => y");
836 invalid("var f = cond ? x=>x.foo; : x=>x + x + x + x + x + x + x");
837 invalid("var f = cond ? x=>x.foo : : x=>x + x + x + x + x + x + x");
838 invalid("var f = cond ? x=>{x.foo :} : x=>x + x + x + x + x + x + x");
839 invalid("var f = cond ? x=>{x.foo } => : x=>x + x + x + x + x + x + x");
840 valid("class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { x(y = () => super.foo) { return y(); } }");
841 valid("class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { x(y = () => {return super.foo}) { return y(); } }");
842 valid("class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { x(y = () => {return () => super.foo}) { return y()(); } }");
843 valid("class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { x(y = (y = () => super.foo) => {return y()}) { return y(); } }");
844 valid("class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { constructor(x = () => super.foo) { super(); this._x_f = x; } x() { return this._x_f(); } }");
845 valid("class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { constructor(x = () => super()) { x(); } x() { return super.foo; } }");
846 invalid("let x = (a,a)=>a;");
847 invalid("let x = ([a],a)=>a;");
848 invalid("let x = ([a, a])=>a;");
849 invalid("let x = ({a, b:{a}})=>a;");
850 invalid("let x = (a,a)=>{ a };");
851 invalid("let x = ([a],a)=>{ };");
852 invalid("let x = ([a, a])=>{ };");
853 invalid("let x = (a, ...a)=>{ };");
854 invalid("let x = (b, c, b)=>{ };");
855 invalid("let x = (a, b, c, d, {a})=>{ };");
856 invalid("let x = (b = (a,a)=>a, b)=>{ };");
857 invalid("((a,a)=>a);");
858 invalid("let x = (a)\n=>a;");
859
860 invalid("({ foo(a,a){} });");
861 invalid("({ foo(b, c, b){} });");
862 invalid("({ *foo(a,a){} });");
863 invalid("({ *foo(b, c, b){} });");
864 invalid("({ async foo(a,a){} });");
865 invalid("({ async foo(b, c, b){} });");
866 valid("({ foo: function(a,a){} });");
867 valid("({ foo: function(b, c, b){} });");
868 valid("({ foo: function*(a,a){} });");
869 valid("({ foo: function*(b, c, b){} });");
870 valid("({ foo: async function(a,a){} });");
871 valid("({ foo: async function(b, c, b){} });");
872 invalid("({ foo({a},a){} });");
873 invalid("({ foo(a,{a}){} });");
874 invalid("({ foo(a,...a){} });");
875 invalid("({ foo({a},...a){} });");
876 invalid("({ foo({...a},...a){} });");
877 invalid("({ *foo({a},a){} });");
878 invalid("({ *foo(a,{a}){} });");
879 invalid("({ *foo(a,...a){} });");
880 invalid("({ *foo({a},...a){} });");
881 invalid("({ *foo({...a},...a){} });");
882 invalid("({ async foo({a},a){} });");
883 invalid("({ async foo(a,{a}){} });");
884 invalid("({ async foo(a,...a){} });");
885 invalid("({ async foo({a},...a){} });");
886 invalid("({ async foo({...a},...a){} });");
887 valid("({ foo(a, ...b){} });");
888 valid("({ foo({a}, ...b){} });");
889 valid("({ foo({a, ...b}){} });");
890 valid("({ foo({b, ...a}, ...c){} });");
891
892 debug("Weird things that used to crash.");
893 invalid(`or ([[{break //(elseifo (a=0;a<2;a++)n=
894         [[{aFYY sga=
895         [[{a=Yth FunctionRY&=Ylet 'a'}V a`)
896
897 try { eval("a.b.c = {};"); } catch(e1) { e=e1; shouldBe("e.line", "1") }
898 foo = 'FAIL';
899 bar = 'PASS';
900 try {
901      eval("foo = 'PASS'; a.b.c = {}; bar  = 'FAIL';");
902 } catch(e) {
903      shouldBe("foo", "'PASS'");
904      shouldBe("bar", "'PASS'");
905 }