support array destructuring on iterables - fixes #194

This commit is contained in:
Sebastian McKenzie 2014-11-19 21:10:40 +11:00
parent 102a566b1d
commit fb39df71eb
17 changed files with 121 additions and 59 deletions

View File

@ -37,7 +37,7 @@ A polyfill is required for for-of functionality that implements `Symbol` and
adds `prototype[Symbol.iterator]` behaviour to built-ins. Using the polyfills adds `prototype[Symbol.iterator]` behaviour to built-ins. Using the polyfills
specified in [polyfill](polyfill.md) suffices. specified in [polyfill](polyfill.md) suffices.
## Spread ### Array destructuring / Spread
An [ES6 polyfill](polyfill.md) is required in order for spread to work. More An [ES6 polyfill](polyfill.md) is required for spread and array destructuring.
specifically a polyfill for `Array.from`. More specifically a polyfill for `Array.from`.

View File

@ -0,0 +1 @@
Array.from(VALUE);

View File

@ -1,5 +1,6 @@
var t = require("../../types"); var util = require("../../util");
var _ = require("lodash"); var t = require("../../types");
var _ = require("lodash");
var buildVariableAssign = function (kind, id, init) { var buildVariableAssign = function (kind, id, init) {
if (kind === false) { if (kind === false) {
@ -11,45 +12,60 @@ var buildVariableAssign = function (kind, id, init) {
} }
}; };
var push = function (kind, nodes, elem, parentId) { var push = function (opts, nodes, elem, parentId) {
if (t.isObjectPattern(elem)) { if (t.isObjectPattern(elem)) {
pushObjectPattern(kind, nodes, elem, parentId); pushObjectPattern(opts, nodes, elem, parentId);
} else if (t.isArrayPattern(elem)) { } else if (t.isArrayPattern(elem)) {
pushArrayPattern(kind, nodes, elem, parentId); pushArrayPattern(opts, nodes, elem, parentId);
} else if (t.isMemberExpression(elem)) { } else if (t.isMemberExpression(elem)) {
nodes.push(buildVariableAssign(false, elem, parentId)); nodes.push(buildVariableAssign(false, elem, parentId));
} else { } else {
nodes.push(buildVariableAssign(kind, elem, parentId)); nodes.push(buildVariableAssign(opts.kind, elem, parentId));
} }
}; };
var pushObjectPattern = function (kind, nodes, pattern, parentId) { var pushObjectPattern = function (opts, nodes, pattern, parentId) {
_.each(pattern.properties, function (prop) { _.each(pattern.properties, function (prop) {
var pattern2 = prop.value; var pattern2 = prop.value;
var patternId2 = t.memberExpression(parentId, prop.key); var patternId2 = t.memberExpression(parentId, prop.key);
if (t.isPattern(pattern2)) { if (t.isPattern(pattern2)) {
push(kind, nodes, pattern2, patternId2); push(opts, nodes, pattern2, patternId2);
} else { } else {
nodes.push(buildVariableAssign(kind, pattern2, patternId2)); nodes.push(buildVariableAssign(opts.kind, pattern2, patternId2));
} }
}); });
}; };
var pushArrayPattern = function (kind, nodes, pattern, parentId) { var pushArrayPattern = function (opts, nodes, pattern, parentId) {
var _parentId = t.identifier(opts.file.generateUid("ref", opts.scope));
nodes.push(t.variableDeclaration("var", [
t.variableDeclarator(_parentId, util.template("array-from", {
VALUE: parentId
}))
]));
parentId = _parentId;
_.each(pattern.elements, function (elem, i) { _.each(pattern.elements, function (elem, i) {
if (!elem) return; if (!elem) return;
var newPatternId; var newPatternId;
if (t.isSpreadElement(elem)) { if (t.isSpreadElement(elem)) {
newPatternId = t.callExpression(t.memberExpression(parentId, t.identifier("slice")), [t.literal(i)]); newPatternId = util.template("array-from", {
VALUE: parentId
});
if (+i > 0) {
newPatternId = t.callExpression(t.memberExpression(newPatternId, t.identifier("slice")), [t.literal(i)]);
}
elem = elem.argument; elem = elem.argument;
} else { } else {
newPatternId = t.memberExpression(parentId, t.literal(i), true); newPatternId = t.memberExpression(parentId, t.literal(i), true);
} }
push(kind, nodes, elem, newPatternId); push(opts, nodes, elem, newPatternId);
}); });
}; };
@ -71,7 +87,7 @@ var pushPattern = function (opts) {
parentId = key; parentId = key;
} }
push(kind, nodes, pattern, parentId); push(opts, nodes, pattern, parentId);
}; };
exports.ForInStatement = exports.ForInStatement =
@ -89,7 +105,11 @@ exports.ForOfStatement = function (node, parent, file, scope) {
var nodes = []; var nodes = [];
push(declar.kind, nodes, pattern, key); push({
kind: declar.kind,
file: file,
scope: scope
}, nodes, pattern, key);
t.ensureBlock(node); t.ensureBlock(node);
@ -141,7 +161,11 @@ exports.ExpressionStatement = function (node, parent, file, scope) {
t.variableDeclarator(ref, expr.right) t.variableDeclarator(ref, expr.right)
])); ]));
push(false, nodes, expr.left, ref); push({
kind: false,
file: file,
scope: scope
}, nodes, expr.left, ref);
return nodes; return nodes;
}; };

View File

@ -1,13 +1,13 @@
var t = require("../../types"); var util = require("../../util");
var _ = require("lodash"); var t = require("../../types");
var _ = require("lodash");
var getSpreadLiteral = function (spread) { var getSpreadLiteral = function (spread) {
var literal = spread.argument; var literal = spread.argument;
if (!t.isArrayExpression(literal)) { if (!t.isArrayExpression(literal)) {
literal = t.callExpression( literal = util.template("array-from", {
t.memberExpression(t.identifier("Array"), t.identifier("from")), VALUE: literal
[literal] });
);
} }
return literal; return literal;
}; };

View File

@ -2,7 +2,13 @@
var _ref = ["hello", [", ", "junk"], ["world"]]; var _ref = ["hello", [", ", "junk"], ["world"]];
var a = _ref[0]; var _ref2 = Array.from(_ref);
var b = _ref[1][0];
var c = _ref[2][0]; var a = _ref2[0];
var d = _ref[3]; var _ref3 = Array.from(_ref2[1]);
var b = _ref3[0];
var _ref4 = Array.from(_ref2[2]);
var c = _ref4[0];
var d = _ref2[3];

View File

@ -2,5 +2,7 @@
var _ref = f(); var _ref = f();
a = _ref[0]; var _ref2 = Array.from(_ref);
b = _ref[1];
a = _ref2[0];
b = _ref2[1];

View File

@ -2,7 +2,13 @@
var _ref = ["foo", "hello", [", ", "junk"], ["world"]]; var _ref = ["foo", "hello", [", ", "junk"], ["world"]];
var a = _ref[1]; var _ref2 = Array.from(_ref);
var b = _ref[2][0];
var c = _ref[3][0]; var a = _ref2[1];
var d = _ref[4]; var _ref3 = Array.from(_ref2[2]);
var b = _ref3[0];
var _ref4 = Array.from(_ref2[3]);
var c = _ref4[0];
var d = _ref2[4];

View File

@ -1,7 +1,9 @@
"use strict"; "use strict";
for (var _ref in obj) { for (var _ref in obj) {
var name = _ref[0]; var _ref2 = Array.from(_ref);
var value = _ref[1];
var name = _ref2[0];
var value = _ref2[1];
print("Name: " + name + ", Value: " + value); print("Name: " + name + ", Value: " + value);
} }

View File

@ -2,7 +2,9 @@
for (var _iterator = this.test.expectation.registers[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { for (var _iterator = this.test.expectation.registers[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) {
var _ref = _step.value; var _ref = _step.value;
var name = _ref[0]; var _ref2 = Array.from(_ref);
var before = _ref[1];
var after = _ref[2]; var name = _ref2[0];
} var before = _ref2[1];
var after = _ref2[2];
}

View File

@ -2,5 +2,7 @@
var _ref = [1, 2]; var _ref = [1, 2];
this.foo = _ref[0]; var _ref2 = Array.from(_ref);
this.bar = _ref[1];
this.foo = _ref2[0];
this.bar = _ref2[1];

View File

@ -1,6 +1,10 @@
"use strict"; "use strict";
var x1 = rect.topLeft[0]; var _ref = Array.from(rect.topLeft);
var y1 = rect.topLeft[1];
var x2 = rect.bottomRight[0]; var x1 = _ref[0];
var y2 = rect.bottomRight[1]; var y1 = _ref[1];
var _ref2 = Array.from(rect.bottomRight);
var x2 = _ref2[0];
var y2 = _ref2[1];

View File

@ -2,4 +2,4 @@
var x = coords.x; var x = coords.x;
var y = coords.y; var y = coords.y;
var foo = "bar"; var foo = "bar";

View File

@ -3,4 +3,4 @@
var x1 = rect.topLeft.x; var x1 = rect.topLeft.x;
var y1 = rect.topLeft.y; var y1 = rect.topLeft.y;
var x2 = rect.bottomRight.x; var x2 = rect.bottomRight.x;
var y2 = rect.bottomRight.y; var y2 = rect.bottomRight.y;

View File

@ -1,4 +1,4 @@
"use strict"; "use strict";
var x = coords.x; var x = coords.x;
var y = coords.y; var y = coords.y;

View File

@ -15,13 +15,17 @@ function unpackObject(_ref2) {
console.log(unpackObject({ title: "title", author: "author" })); console.log(unpackObject({ title: "title", author: "author" }));
var unpackArray = function (_ref3, _ref4) { var unpackArray = function (_ref3, _ref5) {
var a = _ref3[0]; var _ref4 = Array.from(_ref3);
var b = _ref3[1];
var c = _ref3[2]; var a = _ref4[0];
var x = _ref4[0]; var b = _ref4[1];
var y = _ref4[1]; var c = _ref4[2];
var z = _ref4[2]; var _ref6 = Array.from(_ref5);
var x = _ref6[0];
var y = _ref6[1];
var z = _ref6[2];
return a + b + c; return a + b + c;
}; };

View File

@ -0,0 +1,7 @@
function* f() {
for (var i = 0; i < 3; i++) {
yield i;
}
}
var [...xs] = f();
assert.deepEqual(xs, [0, 1, 2]);

View File

@ -1,9 +1,11 @@
"use strict"; "use strict";
var isSorted = function (_ref) { var isSorted = function (_ref) {
var x = _ref[0]; var _ref2 = Array.from(_ref);
var y = _ref[1];
var wow = _ref.slice(2); var x = _ref2[0];
var y = _ref2[1];
var wow = Array.from(_ref2).slice(2);
if (!zs.length) return true; if (!zs.length) return true;
if (y > x) return isSorted(zs); if (y > x) return isSorted(zs);