7ffdb5194d
Also support patterns in ``for (var p in/of ...)`` This CL extends the rewriting we used to do for ``for (let p in/of...)`` to ``for (var p in/of ...)``. For all for..in/of loop declaring variable, we rewrite for (var/let/const pattern in/of e) b into for (x' in/of e) { var/let/const pattern = e; b } This adds a small complication for debugger: for a statement for (var v in/of e) ... we used to have var v; for (v in/of e) ... and there was a separate breakpoint on ``var v`` line. This breakpoint is actually useless since it is immediately followed by a breakpoint on evaluation of ``e``, so this CL removes that breakpoint location. Similiraly, for let, it used to be that for (let v in/of e) ... became for (x' in/of e) { let v; v = x'; ... } ``let v``generetaed a useless breakpoint (with the location at the loop's head. This CL removes that breakpoint as well. R=arv@chromium.org,rossberg@chromium.org BUG=v8:811 LOG=N Review URL: https://codereview.chromium.org/1149043005 Cr-Commit-Position: refs/heads/master@{#28565}
689 lines
14 KiB
JavaScript
689 lines
14 KiB
JavaScript
// Copyright 2015 the V8 project authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
//
|
|
// Flags: --harmony-destructuring --harmony-computed-property-names
|
|
|
|
(function TestObjectLiteralPattern() {
|
|
var { x : x, y : y } = { x : 1, y : 2 };
|
|
assertEquals(1, x);
|
|
assertEquals(2, y);
|
|
|
|
var {z} = { z : 3 };
|
|
assertEquals(3, z);
|
|
|
|
|
|
var sum = 0;
|
|
for (var {z} = { z : 3 }; z != 0; z--) {
|
|
sum += z;
|
|
}
|
|
assertEquals(6, sum);
|
|
|
|
|
|
var log = [];
|
|
var o = {
|
|
get x() {
|
|
log.push("x");
|
|
return 0;
|
|
},
|
|
get y() {
|
|
log.push("y");
|
|
return {
|
|
get z() { log.push("z"); return 1; }
|
|
}
|
|
}
|
|
};
|
|
var { x : x0, y : { z : z1 }, x : x1 } = o;
|
|
assertSame(0, x0);
|
|
assertSame(1, z1);
|
|
assertSame(0, x1);
|
|
assertArrayEquals(["x", "y", "z", "x"], log);
|
|
}());
|
|
|
|
|
|
(function TestObjectLiteralPatternInitializers() {
|
|
var { x : x, y : y = 2 } = { x : 1 };
|
|
assertEquals(1, x);
|
|
assertEquals(2, y);
|
|
|
|
var {z = 3} = {};
|
|
assertEquals(3, z);
|
|
|
|
var sum = 0;
|
|
for (var {z = 3} = {}; z != 0; z--) {
|
|
sum += z;
|
|
}
|
|
assertEquals(6, sum);
|
|
|
|
var log = [];
|
|
var o = {
|
|
get x() {
|
|
log.push("x");
|
|
return undefined;
|
|
},
|
|
get y() {
|
|
log.push("y");
|
|
return {
|
|
get z() { log.push("z"); return undefined; }
|
|
}
|
|
}
|
|
};
|
|
var { x : x0 = 0, y : { z : z1 = 1}, x : x1 = 0} = o;
|
|
assertSame(0, x0);
|
|
assertSame(1, z1);
|
|
assertSame(0, x1);
|
|
assertArrayEquals(["x", "y", "z", "x"], log);
|
|
}());
|
|
|
|
|
|
(function TestObjectLiteralPatternLexicalInitializers() {
|
|
'use strict';
|
|
let { x : x, y : y = 2 } = { x : 1 };
|
|
assertEquals(1, x);
|
|
assertEquals(2, y);
|
|
|
|
let {z = 3} = {};
|
|
assertEquals(3, z);
|
|
|
|
let log = [];
|
|
let o = {
|
|
get x() {
|
|
log.push("x");
|
|
return undefined;
|
|
},
|
|
get y() {
|
|
log.push("y");
|
|
return {
|
|
get z() { log.push("z"); return undefined; }
|
|
}
|
|
}
|
|
};
|
|
|
|
let { x : x0 = 0, y : { z : z1 = 1 }, x : x1 = 5} = o;
|
|
assertSame(0, x0);
|
|
assertSame(1, z1);
|
|
assertSame(5, x1);
|
|
assertArrayEquals(["x", "y", "z", "x"], log);
|
|
|
|
let sum = 0;
|
|
for (let {x = 0, z = 3} = {}; z != 0; z--) {
|
|
assertEquals(0, x);
|
|
sum += z;
|
|
}
|
|
assertEquals(6, sum);
|
|
}());
|
|
|
|
|
|
(function TestObjectLiteralPatternLexical() {
|
|
'use strict';
|
|
let { x : x, y : y } = { x : 1, y : 2 };
|
|
assertEquals(1, x);
|
|
assertEquals(2, y);
|
|
|
|
let {z} = { z : 3 };
|
|
assertEquals(3, z);
|
|
|
|
let log = [];
|
|
let o = {
|
|
get x() {
|
|
log.push("x");
|
|
return 0;
|
|
},
|
|
get y() {
|
|
log.push("y");
|
|
return {
|
|
get z() { log.push("z"); return 1; }
|
|
}
|
|
}
|
|
};
|
|
let { x : x0, y : { z : z1 }, x : x1 } = o;
|
|
assertSame(0, x0);
|
|
assertSame(1, z1);
|
|
assertSame(0, x1);
|
|
assertArrayEquals(["x", "y", "z", "x"], log);
|
|
|
|
let sum = 0;
|
|
for (let {x, z} = { x : 0, z : 3 }; z != 0; z--) {
|
|
assertEquals(0, x);
|
|
sum += z;
|
|
}
|
|
assertEquals(6, sum);
|
|
}());
|
|
|
|
|
|
(function TestObjectLiteralPatternLexicalConst() {
|
|
'use strict';
|
|
const { x : x, y : y } = { x : 1, y : 2 };
|
|
assertEquals(1, x);
|
|
assertEquals(2, y);
|
|
|
|
assertThrows(function() { x++; }, TypeError);
|
|
assertThrows(function() { y++; }, TypeError);
|
|
|
|
const {z} = { z : 3 };
|
|
assertEquals(3, z);
|
|
|
|
for (const {x, z} = { x : 0, z : 3 }; z != 3 || x != 0;) {
|
|
assertTrue(false);
|
|
}
|
|
}());
|
|
|
|
|
|
(function TestFailingMatchesSloppy() {
|
|
var {x, y} = {};
|
|
assertSame(undefined, x);
|
|
assertSame(undefined, y);
|
|
|
|
var { x : { z1 }, y2} = { x : {}, y2 : 42 }
|
|
assertSame(undefined, z1);
|
|
assertSame(42, y2);
|
|
}());
|
|
|
|
|
|
(function TestFailingMatchesStrict() {
|
|
'use strict';
|
|
var {x, y} = {};
|
|
assertSame(undefined, x);
|
|
assertSame(undefined, y);
|
|
|
|
var { x : { z1 }, y2} = { x : {}, y2 : 42 }
|
|
assertSame(undefined, z1);
|
|
assertSame(42, y2);
|
|
|
|
{
|
|
let {x1,y1} = {};
|
|
assertSame(undefined, x1);
|
|
assertSame(undefined, y1);
|
|
|
|
let { x : { z1 }, y2} = { x : {}, y2 : 42 }
|
|
assertSame(undefined, z1);
|
|
assertSame(42, y2);
|
|
}
|
|
}());
|
|
|
|
|
|
(function TestTDZInIntializers() {
|
|
'use strict';
|
|
{
|
|
let {x, y = x} = {x : 42, y : 27};
|
|
assertSame(42, x);
|
|
assertSame(27, y);
|
|
}
|
|
|
|
{
|
|
let {x, y = x + 1} = { x : 42 };
|
|
assertSame(42, x);
|
|
assertSame(43, y);
|
|
}
|
|
assertThrows(function() {
|
|
let {x = y, y} = { y : 42 };
|
|
}, ReferenceError);
|
|
|
|
{
|
|
let {x, y = eval("x+1")} = {x:42};
|
|
assertEquals(42, x);
|
|
assertEquals(43, y);
|
|
}
|
|
|
|
{
|
|
let {x = function() {return y+1;}, y} = {y:42};
|
|
assertEquals(43, x());
|
|
assertEquals(42, y);
|
|
}
|
|
{
|
|
let {x = function() {return eval("y+1");}, y} = {y:42};
|
|
assertEquals(43, x());
|
|
assertEquals(42, y);
|
|
}
|
|
}());
|
|
|
|
|
|
(function TestSideEffectsInInitializers() {
|
|
var callCount = 0;
|
|
function f(v) { callCount++; return v; }
|
|
|
|
callCount = 0;
|
|
var { x = f(42) } = { x : 27 };
|
|
assertSame(27, x);
|
|
assertEquals(0, callCount);
|
|
|
|
callCount = 0;
|
|
var { x = f(42) } = {};
|
|
assertSame(42, x);
|
|
assertEquals(1, callCount);
|
|
}());
|
|
|
|
|
|
(function TestMultipleAccesses() {
|
|
assertThrows(
|
|
"'use strict';"+
|
|
"const {x,x} = {x:1};",
|
|
SyntaxError);
|
|
|
|
assertThrows(
|
|
"'use strict';"+
|
|
"let {x,x} = {x:1};",
|
|
SyntaxError);
|
|
|
|
(function() {
|
|
var {x,x = 2} = {x : 1};
|
|
assertSame(1, x);
|
|
}());
|
|
|
|
assertThrows(function () {
|
|
'use strict';
|
|
let {x = (function() { x = 2; }())} = {};
|
|
}, ReferenceError);
|
|
|
|
(function() {
|
|
'use strict';
|
|
let {x = (function() { x = 2; }())} = {x:1};
|
|
assertSame(1, x);
|
|
}());
|
|
}());
|
|
|
|
|
|
(function TestComputedNames() {
|
|
var x = 1;
|
|
var {[x]:y} = {1:2};
|
|
assertSame(2, y);
|
|
|
|
(function(){
|
|
'use strict';
|
|
let {[x]:y} = {1:2};
|
|
assertSame(2, y);
|
|
}());
|
|
|
|
var callCount = 0;
|
|
function foo(v) { callCount++; return v; }
|
|
|
|
(function() {
|
|
callCount = 0;
|
|
var {[foo("abc")]:x} = {abc:42};
|
|
assertSame(42, x);
|
|
assertEquals(1, callCount);
|
|
}());
|
|
|
|
(function() {
|
|
'use strict';
|
|
callCount = 0;
|
|
let {[foo("abc")]:x} = {abc:42};
|
|
assertSame(42, x);
|
|
assertEquals(1, callCount);
|
|
}());
|
|
|
|
(function() {
|
|
callCount = 0;
|
|
var {[foo("abc")]:x} = {};
|
|
assertSame(undefined, x);
|
|
assertEquals(1, callCount);
|
|
}());
|
|
|
|
(function() {
|
|
'use strict';
|
|
callCount = 0;
|
|
let {[foo("abc")]:x} = {};
|
|
assertSame(undefined, x);
|
|
assertEquals(1, callCount);
|
|
}());
|
|
|
|
for (val of [null, undefined]) {
|
|
callCount = 0;
|
|
assertThrows(function() {
|
|
var {[foo()]:x} = val;
|
|
}, TypeError);
|
|
assertEquals(0, callCount);
|
|
|
|
callCount = 0;
|
|
assertThrows(function() {
|
|
'use strict';
|
|
let {[foo()]:x} = val;
|
|
}, TypeError);
|
|
assertEquals(0, callCount);
|
|
}
|
|
|
|
var log = [];
|
|
var o = {
|
|
get x() { log.push("get x"); return 1; },
|
|
get y() { log.push("get y"); return 2; }
|
|
}
|
|
function f(v) { log.push("f " + v); return v; }
|
|
|
|
(function() {
|
|
log = [];
|
|
var { [f('x')]:x, [f('y')]:y } = o;
|
|
assertSame(1, x);
|
|
assertSame(2, y);
|
|
assertArrayEquals(["f x", "get x", "f y", "get y"], log);
|
|
}());
|
|
|
|
(function() {
|
|
'use strict';
|
|
log = [];
|
|
let { [f('x')]:x, [f('y')]:y } = o;
|
|
assertSame(1, x);
|
|
assertSame(2, y);
|
|
assertArrayEquals(["f x", "get x", "f y", "get y"], log);
|
|
}());
|
|
|
|
(function() {
|
|
'use strict';
|
|
log = [];
|
|
const { [f('x')]:x, [f('y')]:y } = o;
|
|
assertSame(1, x);
|
|
assertSame(2, y);
|
|
assertArrayEquals(["f x", "get x", "f y", "get y"], log);
|
|
}());
|
|
}());
|
|
|
|
|
|
(function TestExceptions() {
|
|
for (var val of [null, undefined]) {
|
|
assertThrows(function() { var {} = val; }, TypeError);
|
|
assertThrows(function() { var {x} = val; }, TypeError);
|
|
assertThrows(function() { var { x : {} } = { x : val }; }, TypeError);
|
|
assertThrows(function() { 'use strict'; let {} = val; }, TypeError);
|
|
assertThrows(function() { 'use strict'; let {x} = val; }, TypeError);
|
|
assertThrows(function() { 'use strict'; let { x : {} } = { x : val }; },
|
|
TypeError);
|
|
}
|
|
}());
|
|
|
|
|
|
(function TestArrayLiteral() {
|
|
var [a, b, c] = [1, 2, 3];
|
|
assertSame(1, a);
|
|
assertSame(2, b);
|
|
assertSame(3, c);
|
|
}());
|
|
|
|
(function TestIterators() {
|
|
var log = [];
|
|
function* f() {
|
|
log.push("1");
|
|
yield 1;
|
|
log.push("2");
|
|
yield 2;
|
|
log.push("3");
|
|
yield 3;
|
|
log.push("done");
|
|
};
|
|
|
|
(function() {
|
|
log = [];
|
|
var [a, b, c] = f();
|
|
assertSame(1, a);
|
|
assertSame(2, b);
|
|
assertSame(3, c);
|
|
assertArrayEquals(["1", "2", "3"], log);
|
|
}());
|
|
|
|
(function() {
|
|
log = [];
|
|
var [a, b, c, d] = f();
|
|
assertSame(1, a);
|
|
assertSame(2, b);
|
|
assertSame(3, c);
|
|
assertSame(undefined, d);
|
|
assertArrayEquals(["1", "2", "3", "done"], log);
|
|
}());
|
|
|
|
(function() {
|
|
log = [];
|
|
var [a, , c] = f();
|
|
assertSame(1, a);
|
|
assertSame(3, c);
|
|
assertArrayEquals(["1", "2", "3"], log);
|
|
}());
|
|
|
|
(function() {
|
|
log = [];
|
|
var [a, , c, d] = f();
|
|
assertSame(1, a);
|
|
assertSame(3, c);
|
|
assertSame(undefined, d);
|
|
assertArrayEquals(["1", "2", "3", "done"], log);
|
|
}());
|
|
|
|
(function() {
|
|
log = [];
|
|
// last comma is not an elision.
|
|
var [a, b,] = f();
|
|
assertSame(1, a);
|
|
assertSame(2, b);
|
|
assertArrayEquals(["1", "2"], log);
|
|
}());
|
|
|
|
(function() {
|
|
log = [];
|
|
// last comma is not an elision, but the comma before the last is.
|
|
var [a, b, ,] = f();
|
|
assertSame(1, a);
|
|
assertSame(2, b);
|
|
assertArrayEquals(["1", "2", "3"], log);
|
|
}());
|
|
|
|
(function() {
|
|
log = [];
|
|
var [a, ...rest] = f();
|
|
assertSame(1, a);
|
|
assertArrayEquals([2,3], rest);
|
|
assertArrayEquals(["1", "2", "3", "done"], log);
|
|
}());
|
|
|
|
(function() {
|
|
log = [];
|
|
var [a, b, c, ...rest] = f();
|
|
assertSame(1, a);
|
|
assertSame(2, b);
|
|
assertSame(3, c);
|
|
assertArrayEquals([], rest);
|
|
assertArrayEquals(["1", "2", "3", "done"], log);
|
|
}());
|
|
|
|
(function() {
|
|
log = [];
|
|
var [a, b, c, d, ...rest] = f();
|
|
assertSame(1, a);
|
|
assertSame(2, b);
|
|
assertSame(3, c);
|
|
assertSame(undefined, d);
|
|
assertArrayEquals([], rest);
|
|
assertArrayEquals(["1", "2", "3", "done"], log);
|
|
}());
|
|
}());
|
|
|
|
|
|
(function TestIteratorsLexical() {
|
|
'use strict';
|
|
var log = [];
|
|
function* f() {
|
|
log.push("1");
|
|
yield 1;
|
|
log.push("2");
|
|
yield 2;
|
|
log.push("3");
|
|
yield 3;
|
|
log.push("done");
|
|
};
|
|
|
|
(function() {
|
|
log = [];
|
|
let [a, b, c] = f();
|
|
assertSame(1, a);
|
|
assertSame(2, b);
|
|
assertSame(3, c);
|
|
assertArrayEquals(["1", "2", "3"], log);
|
|
}());
|
|
|
|
(function() {
|
|
log = [];
|
|
let [a, b, c, d] = f();
|
|
assertSame(1, a);
|
|
assertSame(2, b);
|
|
assertSame(3, c);
|
|
assertSame(undefined, d);
|
|
assertArrayEquals(["1", "2", "3", "done"], log);
|
|
}());
|
|
|
|
(function() {
|
|
log = [];
|
|
let [a, , c] = f();
|
|
assertSame(1, a);
|
|
assertSame(3, c);
|
|
assertArrayEquals(["1", "2", "3"], log);
|
|
}());
|
|
|
|
(function() {
|
|
log = [];
|
|
let [a, , c, d] = f();
|
|
assertSame(1, a);
|
|
assertSame(3, c);
|
|
assertSame(undefined, d);
|
|
assertArrayEquals(["1", "2", "3", "done"], log);
|
|
}());
|
|
|
|
(function() {
|
|
log = [];
|
|
// last comma is not an elision.
|
|
let [a, b,] = f();
|
|
assertSame(1, a);
|
|
assertSame(2, b);
|
|
assertArrayEquals(["1", "2"], log);
|
|
}());
|
|
|
|
(function() {
|
|
log = [];
|
|
// last comma is not an elision, but the comma before the last is.
|
|
let [a, b, ,] = f();
|
|
assertSame(1, a);
|
|
assertSame(2, b);
|
|
assertArrayEquals(["1", "2", "3"], log);
|
|
}());
|
|
|
|
(function() {
|
|
log = [];
|
|
let [a, ...rest] = f();
|
|
assertSame(1, a);
|
|
assertArrayEquals([2,3], rest);
|
|
assertArrayEquals(["1", "2", "3", "done"], log);
|
|
}());
|
|
|
|
(function() {
|
|
log = [];
|
|
let [a, b, c, ...rest] = f();
|
|
assertSame(1, a);
|
|
assertSame(2, b);
|
|
assertSame(3, c);
|
|
assertArrayEquals([], rest);
|
|
assertArrayEquals(["1", "2", "3", "done"], log);
|
|
}());
|
|
|
|
(function() {
|
|
log = [];
|
|
let [a, b, c, d, ...rest] = f();
|
|
assertSame(1, a);
|
|
assertSame(2, b);
|
|
assertSame(3, c);
|
|
assertSame(undefined, d);
|
|
assertArrayEquals([], rest);
|
|
assertArrayEquals(["1", "2", "3", "done"], log);
|
|
}());
|
|
}());
|
|
|
|
(function TestIteratorsRecursive() {
|
|
var log = [];
|
|
function* f() {
|
|
log.push("1");
|
|
yield {x : 1, y : 2};
|
|
log.push("2");
|
|
yield [42, 27, 30];
|
|
log.push("3");
|
|
yield "abc";
|
|
log.push("done");
|
|
};
|
|
|
|
(function() {
|
|
var [{x, y}, [a, b]] = f();
|
|
assertSame(1, x);
|
|
assertSame(2, y);
|
|
assertSame(42, a);
|
|
assertSame(27, b);
|
|
assertArrayEquals(["1", "2"], log);
|
|
}());
|
|
|
|
(function() {
|
|
'use strict';
|
|
log = [];
|
|
let [{x, y}, [a, b]] = f();
|
|
assertSame(1, x);
|
|
assertSame(2, y);
|
|
assertSame(42, a);
|
|
assertSame(27, b);
|
|
assertArrayEquals(["1", "2"], log);
|
|
}());
|
|
}());
|
|
|
|
|
|
(function TestForEachLexical() {
|
|
'use strict';
|
|
let a = [{x:1, y:-1}, {x:2,y:-2}, {x:3,y:-3}];
|
|
let sumX = 0;
|
|
let sumY = 0;
|
|
let fs = [];
|
|
for (let {x,y} of a) {
|
|
sumX += x;
|
|
sumY += y;
|
|
fs.push({fx : function() { return x; }, fy : function() { return y }});
|
|
}
|
|
assertSame(6, sumX);
|
|
assertSame(-6, sumY);
|
|
assertSame(3, fs.length);
|
|
for (let i = 0; i < fs.length; i++) {
|
|
let {fx,fy} = fs[i];
|
|
assertSame(i+1, fx());
|
|
assertSame(-(i+1), fy());
|
|
}
|
|
|
|
var o = { __proto__:null, 'a1':1, 'b2':2 };
|
|
let sx = '';
|
|
let sy = '';
|
|
for (let [x,y] in o) {
|
|
sx += x;
|
|
sy += y;
|
|
}
|
|
assertEquals('ab', sx);
|
|
assertEquals('12', sy);
|
|
}());
|
|
|
|
|
|
(function TestForEachVars() {
|
|
var a = [{x:1, y:-1}, {x:2,y:-2}, {x:3,y:-3}];
|
|
var sumX = 0;
|
|
var sumY = 0;
|
|
var fs = [];
|
|
for (var {x,y} of a) {
|
|
sumX += x;
|
|
sumY += y;
|
|
fs.push({fx : function() { return x; }, fy : function() { return y }});
|
|
}
|
|
assertSame(6, sumX);
|
|
assertSame(-6, sumY);
|
|
assertSame(3, fs.length);
|
|
for (var i = 0; i < fs.length; i++) {
|
|
var {fx,fy} = fs[i];
|
|
assertSame(3, fx());
|
|
assertSame(-3, fy());
|
|
}
|
|
|
|
var o = { __proto__:null, 'a1':1, 'b2':2 };
|
|
var sx = '';
|
|
var sy = '';
|
|
for (var [x,y] in o) {
|
|
sx += x;
|
|
sy += y;
|
|
}
|
|
assertEquals('ab', sx);
|
|
assertEquals('12', sy);
|
|
}());
|