fix class computed methods

This commit is contained in:
Sebastian McKenzie
2014-11-04 15:53:36 +11:00
parent d7ae3b506a
commit 5ff6f445b2
5 changed files with 31 additions and 21 deletions

View File

@@ -22,12 +22,12 @@ transform._ensureTransformerNames = function (type, keys) {
transform.transformers = {
modules: require("./transformers/modules"),
computedPropertyNames: require("./transformers/computed-property-names"),
propertyNameShorthand: require("./transformers/property-name-shorthand"),
constants: require("./transformers/constants"),
arrayComprehension: require("./transformers/array-comprehension"),
arrowFunctions: require("./transformers/arrow-functions"),
classes: require("./transformers/classes"),
computedPropertyNames: require("./transformers/computed-property-names"),
spread: require("./transformers/spread"),
templateLiterals: require("./transformers/template-literals"),
propertyMethodAssignment: require("./transformers/property-method-assignment"),

View File

@@ -88,17 +88,17 @@ var buildClassBody = function (opts) {
var classBody = node.body.body;
_.each(classBody, function (node) {
var methodName = node.key.name;
var methodName = node.key;
var method = node.value;
replaceInstanceSuperReferences(superName, method, node, methodName);
replaceInstanceSuperReferences(superName, node);
if (methodName === "constructor") {
if (node.key.name === "constructor") {
if (node.kind === "") {
hasConstructor = true;
addConstructor(constructor, method);
} else {
throw file.errorWithNode(node, "unknown kind for constructor method");
throw file.errorWithNode(node, "illegal kind for constructor method");
}
} else {
var mutatorMap = instanceMutatorMap;
@@ -148,14 +148,16 @@ var buildClassBody = function (opts) {
}
};
var superIdentifier = function (superName, methodNode, methodName, node, parent) {
var superIdentifier = function (superName, methodNode, node, parent) {
var methodName = methodNode.key;
if (parent.property === node) {
return;
} else if (t.isCallExpression(parent) && parent.callee === node) {
// super(); -> ClassName.prototype.MethodName.call(this);
parent.arguments.unshift(t.thisExpression());
if (methodName === "constructor") {
if (methodName.name === "constructor") {
// constructor() { super(); }
return t.memberExpression(superName, t.identifier("call"));
} else {
@@ -166,7 +168,7 @@ var superIdentifier = function (superName, methodNode, methodName, node, parent)
node = t.memberExpression(node, t.identifier("prototype"));
}
node = t.memberExpression(node, t.identifier(methodName));
node = t.memberExpression(node, methodName, methodNode.computed);
return t.memberExpression(node, t.identifier("call"));
}
} else if (t.isMemberExpression(parent) && !methodNode.static) {
@@ -177,12 +179,15 @@ var superIdentifier = function (superName, methodNode, methodName, node, parent)
}
};
var replaceInstanceSuperReferences = function (superName, method, methodNode, methodName) {
var replaceInstanceSuperReferences = function (superName, methodNode) {
var methodName = methodNode.key;
var method = methodNode.value;
superName = superName || t.identifier("Function");
traverse(method, function (node, parent) {
if (t.isIdentifier(node) && node.name === "super") {
return superIdentifier(superName, methodNode, methodName, node, parent);
return superIdentifier(superName, methodNode, node, parent);
} else if (t.isCallExpression(node)) {
var callee = node.callee;
if (!t.isMemberExpression(callee)) return;

View File

@@ -10,7 +10,7 @@ exports.ObjectExpression = function (node, parent, file) {
node.properties = node.properties.filter(function (prop) {
if (prop.kind === "get" || prop.kind === "set") {
util.pushMutatorMap(mutatorMap, prop.key.name, prop.kind, prop.value);
util.pushMutatorMap(mutatorMap, prop.key, prop.kind, prop.value);
return false;
} else {
return true;

View File

@@ -11,7 +11,7 @@
"Literal": ["value"],
"MemberExpression": ["object", "property", "computed"],
"ObjectExpression": ["properties"],
"Property": ["kind", "key", "value"],
"Property": ["kind", "key", "value", "computed"],
"ReturnStatement": ["argument"],
"SequenceExpression": ["expressions"],
"UnaryExpression": ["operator", "argument", "prefix"],

View File

@@ -58,30 +58,35 @@ exports.sourceMapToComment = function (map) {
};
exports.pushMutatorMap = function (mutatorMap, key, kind, method) {
var alias = JSON.stringify(traverse.removeProperties(_.cloneDeep(key)));
var map;
if (_.has(mutatorMap, key)) {
map = mutatorMap[key];
if (_.has(mutatorMap, alias)) {
map = mutatorMap[alias];
} else {
map = {};
}
mutatorMap[key] = map;
mutatorMap[alias] = map;
if (map[kind]) {
throw new Error("a " + kind + " already exists for this property");
} else {
map[kind] = method;
map._key = key;
if (method.computed) {
map._computed = true;
}
map[kind] = method;
};
exports.buildDefineProperties = function (mutatorMap) {
var objExpr = t.objectExpression([]);
_.each(mutatorMap, function (map, key) {
_.each(mutatorMap, function (map) {
var mapNode = t.objectExpression([]);
var propNode = t.property("init", t.identifier(key), mapNode);
var propNode = t.property("init", map._key, mapNode, map._computed);
_.each(map, function (node, key) {
if (key[0] === "_") return;
node = _.clone(node);
if (t.isMethodDefinition(node)) node = node.value;
mapNode.properties.push(t.property("init", t.identifier(key), node));