diff --git a/src/babel/transformation/templates/class-derived-default-constructor.js b/src/babel/transformation/templates/class-derived-default-constructor.js new file mode 100644 index 0000000000..7f6d7e288d --- /dev/null +++ b/src/babel/transformation/templates/class-derived-default-constructor.js @@ -0,0 +1,3 @@ +(function () { + super(...arguments); +}) diff --git a/src/babel/transformation/templates/class-super-constructor-call-loose.js b/src/babel/transformation/templates/class-super-constructor-call-loose.js deleted file mode 100644 index ab957160f2..0000000000 --- a/src/babel/transformation/templates/class-super-constructor-call-loose.js +++ /dev/null @@ -1,3 +0,0 @@ -if (SUPER_NAME != null) { - SUPER_NAME.apply(this, arguments); -} diff --git a/src/babel/transformation/templates/class-super-constructor-call.js b/src/babel/transformation/templates/class-super-constructor-call.js deleted file mode 100644 index ab957160f2..0000000000 --- a/src/babel/transformation/templates/class-super-constructor-call.js +++ /dev/null @@ -1,3 +0,0 @@ -if (SUPER_NAME != null) { - SUPER_NAME.apply(this, arguments); -} diff --git a/src/babel/transformation/templates/class-super-native-constructor-call.js b/src/babel/transformation/templates/class-super-native-constructor-call.js deleted file mode 100644 index 596467e045..0000000000 --- a/src/babel/transformation/templates/class-super-native-constructor-call.js +++ /dev/null @@ -1,5 +0,0 @@ -if (SUPER_NAME != null) { - var NATIVE_REF = new SUPER_NAME(...arguments); - NATIVE_REF.__proto__ = CLASS_NAME.prototype; - return NATIVE_REF; -} diff --git a/src/babel/transformation/transformers/es6/classes.js b/src/babel/transformation/transformers/es6/classes.js index 5a0e11b936..223ba9834c 100644 --- a/src/babel/transformation/transformers/es6/classes.js +++ b/src/babel/transformation/transformers/es6/classes.js @@ -251,20 +251,43 @@ class ClassTransformer { } } + /** + * https://www.youtube.com/watch?v=fWNaR-rxAic + */ + + constructorMeMaybe() { + if (!this.hasSuper) return; + + var hasConstructor = false; + var paths = this.path.get("body.body"); + + for (var path of (paths: Array)) { + hasConstructor = path.equals("kind", "constructor"); + if (hasConstructor) break; + } + + if (!hasConstructor) { + this.path.get("body").unshiftContainer("body", t.methodDefinition( + t.identifier("constructor"), + util.template("class-derived-default-constructor"), + "constructor" + )); + } + } + /** * Description */ buildBody() { + this.constructorMeMaybe(); + var constructorBody = this.constructorBody; - var classBody = this.node.body.body; + var classBodyPaths = this.path.get("body.body"); var body = this.body; - var classBodyPaths = this.path.get("body").get("body"); - - for (var i = 0; i < classBody.length; i++) { - var node = classBody[i]; - var path = classBodyPaths[i]; + for (var path of (classBodyPaths: Array)) { + var node = path.node; if (node.decorators) { memoiseDecorators(node.decorators, this.scope); @@ -297,16 +320,6 @@ class ClassTransformer { } } - // we have no constructor, but we're a derived class - if (!this.hasConstructor && this.hasSuper) { - var helperName = "class-super-constructor-call"; - if (this.isLoose) helperName += "-loose"; - constructorBody.body.push(util.template(helperName, { - CLASS_NAME: this.classRef, - SUPER_NAME: this.superName - }, true)); - } - // this.placePropertyInitializers(); diff --git a/src/babel/traversal/path/modification.js b/src/babel/traversal/path/modification.js index 22f16a8dbb..9594ae4389 100644 --- a/src/babel/traversal/path/modification.js +++ b/src/babel/traversal/path/modification.js @@ -16,7 +16,7 @@ export function insertBefore(nodes) { } else if (this.isNodeType("Expression") || (this.parentPath.isForStatement() && this.key === "init")) { if (this.node) nodes.push(this.node); this.replaceExpressionWithStatements(nodes); - } else if (this.isNodeType("Statement") || !this.type) { + } else { this._maybePopFromStatements(nodes); if (Array.isArray(this.container)) { return this._containerInsertBefore(nodes); @@ -26,8 +26,6 @@ export function insertBefore(nodes) { } else { throw new Error("We don't know what to do with this node type. We were previously a Statement but we can't fit in here?"); } - } else { - throw new Error("No clue what to do with this node type."); } return [this]; @@ -94,7 +92,7 @@ export function insertAfter(nodes) { nodes.push(t.expressionStatement(temp)); } this.replaceExpressionWithStatements(nodes); - } else if (this.isNodeType("Statement") || !this.type) { + } else { this._maybePopFromStatements(nodes); if (Array.isArray(this.container)) { return this._containerInsertAfter(nodes); @@ -104,8 +102,6 @@ export function insertAfter(nodes) { } else { throw new Error("We don't know what to do with this node type. We were previously a Statement but we can't fit in here?"); } - } else { - throw new Error("No clue what to do with this node type."); } return [this]; diff --git a/test/core/fixtures/transformation/es6.classes-loose/super-class-id-member-expression/expected.js b/test/core/fixtures/transformation/es6.classes-loose/super-class-id-member-expression/expected.js index c71784d934..a7e5700da9 100644 --- a/test/core/fixtures/transformation/es6.classes-loose/super-class-id-member-expression/expected.js +++ b/test/core/fixtures/transformation/es6.classes-loose/super-class-id-member-expression/expected.js @@ -4,9 +4,7 @@ var BaseController = (function (_Chaplin$Controller) { function BaseController() { babelHelpers.classCallCheck(this, BaseController); - if (_Chaplin$Controller != null) { - _Chaplin$Controller.apply(this, arguments); - } + _Chaplin$Controller.call.apply(_Chaplin$Controller, [this].concat(babelHelpers.slice.call(arguments))); } babelHelpers.inherits(BaseController, _Chaplin$Controller); @@ -17,9 +15,7 @@ var BaseController2 = (function (_Chaplin$Controller$Another) { function BaseController2() { babelHelpers.classCallCheck(this, BaseController2); - if (_Chaplin$Controller$Another != null) { - _Chaplin$Controller$Another.apply(this, arguments); - } + _Chaplin$Controller$Another.call.apply(_Chaplin$Controller$Another, [this].concat(babelHelpers.slice.call(arguments))); } babelHelpers.inherits(BaseController2, _Chaplin$Controller$Another); diff --git a/test/core/fixtures/transformation/es6.classes-loose/super-class/expected.js b/test/core/fixtures/transformation/es6.classes-loose/super-class/expected.js index d44d5f9b50..433fc71c72 100644 --- a/test/core/fixtures/transformation/es6.classes-loose/super-class/expected.js +++ b/test/core/fixtures/transformation/es6.classes-loose/super-class/expected.js @@ -4,9 +4,7 @@ var Test = (function (_Foo) { function Test() { babelHelpers.classCallCheck(this, Test); - if (_Foo != null) { - _Foo.apply(this, arguments); - } + _Foo.call.apply(_Foo, [this].concat(babelHelpers.slice.call(arguments))); } babelHelpers.inherits(Test, _Foo); diff --git a/test/core/fixtures/transformation/es6.classes/super-class-anonymous/expected.js b/test/core/fixtures/transformation/es6.classes/super-class-anonymous/expected.js index bde3fbe766..978b895f62 100644 --- a/test/core/fixtures/transformation/es6.classes/super-class-anonymous/expected.js +++ b/test/core/fixtures/transformation/es6.classes/super-class-anonymous/expected.js @@ -3,10 +3,7 @@ var TestEmpty = (function (_ref) { function TestEmpty() { babelHelpers.classCallCheck(this, TestEmpty); - - if (_ref != null) { - _ref.apply(this, arguments); - } + babelHelpers.get(Object.getPrototypeOf(TestEmpty.prototype), "constructor", this).apply(this, arguments); } babelHelpers.inherits(TestEmpty, _ref); @@ -22,10 +19,7 @@ var TestEmpty = (function (_ref) { var TestConstructorOnly = (function (_ref2) { function TestConstructorOnly() { babelHelpers.classCallCheck(this, TestConstructorOnly); - - if (_ref2 != null) { - _ref2.apply(this, arguments); - } + babelHelpers.get(Object.getPrototypeOf(TestConstructorOnly.prototype), "constructor", this).apply(this, arguments); } babelHelpers.inherits(TestConstructorOnly, _ref2); @@ -41,10 +35,7 @@ var TestConstructorOnly = (function (_ref2) { var TestMethodOnly = (function (_ref3) { function TestMethodOnly() { babelHelpers.classCallCheck(this, TestMethodOnly); - - if (_ref3 != null) { - _ref3.apply(this, arguments); - } + babelHelpers.get(Object.getPrototypeOf(TestMethodOnly.prototype), "constructor", this).apply(this, arguments); } babelHelpers.inherits(TestMethodOnly, _ref3); @@ -64,10 +55,7 @@ var TestMethodOnly = (function (_ref3) { var TestConstructorAndMethod = (function (_ref4) { function TestConstructorAndMethod() { babelHelpers.classCallCheck(this, TestConstructorAndMethod); - - if (_ref4 != null) { - _ref4.apply(this, arguments); - } + babelHelpers.get(Object.getPrototypeOf(TestConstructorAndMethod.prototype), "constructor", this).apply(this, arguments); } babelHelpers.inherits(TestConstructorAndMethod, _ref4); @@ -87,10 +75,7 @@ var TestConstructorAndMethod = (function (_ref4) { var TestMultipleMethods = (function (_ref5) { function TestMultipleMethods() { babelHelpers.classCallCheck(this, TestMultipleMethods); - - if (_ref5 != null) { - _ref5.apply(this, arguments); - } + babelHelpers.get(Object.getPrototypeOf(TestMultipleMethods.prototype), "constructor", this).apply(this, arguments); } babelHelpers.inherits(TestMultipleMethods, _ref5); @@ -108,4 +93,4 @@ var TestMultipleMethods = (function (_ref5) { value: function m2() {} }]); return _class5; -})()); +})()); \ No newline at end of file diff --git a/test/core/fixtures/transformation/es6.classes/super-class-id-member-expression/expected.js b/test/core/fixtures/transformation/es6.classes/super-class-id-member-expression/expected.js index c71784d934..3aadfc32b9 100644 --- a/test/core/fixtures/transformation/es6.classes/super-class-id-member-expression/expected.js +++ b/test/core/fixtures/transformation/es6.classes/super-class-id-member-expression/expected.js @@ -3,10 +3,7 @@ var BaseController = (function (_Chaplin$Controller) { function BaseController() { babelHelpers.classCallCheck(this, BaseController); - - if (_Chaplin$Controller != null) { - _Chaplin$Controller.apply(this, arguments); - } + babelHelpers.get(Object.getPrototypeOf(BaseController.prototype), "constructor", this).apply(this, arguments); } babelHelpers.inherits(BaseController, _Chaplin$Controller); @@ -16,10 +13,7 @@ var BaseController = (function (_Chaplin$Controller) { var BaseController2 = (function (_Chaplin$Controller$Another) { function BaseController2() { babelHelpers.classCallCheck(this, BaseController2); - - if (_Chaplin$Controller$Another != null) { - _Chaplin$Controller$Another.apply(this, arguments); - } + babelHelpers.get(Object.getPrototypeOf(BaseController2.prototype), "constructor", this).apply(this, arguments); } babelHelpers.inherits(BaseController2, _Chaplin$Controller$Another); diff --git a/test/core/fixtures/transformation/es6.classes/super-class/expected.js b/test/core/fixtures/transformation/es6.classes/super-class/expected.js index d44d5f9b50..9f13499a4a 100644 --- a/test/core/fixtures/transformation/es6.classes/super-class/expected.js +++ b/test/core/fixtures/transformation/es6.classes/super-class/expected.js @@ -3,10 +3,7 @@ var Test = (function (_Foo) { function Test() { babelHelpers.classCallCheck(this, Test); - - if (_Foo != null) { - _Foo.apply(this, arguments); - } + babelHelpers.get(Object.getPrototypeOf(Test.prototype), "constructor", this).apply(this, arguments); } babelHelpers.inherits(Test, _Foo); diff --git a/test/core/fixtures/transformation/es7.class-properties/derived/expected.js b/test/core/fixtures/transformation/es7.class-properties/derived/expected.js index 1e6b388886..0362065035 100644 --- a/test/core/fixtures/transformation/es7.class-properties/derived/expected.js +++ b/test/core/fixtures/transformation/es7.class-properties/derived/expected.js @@ -3,14 +3,10 @@ var Foo = (function (_Bar) { function Foo() { babelHelpers.classCallCheck(this, Foo); - - if (_Bar != null) { - _Bar.apply(this, arguments); - } - + babelHelpers.get(Object.getPrototypeOf(Foo.prototype), "constructor", this).apply(this, arguments); this.bar = "foo"; } babelHelpers.inherits(Foo, _Bar); return Foo; -})(Bar); +})(Bar); \ No newline at end of file diff --git a/test/core/fixtures/transformation/react/optimisation.react.constant-elements/expected.js b/test/core/fixtures/transformation/react/optimisation.react.constant-elements/expected.js index 73208af7d5..66274bd2b5 100644 --- a/test/core/fixtures/transformation/react/optimisation.react.constant-elements/expected.js +++ b/test/core/fixtures/transformation/react/optimisation.react.constant-elements/expected.js @@ -11,10 +11,7 @@ var _ref = React.createElement( var App = (function (_React$Component) { function App() { babelHelpers.classCallCheck(this, App); - - if (_React$Component != null) { - _React$Component.apply(this, arguments); - } + babelHelpers.get(Object.getPrototypeOf(App.prototype), "constructor", this).apply(this, arguments); } babelHelpers.inherits(App, _React$Component); @@ -39,4 +36,4 @@ var App = (function (_React$Component) { } }]); return App; -})(React.Component); +})(React.Component); \ No newline at end of file diff --git a/test/core/fixtures/transformation/spec.function-name/modules-3/expected.js b/test/core/fixtures/transformation/spec.function-name/modules-3/expected.js index 3970c63d32..7cd9ac5a1a 100644 --- a/test/core/fixtures/transformation/spec.function-name/modules-3/expected.js +++ b/test/core/fixtures/transformation/spec.function-name/modules-3/expected.js @@ -9,10 +9,7 @@ var _store = require("./store"); var Login = (function (_React$Component) { function Login() { babelHelpers.classCallCheck(this, Login); - - if (_React$Component != null) { - _React$Component.apply(this, arguments); - } + babelHelpers.get(Object.getPrototypeOf(Login.prototype), "constructor", this).apply(this, arguments); } babelHelpers.inherits(Login, _React$Component); @@ -26,4 +23,4 @@ var Login = (function (_React$Component) { })(React.Component); exports["default"] = Login; -module.exports = exports["default"]; +module.exports = exports["default"]; \ No newline at end of file diff --git a/test/core/fixtures/transformation/spec.proto-to-assign/class/expected.js b/test/core/fixtures/transformation/spec.proto-to-assign/class/expected.js index 51c77f4361..d308a11edc 100644 --- a/test/core/fixtures/transformation/spec.proto-to-assign/class/expected.js +++ b/test/core/fixtures/transformation/spec.proto-to-assign/class/expected.js @@ -1,5 +1,7 @@ "use strict"; +var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; + function _defaults(obj, defaults) { var keys = Object.getOwnPropertyNames(defaults); for (var i = 0; i < keys.length; i++) { var key = keys[i]; var value = Object.getOwnPropertyDescriptor(defaults, key); if (value && value.configurable && obj[key] === undefined) { Object.defineProperty(obj, key, value); } } return obj; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } @@ -10,9 +12,7 @@ var Foo = (function (_Bar) { function Foo() { _classCallCheck(this, Foo); - if (_Bar != null) { - _Bar.apply(this, arguments); - } + _get(Object.getPrototypeOf(Foo.prototype), "constructor", this).apply(this, arguments); } _inherits(Foo, _Bar);