add classesFastSuper optional transformer - fixes #451
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
(function () {
|
||||
if (SUPER_NAME != null) {
|
||||
SUPER_NAME.apply(this, arguments);
|
||||
}
|
||||
});
|
||||
@@ -58,6 +58,7 @@ _.each({
|
||||
arrayComprehension: require("./transformers/es7-array-comprehension"),
|
||||
generatorComprehension: require("./transformers/es7-generator-comprehension"),
|
||||
arrowFunctions: require("./transformers/es6-arrow-functions"),
|
||||
classesFastSuper: require("./transformers/optional-classes-fast-super"),
|
||||
classes: require("./transformers/es6-classes"),
|
||||
|
||||
objectSpread: require("./transformers/es7-object-spread"),
|
||||
|
||||
@@ -291,7 +291,7 @@ Class.prototype.replaceInstanceSuperReferences = function (methodNode) {
|
||||
*/
|
||||
|
||||
Class.prototype.pushConstructor = function (method) {
|
||||
if (method.kind !== "") {
|
||||
if (method.kind) {
|
||||
throw this.file.errorWithNode(method, "illegal kind for constructor method");
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
var traverse = require("../../traverse");
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
|
||||
exports.optional = true;
|
||||
|
||||
exports.Class = function (node) {
|
||||
var superClass = node.superClass || t.identifier("Function");
|
||||
|
||||
var hasConstructor = false;
|
||||
var body = node.body.body;
|
||||
|
||||
for (var i in body) {
|
||||
var methodNode = body[i];
|
||||
|
||||
hasConstructor = hasConstructor || methodNode.key.name === "constructor";
|
||||
|
||||
traverse(methodNode, {
|
||||
enter: function (node, parent) {
|
||||
if (t.isIdentifier(node, { name: "super" })) {
|
||||
return superIdentifier(superClass, methodNode, node, parent);
|
||||
} else if (t.isCallExpression(node)) {
|
||||
var callee = node.callee;
|
||||
if (!t.isMemberExpression(callee)) return;
|
||||
if (callee.object.name !== "super") return;
|
||||
|
||||
// super.test(); -> ClassName.prototype.MethodName.call(this);
|
||||
t.appendToMemberExpression(callee, t.identifier("call"));
|
||||
node.arguments.unshift(t.thisExpression());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (node.superClass && !hasConstructor) {
|
||||
body.unshift(t.methodDefinition(
|
||||
t.identifier("constructor"),
|
||||
util.template("class-super-constructor-call-fast", {
|
||||
SUPER_NAME: superClass
|
||||
})
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
var superIdentifier = function (superClass, methodNode, id, parent) {
|
||||
var methodName = methodNode.key;
|
||||
|
||||
if (parent.property === id) {
|
||||
return;
|
||||
} else if (t.isCallExpression(parent, { callee: id })) {
|
||||
// super(); -> ClassName.prototype.MethodName.call(this);
|
||||
parent.arguments.unshift(t.thisExpression());
|
||||
|
||||
if (methodName.name === "constructor") {
|
||||
// constructor() { super(); }
|
||||
return t.memberExpression(superClass, t.identifier("call"));
|
||||
} else {
|
||||
id = superClass;
|
||||
|
||||
// foo() { super(); }
|
||||
if (!methodNode.static) {
|
||||
id = t.memberExpression(id, t.identifier("prototype"));
|
||||
}
|
||||
|
||||
id = t.memberExpression(id, methodName, methodNode.computed);
|
||||
return t.memberExpression(id, t.identifier("call"));
|
||||
}
|
||||
} else if (t.isMemberExpression(parent) && !methodNode.static) {
|
||||
// super.test -> ClassName.prototype.test
|
||||
return t.memberExpression(superClass, t.identifier("prototype"));
|
||||
} else {
|
||||
return superClass;
|
||||
}
|
||||
};
|
||||
@@ -16,6 +16,7 @@
|
||||
"Literal": ["value"],
|
||||
"LogicalExpression": ["operator", "left", "right"],
|
||||
"MemberExpression": ["object", "property", "computed"],
|
||||
"MethodDefinition": ["key", "value", "computed", "kind"],
|
||||
"NewExpression": ["callee", "arguments"],
|
||||
"ObjectExpression": ["properties"],
|
||||
"Program": ["body"],
|
||||
|
||||
Reference in New Issue
Block a user