From 123186003c3d4d6a6ec734dd37e699b043e8b59a Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 13 Jan 2015 01:00:35 +1100 Subject: [PATCH] add support for super instead of closures - fixes #425 --- .../transformers/es6-classes.js | 105 +++++++++++------- 1 file changed, 64 insertions(+), 41 deletions(-) diff --git a/lib/6to5/transformation/transformers/es6-classes.js b/lib/6to5/transformation/transformers/es6-classes.js index 55d09c3c60..15f8b7addc 100644 --- a/lib/6to5/transformation/transformers/es6-classes.js +++ b/lib/6to5/transformation/transformers/es6-classes.js @@ -62,8 +62,8 @@ Class.prototype.run = function () { } this.constructor = constructor; - var closureArgs = []; var closureParams = []; + var closureArgs = []; // @@ -229,54 +229,77 @@ Class.prototype.replaceInstanceSuperReferences = function (methodNode) { var method = methodNode.value; var self = this; - traverse(method, { - enter: function (node, parent) { - var property; - var computed; - var args; + var topLevelThisReference; - if (t.isIdentifier(node, { name: "super" })) { - if (!(t.isMemberExpression(parent) && !parent.computed && parent.property === node)) { - throw self.file.errorWithNode(node, "illegal use of bare super"); + traverse2(method, true); + + if (topLevelThisReference) { + method.body.body.unshift(t.variableDeclaration("var", [ + t.variableDeclarator(topLevelThisReference, t.thisExpression()) + ])); + } + + function traverse2(node, topLevel) { + traverse(node, { + enter: function (node, parent) { + if (t.isFunction(node) && !t.isArrowFunctionExpression(node)) { + traverse2(node, false); + return this.skip(); } - } else if (t.isCallExpression(node)) { - var callee = node.callee; - if (t.isIdentifier(callee, { name: "super" })) { - // super(); -> _get(Object.getPrototypeOf(ClassName), "MethodName", this).call(this); - property = methodNode.key; - computed = methodNode.computed; - args = node.arguments; - } else { - if (!t.isMemberExpression(callee)) return; - if (callee.object.name !== "super") return; - // super.test(); -> _get(Object.getPrototypeOf(ClassName.prototype), "test", this).call(this); - property = callee.property; - computed = callee.computed; - args = node.arguments; + var property; + var computed; + var args; + + if (t.isIdentifier(node, { name: "super" })) { + if (!(t.isMemberExpression(parent) && !parent.computed && parent.property === node)) { + throw self.file.errorWithNode(node, "illegal use of bare super"); + } + } else if (t.isCallExpression(node)) { + var callee = node.callee; + if (t.isIdentifier(callee, { name: "super" })) { + // super(); -> _get(Object.getPrototypeOf(ClassName), "MethodName", this).call(this); + property = methodNode.key; + computed = methodNode.computed; + args = node.arguments; + } else { + if (!t.isMemberExpression(callee)) return; + if (callee.object.name !== "super") return; + + // super.test(); -> _get(Object.getPrototypeOf(ClassName.prototype), "test", this).call(this); + property = callee.property; + computed = callee.computed; + args = node.arguments; + } + } else if (t.isMemberExpression(node)) { + if (!t.isIdentifier(node.object, { name: "super" })) return; + + // super.name; -> _get(Object.getPrototypeOf(ClassName.prototype), "name", this); + property = node.property; + computed = node.computed; } - } else if (t.isMemberExpression(node)) { - if (!t.isIdentifier(node.object, { name: "super" })) return; - // super.name; -> _get(Object.getPrototypeOf(ClassName.prototype), "name", this); - property = node.property; - computed = node.computed; - } + if (property) { + var thisReference; + if (topLevel) { + thisReference = t.thisExpression(); + } else { + topLevelThisReference = thisReference = topLevelThisReference || self.file.generateUidIdentifier("this"); + } - if (property) { - var thisExpression = t.thisExpression(); - var superProperty = self.superProperty(property, methodNode.static, computed, thisExpression); - if (args) { - return t.callExpression( - t.memberExpression(superProperty, t.identifier("call"), false), - [thisExpression].concat(args) - ); - } else { - return superProperty; + var superProperty = self.superProperty(property, methodNode.static, computed, thisReference); + if (args) { + return t.callExpression( + t.memberExpression(superProperty, t.identifier("call"), false), + [thisReference].concat(args) + ); + } else { + return superProperty; + } } } - } - }); + }); + } }; /**