From 324a4a1b22c5cd6b624d7689f8ec97a8c36eb165 Mon Sep 17 00:00:00 2001 From: Brian Donovan Date: Tue, 6 Jan 2015 08:00:08 -0800 Subject: [PATCH 1/5] Fix super with getters and setters and with class prototypes changing. --- lib/6to5/file.js | 3 +- lib/6to5/transformation/templates/get.js | 23 ++++ .../transformers/es6-classes.js | 120 ++++++++++++++++-- .../accessing-super-class/expected.js | 53 +++++--- .../accessing-super-properties/expected.js | 27 +++- .../calling-super-properties/expected.js | 29 ++++- .../super-function-fallback/expected.js | 27 +++- 7 files changed, 246 insertions(+), 36 deletions(-) create mode 100644 lib/6to5/transformation/templates/get.js diff --git a/lib/6to5/file.js b/lib/6to5/file.js index da5b168fa3..9f73eae828 100644 --- a/lib/6to5/file.js +++ b/lib/6to5/file.js @@ -36,7 +36,8 @@ File.helpers = [ "interop-require-wildcard", "typeof", "exports-wildcard", - "extends" + "extends", + "get" ]; File.excludeHelpersFromRuntime = [ diff --git a/lib/6to5/transformation/templates/get.js b/lib/6to5/transformation/templates/get.js new file mode 100644 index 0000000000..472d5b7481 --- /dev/null +++ b/lib/6to5/transformation/templates/get.js @@ -0,0 +1,23 @@ +(function get(object, property, receiver) { + var desc = Object.getOwnPropertyDescriptor(object, property); + + if (desc === void 0) { + var parent = Object.getPrototypeOf(object); + + if (parent === null) { + return void 0; + } else { + return get(parent); + } + } else if ("value" in desc && "writable" in desc) { + return desc.value; + } else { + var getter = desc.get; + + if (getter === void 0) { + return void 0; + } + + return getter.call(receiver); + } +}); diff --git a/lib/6to5/transformation/transformers/es6-classes.js b/lib/6to5/transformation/transformers/es6-classes.js index f0922ebb8b..ca56cc687d 100644 --- a/lib/6to5/transformation/transformers/es6-classes.js +++ b/lib/6to5/transformation/transformers/es6-classes.js @@ -218,7 +218,7 @@ Class.prototype.pushMethod = function (node) { * Given a `methodNode`, produce a `MemberExpression` super class reference. * * @param {Node} methodNode MethodDefinition - * @param {Node} node Identifier + * @param {Node} id Identifier * @param {Node} parent * * @returns {Node} @@ -227,26 +227,48 @@ Class.prototype.pushMethod = function (node) { Class.prototype.superIdentifier = function (methodNode, id, parent) { var methodName = methodNode.key; var superName = this.superName || t.identifier("Function"); + var className = this.className; if (parent.property === id) { return; } else if (t.isCallExpression(parent, { callee: id })) { - // super(); -> ClassName.prototype.MethodName.call(this); + // super(); -> _get(Object.getPrototypeOf(ClassName.prototype), "MethodName", this).call(this); + var superProto = t.callExpression( + t.memberExpression( + t.identifier("Object"), + t.identifier("getPrototypeOf"), + false + ), + [ + methodNode.static ? + className : + t.memberExpression(className, t.identifier("prototype")) + ] + ); + var superCallee = t.callExpression( + this.file.addHelper("get"), + [ + superProto, + methodNode.computed ? methodName : t.literal(methodName.name), + t.thisExpression() + ] + ); + parent.arguments.unshift(t.thisExpression()); if (methodName.name === "constructor") { // constructor() { super(); } - return t.memberExpression(superName, t.identifier("call")); + return t.memberExpression(superCallee, t.identifier("call")); } else { id = superName; // foo() { super(); } - if (!methodNode.static) { - id = t.memberExpression(id, t.identifier("prototype")); - } + //if (!methodNode.static) { + // id = t.memberExpression(id, t.identifier("prototype")); + //} - id = t.memberExpression(id, methodName, methodNode.computed); - return t.memberExpression(id, t.identifier("call")); + //id = t.memberExpression(id, methodName, methodNode.computed); + return t.memberExpression(superCallee, t.identifier("call")); } } else if (t.isMemberExpression(parent) && !methodNode.static) { // super.test -> ClassName.prototype.test @@ -268,21 +290,93 @@ Class.prototype.replaceInstanceSuperReferences = function (methodNode) { traverse(method, { enter: function (node, parent) { + var property; + var computed; + var args; + if (t.isIdentifier(node, { name: "super" })) { return self.superIdentifier(methodNode, node, parent); } else if (t.isCallExpression(node)) { var callee = node.callee; - if (!t.isMemberExpression(callee)) return; - if (callee.object.name !== "super") return; + if (t.isIdentifier(callee) && 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(); -> ClassName.prototype.MethodName.call(this); - t.appendToMemberExpression(callee, t.identifier("call")); - node.arguments.unshift(t.thisExpression()); + // 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; + } + + if (property) { + var superProperty = self.superProperty(property, methodNode.static, computed); + if (args) { + return t.callExpression( + t.memberExpression(superProperty, t.identifier('call'), false), + [t.thisExpression()].concat(args) + ); + } else { + return superProperty; + } } } }); }; +/** + * Gets a node representing the super class value of the named property. + * + * @example + * + * _get(Object.getPrototypeOf(CLASS.prototype), "METHOD", this) + * + * @param {Node} property + * @param {boolean} isStatic + * @param {boolean} isComputed + * + * @returns {Node} + */ + +Class.prototype.superProperty = function (property, isStatic, isComputed) { + return t.callExpression( + this.file.addHelper('get'), + [ + t.callExpression( + t.memberExpression( + t.identifier('Object'), + t.identifier('getPrototypeOf'), + false + ), + [ + isStatic ? + this.className : + t.memberExpression( + this.className, + t.identifier('prototype'), + false + ) + ] + ), + isComputed ? + property : + t.literal(property.name), + t.thisExpression() + ] + ); +}; + /** * Replace the constructor body of our class. * diff --git a/test/fixtures/transformation/es6-classes/accessing-super-class/expected.js b/test/fixtures/transformation/es6-classes/accessing-super-class/expected.js index 1600d655fb..b7ba571c53 100644 --- a/test/fixtures/transformation/es6-classes/accessing-super-class/expected.js +++ b/test/fixtures/transformation/es6-classes/accessing-super-class/expected.js @@ -1,6 +1,28 @@ "use strict"; var _slice = Array.prototype.slice; +var _get = function get(object, property, receiver) { + var desc = Object.getOwnPropertyDescriptor(object, property); + + if (desc === void 0) { + var parent = Object.getPrototypeOf(object); + + if (parent === null) { + return void 0; + } else { + return get(parent); + } + } else if ("value" in desc && "writable" in desc) { + return desc.value; + } else { + var getter = desc.get; + if (getter === void 0) { + return void 0; + } + return getter.call(receiver); + } +}; + var _inherits = function (child, parent) { if (typeof parent !== "function" && parent !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof parent); @@ -19,34 +41,35 @@ var _inherits = function (child, parent) { var Test = (function () { var _Foo = Foo; var Test = function Test() { - var _Foo$prototype$test, _Foo$prototype$test2; + var _get2, _get3, _get4, _get5; woops["super"].test(); - _Foo.call(this); - _Foo.prototype.test.call(this); + _get(Object.getPrototypeOf(Test.prototype), "constructor", this).call(this); + _get(Object.getPrototypeOf(Test.prototype), "test", this).call(this); foob(_Foo); - _Foo.call.apply(_Foo, [this].concat(_slice.call(arguments))); - _Foo.call.apply(_Foo, [this, "test"].concat(_slice.call(arguments))); + (_get2 = _get(Object.getPrototypeOf(Test.prototype), "constructor", this)).call.apply(_get2, [this].concat(_slice.call(arguments))); + (_get3 = _get(Object.getPrototypeOf(Test.prototype), "constructor", this)).call.apply(_get3, [this, "test"].concat(_slice.call(arguments))); - (_Foo$prototype$test = _Foo.prototype.test).call.apply(_Foo$prototype$test, [this].concat(_slice.call(arguments))); - (_Foo$prototype$test2 = _Foo.prototype.test).call.apply(_Foo$prototype$test2, [this, "test"].concat(_slice.call(arguments))); + (_get4 = _get(Object.getPrototypeOf(Test.prototype), "test", this)).call.apply(_get4, [this].concat(_slice.call(arguments))); + (_get5 = _get(Object.getPrototypeOf(Test.prototype), "test", this)).call.apply(_get5, [this, "test"].concat(_slice.call(arguments))); }; _inherits(Test, _Foo); Test.prototype.test = function () { - var _Foo$prototype$test3, _Foo$prototype$test4; - _Foo.prototype.test.call(this); - (_Foo$prototype$test3 = _Foo.prototype.test).call.apply(_Foo$prototype$test3, [this].concat(_slice.call(arguments))); - (_Foo$prototype$test4 = _Foo.prototype.test).call.apply(_Foo$prototype$test4, [this, "test"].concat(_slice.call(arguments))); + var _get6, _get7; + _get(Object.getPrototypeOf(Test.prototype), "test", this).call(this); + (_get6 = _get(Object.getPrototypeOf(Test.prototype), "test", this)).call.apply(_get6, [this].concat(_slice.call(arguments))); + (_get7 = _get(Object.getPrototypeOf(Test.prototype), "test", this)).call.apply(_get7, [this, "test"].concat(_slice.call(arguments))); }; Test.foo = function () { - var _Foo$foo, _Foo$foo2; - _Foo.foo.call(this); - (_Foo$foo = _Foo.foo).call.apply(_Foo$foo, [this].concat(_slice.call(arguments))); - (_Foo$foo2 = _Foo.foo).call.apply(_Foo$foo2, [this, "test"].concat(_slice.call(arguments))); + var _get8, _get9; + _get(Object.getPrototypeOf(Test), "foo", this).call(this); + (_get8 = _get(Object.getPrototypeOf(Test), "foo", this)).call.apply(_get8, [this].concat(_slice.call(arguments))); + (_get9 = _get(Object.getPrototypeOf(Test), "foo", this)).call.apply(_get9, [this, "test"].concat(_slice.call(arguments))); }; return Test; })(); + diff --git a/test/fixtures/transformation/es6-classes/accessing-super-properties/expected.js b/test/fixtures/transformation/es6-classes/accessing-super-properties/expected.js index 29526be129..280ae65b77 100644 --- a/test/fixtures/transformation/es6-classes/accessing-super-properties/expected.js +++ b/test/fixtures/transformation/es6-classes/accessing-super-properties/expected.js @@ -1,5 +1,27 @@ "use strict"; +var _get = function get(object, property, receiver) { + var desc = Object.getOwnPropertyDescriptor(object, property); + + if (desc === void 0) { + var parent = Object.getPrototypeOf(object); + + if (parent === null) { + return void 0; + } else { + return get(parent); + } + } else if ("value" in desc && "writable" in desc) { + return desc.value; + } else { + var getter = desc.get; + if (getter === void 0) { + return void 0; + } + return getter.call(receiver); + } +}; + var _inherits = function (child, parent) { if (typeof parent !== "function" && parent !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof parent); @@ -18,11 +40,12 @@ var _inherits = function (child, parent) { var Test = (function () { var _Foo = Foo; var Test = function Test() { - _Foo.prototype.test; - _Foo.prototype.test.whatever; + _get(Object.getPrototypeOf(Test.prototype), "test", this); + _get(Object.getPrototypeOf(Test.prototype), "test", this).whatever; }; _inherits(Test, _Foo); return Test; })(); + diff --git a/test/fixtures/transformation/es6-classes/calling-super-properties/expected.js b/test/fixtures/transformation/es6-classes/calling-super-properties/expected.js index 7e8f2bfd43..172db52398 100644 --- a/test/fixtures/transformation/es6-classes/calling-super-properties/expected.js +++ b/test/fixtures/transformation/es6-classes/calling-super-properties/expected.js @@ -1,5 +1,27 @@ "use strict"; +var _get = function get(object, property, receiver) { + var desc = Object.getOwnPropertyDescriptor(object, property); + + if (desc === void 0) { + var parent = Object.getPrototypeOf(object); + + if (parent === null) { + return void 0; + } else { + return get(parent); + } + } else if ("value" in desc && "writable" in desc) { + return desc.value; + } else { + var getter = desc.get; + if (getter === void 0) { + return void 0; + } + return getter.call(receiver); + } +}; + var _inherits = function (child, parent) { if (typeof parent !== "function" && parent !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof parent); @@ -18,15 +40,16 @@ var _inherits = function (child, parent) { var Test = (function () { var _Foo = Foo; var Test = function Test() { - _Foo.prototype.test.whatever(); - _Foo.prototype.test.call(this); + _get(Object.getPrototypeOf(Test.prototype), "test", this).whatever(); + _get(Object.getPrototypeOf(Test.prototype), "test", this).call(this); }; _inherits(Test, _Foo); Test.test = function () { - return _Foo.wow.call(this); + return _get(Object.getPrototypeOf(Test), "wow", this).call(this); }; return Test; })(); + diff --git a/test/fixtures/transformation/es6-classes/super-function-fallback/expected.js b/test/fixtures/transformation/es6-classes/super-function-fallback/expected.js index e17e74db06..390f5a4d4a 100644 --- a/test/fixtures/transformation/es6-classes/super-function-fallback/expected.js +++ b/test/fixtures/transformation/es6-classes/super-function-fallback/expected.js @@ -1,5 +1,28 @@ "use strict"; -var Test = function Test() { - Function.prototype.hasOwnProperty.call(this, "test"); +var _get = function get(object, property, receiver) { + var desc = Object.getOwnPropertyDescriptor(object, property); + + if (desc === void 0) { + var parent = Object.getPrototypeOf(object); + + if (parent === null) { + return void 0; + } else { + return get(parent); + } + } else if ("value" in desc && "writable" in desc) { + return desc.value; + } else { + var getter = desc.get; + if (getter === void 0) { + return void 0; + } + return getter.call(receiver); + } }; + +var Test = function Test() { + _get(Object.getPrototypeOf(Test.prototype), "hasOwnProperty", this).call(this, "test"); +}; + From 5b4d6d7ba9ecc7c0ea02b6422573145c23711dfd Mon Sep 17 00:00:00 2001 From: Brian Donovan Date: Thu, 8 Jan 2015 08:36:16 -0800 Subject: [PATCH 2/5] Replace superIdentifier with superProperty. This also disallows the usage of bare `super` that is not part of a member expression, call expression, or new expression. --- .../transformers/es6-classes.js | 136 +++++------------- .../accessing-super-class/actual.js | 1 - .../accessing-super-class/expected.js | 1 - .../es6-classes/bare-super/actual.js | 5 + .../es6-classes/bare-super/options.json | 3 + 5 files changed, 45 insertions(+), 101 deletions(-) create mode 100644 test/fixtures/transformation/es6-classes/bare-super/actual.js create mode 100644 test/fixtures/transformation/es6-classes/bare-super/options.json diff --git a/lib/6to5/transformation/transformers/es6-classes.js b/lib/6to5/transformation/transformers/es6-classes.js index ca56cc687d..593164be90 100644 --- a/lib/6to5/transformation/transformers/es6-classes.js +++ b/lib/6to5/transformation/transformers/es6-classes.js @@ -215,67 +215,45 @@ Class.prototype.pushMethod = function (node) { }; /** - * Given a `methodNode`, produce a `MemberExpression` super class reference. + * Gets a node representing the super class value of the named property. * - * @param {Node} methodNode MethodDefinition - * @param {Node} id Identifier - * @param {Node} parent + * @example + * + * _get(Object.getPrototypeOf(CLASS.prototype), "METHOD", this) + * + * @param {Node} property + * @param {boolean} isStatic + * @param {boolean} isComputed * * @returns {Node} */ -Class.prototype.superIdentifier = function (methodNode, id, parent) { - var methodName = methodNode.key; - var superName = this.superName || t.identifier("Function"); - var className = this.className; - - if (parent.property === id) { - return; - } else if (t.isCallExpression(parent, { callee: id })) { - // super(); -> _get(Object.getPrototypeOf(ClassName.prototype), "MethodName", this).call(this); - var superProto = t.callExpression( - t.memberExpression( - t.identifier("Object"), - t.identifier("getPrototypeOf"), - false +Class.prototype.superProperty = function (property, isStatic, isComputed) { + return t.callExpression( + this.file.addHelper("get"), + [ + t.callExpression( + t.memberExpression( + t.identifier("Object"), + t.identifier("getPrototypeOf"), + false + ), + [ + isStatic ? + this.className : + t.memberExpression( + this.className, + t.identifier("prototype"), + false + ) + ] ), - [ - methodNode.static ? - className : - t.memberExpression(className, t.identifier("prototype")) - ] - ); - var superCallee = t.callExpression( - this.file.addHelper("get"), - [ - superProto, - methodNode.computed ? methodName : t.literal(methodName.name), - t.thisExpression() - ] - ); - - parent.arguments.unshift(t.thisExpression()); - - if (methodName.name === "constructor") { - // constructor() { super(); } - return t.memberExpression(superCallee, t.identifier("call")); - } else { - id = superName; - - // foo() { super(); } - //if (!methodNode.static) { - // id = t.memberExpression(id, t.identifier("prototype")); - //} - - //id = t.memberExpression(id, methodName, methodNode.computed); - return t.memberExpression(superCallee, t.identifier("call")); - } - } else if (t.isMemberExpression(parent) && !methodNode.static) { - // super.test -> ClassName.prototype.test - return t.memberExpression(superName, t.identifier("prototype")); - } else { - return superName; - } + isComputed ? + property : + t.literal(property.name), + t.thisExpression() + ] + ); }; /** @@ -295,7 +273,9 @@ Class.prototype.replaceInstanceSuperReferences = function (methodNode) { var args; if (t.isIdentifier(node, { name: "super" })) { - return self.superIdentifier(methodNode, node, parent); + 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) && callee.name === "super") { @@ -324,7 +304,7 @@ Class.prototype.replaceInstanceSuperReferences = function (methodNode) { var superProperty = self.superProperty(property, methodNode.static, computed); if (args) { return t.callExpression( - t.memberExpression(superProperty, t.identifier('call'), false), + t.memberExpression(superProperty, t.identifier("call"), false), [t.thisExpression()].concat(args) ); } else { @@ -335,48 +315,6 @@ Class.prototype.replaceInstanceSuperReferences = function (methodNode) { }); }; -/** - * Gets a node representing the super class value of the named property. - * - * @example - * - * _get(Object.getPrototypeOf(CLASS.prototype), "METHOD", this) - * - * @param {Node} property - * @param {boolean} isStatic - * @param {boolean} isComputed - * - * @returns {Node} - */ - -Class.prototype.superProperty = function (property, isStatic, isComputed) { - return t.callExpression( - this.file.addHelper('get'), - [ - t.callExpression( - t.memberExpression( - t.identifier('Object'), - t.identifier('getPrototypeOf'), - false - ), - [ - isStatic ? - this.className : - t.memberExpression( - this.className, - t.identifier('prototype'), - false - ) - ] - ), - isComputed ? - property : - t.literal(property.name), - t.thisExpression() - ] - ); -}; - /** * Replace the constructor body of our class. * diff --git a/test/fixtures/transformation/es6-classes/accessing-super-class/actual.js b/test/fixtures/transformation/es6-classes/accessing-super-class/actual.js index 64b349152c..154d85730b 100644 --- a/test/fixtures/transformation/es6-classes/accessing-super-class/actual.js +++ b/test/fixtures/transformation/es6-classes/accessing-super-class/actual.js @@ -3,7 +3,6 @@ class Test extends Foo { woops.super.test(); super(); super.test(); - foob(super); super(...arguments); super("test", ...arguments); diff --git a/test/fixtures/transformation/es6-classes/accessing-super-class/expected.js b/test/fixtures/transformation/es6-classes/accessing-super-class/expected.js index b7ba571c53..6c99bfd509 100644 --- a/test/fixtures/transformation/es6-classes/accessing-super-class/expected.js +++ b/test/fixtures/transformation/es6-classes/accessing-super-class/expected.js @@ -45,7 +45,6 @@ var Test = (function () { woops["super"].test(); _get(Object.getPrototypeOf(Test.prototype), "constructor", this).call(this); _get(Object.getPrototypeOf(Test.prototype), "test", this).call(this); - foob(_Foo); (_get2 = _get(Object.getPrototypeOf(Test.prototype), "constructor", this)).call.apply(_get2, [this].concat(_slice.call(arguments))); (_get3 = _get(Object.getPrototypeOf(Test.prototype), "constructor", this)).call.apply(_get3, [this, "test"].concat(_slice.call(arguments))); diff --git a/test/fixtures/transformation/es6-classes/bare-super/actual.js b/test/fixtures/transformation/es6-classes/bare-super/actual.js new file mode 100644 index 0000000000..6e053ecf76 --- /dev/null +++ b/test/fixtures/transformation/es6-classes/bare-super/actual.js @@ -0,0 +1,5 @@ +class Test { + constructor() { + console.log(super); + } +} diff --git a/test/fixtures/transformation/es6-classes/bare-super/options.json b/test/fixtures/transformation/es6-classes/bare-super/options.json new file mode 100644 index 0000000000..f878b7f9cd --- /dev/null +++ b/test/fixtures/transformation/es6-classes/bare-super/options.json @@ -0,0 +1,3 @@ +{ + "throws": "illegal use of bare super" +} From 8c478f29bc0a1a780c72c1170fd99b0172c035f1 Mon Sep 17 00:00:00 2001 From: Brian Donovan Date: Thu, 8 Jan 2015 08:52:59 -0800 Subject: [PATCH 3/5] Use `desc.writable` instead of `"writable" in desc` as suggested by @stefanpenner. --- lib/6to5/transformation/templates/get.js | 2 +- .../es6-classes/accessing-super-class/expected.js | 2 +- .../es6-classes/accessing-super-properties/expected.js | 2 +- .../es6-classes/calling-super-properties/expected.js | 2 +- .../es6-classes/super-function-fallback/expected.js | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/6to5/transformation/templates/get.js b/lib/6to5/transformation/templates/get.js index 472d5b7481..d30b217f17 100644 --- a/lib/6to5/transformation/templates/get.js +++ b/lib/6to5/transformation/templates/get.js @@ -9,7 +9,7 @@ } else { return get(parent); } - } else if ("value" in desc && "writable" in desc) { + } else if ("value" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; diff --git a/test/fixtures/transformation/es6-classes/accessing-super-class/expected.js b/test/fixtures/transformation/es6-classes/accessing-super-class/expected.js index 6c99bfd509..a73324009d 100644 --- a/test/fixtures/transformation/es6-classes/accessing-super-class/expected.js +++ b/test/fixtures/transformation/es6-classes/accessing-super-class/expected.js @@ -12,7 +12,7 @@ var _get = function get(object, property, receiver) { } else { return get(parent); } - } else if ("value" in desc && "writable" in desc) { + } else if ("value" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; diff --git a/test/fixtures/transformation/es6-classes/accessing-super-properties/expected.js b/test/fixtures/transformation/es6-classes/accessing-super-properties/expected.js index 280ae65b77..80d88837a8 100644 --- a/test/fixtures/transformation/es6-classes/accessing-super-properties/expected.js +++ b/test/fixtures/transformation/es6-classes/accessing-super-properties/expected.js @@ -11,7 +11,7 @@ var _get = function get(object, property, receiver) { } else { return get(parent); } - } else if ("value" in desc && "writable" in desc) { + } else if ("value" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; diff --git a/test/fixtures/transformation/es6-classes/calling-super-properties/expected.js b/test/fixtures/transformation/es6-classes/calling-super-properties/expected.js index 172db52398..015bca81e1 100644 --- a/test/fixtures/transformation/es6-classes/calling-super-properties/expected.js +++ b/test/fixtures/transformation/es6-classes/calling-super-properties/expected.js @@ -11,7 +11,7 @@ var _get = function get(object, property, receiver) { } else { return get(parent); } - } else if ("value" in desc && "writable" in desc) { + } else if ("value" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; diff --git a/test/fixtures/transformation/es6-classes/super-function-fallback/expected.js b/test/fixtures/transformation/es6-classes/super-function-fallback/expected.js index 390f5a4d4a..b2763dda75 100644 --- a/test/fixtures/transformation/es6-classes/super-function-fallback/expected.js +++ b/test/fixtures/transformation/es6-classes/super-function-fallback/expected.js @@ -11,7 +11,7 @@ var _get = function get(object, property, receiver) { } else { return get(parent); } - } else if ("value" in desc && "writable" in desc) { + } else if ("value" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; From af1912ab7af99a4cfed061e49d7e1ad454410c7f Mon Sep 17 00:00:00 2001 From: Brian Donovan Date: Thu, 8 Jan 2015 09:31:18 -0800 Subject: [PATCH 4/5] Ensure constructors use the current super class. This is an extension of 324a4a1b22c5cd6b624d7689f8ec97a8c36eb165. --- .../templates/class-super-constructor-call.js | 4 ++-- lib/6to5/transformation/transformers/es6-classes.js | 2 +- .../super-class-id-member-expression/expected.js | 8 ++++---- .../transformation/es6-classes/super-class/expected.js | 4 ++-- .../optional-proto-to-assign/class/expected.js | 4 ++-- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/6to5/transformation/templates/class-super-constructor-call.js b/lib/6to5/transformation/templates/class-super-constructor-call.js index c9b822f013..21034b6201 100644 --- a/lib/6to5/transformation/templates/class-super-constructor-call.js +++ b/lib/6to5/transformation/templates/class-super-constructor-call.js @@ -1,3 +1,3 @@ -if (SUPER_NAME !== null) { - SUPER_NAME.apply(this, arguments); +if (Object.getPrototypeOf(CLASS_NAME) !== null) { + Object.getPrototypeOf(CLASS_NAME).apply(this, arguments); } diff --git a/lib/6to5/transformation/transformers/es6-classes.js b/lib/6to5/transformation/transformers/es6-classes.js index 593164be90..9c780bf741 100644 --- a/lib/6to5/transformation/transformers/es6-classes.js +++ b/lib/6to5/transformation/transformers/es6-classes.js @@ -149,7 +149,7 @@ Class.prototype.buildBody = function () { if (!this.hasConstructor && superName && !t.isFalsyExpression(superName)) { constructor.body.body.push(util.template("class-super-constructor-call", { - SUPER_NAME: superName + CLASS_NAME: className }, true)); } diff --git a/test/fixtures/transformation/es6-classes/super-class-id-member-expression/expected.js b/test/fixtures/transformation/es6-classes/super-class-id-member-expression/expected.js index d9a40e4753..a8ecac411b 100644 --- a/test/fixtures/transformation/es6-classes/super-class-id-member-expression/expected.js +++ b/test/fixtures/transformation/es6-classes/super-class-id-member-expression/expected.js @@ -18,8 +18,8 @@ var _inherits = function (child, parent) { var BaseController = (function () { var _Chaplin$Controller = Chaplin.Controller; var BaseController = function BaseController() { - if (_Chaplin$Controller !== null) { - _Chaplin$Controller.apply(this, arguments); + if (Object.getPrototypeOf(BaseController) !== null) { + Object.getPrototypeOf(BaseController).apply(this, arguments); } }; @@ -31,8 +31,8 @@ var BaseController = (function () { var BaseController2 = (function () { var _Chaplin$Controller$Another = Chaplin.Controller.Another; var BaseController2 = function BaseController2() { - if (_Chaplin$Controller$Another !== null) { - _Chaplin$Controller$Another.apply(this, arguments); + if (Object.getPrototypeOf(BaseController2) !== null) { + Object.getPrototypeOf(BaseController2).apply(this, arguments); } }; diff --git a/test/fixtures/transformation/es6-classes/super-class/expected.js b/test/fixtures/transformation/es6-classes/super-class/expected.js index 01534a385f..fdd356cf96 100644 --- a/test/fixtures/transformation/es6-classes/super-class/expected.js +++ b/test/fixtures/transformation/es6-classes/super-class/expected.js @@ -18,8 +18,8 @@ var _inherits = function (child, parent) { var Test = (function () { var _Foo = Foo; var Test = function Test() { - if (_Foo !== null) { - _Foo.apply(this, arguments); + if (Object.getPrototypeOf(Test) !== null) { + Object.getPrototypeOf(Test).apply(this, arguments); } }; diff --git a/test/fixtures/transformation/optional-proto-to-assign/class/expected.js b/test/fixtures/transformation/optional-proto-to-assign/class/expected.js index 2d7d562265..b6517c4263 100644 --- a/test/fixtures/transformation/optional-proto-to-assign/class/expected.js +++ b/test/fixtures/transformation/optional-proto-to-assign/class/expected.js @@ -28,8 +28,8 @@ var _inherits = function (child, parent) { var Foo = (function () { var _Bar = Bar; var Foo = function Foo() { - if (_Bar !== null) { - _Bar.apply(this, arguments); + if (Object.getPrototypeOf(Foo) !== null) { + Object.getPrototypeOf(Foo).apply(this, arguments); } }; From 07131576cf716d4e7c9d354231dba7102d8fbffa Mon Sep 17 00:00:00 2001 From: Brian Donovan Date: Thu, 8 Jan 2015 11:41:53 -0800 Subject: [PATCH 5/5] Use `undefined` instead of `void 0`. --- lib/6to5/transformation/templates/get.js | 8 ++++---- .../es6-classes/accessing-super-class/expected.js | 8 ++++---- .../es6-classes/accessing-super-properties/expected.js | 8 ++++---- .../es6-classes/calling-super-properties/expected.js | 8 ++++---- .../es6-classes/super-function-fallback/expected.js | 8 ++++---- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/lib/6to5/transformation/templates/get.js b/lib/6to5/transformation/templates/get.js index d30b217f17..87e4f7218f 100644 --- a/lib/6to5/transformation/templates/get.js +++ b/lib/6to5/transformation/templates/get.js @@ -1,11 +1,11 @@ (function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); - if (desc === void 0) { + if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { - return void 0; + return undefined; } else { return get(parent); } @@ -14,8 +14,8 @@ } else { var getter = desc.get; - if (getter === void 0) { - return void 0; + if (getter === undefined) { + return undefined; } return getter.call(receiver); diff --git a/test/fixtures/transformation/es6-classes/accessing-super-class/expected.js b/test/fixtures/transformation/es6-classes/accessing-super-class/expected.js index a73324009d..6900d5d283 100644 --- a/test/fixtures/transformation/es6-classes/accessing-super-class/expected.js +++ b/test/fixtures/transformation/es6-classes/accessing-super-class/expected.js @@ -4,11 +4,11 @@ var _slice = Array.prototype.slice; var _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); - if (desc === void 0) { + if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { - return void 0; + return undefined; } else { return get(parent); } @@ -16,8 +16,8 @@ var _get = function get(object, property, receiver) { return desc.value; } else { var getter = desc.get; - if (getter === void 0) { - return void 0; + if (getter === undefined) { + return undefined; } return getter.call(receiver); } diff --git a/test/fixtures/transformation/es6-classes/accessing-super-properties/expected.js b/test/fixtures/transformation/es6-classes/accessing-super-properties/expected.js index 80d88837a8..0afdcd06c1 100644 --- a/test/fixtures/transformation/es6-classes/accessing-super-properties/expected.js +++ b/test/fixtures/transformation/es6-classes/accessing-super-properties/expected.js @@ -3,11 +3,11 @@ var _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); - if (desc === void 0) { + if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { - return void 0; + return undefined; } else { return get(parent); } @@ -15,8 +15,8 @@ var _get = function get(object, property, receiver) { return desc.value; } else { var getter = desc.get; - if (getter === void 0) { - return void 0; + if (getter === undefined) { + return undefined; } return getter.call(receiver); } diff --git a/test/fixtures/transformation/es6-classes/calling-super-properties/expected.js b/test/fixtures/transformation/es6-classes/calling-super-properties/expected.js index 015bca81e1..090e82a9bb 100644 --- a/test/fixtures/transformation/es6-classes/calling-super-properties/expected.js +++ b/test/fixtures/transformation/es6-classes/calling-super-properties/expected.js @@ -3,11 +3,11 @@ var _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); - if (desc === void 0) { + if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { - return void 0; + return undefined; } else { return get(parent); } @@ -15,8 +15,8 @@ var _get = function get(object, property, receiver) { return desc.value; } else { var getter = desc.get; - if (getter === void 0) { - return void 0; + if (getter === undefined) { + return undefined; } return getter.call(receiver); } diff --git a/test/fixtures/transformation/es6-classes/super-function-fallback/expected.js b/test/fixtures/transformation/es6-classes/super-function-fallback/expected.js index b2763dda75..c7fd43b7ff 100644 --- a/test/fixtures/transformation/es6-classes/super-function-fallback/expected.js +++ b/test/fixtures/transformation/es6-classes/super-function-fallback/expected.js @@ -3,11 +3,11 @@ var _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); - if (desc === void 0) { + if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { - return void 0; + return undefined; } else { return get(parent); } @@ -15,8 +15,8 @@ var _get = function get(object, property, receiver) { return desc.value; } else { var getter = desc.get; - if (getter === void 0) { - return void 0; + if (getter === undefined) { + return undefined; } return getter.call(receiver); }