From 5ff6f445b20f9db87cd42e165e749e00abda81a6 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 4 Nov 2014 15:53:36 +1100 Subject: [PATCH] fix class computed methods --- lib/6to5/transform.js | 2 +- lib/6to5/transformers/classes.js | 23 +++++++++++-------- .../property-method-assignment.js | 2 +- lib/6to5/types/builder-keys.json | 2 +- lib/6to5/util.js | 23 +++++++++++-------- 5 files changed, 31 insertions(+), 21 deletions(-) diff --git a/lib/6to5/transform.js b/lib/6to5/transform.js index b734387f86..3cf50a3fd9 100644 --- a/lib/6to5/transform.js +++ b/lib/6to5/transform.js @@ -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"), diff --git a/lib/6to5/transformers/classes.js b/lib/6to5/transformers/classes.js index 80766479f3..49e37fd9ef 100644 --- a/lib/6to5/transformers/classes.js +++ b/lib/6to5/transformers/classes.js @@ -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; diff --git a/lib/6to5/transformers/property-method-assignment.js b/lib/6to5/transformers/property-method-assignment.js index 5fbc5dac48..048d65b7e4 100644 --- a/lib/6to5/transformers/property-method-assignment.js +++ b/lib/6to5/transformers/property-method-assignment.js @@ -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; diff --git a/lib/6to5/types/builder-keys.json b/lib/6to5/types/builder-keys.json index 8a85f2ef0a..fcbd07e2b9 100644 --- a/lib/6to5/types/builder-keys.json +++ b/lib/6to5/types/builder-keys.json @@ -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"], diff --git a/lib/6to5/util.js b/lib/6to5/util.js index 04e4e97ce3..04ced6f323 100644 --- a/lib/6to5/util.js +++ b/lib/6to5/util.js @@ -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));