blob: e84abd112f9a79557d3aa1c254f143a0c9179d0f [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// Copyright 2015 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4//
5// Flags: --harmony-destructuring-bind
6// Flags: --harmony-default-parameters
7
8(function TestObjectLiteralPattern() {
9 var { x : x, y : y, get, set } = { x : 1, y : 2, get: 3, set: 4 };
10 assertEquals(1, x);
11 assertEquals(2, y);
12 assertEquals(3, get);
13 assertEquals(4, set);
14
15 var {z} = { z : 3 };
16 assertEquals(3, z);
17
18
19 var sum = 0;
20 for (var {z} = { z : 3 }; z != 0; z--) {
21 sum += z;
22 }
23 assertEquals(6, sum);
24
25
26 var log = [];
27 var o = {
28 get x() {
29 log.push("x");
30 return 0;
31 },
32 get y() {
33 log.push("y");
34 return {
35 get z() { log.push("z"); return 1; }
36 }
37 }
38 };
39 var { x : x0, y : { z : z1 }, x : x1 } = o;
40 assertSame(0, x0);
41 assertSame(1, z1);
42 assertSame(0, x1);
43 assertArrayEquals(["x", "y", "z", "x"], log);
44}());
45
46
47(function TestObjectLiteralPatternInitializers() {
48 var { x : x, y : y = 2 } = { x : 1 };
49 assertEquals(1, x);
50 assertEquals(2, y);
51
52 var {z = 3} = {};
53 assertEquals(3, z);
54
55 var sum = 0;
56 for (var {z = 3} = {}; z != 0; z--) {
57 sum += z;
58 }
59 assertEquals(6, sum);
60
61 var log = [];
62 var o = {
63 get x() {
64 log.push("x");
65 return undefined;
66 },
67 get y() {
68 log.push("y");
69 return {
70 get z() { log.push("z"); return undefined; }
71 }
72 }
73 };
74 var { x : x0 = 0, y : { z : z1 = 1}, x : x1 = 0} = o;
75 assertSame(0, x0);
76 assertSame(1, z1);
77 assertSame(0, x1);
78 assertArrayEquals(["x", "y", "z", "x"], log);
79}());
80
81
82(function TestObjectLiteralPatternLexicalInitializers() {
83 'use strict';
84 let { x : x, y : y = 2 } = { x : 1 };
85 assertEquals(1, x);
86 assertEquals(2, y);
87
88 let {z = 3} = {};
89 assertEquals(3, z);
90
91 let log = [];
92 let o = {
93 get x() {
94 log.push("x");
95 return undefined;
96 },
97 get y() {
98 log.push("y");
99 return {
100 get z() { log.push("z"); return undefined; }
101 }
102 }
103 };
104
105 let { x : x0 = 0, y : { z : z1 = 1 }, x : x1 = 5} = o;
106 assertSame(0, x0);
107 assertSame(1, z1);
108 assertSame(5, x1);
109 assertArrayEquals(["x", "y", "z", "x"], log);
110
111 let sum = 0;
112 for (let {x = 0, z = 3} = {}; z != 0; z--) {
113 assertEquals(0, x);
114 sum += z;
115 }
116 assertEquals(6, sum);
117}());
118
119
120(function TestObjectLiteralPatternLexical() {
121 'use strict';
122 let { x : x, y : y } = { x : 1, y : 2 };
123 assertEquals(1, x);
124 assertEquals(2, y);
125
126 let {z} = { z : 3 };
127 assertEquals(3, z);
128
129 let log = [];
130 let o = {
131 get x() {
132 log.push("x");
133 return 0;
134 },
135 get y() {
136 log.push("y");
137 return {
138 get z() { log.push("z"); return 1; }
139 }
140 }
141 };
142 let { x : x0, y : { z : z1 }, x : x1 } = o;
143 assertSame(0, x0);
144 assertSame(1, z1);
145 assertSame(0, x1);
146 assertArrayEquals(["x", "y", "z", "x"], log);
147
148 let sum = 0;
149 for (let {x, z} = { x : 0, z : 3 }; z != 0; z--) {
150 assertEquals(0, x);
151 sum += z;
152 }
153 assertEquals(6, sum);
154}());
155
156
157(function TestObjectLiteralPatternLexicalConst() {
158 'use strict';
159 const { x : x, y : y } = { x : 1, y : 2 };
160 assertEquals(1, x);
161 assertEquals(2, y);
162
163 assertThrows(function() { x++; }, TypeError);
164 assertThrows(function() { y++; }, TypeError);
165
166 const {z} = { z : 3 };
167 assertEquals(3, z);
168
169 for (const {x, z} = { x : 0, z : 3 }; z != 3 || x != 0;) {
170 assertTrue(false);
171 }
172}());
173
174
175(function TestFailingMatchesSloppy() {
176 var {x, y} = {};
177 assertSame(undefined, x);
178 assertSame(undefined, y);
179
180 var { x : { z1 }, y2} = { x : {}, y2 : 42 }
181 assertSame(undefined, z1);
182 assertSame(42, y2);
183}());
184
185
186(function TestFailingMatchesStrict() {
187 'use strict';
188 var {x, y} = {};
189 assertSame(undefined, x);
190 assertSame(undefined, y);
191
192 var { x : { z1 }, y2} = { x : {}, y2 : 42 }
193 assertSame(undefined, z1);
194 assertSame(42, y2);
195
196 {
197 let {x1,y1} = {};
198 assertSame(undefined, x1);
199 assertSame(undefined, y1);
200
201 let { x : { z1 }, y2} = { x : {}, y2 : 42 }
202 assertSame(undefined, z1);
203 assertSame(42, y2);
204 }
205}());
206
207
208(function TestTDZInIntializers() {
209 'use strict';
210 {
211 let {x, y = x} = {x : 42, y : 27};
212 assertSame(42, x);
213 assertSame(27, y);
214 }
215
216 {
217 let {x, y = x + 1} = { x : 42 };
218 assertSame(42, x);
219 assertSame(43, y);
220 }
221 assertThrows(function() {
222 let {x = y, y} = { y : 42 };
223 }, ReferenceError);
224
225 {
226 let {x, y = eval("x+1")} = {x:42};
227 assertEquals(42, x);
228 assertEquals(43, y);
229 }
230
231 {
232 let {x, y = () => eval("x+1")} = {x:42};
233 assertEquals(42, x);
234 assertEquals(43, y());
235 }
236
237 {
238 let {x = function() {return y+1;}, y} = {y:42};
239 assertEquals(43, x());
240 assertEquals(42, y);
241 }
242 {
243 let {x = function() {return eval("y+1");}, y} = {y:42};
244 assertEquals(43, x());
245 assertEquals(42, y);
246 }
247}());
248
249
250(function TestSideEffectsInInitializers() {
251 var callCount = 0;
252 function f(v) { callCount++; return v; }
253
254 callCount = 0;
255 var { x = f(42) } = { x : 27 };
256 assertSame(27, x);
257 assertEquals(0, callCount);
258
259 callCount = 0;
260 var { x = f(42) } = {};
261 assertSame(42, x);
262 assertEquals(1, callCount);
263}());
264
265
Ben Murdoch097c5b22016-05-18 11:27:45 +0100266(function TestAssignmentExprInInitializers() {
267 {
268 let x, y;
269 {
270 let { x = y = 1 } = {};
271 assertSame(x, 1);
272 assertSame(y, 1);
273 }
274 assertSame(undefined, x);
275 assertSame(1, y);
276 }
277
278 {
279 let x, y;
280 {
281 let { x: x = y = 1 } = {};
282 assertSame(1, x);
283 assertSame(1, y);
284 }
285 assertSame(undefined, x);
286 assertSame(1, y);
287 }
288
289 {
290 let x, y;
291 {
292 let [ x = y = 1 ] = [];
293 assertSame(1, x);
294 assertSame(1, y);
295 }
296 assertSame(undefined, x);
297 assertSame(1, y);
298 }
299
300 {
301 let x, y;
302 (function({ x = y = 1 }) {}({}));
303 assertSame(undefined, x);
304 assertSame(1, y);
305 }
306
307 {
308 let x, y;
309 (function({ x: x = y = 1 }) {}({}));
310 assertSame(undefined, x);
311 assertSame(1, y);
312 }
313
314 {
315 let x, y;
316 (function([ x = y = 1 ]) {}([]));
317 assertSame(undefined, x);
318 assertSame(1, y);
319 }
320}());
321
322
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000323(function TestMultipleAccesses() {
324 assertThrows(
325 "'use strict';"+
326 "const {x,x} = {x:1};",
327 SyntaxError);
328
329 assertThrows(
330 "'use strict';"+
331 "let {x,x} = {x:1};",
332 SyntaxError);
333
334 (function() {
335 var {x,x = 2} = {x : 1};
336 assertSame(1, x);
337 }());
338
339 assertThrows(function () {
340 'use strict';
341 let {x = (function() { x = 2; }())} = {};
342 }, ReferenceError);
343
344 (function() {
345 'use strict';
346 let {x = (function() { x = 2; }())} = {x:1};
347 assertSame(1, x);
348 }());
349}());
350
351
352(function TestComputedNames() {
353 var x = 1;
354 var {[x]:y} = {1:2};
355 assertSame(2, y);
356
357 (function(){
358 'use strict';
359 let {[x]:y} = {1:2};
360 assertSame(2, y);
361 }());
362
363 var callCount = 0;
364 function foo(v) { callCount++; return v; }
365
366 (function() {
367 callCount = 0;
368 var {[foo("abc")]:x} = {abc:42};
369 assertSame(42, x);
370 assertEquals(1, callCount);
371 }());
372
373 (function() {
374 'use strict';
375 callCount = 0;
376 let {[foo("abc")]:x} = {abc:42};
377 assertSame(42, x);
378 assertEquals(1, callCount);
379 }());
380
381 (function() {
382 callCount = 0;
383 var {[foo("abc")]:x} = {};
384 assertSame(undefined, x);
385 assertEquals(1, callCount);
386 }());
387
388 (function() {
389 'use strict';
390 callCount = 0;
391 let {[foo("abc")]:x} = {};
392 assertSame(undefined, x);
393 assertEquals(1, callCount);
394 }());
395
396 for (val of [null, undefined]) {
397 callCount = 0;
398 assertThrows(function() {
399 var {[foo()]:x} = val;
400 }, TypeError);
401 assertEquals(0, callCount);
402
403 callCount = 0;
404 assertThrows(function() {
405 'use strict';
406 let {[foo()]:x} = val;
407 }, TypeError);
408 assertEquals(0, callCount);
409 }
410
411 var log = [];
412 var o = {
413 get x() { log.push("get x"); return 1; },
414 get y() { log.push("get y"); return 2; }
415 }
416 function f(v) { log.push("f " + v); return v; }
417
418 (function() {
419 log = [];
420 var { [f('x')]:x, [f('y')]:y } = o;
421 assertSame(1, x);
422 assertSame(2, y);
423 assertArrayEquals(["f x", "get x", "f y", "get y"], log);
424 }());
425
426 (function() {
427 'use strict';
428 log = [];
429 let { [f('x')]:x, [f('y')]:y } = o;
430 assertSame(1, x);
431 assertSame(2, y);
432 assertArrayEquals(["f x", "get x", "f y", "get y"], log);
433 }());
434
435 (function() {
436 'use strict';
437 log = [];
438 const { [f('x')]:x, [f('y')]:y } = o;
439 assertSame(1, x);
440 assertSame(2, y);
441 assertArrayEquals(["f x", "get x", "f y", "get y"], log);
442 }());
443}());
444
445
446(function TestExceptions() {
447 for (var val of [null, undefined]) {
448 assertThrows(function() { var {} = val; }, TypeError);
449 assertThrows(function() { var {x} = val; }, TypeError);
450 assertThrows(function() { var { x : {} } = { x : val }; }, TypeError);
451 assertThrows(function() { 'use strict'; let {} = val; }, TypeError);
452 assertThrows(function() { 'use strict'; let {x} = val; }, TypeError);
453 assertThrows(function() { 'use strict'; let { x : {} } = { x : val }; },
454 TypeError);
455 }
456}());
457
458
459(function TestArrayLiteral() {
460 var [a, b, c] = [1, 2, 3];
461 assertSame(1, a);
462 assertSame(2, b);
463 assertSame(3, c);
464}());
465
466(function TestIterators() {
467 var log = [];
468 function* f() {
469 log.push("1");
470 yield 1;
471 log.push("2");
472 yield 2;
473 log.push("3");
474 yield 3;
475 log.push("done");
476 };
477
478 (function() {
479 log = [];
480 var [a, b, c] = f();
481 assertSame(1, a);
482 assertSame(2, b);
483 assertSame(3, c);
484 assertArrayEquals(["1", "2", "3"], log);
485 }());
486
487 (function() {
488 log = [];
489 var [a, b, c, d] = f();
490 assertSame(1, a);
491 assertSame(2, b);
492 assertSame(3, c);
493 assertSame(undefined, d);
494 assertArrayEquals(["1", "2", "3", "done"], log);
495 }());
496
497 (function() {
498 log = [];
499 var [a, , c] = f();
500 assertSame(1, a);
501 assertSame(3, c);
502 assertArrayEquals(["1", "2", "3"], log);
503 }());
504
505 (function() {
506 log = [];
507 var [a, , c, d] = f();
508 assertSame(1, a);
509 assertSame(3, c);
510 assertSame(undefined, d);
511 assertArrayEquals(["1", "2", "3", "done"], log);
512 }());
513
514 (function() {
515 log = [];
516 // last comma is not an elision.
517 var [a, b,] = f();
518 assertSame(1, a);
519 assertSame(2, b);
520 assertArrayEquals(["1", "2"], log);
521 }());
522
523 (function() {
524 log = [];
525 // last comma is not an elision, but the comma before the last is.
526 var [a, b, ,] = f();
527 assertSame(1, a);
528 assertSame(2, b);
529 assertArrayEquals(["1", "2", "3"], log);
530 }());
531
532 (function() {
533 log = [];
534 var [a, ...rest] = f();
535 assertSame(1, a);
536 assertArrayEquals([2,3], rest);
537 assertArrayEquals(["1", "2", "3", "done"], log);
538 }());
539
540 (function() {
541 log = [];
542 var [a, b, c, ...rest] = f();
543 assertSame(1, a);
544 assertSame(2, b);
545 assertSame(3, c);
546 assertArrayEquals([], rest);
547 assertArrayEquals(["1", "2", "3", "done"], log);
548 }());
549
550 (function() {
551 log = [];
552 var [a, b, c, d, ...rest] = f();
553 assertSame(1, a);
554 assertSame(2, b);
555 assertSame(3, c);
556 assertSame(undefined, d);
557 assertArrayEquals([], rest);
558 assertArrayEquals(["1", "2", "3", "done"], log);
559 }());
560}());
561
562
563(function TestIteratorsLexical() {
564 'use strict';
565 var log = [];
566 function* f() {
567 log.push("1");
568 yield 1;
569 log.push("2");
570 yield 2;
571 log.push("3");
572 yield 3;
573 log.push("done");
574 };
575
576 (function() {
577 log = [];
578 let [a, b, c] = f();
579 assertSame(1, a);
580 assertSame(2, b);
581 assertSame(3, c);
582 assertArrayEquals(["1", "2", "3"], log);
583 }());
584
585 (function() {
586 log = [];
587 let [a, b, c, d] = f();
588 assertSame(1, a);
589 assertSame(2, b);
590 assertSame(3, c);
591 assertSame(undefined, d);
592 assertArrayEquals(["1", "2", "3", "done"], log);
593 }());
594
595 (function() {
596 log = [];
597 let [a, , c] = f();
598 assertSame(1, a);
599 assertSame(3, c);
600 assertArrayEquals(["1", "2", "3"], log);
601 }());
602
603 (function() {
604 log = [];
605 let [a, , c, d] = f();
606 assertSame(1, a);
607 assertSame(3, c);
608 assertSame(undefined, d);
609 assertArrayEquals(["1", "2", "3", "done"], log);
610 }());
611
612 (function() {
613 log = [];
614 // last comma is not an elision.
615 let [a, b,] = f();
616 assertSame(1, a);
617 assertSame(2, b);
618 assertArrayEquals(["1", "2"], log);
619 }());
620
621 (function() {
622 log = [];
623 // last comma is not an elision, but the comma before the last is.
624 let [a, b, ,] = f();
625 assertSame(1, a);
626 assertSame(2, b);
627 assertArrayEquals(["1", "2", "3"], log);
628 }());
629
630 (function() {
631 log = [];
632 let [a, ...rest] = f();
633 assertSame(1, a);
634 assertArrayEquals([2,3], rest);
635 assertArrayEquals(["1", "2", "3", "done"], log);
636 }());
637
638 (function() {
639 log = [];
640 let [a, b, c, ...rest] = f();
641 assertSame(1, a);
642 assertSame(2, b);
643 assertSame(3, c);
644 assertArrayEquals([], rest);
645 assertArrayEquals(["1", "2", "3", "done"], log);
646 }());
647
648 (function() {
649 log = [];
650 let [a, b, c, d, ...rest] = f();
651 assertSame(1, a);
652 assertSame(2, b);
653 assertSame(3, c);
654 assertSame(undefined, d);
655 assertArrayEquals([], rest);
656 assertArrayEquals(["1", "2", "3", "done"], log);
657 }());
658}());
659
660(function TestIteratorsRecursive() {
661 var log = [];
662 function* f() {
663 log.push("1");
664 yield {x : 1, y : 2};
665 log.push("2");
666 yield [42, 27, 30];
667 log.push("3");
668 yield "abc";
669 log.push("done");
670 };
671
672 (function() {
673 var [{x, y}, [a, b]] = f();
674 assertSame(1, x);
675 assertSame(2, y);
676 assertSame(42, a);
677 assertSame(27, b);
678 assertArrayEquals(["1", "2"], log);
679 }());
680
681 (function() {
682 'use strict';
683 log = [];
684 let [{x, y}, [a, b]] = f();
685 assertSame(1, x);
686 assertSame(2, y);
687 assertSame(42, a);
688 assertSame(27, b);
689 assertArrayEquals(["1", "2"], log);
690 }());
691}());
692
693
694(function TestForEachLexical() {
695 'use strict';
696 let a = [{x:1, y:-1}, {x:2,y:-2}, {x:3,y:-3}];
697 let sumX = 0;
698 let sumY = 0;
699 let fs = [];
700 for (let {x,y} of a) {
701 sumX += x;
702 sumY += y;
703 fs.push({fx : function() { return x; }, fy : function() { return y }});
704 }
705 assertSame(6, sumX);
706 assertSame(-6, sumY);
707 assertSame(3, fs.length);
708 for (let i = 0; i < fs.length; i++) {
709 let {fx,fy} = fs[i];
710 assertSame(i+1, fx());
711 assertSame(-(i+1), fy());
712 }
713
714 var o = { __proto__:null, 'a1':1, 'b2':2 };
715 let sx = '';
716 let sy = '';
717 for (let [x,y] in o) {
718 sx += x;
719 sy += y;
720 }
721 assertEquals('ab', sx);
722 assertEquals('12', sy);
723}());
724
725
726(function TestForEachVars() {
727 var a = [{x:1, y:-1}, {x:2,y:-2}, {x:3,y:-3}];
728 var sumX = 0;
729 var sumY = 0;
730 var fs = [];
731 for (var {x,y} of a) {
732 sumX += x;
733 sumY += y;
734 fs.push({fx : function() { return x; }, fy : function() { return y }});
735 }
736 assertSame(6, sumX);
737 assertSame(-6, sumY);
738 assertSame(3, fs.length);
739 for (var i = 0; i < fs.length; i++) {
740 var {fx,fy} = fs[i];
741 assertSame(3, fx());
742 assertSame(-3, fy());
743 }
744
745 var o = { __proto__:null, 'a1':1, 'b2':2 };
746 var sx = '';
747 var sy = '';
748 for (var [x,y] in o) {
749 sx += x;
750 sy += y;
751 }
752 assertEquals('ab', sx);
753 assertEquals('12', sy);
754}());
755
756
757(function TestParameters() {
758 function f({a, b}) { return a - b; }
759 assertEquals(1, f({a : 6, b : 5}));
760
761 function f1(c, {a, b}) { return c + a - b; }
762 assertEquals(8, f1(7, {a : 6, b : 5}));
763
764 function f2({c, d}, {a, b}) { return c - d + a - b; }
765 assertEquals(7, f2({c : 7, d : 1}, {a : 6, b : 5}));
766
767 function f3([{a, b}]) { return a - b; }
768 assertEquals(1, f3([{a : 6, b : 5}]));
769
770 var g = ({a, b}) => { return a - b; };
771 assertEquals(1, g({a : 6, b : 5}));
772
773 var g1 = (c, {a, b}) => { return c + a - b; };
774 assertEquals(8, g1(7, {a : 6, b : 5}));
775
776 var g2 = ({c, d}, {a, b}) => { return c - d + a - b; };
777 assertEquals(7, g2({c : 7, d : 1}, {a : 6, b : 5}));
778
779 var g3 = ([{a, b}]) => { return a - b; };
780 assertEquals(1, g3([{a : 6, b : 5}]));
781}());
782
783
784(function TestExpressionsInParameters() {
785 function f0(x = eval(0)) { return x }
786 assertEquals(0, f0());
787 function f1({a = eval(1)}) { return a }
788 assertEquals(1, f1({}));
789 function f2([x = eval(2)]) { return x }
790 assertEquals(2, f2([]));
791 function f3({[eval(7)]: x}) { return x }
792 assertEquals(3, f3({7: 3}));
793})();
794
795
796(function TestParameterScoping() {
797 var x = 1;
798
799 function f1({a = x}) { var x = 2; return a; }
800 assertEquals(1, f1({}));
801 function f2({a = x}) { function x() {}; return a; }
802 assertEquals(1, f2({}));
803 (function() {
804 'use strict';
805 function f3({a = x}) { let x = 2; return a; }
806 assertEquals(1, f3({}));
807 function f4({a = x}) { const x = 2; return a; }
808 assertEquals(1, f4({}));
809 function f5({a = x}) { function x() {}; return a; }
810 assertEquals(1, f5({}));
811 })();
812 function f6({a = eval("x")}) { var x; return a; }
813 assertEquals(1, f6({}));
814 (function() {
815 'use strict';
816 function f61({a = eval("x")}) { var x; return a; }
817 assertEquals(1, f61({}));
818 })();
819 function f62({a = eval("'use strict'; x")}) { var x; return a; }
820 assertEquals(1, f62({}));
821 function f7({a = function() { return x }}) { var x; return a(); }
822 assertEquals(1, f7({}));
823 function f8({a = () => x}) { var x; return a(); }
824 assertEquals(1, f8({}));
825 function f9({a = () => eval("x")}) { var x; return a(); }
826 assertEquals(1, f9({}));
827 (function TestInitializedWithEvalArrowStrict() {
828 'use strict';
829 function f91({a = () => eval("x")}) { var x; return a(); }
830 assertEquals(1, f91({}));
831 })();
832 function f92({a = () => { 'use strict'; return eval("x") }}) { var x; return a(); }
833 assertEquals(1, f92({}));
834 function f93({a = () => eval("'use strict'; x")}) { var x; return a(); }
835 assertEquals(1, f93({}));
836
837 var g1 = ({a = x}) => { var x = 2; return a; };
838 assertEquals(1, g1({}));
839 var g2 = ({a = x}) => { function x() {}; return a; };
840 assertEquals(1, g2({}));
841 (function() {
842 'use strict';
843 var g3 = ({a = x}) => { let x = 2; return a; };
844 assertEquals(1, g3({}));
845 var g4 = ({a = x}) => { const x = 2; return a; };
846 assertEquals(1, g4({}));
847 var g5 = ({a = x}) => { function x() {}; return a; };
848 assertEquals(1, g5({}));
849 })();
850 var g6 = ({a = eval("x")}) => { var x; return a; };
851 assertEquals(1, g6({}));
852 (function() {
853 'use strict';
854 var g61 = ({a = eval("x")}) => { var x; return a; };
855 assertEquals(1, g61({}));
856 })();
857 var g62 = ({a = eval("'use strict'; x")}) => { var x; return a; };
858 assertEquals(1, g62({}));
859 var g7 = ({a = function() { return x }}) => { var x; return a(); };
860 assertEquals(1, g7({}));
861 var g8 = ({a = () => x}) => { var x; return a(); };
862 assertEquals(1, g8({}));
863 var g9 = ({a = () => eval("x")}) => { var x; return a(); };
864 assertEquals(1, g9({}));
865 (function() {
866 'use strict';
867 var g91 = ({a = () => eval("x")}) => { var x; return a(); };
868 assertEquals(1, g91({}));
869 var g92 = ({a = () => { return eval("x") }}) => { var x; return a(); };
870 assertEquals(1, g92({}));
871 })();
872 var g93 = ({a = () => eval("'use strict'; x")}) => { var x; return a(); };
873 assertEquals(1, g93({}));
874
875 var f11 = function f({x = f}) { var f; return x; }
876 assertSame(f11, f11({}));
877 var f12 = function f({x = f}) { function f() {}; return x; }
878 assertSame(f12, f12({}));
879 (function() {
880 'use strict';
881 var f13 = function f({x = f}) { let f; return x; }
882 assertSame(f13, f13({}));
883 var f14 = function f({x = f}) { const f = 0; return x; }
884 assertSame(f14, f14({}));
885 var f15 = function f({x = f}) { function f() {}; return x; }
886 assertSame(f15, f15({}));
887 })();
888 var f16 = function f({f = 7, x = f}) { return x; }
889 assertSame(7, f16({}));
890
891 var y = 'a';
892 function f20({[y]: x}) { var y = 'b'; return x; }
893 assertEquals(1, f20({a: 1, b: 2}));
894 function f21({[eval('y')]: x}) { var y = 'b'; return x; }
895 assertEquals(1, f21({a: 1, b: 2}));
896 var g20 = ({[y]: x}) => { var y = 'b'; return x; };
897 assertEquals(1, g20({a: 1, b: 2}));
898 var g21 = ({[eval('y')]: x}) => { var y = 'b'; return x; };
899 assertEquals(1, g21({a: 1, b: 2}));
900})();
901
902
903(function TestParameterDestructuringTDZ() {
904 function f1({a = x}, x) { return a }
905 assertThrows(() => f1({}, 4), ReferenceError);
906 assertEquals(4, f1({a: 4}, 5));
907 function f2({a = eval("x")}, x) { return a }
908 assertThrows(() => f2({}, 4), ReferenceError);
909 assertEquals(4, f2({a: 4}, 5));
910 (function() {
911 'use strict';
912 function f3({a = eval("x")}, x) { return a }
913 assertThrows(() => f3({}, 4), ReferenceError);
914 assertEquals(4, f3({a: 4}, 5));
915 })();
916 function f4({a = eval("'use strict'; x")}, x) { return a }
917 assertThrows(() => f4({}, 4), ReferenceError);
918 assertEquals(4, f4({a: 4}, 5));
919
920 function f5({a = () => x}, x) { return a() }
921 assertEquals(4, f5({a: () => 4}, 5));
922 function f6({a = () => eval("x")}, x) { return a() }
923 assertEquals(4, f6({a: () => 4}, 5));
924 (function() {
925 'use strict';
926 function f7({a = () => eval("x")}, x) { return a() }
927 assertEquals(4, f7({a: () => 4}, 5));
928 })();
929 function f8({a = () => eval("'use strict'; x")}, x) { return a() }
930 assertEquals(4, f8({a: () => 4}, 5));
931
932 function f11({a = b}, {b}) { return a }
933 assertThrows(() => f11({}, {b: 4}), ReferenceError);
934 assertEquals(4, f11({a: 4}, {b: 5}));
935 function f12({a = eval("b")}, {b}) { return a }
936 assertThrows(() => f12({}, {b: 4}), ReferenceError);
937 assertEquals(4, f12({a: 4}, {b: 5}));
938 (function() {
939 'use strict';
940 function f13({a = eval("b")}, {b}) { return a }
941 assertThrows(() => f13({}, {b: 4}), ReferenceError);
942 assertEquals(4, f13({a: 4}, {b: 5}));
943 })();
944 function f14({a = eval("'use strict'; b")}, {b}) { return a }
945 assertThrows(() => f14({}, {b: 4}), ReferenceError);
946 assertEquals(4, f14({a: 4}, {b: 5}));
947
948 function f15({a = () => b}, {b}) { return a() }
949 assertEquals(4, f15({a: () => 4}, {b: 5}));
950 function f16({a = () => eval("b")}, {b}) { return a() }
951 assertEquals(4, f16({a: () => 4}, {b: 5}));
952 (function() {
953 'use strict';
954 function f17({a = () => eval("b")}, {b}) { return a() }
955 assertEquals(4, f17({a: () => 4}, {b: 5}));
956 })();
957 function f18({a = () => eval("'use strict'; b")}, {b}) { return a() }
958 assertEquals(4, f18({a: () => 4}, {b: 5}));
959
960 // TODO(caitp): TDZ for rest parameters is not working yet.
961 // function f30({x = a}, ...a) { return x[0] }
962 // assertThrows(() => f30({}), ReferenceError);
963 // assertEquals(4, f30({a: [4]}, 5));
964 // function f31({x = eval("a")}, ...a) { return x[0] }
965 // assertThrows(() => f31({}), ReferenceError);
966 // assertEquals(4, f31({a: [4]}, 5));
967 // function f32({x = eval("a")}, ...a) { 'use strict'; return x[0] }
968 // assertThrows(() => f32({}), ReferenceError);
969 // assertEquals(4, f32({a: [4]}, 5));
970 // function f33({x = eval("'use strict'; a")}, ...a) { return x[0] }
971 // assertThrows(() => f33({}), ReferenceError);
972 // assertEquals(4, f33({a: [4]}, 5));
973
974 function f34({x = function() { return a }}, ...a) { return x()[0] }
975 assertEquals(4, f34({}, 4));
976 function f35({x = () => a}, ...a) { return x()[0] }
977 assertEquals(4, f35({}, 4));
978 function f36({x = () => eval("a")}, ...a) { return x()[0] }
979 assertEquals(4, f36({}, 4));
980 (function() {
981 'use strict';
982 function f37({x = () => eval("a")}, ...a) { return x()[0] }
983 assertEquals(4, f37({}, 4));
984 })();
985 function f38({x = () => { 'use strict'; return eval("a") }}, ...a) { return x()[0] }
986 assertEquals(4, f38({}, 4));
987 function f39({x = () => eval("'use strict'; a")}, ...a) { return x()[0] }
988 assertEquals(4, f39({}, 4));
989
990 // var g30 = ({x = a}, ...a) => {};
991 // assertThrows(() => g30({}), ReferenceError);
992 // var g31 = ({x = eval("a")}, ...a) => {};
993 // assertThrows(() => g31({}), ReferenceError);
994 // var g32 = ({x = eval("a")}, ...a) => { 'use strict'; };
995 // assertThrows(() => g32({}), ReferenceError);
996 // var g33 = ({x = eval("'use strict'; a")}, ...a) => {};
997 // assertThrows(() => g33({}), ReferenceError);
998 var g34 = ({x = function() { return a }}, ...a) => { return x()[0] };
999 assertEquals(4, g34({}, 4));
1000 var g35 = ({x = () => a}, ...a) => { return x()[0] };
1001 assertEquals(4, g35({}, 4));
1002})();
1003
1004
1005(function TestDuplicatesInParameters() {
1006 assertThrows("'use strict';function f(x,x){}", SyntaxError);
1007 assertThrows("'use strict';function f({x,x}){}", SyntaxError);
1008 assertThrows("'use strict';function f(x, {x}){}", SyntaxError);
1009 assertThrows("'use strict';var f = (x,x) => {};", SyntaxError);
1010 assertThrows("'use strict';var f = ({x,x}) => {};", SyntaxError);
1011 assertThrows("'use strict';var f = (x, {x}) => {};", SyntaxError);
1012
1013 function ok1(x) { var x; return x; };
1014 assertEquals(1, ok1(1));
1015 function ok2(x) { 'use strict'; { let x = 2; return x; } };
1016 assertEquals(2, ok2(1));
1017}());
1018
1019
1020(function TestShadowingOfParameters() {
1021 function f1({x}) { var x = 2; return x }
1022 assertEquals(2, f1({x: 1}));
1023 function f2({x}) { { var x = 2; } return x; }
1024 assertEquals(2, f2({x: 1}));
1025 function f3({x}) { var y = x; var x = 2; return y; }
1026 assertEquals(1, f3({x: 1}));
1027 function f4({x}) { { var y = x; var x = 2; } return y; }
1028 assertEquals(1, f4({x: 1}));
1029 function f5({x}, g = () => x) { var x = 2; return g(); }
1030 assertEquals(1, f5({x: 1}));
1031 function f6({x}, g = () => x) { { var x = 2; } return g(); }
1032 assertEquals(1, f6({x: 1}));
1033 function f7({x}) { var g = () => x; var x = 2; return g(); }
1034 assertEquals(2, f7({x: 1}));
1035 function f8({x}) { { var g = () => x; var x = 2; } return g(); }
1036 assertEquals(2, f8({x: 1}));
1037 function f9({x}, g = () => eval("x")) { var x = 2; return g(); }
1038 assertEquals(1, f9({x: 1}));
1039
1040 function f10({x}, y) { var y; return y }
1041 assertEquals(2, f10({x: 6}, 2));
1042 function f11({x}, y) { var z = y; var y = 2; return z; }
1043 assertEquals(1, f11({x: 6}, 1));
1044 function f12(y, g = () => y) { var y = 2; return g(); }
1045 assertEquals(1, f12(1));
1046 function f13({x}, y, [z], v) { var x, y, z; return x*y*z*v }
1047 assertEquals(210, f13({x: 2}, 3, [5], 7));
1048
1049 function f20({x}) { function x() { return 2 }; return x(); }
1050 assertEquals(2, f20({x: 1}));
1051 // Function hoisting is blocked by the conflicting x declaration
1052 function f21({x}) { { function x() { return 2 } } return x(); }
1053 assertThrows(() => f21({x: 1}), TypeError);
1054
1055 var g1 = ({x}) => { var x = 2; return x };
1056 assertEquals(2, g1({x: 1}));
1057 var g2 = ({x}) => { { var x = 2; } return x; };
1058 assertEquals(2, g2({x: 1}));
1059 var g3 = ({x}) => { var y = x; var x = 2; return y; };
1060 assertEquals(1, g3({x: 1}));
1061 var g4 = ({x}) => { { var y = x; var x = 2; } return y; };
1062 assertEquals(1, g4({x: 1}));
1063 var g5 = ({x}, g = () => x) => { var x = 2; return g(); };
1064 assertEquals(1, g5({x: 1}));
1065 var g6 = ({x}, g = () => x) => { { var x = 2; } return g(); };
1066 assertEquals(1, g6({x: 1}));
1067 var g7 = ({x}) => { var g = () => x; var x = 2; return g(); };
1068 assertEquals(2, g7({x: 1}));
1069 var g8 = ({x}) => { { var g = () => x; var x = 2; } return g(); };
1070 assertEquals(2, g8({x: 1}));
1071 var g9 = ({x}, g = () => eval("x")) => { var x = 2; return g(); };
1072 assertEquals(1, g9({x: 1}));
1073
1074 var g10 = ({x}, y) => { var y; return y };
1075 assertEquals(2, g10({x: 6}, 2));
1076 var g11 = ({x}, y) => { var z = y; var y = 2; return z; };
1077 assertEquals(1, g11({x: 6}, 1));
1078 var g12 = (y, g = () => y) => { var y = 2; return g(); };
1079 assertEquals(1, g12(1));
1080 var g13 = ({x}, y, [z], v) => { var x, y, z; return x*y*z*v };
1081 assertEquals(210, g13({x: 2}, 3, [5], 7));
1082
1083 var g20 = ({x}) => { function x() { return 2 }; return x(); }
1084 assertEquals(2, g20({x: 1}));
1085 var g21 = ({x}) => { { function x() { return 2 } } return x(); }
1086 assertThrows(() => g21({x: 1}), TypeError);
1087
1088 assertThrows("'use strict'; function f(x) { let x = 0; }; f({});", SyntaxError);
1089 assertThrows("'use strict'; function f({x}) { let x = 0; }; f({});", SyntaxError);
1090 assertThrows("'use strict'; function f(x) { const x = 0; }; f({});", SyntaxError);
1091 assertThrows("'use strict'; function f({x}) { const x = 0; }; f({});", SyntaxError);
1092
1093 assertThrows("'use strict'; let g = (x) => { let x = 0; }; f({});", SyntaxError);
1094 assertThrows("'use strict'; let g = ({x}) => { let x = 0; }; f({});", SyntaxError);
1095 assertThrows("'use strict'; let g = (x) => { const x = 0; }; f({});", SyntaxError);
1096 assertThrows("'use strict'; let g = ({x}) => { const x = 0; }; f({});", SyntaxError);
1097}());
1098
1099
1100(function TestArgumentsForNonSimpleParameters() {
1101 function f1({}, x) { arguments[1] = 0; return x }
1102 assertEquals(6, f1({}, 6));
1103 function f2({}, x) { x = 2; return arguments[1] }
1104 assertEquals(7, f2({}, 7));
1105 function f3(x, {}) { arguments[0] = 0; return x }
1106 assertEquals(6, f3(6, {}));
1107 function f4(x, {}) { x = 2; return arguments[0] }
1108 assertEquals(7, f4(7, {}));
1109 function f5(x, ...a) { arguments[0] = 0; return x }
1110 assertEquals(6, f5(6, {}));
1111 function f6(x, ...a) { x = 2; return arguments[0] }
1112 assertEquals(6, f6(6, {}));
1113 function f7({a: x}) { x = 2; return arguments[0].a }
1114 assertEquals(5, f7({a: 5}));
1115 function f8(x, ...a) { a = []; return arguments[1] }
1116 assertEquals(6, f8(5, 6));
1117}());
1118
1119
1120(function TestForInOfTDZ() {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001121 assertThrows("'use strict'; let x = {}; for (let [x, y] of [x]);", ReferenceError);
1122 assertThrows("'use strict'; let x = {}; for (let [y, x] of [x]);", ReferenceError);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001123 assertThrows("'use strict'; let x = {}; for (let [x, y] in {x});", ReferenceError);
1124 assertThrows("'use strict'; let x = {}; for (let [y, x] in {x});", ReferenceError);
1125}());
1126
1127
1128(function TestFunctionLength() {
1129 assertEquals(1, (function({}) {}).length);
1130 assertEquals(1, (function([]) {}).length);
1131 assertEquals(1, (function({x}) {}).length);
1132 assertEquals(1, (function({}, ...a) {}).length);
1133 assertEquals(1, (function({x}, {y} = {}) {}).length);
1134 assertEquals(1, (function({x}, {y} = {}, ...a) {}).length);
1135 assertEquals(2, (function(x, {y}, {z} = {}) {}).length);
1136 assertEquals(2, (function({x}, {}, {z} = {}, ...a) {}).length);
1137 assertEquals(1, (function(x, {y} = {}, {z}) {}).length);
1138 assertEquals(1, (function({x}, {y} = {}, {z}, ...a) {}).length);
1139 assertEquals(1, (function(x, {y} = {}, {z}, {v} = {}) {}).length);
1140 assertEquals(1, (function({x}, {y} = {}, {z}, {v} = {}, ...a) {}).length);
1141})();
1142
1143
1144(function TestDirectiveThrows() {
1145 "use strict";
1146
1147 assertThrows(function(){ eval("function({}){'use strict';}") }, SyntaxError);
1148 assertThrows(function(){ eval("({}) => {'use strict';}") }, SyntaxError);
1149 assertThrows(
1150 function(){ eval("(class{foo({}) {'use strict';}});") }, SyntaxError);
1151
1152 assertThrows(
1153 function(){ eval("function(a, {}){'use strict';}") }, SyntaxError);
1154 assertThrows(function(){ eval("(a, {}) => {'use strict';}") }, SyntaxError);
1155 assertThrows(
1156 function(){ eval("(class{foo(a, {}) {'use strict';}});") }, SyntaxError);
1157})();
1158
1159
1160(function TestLegacyConstDestructuringInForLoop() {
1161 var result;
1162 for (const {foo} of [{foo: 1}]) { result = foo; }
1163 assertEquals(1, result);
1164})();
1165
1166
1167(function TestCatch() {
1168 "use strict";
1169
1170 // For testing proper scoping.
1171 var foo = "hello", bar = "world", baz = 42;
1172
1173 try {
1174 throw {foo: 1, bar: 2};
1175 } catch ({foo, bar, baz = 3}) {
1176 assertEquals(1, foo);
1177 assertEquals(2, bar);
1178 assertEquals(3, baz);
1179 }
1180
1181 try {
1182 throw [1, 2, 3];
1183 } catch ([foo, ...bar]) {
1184 assertEquals(1, foo);
1185 assertEquals([2, 3], bar);
1186 }
1187
1188 assertEquals("hello", foo);
1189 assertEquals("world", bar);
1190 assertEquals(42, baz);
1191})();