From c8139317ee6e2ad7bf4b9c52e3d7699ec24ee5d5 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Mon, 3 Nov 2014 13:09:36 +1100 Subject: [PATCH 1/2] add static property inherit warning for IE <= 9 to README - closes #116 --- README.md | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b9dd9fd937..f74281f289 100644 --- a/README.md +++ b/README.md @@ -102,9 +102,9 @@ map embedded in a comment at the bottom. Compile the entire `src` directory and output it to the `lib` directory. $ 6to5 src --out-dir lib - + Compile the entire `src` directory and output it to the one concatenated file. - + $ 6to5 src --out-file script-compiled.js Pipe a file in via stdin and output it to `script-compiled.js` @@ -283,6 +283,23 @@ If you're inheriting from a class then static properties are inherited from it via [\_\_proto\_\_](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto), this is widely supported but you may run into problems with much older browsers. +**NOTE:** `__proto__` is not supported on IE <= 9 so static properties +**will not** be inherited. A possible workaround is to use `super();`: + +```javascript +class Foo { + static foo() { + + } +} + +class Bar extends Foo { + static foo() { + super(); + } +} +``` + ### Generators The [regenerator runtime](https://github.com/facebook/regenerator/blob/master/runtime.js) From c17878913be6ba8e854c03dcba56ddee996ef092 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Mon, 3 Nov 2014 13:36:23 +1100 Subject: [PATCH 2/2] add classProps declaration to simplify/nicen up class property defining - closes #88 --- lib/6to5/templates/class-props.js | 4 +++ lib/6to5/transformers/classes.js | 20 +++++++++--- .../property-method-assignment.js | 5 ++- lib/6to5/util.js | 7 ++--- .../classes/accessing-super-class/expected.js | 31 +++++++++++-------- .../calling-super-properties/expected.js | 10 ++++-- .../instance-getter-and-setter/expected.js | 9 ++++-- .../classes/instance-getter/expected.js | 9 ++++-- .../classes/instance-method/expected.js | 9 ++++-- .../classes/instance-setter/expected.js | 9 ++++-- .../transformation/classes/static/expected.js | 11 +++++-- .../source-maps/class/expected.js | 9 ++++-- .../source-maps/class/source-mappings.json | 2 +- 13 files changed, 95 insertions(+), 40 deletions(-) create mode 100644 lib/6to5/templates/class-props.js diff --git a/lib/6to5/templates/class-props.js b/lib/6to5/templates/class-props.js new file mode 100644 index 0000000000..2838803875 --- /dev/null +++ b/lib/6to5/templates/class-props.js @@ -0,0 +1,4 @@ +(function (child, staticProps, instanceProps) { + if (staticProps) Object.defineProperties(child, staticProps); + if (instanceProps) Object.defineProperties(child.prototype, instanceProps); +}) diff --git a/lib/6to5/transformers/classes.js b/lib/6to5/transformers/classes.js index 0dac35520e..fac8cd0729 100644 --- a/lib/6to5/transformers/classes.js +++ b/lib/6to5/transformers/classes.js @@ -56,14 +56,14 @@ var buildClass = function (node, file) { container.callee.params.push(superClassCallee); } - buildClassBody(body, className, superName, node); + buildClassBody(file, body, className, superName, node); body.push(returnStatement); return container; }; -var buildClassBody = function (body, className, superName, node) { +var buildClassBody = function (file, body, className, superName, node) { var instanceMutatorMap = {}; var staticMutatorMap = {}; var hasConstructor = false; @@ -105,16 +105,28 @@ var buildClassBody = function (body, className, superName, node) { }, true)); } + var instanceProps; + var staticProps; + if (!_.isEmpty(instanceMutatorMap)) { var protoId = util.template("prototype-identifier", { CLASS_NAME: className }); - body.push(util.buildDefineProperties(instanceMutatorMap, protoId)); + instanceProps = util.buildDefineProperties(instanceMutatorMap, protoId); } if (!_.isEmpty(staticMutatorMap)) { - body.push(util.buildDefineProperties(staticMutatorMap, className)); + staticProps = util.buildDefineProperties(staticMutatorMap, className); + } + + if (instanceProps || staticProps) { + instanceProps = instanceProps || b.literal(null); + staticProps = staticProps || b.literal(null); + + body.push(b.expressionStatement( + b.callExpression(file.addDeclaration("class-props"), [className, staticProps, instanceProps]) + )); } }; diff --git a/lib/6to5/transformers/property-method-assignment.js b/lib/6to5/transformers/property-method-assignment.js index b6e77f23fb..5fbc5dac48 100644 --- a/lib/6to5/transformers/property-method-assignment.js +++ b/lib/6to5/transformers/property-method-assignment.js @@ -24,6 +24,9 @@ exports.ObjectExpression = function (node, parent, file) { return util.template("object-define-properties-closure", { KEY: objId, OBJECT: node, - CONTENT: util.buildDefineProperties(mutatorMap, objId).expression + CONTENT: util.template("object-define-properties", { + OBJECT: objId, + PROPS: util.buildDefineProperties(mutatorMap) + }) }); }; diff --git a/lib/6to5/util.js b/lib/6to5/util.js index 94689c8bfe..2582095ac4 100644 --- a/lib/6to5/util.js +++ b/lib/6to5/util.js @@ -147,7 +147,7 @@ exports.pushMutatorMap = function (mutatorMap, key, kind, method) { } }; -exports.buildDefineProperties = function (mutatorMap, keyNode) { +exports.buildDefineProperties = function (mutatorMap) { var objExpr = b.objectExpression([]); _.each(mutatorMap, function (map, key) { @@ -164,10 +164,7 @@ exports.buildDefineProperties = function (mutatorMap, keyNode) { objExpr.properties.push(propNode); }); - return exports.template("object-define-properties", { - OBJECT: keyNode, - PROPS: objExpr - }, true); + return objExpr; }; exports.template = function (name, nodes, keepExpression) { diff --git a/test/fixtures/transformation/classes/accessing-super-class/expected.js b/test/fixtures/transformation/classes/accessing-super-class/expected.js index f9fa968043..95530b559d 100644 --- a/test/fixtures/transformation/classes/accessing-super-class/expected.js +++ b/test/fixtures/transformation/classes/accessing-super-class/expected.js @@ -1,5 +1,12 @@ "use strict"; + var _slice = Array.prototype.slice; + +var _classProps = function (child, staticProps, instanceProps) { + if (staticProps) Object.defineProperties(child, staticProps); + if (instanceProps) Object.defineProperties(child.prototype, instanceProps); +}; + var _extends = function (child, parent) { child.prototype = Object.create(parent.prototype, { constructor: { @@ -27,7 +34,17 @@ var Test = function(Foo) { _extends(Test, Foo); - Object.defineProperties(Test.prototype, { + _classProps(Test, { + foo: { + writable: true, + + value: function() { + Foo.foo.call(this); + Foo.foo.call.apply(Foo.foo, [this].concat(_slice.call(arguments))); + Foo.foo.call.apply(Foo.foo, [this, "test"].concat(_slice.call(arguments))); + } + } + }, { test: { writable: true, @@ -39,17 +56,5 @@ var Test = function(Foo) { } }); - Object.defineProperties(Test, { - foo: { - writable: true, - - value: function() { - Foo.foo.call(this); - Foo.foo.call.apply(Foo.foo, [this].concat(_slice.call(arguments))); - Foo.foo.call.apply(Foo.foo, [this, "test"].concat(_slice.call(arguments))); - } - } - }); - return Test; }(Foo); diff --git a/test/fixtures/transformation/classes/calling-super-properties/expected.js b/test/fixtures/transformation/classes/calling-super-properties/expected.js index 5bbc5432d7..80824f88ae 100644 --- a/test/fixtures/transformation/classes/calling-super-properties/expected.js +++ b/test/fixtures/transformation/classes/calling-super-properties/expected.js @@ -1,5 +1,10 @@ "use strict"; +var _classProps = function (child, staticProps, instanceProps) { + if (staticProps) Object.defineProperties(child, staticProps); + if (instanceProps) Object.defineProperties(child.prototype, instanceProps); +}; + var _extends = function (child, parent) { child.prototype = Object.create(parent.prototype, { constructor: { @@ -13,7 +18,6 @@ var _extends = function (child, parent) { child.__proto__ = parent; }; - var Test = function(Foo) { var Test = function Test() { Foo.prototype.test.whatever(); @@ -22,7 +26,7 @@ var Test = function(Foo) { _extends(Test, Foo); - Object.defineProperties(Test, { + _classProps(Test, { test: { writable: true, @@ -30,7 +34,7 @@ var Test = function(Foo) { return Foo.wow.call(this); } } - }); + }, null); return Test; }(Foo); diff --git a/test/fixtures/transformation/classes/instance-getter-and-setter/expected.js b/test/fixtures/transformation/classes/instance-getter-and-setter/expected.js index 9a769db762..5ab8570499 100644 --- a/test/fixtures/transformation/classes/instance-getter-and-setter/expected.js +++ b/test/fixtures/transformation/classes/instance-getter-and-setter/expected.js @@ -1,9 +1,14 @@ "use strict"; +var _classProps = function (child, staticProps, instanceProps) { + if (staticProps) Object.defineProperties(child, staticProps); + if (instanceProps) Object.defineProperties(child.prototype, instanceProps); +}; + var Test = function() { var Test = function Test() {}; - Object.defineProperties(Test.prototype, { + _classProps(Test, null, { test: { get: function() { return 5 + 5; @@ -16,4 +21,4 @@ var Test = function() { }); return Test; -}(); \ No newline at end of file +}(); diff --git a/test/fixtures/transformation/classes/instance-getter/expected.js b/test/fixtures/transformation/classes/instance-getter/expected.js index 079333bb38..60aaf32f08 100644 --- a/test/fixtures/transformation/classes/instance-getter/expected.js +++ b/test/fixtures/transformation/classes/instance-getter/expected.js @@ -1,9 +1,14 @@ "use strict"; +var _classProps = function (child, staticProps, instanceProps) { + if (staticProps) Object.defineProperties(child, staticProps); + if (instanceProps) Object.defineProperties(child.prototype, instanceProps); +}; + var Test = function() { var Test = function Test() {}; - Object.defineProperties(Test.prototype, { + _classProps(Test, null, { test: { get: function() { return 5 + 5; @@ -12,4 +17,4 @@ var Test = function() { }); return Test; -}(); \ No newline at end of file +}(); diff --git a/test/fixtures/transformation/classes/instance-method/expected.js b/test/fixtures/transformation/classes/instance-method/expected.js index 6c969044fb..50442620fa 100644 --- a/test/fixtures/transformation/classes/instance-method/expected.js +++ b/test/fixtures/transformation/classes/instance-method/expected.js @@ -1,9 +1,14 @@ "use strict"; +var _classProps = function (child, staticProps, instanceProps) { + if (staticProps) Object.defineProperties(child, staticProps); + if (instanceProps) Object.defineProperties(child.prototype, instanceProps); +}; + var Test = function() { var Test = function Test() {}; - Object.defineProperties(Test.prototype, { + _classProps(Test, null, { test: { writable: true, @@ -14,4 +19,4 @@ var Test = function() { }); return Test; -}(); \ No newline at end of file +}(); diff --git a/test/fixtures/transformation/classes/instance-setter/expected.js b/test/fixtures/transformation/classes/instance-setter/expected.js index a1e757f281..fb1e58c8eb 100644 --- a/test/fixtures/transformation/classes/instance-setter/expected.js +++ b/test/fixtures/transformation/classes/instance-setter/expected.js @@ -1,9 +1,14 @@ "use strict"; +var _classProps = function (child, staticProps, instanceProps) { + if (staticProps) Object.defineProperties(child, staticProps); + if (instanceProps) Object.defineProperties(child.prototype, instanceProps); +}; + var Test = function() { var Test = function Test() {}; - Object.defineProperties(Test.prototype, { + _classProps(Test, null, { test: { set: function(val) { this._test = val; @@ -12,4 +17,4 @@ var Test = function() { }); return Test; -}(); \ No newline at end of file +}(); diff --git a/test/fixtures/transformation/classes/static/expected.js b/test/fixtures/transformation/classes/static/expected.js index 75abf10471..52724c0c1b 100644 --- a/test/fixtures/transformation/classes/static/expected.js +++ b/test/fixtures/transformation/classes/static/expected.js @@ -1,9 +1,14 @@ "use strict"; +var _classProps = function (child, staticProps, instanceProps) { + if (staticProps) Object.defineProperties(child, staticProps); + if (instanceProps) Object.defineProperties(child.prototype, instanceProps); +}; + var A = function() { var A = function A() {}; - Object.defineProperties(A, { + _classProps(A, { a: { writable: true, value: function() {} @@ -13,7 +18,7 @@ var A = function() { get: function() {}, set: function(b) {} } - }); + }, null); return A; -}(); \ No newline at end of file +}(); diff --git a/test/fixtures/transformation/source-maps/class/expected.js b/test/fixtures/transformation/source-maps/class/expected.js index f4598117c3..5742ed5c53 100644 --- a/test/fixtures/transformation/source-maps/class/expected.js +++ b/test/fixtures/transformation/source-maps/class/expected.js @@ -1,9 +1,14 @@ "use strict"; +var _classProps = function (child, staticProps, instanceProps) { + if (staticProps) Object.defineProperties(child, staticProps); + if (instanceProps) Object.defineProperties(child.prototype, instanceProps); +}; + var Test = function() { var Test = function Test() {}; - Object.defineProperties(Test.prototype, { + _classProps(Test, null, { bar: { get: function() { throw new Error("wow"); @@ -15,4 +20,4 @@ var Test = function() { }(); var test = new Test(); -test.bar; \ No newline at end of file +test.bar; diff --git a/test/fixtures/transformation/source-maps/class/source-mappings.json b/test/fixtures/transformation/source-maps/class/source-mappings.json index 259fd68b40..12d95d5042 100644 --- a/test/fixtures/transformation/source-maps/class/source-mappings.json +++ b/test/fixtures/transformation/source-maps/class/source-mappings.json @@ -4,7 +4,7 @@ "column": 11 }, "generated": { - "line": 9, + "line": 17, "column": 15 } }]