add experimental es7 object spread/rest - closes #200

This commit is contained in:
Sebastian McKenzie
2014-11-23 21:43:01 +11:00
parent c500532469
commit 3447204d97
23 changed files with 155 additions and 24 deletions

View File

@@ -18,8 +18,16 @@ function File(opts) {
this.ast = {};
}
File.declarations = ["extends", "class-props", "slice", "apply-constructor",
"tagged-template-literal", "interop-require", "to-array"];
File.declarations = [
"extends",
"class-props",
"apply-constructor",
"tagged-template-literal",
"interop-require",
"to-array",
"arguments-to-array",
"object-spread"
];
File.normaliseOptions = function (opts) {
opts = _.cloneDeep(opts || {});
@@ -73,11 +81,14 @@ File.normaliseOptions = function (opts) {
File.prototype.toArray = function (node) {
if (t.isArrayExpression(node)) {
return node;
} else if (t.isIdentifier(node) && node.name === "arguments") {
return t.callExpression(t.memberExpression(this.addDeclaration("slice"), t.identifier("call")), [node]);
} else {
return t.callExpression(this.addDeclaration("to-array"), [node]);
}
var templateName = "to-array";
if (t.isIdentifier(node) && node.name === "arguments") {
templateName = "arguments-to-array";
}
return t.callExpression(this.addDeclaration(templateName), [node]);
};
File.prototype.getModuleFormatter = function (type) {

View File

@@ -4,7 +4,8 @@ exports.Identifier = function (node) {
this.push(node.name);
};
exports.SpreadElement = function (node, print) {
exports.SpreadElement =
exports.SpreadProperty = function (node, print) {
this.push("...");
print(node.argument);
};

View File

@@ -9,6 +9,10 @@ exports.before = {
}
},
SpreadProperty: function (node, parent) {
return exports.before.nodes.Property(node, parent);
},
SwitchCase: function (node, parent) {
if (parent.cases[0] === node) {
return 1;

View File

@@ -38,6 +38,7 @@ _.each({
_propertyLiterals: require("./transformers/_property-literals"),
computedPropertyNames: require("./transformers/es6-computed-property-names"),
objectSpread: require("./transformers/es7-object-spread"),
spread: require("./transformers/es6-spread"),
templateLiterals: require("./transformers/es6-template-literals"),
propertyMethodAssignment: require("./transformers/es5-property-method-assignment"),

View File

@@ -24,14 +24,33 @@ var push = function (opts, nodes, elem, parentId) {
};
var pushObjectPattern = function (opts, nodes, pattern, parentId) {
_.each(pattern.properties, function (prop) {
var pattern2 = prop.value;
var patternId2 = t.memberExpression(parentId, prop.key, prop.computed);
_.each(pattern.properties, function (prop, i) {
if (t.isSpreadProperty(prop)) {
// get all the keys that appear in this object before the current spread
var keys = [];
_.each(pattern.properties, function (prop2, i2) {
if (i2 >= i) return false;
if (t.isSpreadProperty(prop2)) return;
if (t.isPattern(pattern2)) {
push(opts, nodes, pattern2, patternId2);
var key = prop2.key;
if (t.isIdentifier(key)) {
key = t.literal(prop2.key.name);
}
keys.push(key);
});
keys = t.arrayExpression(keys);
var value = t.callExpression(opts.file.addDeclaration("object-spread"), [parentId, keys]);
nodes.push(buildVariableAssign(opts.kind, prop.argument, value));
} else {
nodes.push(buildVariableAssign(opts.kind, pattern2, patternId2));
var pattern2 = prop.value;
var patternId2 = t.memberExpression(parentId, prop.key, prop.computed);
if (t.isPattern(pattern2)) {
push(opts, nodes, pattern2, patternId2);
} else {
nodes.push(buildVariableAssign(opts.kind, pattern2, patternId2));
}
}
});
};

View File

@@ -0,0 +1,41 @@
// https://github.com/sebmarkbage/ecmascript-rest-spread
var t = require("../../types");
var _ = require("lodash");
exports.ObjectExpression = function (node, parent, file) {
var hasSpread = false;
_.each(node.properties, function (prop) {
if (t.isSpreadProperty(prop)) {
hasSpread = true;
return false;
}
});
if (!hasSpread) return;
var args = [];
var props = [];
var push = function () {
if (!props.length) return;
args.push(t.objectExpression(props));
props = [];
};
_.each(node.properties, function (prop) {
if (t.isSpreadProperty(prop)) {
push();
args.push(prop.argument);
} else {
props.push(prop);
}
});
push();
if (!t.isObjectExpression(args[0])) {
args.unshift(t.objectExpression([]));
}
return t.callExpression(t.memberExpression(t.identifier("Object"), t.identifier("assign")), args);
};

View File

@@ -48,6 +48,7 @@
"ReturnStatement": ["argument"],
"SequenceExpression": ["expressions"],
"SpreadElement": ["argument"],
"SpreadProperty": ["argument"],
"SwitchCase": ["test", "consequent"],
"SwitchStatement": ["discriminant", "cases"],
"TaggedTemplateExpression": ["tag", "quasi"],