Home | History | Annotate | Download | only in harmony
      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