support destructuring in AssignmentStatement and ForOf loops

This commit is contained in:
Sebastian McKenzie 2014-10-09 22:26:23 +11:00
parent b6e533ec5d
commit 4df2333938
10 changed files with 86 additions and 21 deletions

View File

@ -114,10 +114,10 @@ transform.transformers = {
templateLiterals: require("./transformers/template-literals"),
propertyMethodAssignment: require("./transformers/property-method-assignment"),
defaultParameters: require("./transformers/default-parameters"),
destructuring: require("./transformers/destructuring"),
generators: require("./transformers/generators"),
blockBinding: require("./transformers/block-binding"),
restParameters: require("./transformers/rest-parameters"),
forOf: require("./transformers/for-of"),
destructuring: require("./transformers/destructuring"),
unicodeRegex: require("./transformers/unicode-regex")
};

View File

@ -2,15 +2,14 @@ var util = require("../util");
var b = require("ast-types").builders;
var _ = require("lodash");
var isPattern = function (id) {
return id.type === "ArrayPattern" || id.type === "ObjectPattern";
};
var buildVariableAssign = function (kind, id, init) {
return b.variableDeclaration(kind, [
b.variableDeclarator(id, init)
]);
if (kind === false) {
return b.expressionStatement(b.assignmentExpression("=", id, init));
} else {
return b.variableDeclaration(kind, [
b.variableDeclarator(id, init)
]);
}
};
var push = function (kind, nodes, pattern, parentId) {
@ -26,7 +25,7 @@ var pushObjectPattern = function (kind, nodes, pattern, parentId) {
var pattern2 = prop.value;
var patternId2 = b.memberExpression(parentId, prop.key, false);
if (isPattern(pattern2)) {
if (util.isPattern(pattern2)) {
push(kind, nodes, pattern2, patternId2);
} else {
nodes.push(buildVariableAssign(kind, pattern2, patternId2));
@ -69,7 +68,7 @@ exports.FunctionExpression = function (node, parent, opts, generateUid) {
var nodes = [];
node.params = node.params.map(function (pattern) {
if (!isPattern(pattern)) return pattern;
if (!util.isPattern(pattern)) return pattern;
var parentId = b.identifier(generateUid("ref"));
@ -78,15 +77,35 @@ exports.FunctionExpression = function (node, parent, opts, generateUid) {
return parentId;
});
block.body = nodes.concat(block.body);
block.body = nodes.concat(block.body || []);
};
exports.ExpressionStatement = function (node, parent, opts, generateUid) {
var expr = node.expression;
if (expr.type !== "AssignmentExpression") return;
if (!util.isPattern(expr.left)) return;
var nodes = [];
var ref = b.identifier(generateUid("ref"));
nodes.push(b.variableDeclaration("var", [
b.variableDeclarator(ref, expr.right)
]));
push(false, nodes, expr.left, ref);
return nodes;
};
exports.VariableDeclaration = function (node, parent, opts, generateUid) {
if (parent.type === "ForInStatement") return;
var nodes = [];
var hasPattern = false;
_.each(node.declarations, function (declar) {
if (isPattern(declar.id)) {
if (util.isPattern(declar.id)) {
hasPattern = true;
return false;
}
@ -96,7 +115,7 @@ exports.VariableDeclaration = function (node, parent, opts, generateUid) {
_.each(node.declarations, function (declar) {
var patternId = declar.init;
var pattern = declar.id;
if (isPattern(pattern)) {
if (util.isPattern(pattern) && patternId) {
pushPattern(node.kind, nodes, pattern, patternId, generateUid);
} else {
nodes.push(buildVariableAssign(node.kind, declar.id, declar.init));

View File

@ -1,18 +1,39 @@
var util = require("../util");
var b = require("ast-types").builders;
exports.ForOfStatement = function (node, parent, opts, generateUid) {
var declar;
var isPattern = false;
var key;
if (node.left.type === "VariableDeclaration") {
declar = node.left;
key = declar.declarations[0].id;
} else {
isPattern = true;
declar = node.left[0];
key = b.identifier(generateUid("ref"));
}
var node2 = util.template("for-of", {
ITERATOR_KEY: generateUid("iterator"),
STEP_KEY: generateUid("step"),
OBJECT: node.right,
KEY: node.left.declarations[0].id
KEY: key
});
var block = node2.body;
block.body = block.body.concat(node.body.body);
if (isPattern) {
block.body.push(b.variableDeclaration(declar.kind, [
b.variableDeclarator(declar.declarations[0].id, key)
]));
}
block.body = block.body.concat(node.body.body || []);
var declar = block.body[0];
declar.kind = node.left.kind;
declar.kind = declar.kind;
return node2;
};

View File

@ -11,15 +11,15 @@ _.each(esprima.Syntax, function (name) {
estraverse.VisitorKeys[name] = estraverse.VisitorKeys[name] || [];
});
exports.parse = function (filename, code, callback) {
exports.parse = function (filename, code, callback, opts) {
try {
var ast = esprima.parse(code, {
var ast = esprima.parse(code, _.extend(opts || {}, {
comment: true,
source: filename,
tokens: true,
range: true,
loc: true
});
}));
estraverse.attachComments(ast, ast.comments, ast.tokens);
@ -41,6 +41,10 @@ exports.parse = function (filename, code, callback) {
}
};
exports.isPattern = function (node) {
return node.type === "ArrayPattern" || node.type === "ObjectPattern";
};
exports.generate = function (ast, opts) {
opts = opts || {};
@ -218,6 +222,8 @@ try {
var loc = templatesLoc + "/" + name;
var code = fs.readFileSync(loc, "utf8");
exports.templates[key] = exports.removeProperties(exports.parse(loc, code));
exports.templates[key] = exports.removeProperties(exports.parse(loc, code, null, {
tolerant: true
}));
});
}

View File

@ -0,0 +1 @@
[a, b] = f();

View File

@ -0,0 +1,3 @@
var _ref = f();
a = _ref[0];
b = _ref[1];

View File

@ -0,0 +1,3 @@
for (var [name, value] in obj) {
print("Name: " + name + ", Value: " + value);
}

View File

@ -0,0 +1,4 @@
for (var name in obj) {
var value = obj[name];
print("Name: " + name + ", Value: " + value);
}

View File

@ -0,0 +1,3 @@
for (var [ name, before, after ] of this.test.expectation.registers) {
}

View File

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