1// 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 266(function TestMultipleAccesses() { 267 assertThrows( 268 "'use strict';"+ 269 "const {x,x} = {x:1};", 270 SyntaxError); 271 272 assertThrows( 273 "'use strict';"+ 274 "let {x,x} = {x:1};", 275 SyntaxError); 276 277 (function() { 278 var {x,x = 2} = {x : 1}; 279 assertSame(1, x); 280 }()); 281 282 assertThrows(function () { 283 'use strict'; 284 let {x = (function() { x = 2; }())} = {}; 285 }, ReferenceError); 286 287 (function() { 288 'use strict'; 289 let {x = (function() { x = 2; }())} = {x:1}; 290 assertSame(1, x); 291 }()); 292}()); 293 294 295(function TestComputedNames() { 296 var x = 1; 297 var {[x]:y} = {1:2}; 298 assertSame(2, y); 299 300 (function(){ 301 'use strict'; 302 let {[x]:y} = {1:2}; 303 assertSame(2, y); 304 }()); 305 306 var callCount = 0; 307 function foo(v) { callCount++; return v; } 308 309 (function() { 310 callCount = 0; 311 var {[foo("abc")]:x} = {abc:42}; 312 assertSame(42, x); 313 assertEquals(1, callCount); 314 }()); 315 316 (function() { 317 'use strict'; 318 callCount = 0; 319 let {[foo("abc")]:x} = {abc:42}; 320 assertSame(42, x); 321 assertEquals(1, callCount); 322 }()); 323 324 (function() { 325 callCount = 0; 326 var {[foo("abc")]:x} = {}; 327 assertSame(undefined, x); 328 assertEquals(1, callCount); 329 }()); 330 331 (function() { 332 'use strict'; 333 callCount = 0; 334 let {[foo("abc")]:x} = {}; 335 assertSame(undefined, x); 336 assertEquals(1, callCount); 337 }()); 338 339 for (val of [null, undefined]) { 340 callCount = 0; 341 assertThrows(function() { 342 var {[foo()]:x} = val; 343 }, TypeError); 344 assertEquals(0, callCount); 345 346 callCount = 0; 347 assertThrows(function() { 348 'use strict'; 349 let {[foo()]:x} = val; 350 }, TypeError); 351 assertEquals(0, callCount); 352 } 353 354 var log = []; 355 var o = { 356 get x() { log.push("get x"); return 1; }, 357 get y() { log.push("get y"); return 2; } 358 } 359 function f(v) { log.push("f " + v); return v; } 360 361 (function() { 362 log = []; 363 var { [f('x')]:x, [f('y')]:y } = o; 364 assertSame(1, x); 365 assertSame(2, y); 366 assertArrayEquals(["f x", "get x", "f y", "get y"], log); 367 }()); 368 369 (function() { 370 'use strict'; 371 log = []; 372 let { [f('x')]:x, [f('y')]:y } = o; 373 assertSame(1, x); 374 assertSame(2, y); 375 assertArrayEquals(["f x", "get x", "f y", "get y"], log); 376 }()); 377 378 (function() { 379 'use strict'; 380 log = []; 381 const { [f('x')]:x, [f('y')]:y } = o; 382 assertSame(1, x); 383 assertSame(2, y); 384 assertArrayEquals(["f x", "get x", "f y", "get y"], log); 385 }()); 386}()); 387 388 389(function TestExceptions() { 390 for (var val of [null, undefined]) { 391 assertThrows(function() { var {} = val; }, TypeError); 392 assertThrows(function() { var {x} = val; }, TypeError); 393 assertThrows(function() { var { x : {} } = { x : val }; }, TypeError); 394 assertThrows(function() { 'use strict'; let {} = val; }, TypeError); 395 assertThrows(function() { 'use strict'; let {x} = val; }, TypeError); 396 assertThrows(function() { 'use strict'; let { x : {} } = { x : val }; }, 397 TypeError); 398 } 399}()); 400 401 402(function TestArrayLiteral() { 403 var [a, b, c] = [1, 2, 3]; 404 assertSame(1, a); 405 assertSame(2, b); 406 assertSame(3, c); 407}()); 408 409(function TestIterators() { 410 var log = []; 411 function* f() { 412 log.push("1"); 413 yield 1; 414 log.push("2"); 415 yield 2; 416 log.push("3"); 417 yield 3; 418 log.push("done"); 419 }; 420 421 (function() { 422 log = []; 423 var [a, b, c] = f(); 424 assertSame(1, a); 425 assertSame(2, b); 426 assertSame(3, c); 427 assertArrayEquals(["1", "2", "3"], log); 428 }()); 429 430 (function() { 431 log = []; 432 var [a, b, c, d] = f(); 433 assertSame(1, a); 434 assertSame(2, b); 435 assertSame(3, c); 436 assertSame(undefined, d); 437 assertArrayEquals(["1", "2", "3", "done"], log); 438 }()); 439 440 (function() { 441 log = []; 442 var [a, , c] = f(); 443 assertSame(1, a); 444 assertSame(3, c); 445 assertArrayEquals(["1", "2", "3"], log); 446 }()); 447 448 (function() { 449 log = []; 450 var [a, , c, d] = f(); 451 assertSame(1, a); 452 assertSame(3, c); 453 assertSame(undefined, d); 454 assertArrayEquals(["1", "2", "3", "done"], log); 455 }()); 456 457 (function() { 458 log = []; 459 // last comma is not an elision. 460 var [a, b,] = f(); 461 assertSame(1, a); 462 assertSame(2, b); 463 assertArrayEquals(["1", "2"], log); 464 }()); 465 466 (function() { 467 log = []; 468 // last comma is not an elision, but the comma before the last is. 469 var [a, b, ,] = f(); 470 assertSame(1, a); 471 assertSame(2, b); 472 assertArrayEquals(["1", "2", "3"], log); 473 }()); 474 475 (function() { 476 log = []; 477 var [a, ...rest] = f(); 478 assertSame(1, a); 479 assertArrayEquals([2,3], rest); 480 assertArrayEquals(["1", "2", "3", "done"], log); 481 }()); 482 483 (function() { 484 log = []; 485 var [a, b, c, ...rest] = f(); 486 assertSame(1, a); 487 assertSame(2, b); 488 assertSame(3, c); 489 assertArrayEquals([], rest); 490 assertArrayEquals(["1", "2", "3", "done"], log); 491 }()); 492 493 (function() { 494 log = []; 495 var [a, b, c, d, ...rest] = f(); 496 assertSame(1, a); 497 assertSame(2, b); 498 assertSame(3, c); 499 assertSame(undefined, d); 500 assertArrayEquals([], rest); 501 assertArrayEquals(["1", "2", "3", "done"], log); 502 }()); 503}()); 504 505 506(function TestIteratorsLexical() { 507 'use strict'; 508 var log = []; 509 function* f() { 510 log.push("1"); 511 yield 1; 512 log.push("2"); 513 yield 2; 514 log.push("3"); 515 yield 3; 516 log.push("done"); 517 }; 518 519 (function() { 520 log = []; 521 let [a, b, c] = f(); 522 assertSame(1, a); 523 assertSame(2, b); 524 assertSame(3, c); 525 assertArrayEquals(["1", "2", "3"], log); 526 }()); 527 528 (function() { 529 log = []; 530 let [a, b, c, d] = f(); 531 assertSame(1, a); 532 assertSame(2, b); 533 assertSame(3, c); 534 assertSame(undefined, d); 535 assertArrayEquals(["1", "2", "3", "done"], log); 536 }()); 537 538 (function() { 539 log = []; 540 let [a, , c] = f(); 541 assertSame(1, a); 542 assertSame(3, c); 543 assertArrayEquals(["1", "2", "3"], log); 544 }()); 545 546 (function() { 547 log = []; 548 let [a, , c, d] = f(); 549 assertSame(1, a); 550 assertSame(3, c); 551 assertSame(undefined, d); 552 assertArrayEquals(["1", "2", "3", "done"], log); 553 }()); 554 555 (function() { 556 log = []; 557 // last comma is not an elision. 558 let [a, b,] = f(); 559 assertSame(1, a); 560 assertSame(2, b); 561 assertArrayEquals(["1", "2"], log); 562 }()); 563 564 (function() { 565 log = []; 566 // last comma is not an elision, but the comma before the last is. 567 let [a, b, ,] = f(); 568 assertSame(1, a); 569 assertSame(2, b); 570 assertArrayEquals(["1", "2", "3"], log); 571 }()); 572 573 (function() { 574 log = []; 575 let [a, ...rest] = f(); 576 assertSame(1, a); 577 assertArrayEquals([2,3], rest); 578 assertArrayEquals(["1", "2", "3", "done"], log); 579 }()); 580 581 (function() { 582 log = []; 583 let [a, b, c, ...rest] = f(); 584 assertSame(1, a); 585 assertSame(2, b); 586 assertSame(3, c); 587 assertArrayEquals([], rest); 588 assertArrayEquals(["1", "2", "3", "done"], log); 589 }()); 590 591 (function() { 592 log = []; 593 let [a, b, c, d, ...rest] = f(); 594 assertSame(1, a); 595 assertSame(2, b); 596 assertSame(3, c); 597 assertSame(undefined, d); 598 assertArrayEquals([], rest); 599 assertArrayEquals(["1", "2", "3", "done"], log); 600 }()); 601}()); 602 603(function TestIteratorsRecursive() { 604 var log = []; 605 function* f() { 606 log.push("1"); 607 yield {x : 1, y : 2}; 608 log.push("2"); 609 yield [42, 27, 30]; 610 log.push("3"); 611 yield "abc"; 612 log.push("done"); 613 }; 614 615 (function() { 616 var [{x, y}, [a, b]] = f(); 617 assertSame(1, x); 618 assertSame(2, y); 619 assertSame(42, a); 620 assertSame(27, b); 621 assertArrayEquals(["1", "2"], log); 622 }()); 623 624 (function() { 625 'use strict'; 626 log = []; 627 let [{x, y}, [a, b]] = f(); 628 assertSame(1, x); 629 assertSame(2, y); 630 assertSame(42, a); 631 assertSame(27, b); 632 assertArrayEquals(["1", "2"], log); 633 }()); 634}()); 635 636 637(function TestForEachLexical() { 638 'use strict'; 639 let a = [{x:1, y:-1}, {x:2,y:-2}, {x:3,y:-3}]; 640 let sumX = 0; 641 let sumY = 0; 642 let fs = []; 643 for (let {x,y} of a) { 644 sumX += x; 645 sumY += y; 646 fs.push({fx : function() { return x; }, fy : function() { return y }}); 647 } 648 assertSame(6, sumX); 649 assertSame(-6, sumY); 650 assertSame(3, fs.length); 651 for (let i = 0; i < fs.length; i++) { 652 let {fx,fy} = fs[i]; 653 assertSame(i+1, fx()); 654 assertSame(-(i+1), fy()); 655 } 656 657 var o = { __proto__:null, 'a1':1, 'b2':2 }; 658 let sx = ''; 659 let sy = ''; 660 for (let [x,y] in o) { 661 sx += x; 662 sy += y; 663 } 664 assertEquals('ab', sx); 665 assertEquals('12', sy); 666}()); 667 668 669(function TestForEachVars() { 670 var a = [{x:1, y:-1}, {x:2,y:-2}, {x:3,y:-3}]; 671 var sumX = 0; 672 var sumY = 0; 673 var fs = []; 674 for (var {x,y} of a) { 675 sumX += x; 676 sumY += y; 677 fs.push({fx : function() { return x; }, fy : function() { return y }}); 678 } 679 assertSame(6, sumX); 680 assertSame(-6, sumY); 681 assertSame(3, fs.length); 682 for (var i = 0; i < fs.length; i++) { 683 var {fx,fy} = fs[i]; 684 assertSame(3, fx()); 685 assertSame(-3, fy()); 686 } 687 688 var o = { __proto__:null, 'a1':1, 'b2':2 }; 689 var sx = ''; 690 var sy = ''; 691 for (var [x,y] in o) { 692 sx += x; 693 sy += y; 694 } 695 assertEquals('ab', sx); 696 assertEquals('12', sy); 697}()); 698 699 700(function TestParameters() { 701 function f({a, b}) { return a - b; } 702 assertEquals(1, f({a : 6, b : 5})); 703 704 function f1(c, {a, b}) { return c + a - b; } 705 assertEquals(8, f1(7, {a : 6, b : 5})); 706 707 function f2({c, d}, {a, b}) { return c - d + a - b; } 708 assertEquals(7, f2({c : 7, d : 1}, {a : 6, b : 5})); 709 710 function f3([{a, b}]) { return a - b; } 711 assertEquals(1, f3([{a : 6, b : 5}])); 712 713 var g = ({a, b}) => { return a - b; }; 714 assertEquals(1, g({a : 6, b : 5})); 715 716 var g1 = (c, {a, b}) => { return c + a - b; }; 717 assertEquals(8, g1(7, {a : 6, b : 5})); 718 719 var g2 = ({c, d}, {a, b}) => { return c - d + a - b; }; 720 assertEquals(7, g2({c : 7, d : 1}, {a : 6, b : 5})); 721 722 var g3 = ([{a, b}]) => { return a - b; }; 723 assertEquals(1, g3([{a : 6, b : 5}])); 724}()); 725 726 727(function TestExpressionsInParameters() { 728 function f0(x = eval(0)) { return x } 729 assertEquals(0, f0()); 730 function f1({a = eval(1)}) { return a } 731 assertEquals(1, f1({})); 732 function f2([x = eval(2)]) { return x } 733 assertEquals(2, f2([])); 734 function f3({[eval(7)]: x}) { return x } 735 assertEquals(3, f3({7: 3})); 736})(); 737 738 739(function TestParameterScoping() { 740 var x = 1; 741 742 function f1({a = x}) { var x = 2; return a; } 743 assertEquals(1, f1({})); 744 function f2({a = x}) { function x() {}; return a; } 745 assertEquals(1, f2({})); 746 (function() { 747 'use strict'; 748 function f3({a = x}) { let x = 2; return a; } 749 assertEquals(1, f3({})); 750 function f4({a = x}) { const x = 2; return a; } 751 assertEquals(1, f4({})); 752 function f5({a = x}) { function x() {}; return a; } 753 assertEquals(1, f5({})); 754 })(); 755 function f6({a = eval("x")}) { var x; return a; } 756 assertEquals(1, f6({})); 757 (function() { 758 'use strict'; 759 function f61({a = eval("x")}) { var x; return a; } 760 assertEquals(1, f61({})); 761 })(); 762 function f62({a = eval("'use strict'; x")}) { var x; return a; } 763 assertEquals(1, f62({})); 764 function f7({a = function() { return x }}) { var x; return a(); } 765 assertEquals(1, f7({})); 766 function f8({a = () => x}) { var x; return a(); } 767 assertEquals(1, f8({})); 768 function f9({a = () => eval("x")}) { var x; return a(); } 769 assertEquals(1, f9({})); 770 (function TestInitializedWithEvalArrowStrict() { 771 'use strict'; 772 function f91({a = () => eval("x")}) { var x; return a(); } 773 assertEquals(1, f91({})); 774 })(); 775 function f92({a = () => { 'use strict'; return eval("x") }}) { var x; return a(); } 776 assertEquals(1, f92({})); 777 function f93({a = () => eval("'use strict'; x")}) { var x; return a(); } 778 assertEquals(1, f93({})); 779 780 var g1 = ({a = x}) => { var x = 2; return a; }; 781 assertEquals(1, g1({})); 782 var g2 = ({a = x}) => { function x() {}; return a; }; 783 assertEquals(1, g2({})); 784 (function() { 785 'use strict'; 786 var g3 = ({a = x}) => { let x = 2; return a; }; 787 assertEquals(1, g3({})); 788 var g4 = ({a = x}) => { const x = 2; return a; }; 789 assertEquals(1, g4({})); 790 var g5 = ({a = x}) => { function x() {}; return a; }; 791 assertEquals(1, g5({})); 792 })(); 793 var g6 = ({a = eval("x")}) => { var x; return a; }; 794 assertEquals(1, g6({})); 795 (function() { 796 'use strict'; 797 var g61 = ({a = eval("x")}) => { var x; return a; }; 798 assertEquals(1, g61({})); 799 })(); 800 var g62 = ({a = eval("'use strict'; x")}) => { var x; return a; }; 801 assertEquals(1, g62({})); 802 var g7 = ({a = function() { return x }}) => { var x; return a(); }; 803 assertEquals(1, g7({})); 804 var g8 = ({a = () => x}) => { var x; return a(); }; 805 assertEquals(1, g8({})); 806 var g9 = ({a = () => eval("x")}) => { var x; return a(); }; 807 assertEquals(1, g9({})); 808 (function() { 809 'use strict'; 810 var g91 = ({a = () => eval("x")}) => { var x; return a(); }; 811 assertEquals(1, g91({})); 812 var g92 = ({a = () => { return eval("x") }}) => { var x; return a(); }; 813 assertEquals(1, g92({})); 814 })(); 815 var g93 = ({a = () => eval("'use strict'; x")}) => { var x; return a(); }; 816 assertEquals(1, g93({})); 817 818 var f11 = function f({x = f}) { var f; return x; } 819 assertSame(f11, f11({})); 820 var f12 = function f({x = f}) { function f() {}; return x; } 821 assertSame(f12, f12({})); 822 (function() { 823 'use strict'; 824 var f13 = function f({x = f}) { let f; return x; } 825 assertSame(f13, f13({})); 826 var f14 = function f({x = f}) { const f = 0; return x; } 827 assertSame(f14, f14({})); 828 var f15 = function f({x = f}) { function f() {}; return x; } 829 assertSame(f15, f15({})); 830 })(); 831 var f16 = function f({f = 7, x = f}) { return x; } 832 assertSame(7, f16({})); 833 834 var y = 'a'; 835 function f20({[y]: x}) { var y = 'b'; return x; } 836 assertEquals(1, f20({a: 1, b: 2})); 837 function f21({[eval('y')]: x}) { var y = 'b'; return x; } 838 assertEquals(1, f21({a: 1, b: 2})); 839 var g20 = ({[y]: x}) => { var y = 'b'; return x; }; 840 assertEquals(1, g20({a: 1, b: 2})); 841 var g21 = ({[eval('y')]: x}) => { var y = 'b'; return x; }; 842 assertEquals(1, g21({a: 1, b: 2})); 843})(); 844 845 846(function TestParameterDestructuringTDZ() { 847 function f1({a = x}, x) { return a } 848 assertThrows(() => f1({}, 4), ReferenceError); 849 assertEquals(4, f1({a: 4}, 5)); 850 function f2({a = eval("x")}, x) { return a } 851 assertThrows(() => f2({}, 4), ReferenceError); 852 assertEquals(4, f2({a: 4}, 5)); 853 (function() { 854 'use strict'; 855 function f3({a = eval("x")}, x) { return a } 856 assertThrows(() => f3({}, 4), ReferenceError); 857 assertEquals(4, f3({a: 4}, 5)); 858 })(); 859 function f4({a = eval("'use strict'; x")}, x) { return a } 860 assertThrows(() => f4({}, 4), ReferenceError); 861 assertEquals(4, f4({a: 4}, 5)); 862 863 function f5({a = () => x}, x) { return a() } 864 assertEquals(4, f5({a: () => 4}, 5)); 865 function f6({a = () => eval("x")}, x) { return a() } 866 assertEquals(4, f6({a: () => 4}, 5)); 867 (function() { 868 'use strict'; 869 function f7({a = () => eval("x")}, x) { return a() } 870 assertEquals(4, f7({a: () => 4}, 5)); 871 })(); 872 function f8({a = () => eval("'use strict'; x")}, x) { return a() } 873 assertEquals(4, f8({a: () => 4}, 5)); 874 875 function f11({a = b}, {b}) { return a } 876 assertThrows(() => f11({}, {b: 4}), ReferenceError); 877 assertEquals(4, f11({a: 4}, {b: 5})); 878 function f12({a = eval("b")}, {b}) { return a } 879 assertThrows(() => f12({}, {b: 4}), ReferenceError); 880 assertEquals(4, f12({a: 4}, {b: 5})); 881 (function() { 882 'use strict'; 883 function f13({a = eval("b")}, {b}) { return a } 884 assertThrows(() => f13({}, {b: 4}), ReferenceError); 885 assertEquals(4, f13({a: 4}, {b: 5})); 886 })(); 887 function f14({a = eval("'use strict'; b")}, {b}) { return a } 888 assertThrows(() => f14({}, {b: 4}), ReferenceError); 889 assertEquals(4, f14({a: 4}, {b: 5})); 890 891 function f15({a = () => b}, {b}) { return a() } 892 assertEquals(4, f15({a: () => 4}, {b: 5})); 893 function f16({a = () => eval("b")}, {b}) { return a() } 894 assertEquals(4, f16({a: () => 4}, {b: 5})); 895 (function() { 896 'use strict'; 897 function f17({a = () => eval("b")}, {b}) { return a() } 898 assertEquals(4, f17({a: () => 4}, {b: 5})); 899 })(); 900 function f18({a = () => eval("'use strict'; b")}, {b}) { return a() } 901 assertEquals(4, f18({a: () => 4}, {b: 5})); 902 903 // TODO(caitp): TDZ for rest parameters is not working yet. 904 // function f30({x = a}, ...a) { return x[0] } 905 // assertThrows(() => f30({}), ReferenceError); 906 // assertEquals(4, f30({a: [4]}, 5)); 907 // function f31({x = eval("a")}, ...a) { return x[0] } 908 // assertThrows(() => f31({}), ReferenceError); 909 // assertEquals(4, f31({a: [4]}, 5)); 910 // function f32({x = eval("a")}, ...a) { 'use strict'; return x[0] } 911 // assertThrows(() => f32({}), ReferenceError); 912 // assertEquals(4, f32({a: [4]}, 5)); 913 // function f33({x = eval("'use strict'; a")}, ...a) { return x[0] } 914 // assertThrows(() => f33({}), ReferenceError); 915 // assertEquals(4, f33({a: [4]}, 5)); 916 917 function f34({x = function() { return a }}, ...a) { return x()[0] } 918 assertEquals(4, f34({}, 4)); 919 function f35({x = () => a}, ...a) { return x()[0] } 920 assertEquals(4, f35({}, 4)); 921 function f36({x = () => eval("a")}, ...a) { return x()[0] } 922 assertEquals(4, f36({}, 4)); 923 (function() { 924 'use strict'; 925 function f37({x = () => eval("a")}, ...a) { return x()[0] } 926 assertEquals(4, f37({}, 4)); 927 })(); 928 function f38({x = () => { 'use strict'; return eval("a") }}, ...a) { return x()[0] } 929 assertEquals(4, f38({}, 4)); 930 function f39({x = () => eval("'use strict'; a")}, ...a) { return x()[0] } 931 assertEquals(4, f39({}, 4)); 932 933 // var g30 = ({x = a}, ...a) => {}; 934 // assertThrows(() => g30({}), ReferenceError); 935 // var g31 = ({x = eval("a")}, ...a) => {}; 936 // assertThrows(() => g31({}), ReferenceError); 937 // var g32 = ({x = eval("a")}, ...a) => { 'use strict'; }; 938 // assertThrows(() => g32({}), ReferenceError); 939 // var g33 = ({x = eval("'use strict'; a")}, ...a) => {}; 940 // assertThrows(() => g33({}), ReferenceError); 941 var g34 = ({x = function() { return a }}, ...a) => { return x()[0] }; 942 assertEquals(4, g34({}, 4)); 943 var g35 = ({x = () => a}, ...a) => { return x()[0] }; 944 assertEquals(4, g35({}, 4)); 945})(); 946 947 948(function TestDuplicatesInParameters() { 949 assertThrows("'use strict';function f(x,x){}", SyntaxError); 950 assertThrows("'use strict';function f({x,x}){}", SyntaxError); 951 assertThrows("'use strict';function f(x, {x}){}", SyntaxError); 952 assertThrows("'use strict';var f = (x,x) => {};", SyntaxError); 953 assertThrows("'use strict';var f = ({x,x}) => {};", SyntaxError); 954 assertThrows("'use strict';var f = (x, {x}) => {};", SyntaxError); 955 956 function ok1(x) { var x; return x; }; 957 assertEquals(1, ok1(1)); 958 function ok2(x) { 'use strict'; { let x = 2; return x; } }; 959 assertEquals(2, ok2(1)); 960}()); 961 962 963(function TestShadowingOfParameters() { 964 function f1({x}) { var x = 2; return x } 965 assertEquals(2, f1({x: 1})); 966 function f2({x}) { { var x = 2; } return x; } 967 assertEquals(2, f2({x: 1})); 968 function f3({x}) { var y = x; var x = 2; return y; } 969 assertEquals(1, f3({x: 1})); 970 function f4({x}) { { var y = x; var x = 2; } return y; } 971 assertEquals(1, f4({x: 1})); 972 function f5({x}, g = () => x) { var x = 2; return g(); } 973 assertEquals(1, f5({x: 1})); 974 function f6({x}, g = () => x) { { var x = 2; } return g(); } 975 assertEquals(1, f6({x: 1})); 976 function f7({x}) { var g = () => x; var x = 2; return g(); } 977 assertEquals(2, f7({x: 1})); 978 function f8({x}) { { var g = () => x; var x = 2; } return g(); } 979 assertEquals(2, f8({x: 1})); 980 function f9({x}, g = () => eval("x")) { var x = 2; return g(); } 981 assertEquals(1, f9({x: 1})); 982 983 function f10({x}, y) { var y; return y } 984 assertEquals(2, f10({x: 6}, 2)); 985 function f11({x}, y) { var z = y; var y = 2; return z; } 986 assertEquals(1, f11({x: 6}, 1)); 987 function f12(y, g = () => y) { var y = 2; return g(); } 988 assertEquals(1, f12(1)); 989 function f13({x}, y, [z], v) { var x, y, z; return x*y*z*v } 990 assertEquals(210, f13({x: 2}, 3, [5], 7)); 991 992 function f20({x}) { function x() { return 2 }; return x(); } 993 assertEquals(2, f20({x: 1})); 994 // Function hoisting is blocked by the conflicting x declaration 995 function f21({x}) { { function x() { return 2 } } return x(); } 996 assertThrows(() => f21({x: 1}), TypeError); 997 998 var g1 = ({x}) => { var x = 2; return x }; 999 assertEquals(2, g1({x: 1})); 1000 var g2 = ({x}) => { { var x = 2; } return x; }; 1001 assertEquals(2, g2({x: 1})); 1002 var g3 = ({x}) => { var y = x; var x = 2; return y; }; 1003 assertEquals(1, g3({x: 1})); 1004 var g4 = ({x}) => { { var y = x; var x = 2; } return y; }; 1005 assertEquals(1, g4({x: 1})); 1006 var g5 = ({x}, g = () => x) => { var x = 2; return g(); }; 1007 assertEquals(1, g5({x: 1})); 1008 var g6 = ({x}, g = () => x) => { { var x = 2; } return g(); }; 1009 assertEquals(1, g6({x: 1})); 1010 var g7 = ({x}) => { var g = () => x; var x = 2; return g(); }; 1011 assertEquals(2, g7({x: 1})); 1012 var g8 = ({x}) => { { var g = () => x; var x = 2; } return g(); }; 1013 assertEquals(2, g8({x: 1})); 1014 var g9 = ({x}, g = () => eval("x")) => { var x = 2; return g(); }; 1015 assertEquals(1, g9({x: 1})); 1016 1017 var g10 = ({x}, y) => { var y; return y }; 1018 assertEquals(2, g10({x: 6}, 2)); 1019 var g11 = ({x}, y) => { var z = y; var y = 2; return z; }; 1020 assertEquals(1, g11({x: 6}, 1)); 1021 var g12 = (y, g = () => y) => { var y = 2; return g(); }; 1022 assertEquals(1, g12(1)); 1023 var g13 = ({x}, y, [z], v) => { var x, y, z; return x*y*z*v }; 1024 assertEquals(210, g13({x: 2}, 3, [5], 7)); 1025 1026 var g20 = ({x}) => { function x() { return 2 }; return x(); } 1027 assertEquals(2, g20({x: 1})); 1028 var g21 = ({x}) => { { function x() { return 2 } } return x(); } 1029 assertThrows(() => g21({x: 1}), TypeError); 1030 1031 assertThrows("'use strict'; function f(x) { let x = 0; }; f({});", SyntaxError); 1032 assertThrows("'use strict'; function f({x}) { let x = 0; }; f({});", SyntaxError); 1033 assertThrows("'use strict'; function f(x) { const x = 0; }; f({});", SyntaxError); 1034 assertThrows("'use strict'; function f({x}) { const x = 0; }; f({});", SyntaxError); 1035 1036 assertThrows("'use strict'; let g = (x) => { let x = 0; }; f({});", SyntaxError); 1037 assertThrows("'use strict'; let g = ({x}) => { let x = 0; }; f({});", SyntaxError); 1038 assertThrows("'use strict'; let g = (x) => { const x = 0; }; f({});", SyntaxError); 1039 assertThrows("'use strict'; let g = ({x}) => { const x = 0; }; f({});", SyntaxError); 1040}()); 1041 1042 1043(function TestArgumentsForNonSimpleParameters() { 1044 function f1({}, x) { arguments[1] = 0; return x } 1045 assertEquals(6, f1({}, 6)); 1046 function f2({}, x) { x = 2; return arguments[1] } 1047 assertEquals(7, f2({}, 7)); 1048 function f3(x, {}) { arguments[0] = 0; return x } 1049 assertEquals(6, f3(6, {})); 1050 function f4(x, {}) { x = 2; return arguments[0] } 1051 assertEquals(7, f4(7, {})); 1052 function f5(x, ...a) { arguments[0] = 0; return x } 1053 assertEquals(6, f5(6, {})); 1054 function f6(x, ...a) { x = 2; return arguments[0] } 1055 assertEquals(6, f6(6, {})); 1056 function f7({a: x}) { x = 2; return arguments[0].a } 1057 assertEquals(5, f7({a: 5})); 1058 function f8(x, ...a) { a = []; return arguments[1] } 1059 assertEquals(6, f8(5, 6)); 1060}()); 1061 1062 1063(function TestForInOfTDZ() { 1064 assertThrows("'use strict'; let x = {}; for (let [x, y] of {x});", ReferenceError); 1065 assertThrows("'use strict'; let x = {}; for (let [y, x] of {x});", ReferenceError); 1066 assertThrows("'use strict'; let x = {}; for (let [x, y] in {x});", ReferenceError); 1067 assertThrows("'use strict'; let x = {}; for (let [y, x] in {x});", ReferenceError); 1068}()); 1069 1070 1071(function TestFunctionLength() { 1072 assertEquals(1, (function({}) {}).length); 1073 assertEquals(1, (function([]) {}).length); 1074 assertEquals(1, (function({x}) {}).length); 1075 assertEquals(1, (function({}, ...a) {}).length); 1076 assertEquals(1, (function({x}, {y} = {}) {}).length); 1077 assertEquals(1, (function({x}, {y} = {}, ...a) {}).length); 1078 assertEquals(2, (function(x, {y}, {z} = {}) {}).length); 1079 assertEquals(2, (function({x}, {}, {z} = {}, ...a) {}).length); 1080 assertEquals(1, (function(x, {y} = {}, {z}) {}).length); 1081 assertEquals(1, (function({x}, {y} = {}, {z}, ...a) {}).length); 1082 assertEquals(1, (function(x, {y} = {}, {z}, {v} = {}) {}).length); 1083 assertEquals(1, (function({x}, {y} = {}, {z}, {v} = {}, ...a) {}).length); 1084})(); 1085 1086 1087(function TestDirectiveThrows() { 1088 "use strict"; 1089 1090 assertThrows(function(){ eval("function({}){'use strict';}") }, SyntaxError); 1091 assertThrows(function(){ eval("({}) => {'use strict';}") }, SyntaxError); 1092 assertThrows( 1093 function(){ eval("(class{foo({}) {'use strict';}});") }, SyntaxError); 1094 1095 assertThrows( 1096 function(){ eval("function(a, {}){'use strict';}") }, SyntaxError); 1097 assertThrows(function(){ eval("(a, {}) => {'use strict';}") }, SyntaxError); 1098 assertThrows( 1099 function(){ eval("(class{foo(a, {}) {'use strict';}});") }, SyntaxError); 1100})(); 1101 1102 1103(function TestLegacyConstDestructuringInForLoop() { 1104 var result; 1105 for (const {foo} of [{foo: 1}]) { result = foo; } 1106 assertEquals(1, result); 1107})(); 1108 1109 1110(function TestCatch() { 1111 "use strict"; 1112 1113 // For testing proper scoping. 1114 var foo = "hello", bar = "world", baz = 42; 1115 1116 try { 1117 throw {foo: 1, bar: 2}; 1118 } catch ({foo, bar, baz = 3}) { 1119 assertEquals(1, foo); 1120 assertEquals(2, bar); 1121 assertEquals(3, baz); 1122 } 1123 1124 try { 1125 throw [1, 2, 3]; 1126 } catch ([foo, ...bar]) { 1127 assertEquals(1, foo); 1128 assertEquals([2, 3], bar); 1129 } 1130 1131 assertEquals("hello", foo); 1132 assertEquals("world", bar); 1133 assertEquals(42, baz); 1134})(); 1135