From 123186003c3d4d6a6ec734dd37e699b043e8b59a Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 13 Jan 2015 01:00:35 +1100 Subject: [PATCH 01/51] 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; + } } } - } - }); + }); + } }; /** From 831b420df3ddd27056f4a47022a17107293fc033 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 13 Jan 2015 01:09:10 +1100 Subject: [PATCH 02/51] special case single super method call with spread, fixes #227 --- .../transformers/es6-classes.js | 16 ++++++++++---- .../accessing-super-class/expected.js | 22 +++++++++---------- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/lib/6to5/transformation/transformers/es6-classes.js b/lib/6to5/transformation/transformers/es6-classes.js index 15f8b7addc..8fcf90c7ba 100644 --- a/lib/6to5/transformation/transformers/es6-classes.js +++ b/lib/6to5/transformation/transformers/es6-classes.js @@ -289,10 +289,18 @@ Class.prototype.replaceInstanceSuperReferences = function (methodNode) { var superProperty = self.superProperty(property, methodNode.static, computed, thisReference); if (args) { - return t.callExpression( - t.memberExpression(superProperty, t.identifier("call"), false), - [thisReference].concat(args) - ); + if (args.length === 1 && t.isSpreadElement(args[0])) { + // super(...arguments); + return t.callExpression( + t.memberExpression(superProperty, t.identifier("apply"), false), + [thisReference, args[0].argument] + ); + } else { + return t.callExpression( + t.memberExpression(superProperty, t.identifier("call"), false), + [thisReference].concat(args) + ); + } } else { return superProperty; } 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 d467b433f5..a762c97203 100644 --- a/test/fixtures/transformation/es6-classes/accessing-super-class/expected.js +++ b/test/fixtures/transformation/es6-classes/accessing-super-class/expected.js @@ -45,16 +45,16 @@ var _inherits = function (subClass, superClass) { var Test = (function (Foo) { function Test() { - var _get2, _get3, _get4, _get5; + var _get2, _get3; woops["super"].test(); _get(Object.getPrototypeOf(Test.prototype), "constructor", this).call(this); _get(Object.getPrototypeOf(Test.prototype), "test", this).call(this); - (_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))); + _get(Object.getPrototypeOf(Test.prototype), "constructor", this).apply(this, arguments); + (_get2 = _get(Object.getPrototypeOf(Test.prototype), "constructor", this)).call.apply(_get2, [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))); + _get(Object.getPrototypeOf(Test.prototype), "test", this).apply(this, arguments); + (_get3 = _get(Object.getPrototypeOf(Test.prototype), "test", this)).call.apply(_get3, [this, "test"].concat(_slice.call(arguments))); } _inherits(Test, Foo); @@ -62,10 +62,10 @@ var Test = (function (Foo) { _prototypeProperties(Test, { foo: { value: function () { - var _get6, _get7; + var _get4; _get(Object.getPrototypeOf(Test), "foo", this).call(this); - (_get6 = _get(Object.getPrototypeOf(Test), "foo", this)).call.apply(_get6, [this].concat(_slice.call(arguments))); - (_get7 = _get(Object.getPrototypeOf(Test), "foo", this)).call.apply(_get7, [this, "test"].concat(_slice.call(arguments))); + _get(Object.getPrototypeOf(Test), "foo", this).apply(this, arguments); + (_get4 = _get(Object.getPrototypeOf(Test), "foo", this)).call.apply(_get4, [this, "test"].concat(_slice.call(arguments))); }, writable: true, enumerable: true, @@ -74,10 +74,10 @@ var Test = (function (Foo) { }, { test: { value: function () { - var _get8, _get9; + var _get5; _get(Object.getPrototypeOf(Test.prototype), "test", this).call(this); - (_get8 = _get(Object.getPrototypeOf(Test.prototype), "test", this)).call.apply(_get8, [this].concat(_slice.call(arguments))); - (_get9 = _get(Object.getPrototypeOf(Test.prototype), "test", this)).call.apply(_get9, [this, "test"].concat(_slice.call(arguments))); + _get(Object.getPrototypeOf(Test.prototype), "test", this).apply(this, arguments); + (_get5 = _get(Object.getPrototypeOf(Test.prototype), "test", this)).call.apply(_get5, [this, "test"].concat(_slice.call(arguments))); }, writable: true, enumerable: true, From df9fa32b8281f84f349f8438b0ec756e035f9f57 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 13 Jan 2015 01:12:14 +1100 Subject: [PATCH 03/51] add optional to keep module id extensions - fixes #420 --- bin/6to5/index.js | 28 +++++++++-------- lib/6to5/file.js | 33 +++++++++++---------- lib/6to5/transformation/modules/_default.js | 6 ++-- 3 files changed, 36 insertions(+), 31 deletions(-) diff --git a/bin/6to5/index.js b/bin/6to5/index.js index 09d7925e43..ea5cc727d5 100755 --- a/bin/6to5/index.js +++ b/bin/6to5/index.js @@ -26,6 +26,7 @@ commander.option("-a, --amd-module-ids", "Insert module id in AMD modules", fals commander.option("-m, --module-ids", "Insert module id in modules", false); commander.option("-R, --react-compat", "Makes the react transformer produce pre-v0.12 code"); commander.option("-E, --include-regenerator", "Include the regenerator runtime if necessary", false); +commander.option("--keep-module-id-extensions", "Keep extensions when generating module ids", false); commander.on("--help", function(){ var outKeys = function (title, obj) { @@ -101,19 +102,20 @@ if (errors.length) { // exports.opts = { - includeRegenerator: commander.includeRegenerator, - sourceMapName: commander.outFile, - experimental: commander.experimental, - reactCompat: commander.reactCompat, - playground: commander.playground, - moduleIds: commander.amdModuleIds || commander.moduleIds, - blacklist: commander.blacklist, - whitelist: commander.whitelist, - sourceMap: commander.sourceMaps || commander.sourceMapsInline, - optional: commander.optional, - comments: !commander.removeComments, - runtime: commander.runtime, - modules: commander.modules, + keepModuleIdExtensions: commander.keepModuleIdExtensions, + includeRegenerator: commander.includeRegenerator, + sourceMapName: commander.outFile, + experimental: commander.experimental, + reactCompat: commander.reactCompat, + playground: commander.playground, + moduleIds: commander.amdModuleIds || commander.moduleIds, + blacklist: commander.blacklist, + whitelist: commander.whitelist, + sourceMap: commander.sourceMaps || commander.sourceMapsInline, + optional: commander.optional, + comments: !commander.removeComments, + runtime: commander.runtime, + modules: commander.modules, format: { indent: { style: util.repeat(parseInt(commander.indent)) diff --git a/lib/6to5/file.js b/lib/6to5/file.js index 17d29b3e99..70a0b900b6 100644 --- a/lib/6to5/file.js +++ b/lib/6to5/file.js @@ -48,22 +48,23 @@ File.normaliseOptions = function (opts) { opts = _.cloneDeep(opts || {}); _.defaults(opts, { - includeRegenerator: false, - experimental: false, - reactCompat: false, - playground: false, - whitespace: true, - moduleIds: opts.amdModuleIds || false, - blacklist: [], - whitelist: [], - sourceMap: false, - optional: [], - comments: true, - filename: "unknown", - modules: "common", - runtime: false, - code: true, - ast: true + keepModuleIdExtensions: false, + includeRegenerator: false, + experimental: false, + reactCompat: false, + playground: false, + whitespace: true, + moduleIds: opts.amdModuleIds || false, + blacklist: [], + whitelist: [], + sourceMap: false, + optional: [], + comments: true, + filename: "unknown", + modules: "common", + runtime: false, + code: true, + ast: true }); // normalise windows path separators to unix diff --git a/lib/6to5/transformation/modules/_default.js b/lib/6to5/transformation/modules/_default.js index a70db37f50..5e8ceb12a7 100644 --- a/lib/6to5/transformation/modules/_default.js +++ b/lib/6to5/transformation/modules/_default.js @@ -156,8 +156,10 @@ DefaultFormatter.prototype.getModuleName = function () { filenameRelative = filenameRelative.replace(sourceRootRegEx, ""); } - // remove extension - filenameRelative = filenameRelative.replace(/\.(.*?)$/, ""); + if (!opts.keepModuleIdExtensions) { + // remove extension + filenameRelative = filenameRelative.replace(/\.(.*?)$/, ""); + } moduleName += filenameRelative; From 02a50c9f7ee0d27e7ea9609e850fb405d386b51e Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 13 Jan 2015 01:16:00 +1100 Subject: [PATCH 04/51] fix unnecessary default parameter iife - fixes #251 --- lib/6to5/transformation/transformers/es6-default-parameters.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/6to5/transformation/transformers/es6-default-parameters.js b/lib/6to5/transformation/transformers/es6-default-parameters.js index ba3c0ad631..eb7b6fc1b3 100644 --- a/lib/6to5/transformation/transformers/es6-default-parameters.js +++ b/lib/6to5/transformation/transformers/es6-default-parameters.js @@ -31,7 +31,7 @@ exports.Function = function (node, parent, file, scope) { throw file.errorWithNode(node, "Temporal dead zone - accessing a variable before it's initialized"); } - if (scope.has(node.name)) { + if (scope.has(node.name, true)) { iife = true; } }; From afd5376c8d7380e0d29f227597501d4be177deab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alu=C3=ADsio=20Augusto=20Silva=20Gon=C3=A7alves?= Date: Mon, 12 Jan 2015 12:29:37 -0200 Subject: [PATCH 05/51] Whitelist constructors aliasable to core-js Expand the list of identifiers for which we substitute `_core.` for ``. Also an alternative fix for #421. --- .../transformers/optional-core-aliasing.js | 14 ++++++++++++-- .../aliased-constructors/actual.js | 7 +++++++ .../expected.js | 7 ++++++- .../ignore-natives/actual.js | 1 - .../ignore-natives/expected.js | 9 --------- .../optional-core-aliasing/map-symbol/actual.js | 2 -- 6 files changed, 25 insertions(+), 15 deletions(-) create mode 100644 test/fixtures/transformation/optional-core-aliasing/aliased-constructors/actual.js rename test/fixtures/transformation/optional-core-aliasing/{map-symbol => aliased-constructors}/expected.js (70%) delete mode 100644 test/fixtures/transformation/optional-core-aliasing/ignore-natives/actual.js delete mode 100644 test/fixtures/transformation/optional-core-aliasing/ignore-natives/expected.js delete mode 100644 test/fixtures/transformation/optional-core-aliasing/map-symbol/actual.js diff --git a/lib/6to5/transformation/transformers/optional-core-aliasing.js b/lib/6to5/transformation/transformers/optional-core-aliasing.js index 806ddb5cfb..6f97bd2c99 100644 --- a/lib/6to5/transformation/transformers/optional-core-aliasing.js +++ b/lib/6to5/transformation/transformers/optional-core-aliasing.js @@ -8,6 +8,16 @@ var coreHas = function (node) { return node.name !== "_" && _.has(core, node.name); }; +var ALIASABLE_CONSTRUCTORS = [ + "Symbol", + "Promise", + "Map", + "WeakMap", + "Set", + "WeakSet", + "Dict", +]; + exports.optional = true; exports.ast = { @@ -31,8 +41,8 @@ exports.ast = { this.skip(); return t.prependToMemberExpression(node, file._coreId); } - } else if (t.isIdentifier(node) && !t.isMemberExpression(parent) && t.isReferenced(node, parent) && node.name === "Symbol") { - // new Symbol -> new _core.Symbol + } else if (t.isIdentifier(node) && !t.isMemberExpression(parent) && t.isReferenced(node, parent) && _.contains(ALIASABLE_CONSTRUCTORS, node.name)) { + // Symbol() -> _core.Symbol(); new Promise -> new _core.Promise return t.memberExpression(file._coreId, node); } else if (t.isCallExpression(node)) { // arr[Symbol.iterator]() -> _core.$for.getIterator(arr) diff --git a/test/fixtures/transformation/optional-core-aliasing/aliased-constructors/actual.js b/test/fixtures/transformation/optional-core-aliasing/aliased-constructors/actual.js new file mode 100644 index 0000000000..b7c61b92b0 --- /dev/null +++ b/test/fixtures/transformation/optional-core-aliasing/aliased-constructors/actual.js @@ -0,0 +1,7 @@ +obj.constructor === Object; +obj.constructor === Promise; + +Symbol(); +Symbol("test"); + +new Map(); diff --git a/test/fixtures/transformation/optional-core-aliasing/map-symbol/expected.js b/test/fixtures/transformation/optional-core-aliasing/aliased-constructors/expected.js similarity index 70% rename from test/fixtures/transformation/optional-core-aliasing/map-symbol/expected.js rename to test/fixtures/transformation/optional-core-aliasing/aliased-constructors/expected.js index d67311567b..7c6e3f9ba2 100644 --- a/test/fixtures/transformation/optional-core-aliasing/map-symbol/expected.js +++ b/test/fixtures/transformation/optional-core-aliasing/aliased-constructors/expected.js @@ -6,5 +6,10 @@ var _interopRequire = function (obj) { var _core = _interopRequire(require("core-js/library")); -_core.Symbol("test"); +obj.constructor === Object; +obj.constructor === _core.Promise; + _core.Symbol(); +_core.Symbol("test"); + +new _core.Map(); diff --git a/test/fixtures/transformation/optional-core-aliasing/ignore-natives/actual.js b/test/fixtures/transformation/optional-core-aliasing/ignore-natives/actual.js deleted file mode 100644 index 60fe1ccd57..0000000000 --- a/test/fixtures/transformation/optional-core-aliasing/ignore-natives/actual.js +++ /dev/null @@ -1 +0,0 @@ -obj.constructor === Object; diff --git a/test/fixtures/transformation/optional-core-aliasing/ignore-natives/expected.js b/test/fixtures/transformation/optional-core-aliasing/ignore-natives/expected.js deleted file mode 100644 index 9ce5ba07b1..0000000000 --- a/test/fixtures/transformation/optional-core-aliasing/ignore-natives/expected.js +++ /dev/null @@ -1,9 +0,0 @@ -"use strict"; - -var _interopRequire = function (obj) { - return obj && (obj["default"] || obj); -}; - -var _core = _interopRequire(require("core-js/library")); - -obj.constructor === Object; diff --git a/test/fixtures/transformation/optional-core-aliasing/map-symbol/actual.js b/test/fixtures/transformation/optional-core-aliasing/map-symbol/actual.js deleted file mode 100644 index 5ebaadcd41..0000000000 --- a/test/fixtures/transformation/optional-core-aliasing/map-symbol/actual.js +++ /dev/null @@ -1,2 +0,0 @@ -Symbol("test"); -Symbol(); From eabbcd31ad34d27875acdd188ee1589fcfc2bc7a Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 13 Jan 2015 01:50:10 +1100 Subject: [PATCH 06/51] add comments to ambiguous code --- lib/6to5/transformation/modules/umd.js | 12 +++++++-- lib/6to5/transformation/transformers/react.js | 25 +++++++++++++------ 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/lib/6to5/transformation/modules/umd.js b/lib/6to5/transformation/modules/umd.js index 32dde9759a..f3933da7ce 100644 --- a/lib/6to5/transformation/modules/umd.js +++ b/lib/6to5/transformation/modules/umd.js @@ -31,15 +31,17 @@ UMDFormatter.prototype.transform = function (ast) { var factory = t.functionExpression(null, args, t.blockStatement(body)); - // runner + // amd var defineArgs = [t.literal("exports")]; if (this.passModuleArg) defineArgs.push(t.literal("module")); defineArgs = defineArgs.concat(names); defineArgs = [t.arrayExpression(defineArgs)]; + // common + var testExports = util.template("test-exports"); - var testModule = util.template("test-module"); + var testModule = util.template("test-module"); var commonTests = this.passModuleArg ? t.logicalExpression("&&", testExports, testModule) : testExports; var commonArgs = [t.identifier("exports")]; @@ -48,6 +50,12 @@ UMDFormatter.prototype.transform = function (ast) { return t.callExpression(t.identifier("require"), [name]); })); + // globals + + var umdArgs = []; + + // + var moduleName = this.getModuleName(); if (moduleName) defineArgs.unshift(t.literal(moduleName)); diff --git a/lib/6to5/transformation/transformers/react.js b/lib/6to5/transformation/transformers/react.js index fd0d7140ac..1e03298253 100644 --- a/lib/6to5/transformation/transformers/react.js +++ b/lib/6to5/transformation/transformers/react.js @@ -42,6 +42,7 @@ var isTag = function(tagName) { exports.XJSOpeningElement = { exit: function (node, parent, file) { + console.log(node); var reactCompat = file.opts.reactCompat; var tagExpr = node.name; var args = []; @@ -61,11 +62,16 @@ exports.XJSOpeningElement = { } } - var props = node.attributes; - if (props.length) { + var attribs = node.attributes; + if (attribs.length) { var _props = []; var objs = []; + // so basically in order to support spread elements we + // loop over all the attributes, breaking on spreads + // we then push a new object containing all prior attributes + // to an array for later processing + var pushProps = function () { if (!_props.length) return; @@ -73,8 +79,8 @@ exports.XJSOpeningElement = { _props = []; }; - while (props.length) { - var prop = props.shift(); + while (attribs.length) { + var prop = attribs.shift(); if (t.isXJSSpreadAttribute(prop)) { pushProps(); objs.push(prop.argument); @@ -86,22 +92,25 @@ exports.XJSOpeningElement = { pushProps(); if (objs.length === 1) { - props = objs[0]; + // only one object + attribs = objs[0]; } else { + // looks like we have multiple objects if (!t.isObjectExpression(objs[0])) { objs.unshift(t.objectExpression([])); } - props = t.callExpression( + // spread it + attribs = t.callExpression( t.memberExpression(t.identifier("React"), t.identifier("__spread")), objs ); } } else { - props = t.literal(null); + attribs = t.literal(null); } - args.push(props); + args.push(attribs); if (reactCompat) { if (tagName && isTag(tagName)) { From 7867daaa0454700b829c98d899e5a73d5b90fa03 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 13 Jan 2015 01:50:16 +1100 Subject: [PATCH 07/51] add 2.11.0 changelog --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a1c2128f2..dac95391d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,19 @@ _Note: Gaps between patch versions are faulty/broken releases._ +## 2.11.0 + + * **Bug Fix** + * Fix unnecessary IIFE in default parameters on method calls. + * Add support for supers inside of closures. + * **New Feature** + * Add `--keep-module-id-extensions`/`keepModuleIdExtensions` option to keep extensions in module ids. + * **Polish** + * Special case single argument spread properties in `super` inside classes. + * Don't use a variable declaration for class declaration IFFE. + * Rename `inherits` helper parameters. + * `coreAliasing` transformer now aliases `Promise`, `Set`, `Map` and more. Thanks [@AluisioASG](https://github.com/AluisioASG). + ## 2.10.1 * **Internal** From 2e497eef98553c1d77cacfa49289b6feecca3d67 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 13 Jan 2015 01:51:21 +1100 Subject: [PATCH 08/51] fix linting errors --- lib/6to5/generation/node/whitespace.js | 2 +- lib/6to5/transformation/modules/umd.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/6to5/generation/node/whitespace.js b/lib/6to5/generation/node/whitespace.js index 03d17659eb..d1defd1cfe 100644 --- a/lib/6to5/generation/node/whitespace.js +++ b/lib/6to5/generation/node/whitespace.js @@ -72,5 +72,5 @@ _.each({ return amount; }; }); - }) + }); }); diff --git a/lib/6to5/transformation/modules/umd.js b/lib/6to5/transformation/modules/umd.js index f3933da7ce..d0122f4f68 100644 --- a/lib/6to5/transformation/modules/umd.js +++ b/lib/6to5/transformation/modules/umd.js @@ -52,7 +52,7 @@ UMDFormatter.prototype.transform = function (ast) { // globals - var umdArgs = []; + //var umdArgs = []; // From cf579f4b6e6eba6f1e0b01bca345e258877916ed Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 13 Jan 2015 01:53:03 +1100 Subject: [PATCH 09/51] v2.11.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e387b2052b..830f87ea41 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "6to5", "description": "Turn ES6 code into readable vanilla ES5 with source maps", - "version": "2.10.1", + "version": "2.11.0", "author": "Sebastian McKenzie ", "homepage": "https://github.com/6to5/6to5", "repository": { From 9361470dc7adc316a4dc059aa32a6e991a1c4826 Mon Sep 17 00:00:00 2001 From: Charles Lavery Date: Mon, 12 Jan 2015 13:19:32 -0500 Subject: [PATCH 10/51] remove console.log from react transforms --- lib/6to5/transformation/transformers/react.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/6to5/transformation/transformers/react.js b/lib/6to5/transformation/transformers/react.js index 1e03298253..2842560fc4 100644 --- a/lib/6to5/transformation/transformers/react.js +++ b/lib/6to5/transformation/transformers/react.js @@ -42,7 +42,6 @@ var isTag = function(tagName) { exports.XJSOpeningElement = { exit: function (node, parent, file) { - console.log(node); var reactCompat = file.opts.reactCompat; var tagExpr = node.name; var args = []; From 6f5270f38f7aa0585d99b9e760d53c7f634e1236 Mon Sep 17 00:00:00 2001 From: Christopher Monsanto Date: Mon, 12 Jan 2015 14:00:43 -0500 Subject: [PATCH 11/51] remove Dict from core aliasable constructors --- lib/6to5/transformation/transformers/optional-core-aliasing.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/6to5/transformation/transformers/optional-core-aliasing.js b/lib/6to5/transformation/transformers/optional-core-aliasing.js index 6f97bd2c99..3610ae8f62 100644 --- a/lib/6to5/transformation/transformers/optional-core-aliasing.js +++ b/lib/6to5/transformation/transformers/optional-core-aliasing.js @@ -14,8 +14,7 @@ var ALIASABLE_CONSTRUCTORS = [ "Map", "WeakMap", "Set", - "WeakSet", - "Dict", + "WeakSet" ]; exports.optional = true; From 09ffeed139469b371917a89092edf36f95dafd70 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 13 Jan 2015 08:19:20 +1100 Subject: [PATCH 12/51] add 2.11.1 changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dac95391d7..ab53376bfd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,12 @@ _Note: Gaps between patch versions are faulty/broken releases._ +## 2.11.1 + + * **Bug Fix** + * Remove stray `console.log` outputting debug code. + * Remove `Dict` from `coreAliasing`. + ## 2.11.0 * **Bug Fix** From cf40fe34307fb59272403c66caa32c354a8beed2 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 13 Jan 2015 08:21:54 +1100 Subject: [PATCH 13/51] v2.11.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 830f87ea41..83eefca287 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "6to5", "description": "Turn ES6 code into readable vanilla ES5 with source maps", - "version": "2.11.0", + "version": "2.11.1", "author": "Sebastian McKenzie ", "homepage": "https://github.com/6to5/6to5", "repository": { From 2cedc843a8dd9eb6abe5af7397a6da74a13203ac Mon Sep 17 00:00:00 2001 From: Christopher Monsanto Date: Mon, 12 Jan 2015 16:49:28 -0500 Subject: [PATCH 14/51] don't print traceback on syntax error in CLI --- bin/6to5/util.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/bin/6to5/util.js b/bin/6to5/util.js index 1adf6d5119..b4cd0141f4 100644 --- a/bin/6to5/util.js +++ b/bin/6to5/util.js @@ -20,7 +20,17 @@ exports.transform = function (filename, code, opts) { opts = _.extend(opts || {}, index.opts); opts.filename = filename; - var result = to5.transform(code, opts); + var result; + try { + result = to5.transform(code, opts); + } catch(e) { + if (e.name === "SyntaxError") { + console.error("SyntaxError:", e.message); + process.exit(1); + } else { + throw e; + } + } result.filename = filename; result.actual = code; return result; From 7b04c501eba8ab83bac14495062a9bb9f652ff14 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 13 Jan 2015 08:54:43 +1100 Subject: [PATCH 15/51] fix formatting of #472 --- bin/6to5/util.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/6to5/util.js b/bin/6to5/util.js index b4cd0141f4..bd196c8fa0 100644 --- a/bin/6to5/util.js +++ b/bin/6to5/util.js @@ -23,8 +23,8 @@ exports.transform = function (filename, code, opts) { var result; try { result = to5.transform(code, opts); - } catch(e) { - if (e.name === "SyntaxError") { + } catch (e) { + if (e instanceof SyntaxError) { console.error("SyntaxError:", e.message); process.exit(1); } else { From e07e74f010f4f08a9e8aa8adef9f61fe238e4238 Mon Sep 17 00:00:00 2001 From: Amjad Masad Date: Mon, 12 Jan 2015 17:32:02 -0500 Subject: [PATCH 16/51] Handle esprima-like AST catch clause in a TryStatement. Fixes #473 --- lib/6to5/generation/generators/statements.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/6to5/generation/generators/statements.js b/lib/6to5/generation/generators/statements.js index 613fdcf630..f3a6babeab 100644 --- a/lib/6to5/generation/generators/statements.js +++ b/lib/6to5/generation/generators/statements.js @@ -107,7 +107,16 @@ exports.TryStatement = function (node, print) { this.keyword("try"); print(node.block); this.space(); - print(node.handler); + + // Esprima bug puts the catch clause in a `handlers` array. + // see https://code.google.com/p/esprima/issues/detail?id=433 + // We run into this from regenerator generated ast. + if (node.handlers) { + print(node.handlers[0]); + } else { + print(node.handler); + } + if (node.finalizer) { this.space(); this.push("finally "); From e5a04ae117bb94793e6403a75339e81e93378ce0 Mon Sep 17 00:00:00 2001 From: Amjad Masad Date: Mon, 12 Jan 2015 17:56:16 -0500 Subject: [PATCH 17/51] Add test --- .../transformation/es6-generators/actual.js | 400 ++++++++++++++++++ .../transformation/es6-generators/expected.js | 1 + .../es6-generators/options.json | 3 + 3 files changed, 404 insertions(+) create mode 100644 test/fixtures/transformation/es6-generators/actual.js create mode 100644 test/fixtures/transformation/es6-generators/expected.js create mode 100644 test/fixtures/transformation/es6-generators/options.json diff --git a/test/fixtures/transformation/es6-generators/actual.js b/test/fixtures/transformation/es6-generators/actual.js new file mode 100644 index 0000000000..3b1d9b0960 --- /dev/null +++ b/test/fixtures/transformation/es6-generators/actual.js @@ -0,0 +1,400 @@ +"use strict"; + +!(function () { + var hasOwn = Object.prototype.hasOwnProperty; + var undefined; + var iteratorSymbol = typeof Symbol === "function" && Symbol.iterator || "@@iterator"; + if (typeof regeneratorRuntime === "object") { + return; + } + var runtime = regeneratorRuntime = typeof exports === "undefined" ? {} : exports; + function wrap(innerFn, outerFn, self, tryList) { + return new Generator(innerFn, outerFn, self || null, tryList || []); + } + + runtime.wrap = wrap; + var GenStateSuspendedStart = "suspendedStart"; + + var GenStateSuspendedYield = "suspendedYield"; + + var GenStateExecuting = "executing"; + + var GenStateCompleted = "completed"; + + var ContinueSentinel = {}; + + function GeneratorFunction() {} + + function GeneratorFunctionPrototype() {} + + var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype; + GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype; + GeneratorFunctionPrototype.constructor = GeneratorFunction; + GeneratorFunction.displayName = "GeneratorFunction"; + runtime.isGeneratorFunction = function (genFun) { + var ctor = typeof genFun === "function" && genFun.constructor; + return ctor ? ctor === GeneratorFunction || (ctor.displayName || ctor.name) === "GeneratorFunction" : false; + }; + + runtime.mark = function (genFun) { + genFun.__proto__ = GeneratorFunctionPrototype; + genFun.prototype = Object.create(Gp); + return genFun; + }; + + runtime.async = function (innerFn, outerFn, self, tryList) { + return new Promise(function (resolve, reject) { + var generator = wrap(innerFn, outerFn, self, tryList); + + var callNext = step.bind(generator.next); + + var callThrow = step.bind(generator["throw"]); + + function step(arg) { + try { + var info = this(arg); + + var value = info.value; + } catch (error) { + return reject(error); + } + if (info.done) { + resolve(value); + } else { + Promise.resolve(value).then(callNext, callThrow); + } + } + + callNext(); + }); + }; + + function Generator(innerFn, outerFn, self, tryList) { + var generator = outerFn ? Object.create(outerFn.prototype) : this; + var context = new Context(tryList); + var state = GenStateSuspendedStart; + function invoke(method, arg) { + if (state === GenStateExecuting) { + throw new Error("Generator is already running"); + } + if (state === GenStateCompleted) { + return doneResult(); + } + while (true) { + var delegate = context.delegate; + if (delegate) { + try { + var info = delegate.iterator[method](arg); + + method = "next"; + arg = undefined; + } catch (uncaught) { + context.delegate = null; + method = "throw"; + arg = uncaught; + continue; + } + if (info.done) { + context[delegate.resultName] = info.value; + context.next = delegate.nextLoc; + } else { + state = GenStateSuspendedYield; + return info; + } + context.delegate = null; + } + if (method === "next") { + if (state === GenStateSuspendedStart && typeof arg !== "undefined") { + throw new TypeError("attempt to send " + JSON.stringify(arg) + " to newborn generator"); + } + if (state === GenStateSuspendedYield) { + context.sent = arg; + } else { + delete context.sent; + } + } else if (method === "throw") { + if (state === GenStateSuspendedStart) { + state = GenStateCompleted; + throw arg; + } + if (context.dispatchException(arg)) { + method = "next"; + arg = undefined; + } + } else if (method === "return") { + context.abrupt("return", arg); + } + state = GenStateExecuting; + try { + var value = innerFn.call(self, context); + + state = context.done ? GenStateCompleted : GenStateSuspendedYield; + var info = { + value: value, + done: context.done + }; + + if (value === ContinueSentinel) { + if (context.delegate && method === "next") { + arg = undefined; + } + } else { + return info; + } + } catch (thrown) { + state = GenStateCompleted; + if (method === "next") { + context.dispatchException(thrown); + } else { + arg = thrown; + } + } + } + } + + generator.next = invoke.bind(generator, "next"); + generator["throw"] = invoke.bind(generator, "throw"); + generator["return"] = invoke.bind(generator, "return"); + return generator; + } + + Gp[iteratorSymbol] = function () { + return this; + }; + + Gp.toString = function () { + return "[object Generator]"; + }; + + function pushTryEntry(triple) { + var entry = { + tryLoc: triple[0] + }; + + if (1 in triple) { + entry.catchLoc = triple[1]; + } + if (2 in triple) { + entry.finallyLoc = triple[2]; + } + this.tryEntries.push(entry); + } + + function resetTryEntry(entry, i) { + var record = entry.completion || {}; + record.type = i === 0 ? "normal" : "return"; + delete record.arg; + entry.completion = record; + } + + function Context(tryList) { + this.tryEntries = [{ + tryLoc: "root" + }]; + tryList.forEach(pushTryEntry, this); + + this.reset(); + } + + runtime.keys = function (object) { + var keys = []; + + for (var key in object) { + keys.push(key); + } + + keys.reverse(); + + return function next() { + while (keys.length) { + var key = keys.pop(); + + if (key in object) { + next.value = key; + next.done = false; + return next; + } + } + next.done = true; + return next; + }; + }; + + function values(iterable) { + if (iterable) { + var iteratorMethod = iterable[iteratorSymbol]; + if (iteratorMethod) { + return iteratorMethod.call(iterable); + } + if (typeof iterable.next === "function") { + return iterable; + } + if (!isNaN(iterable.length)) { + var i = -1; + function next() { + while (++i < iterable.length) { + if (hasOwn.call(iterable, i)) { + next.value = iterable[i]; + next.done = false; + return next; + } + } + next.value = undefined; + next.done = true; + return next; + } + + return next.next = next; + } + } + return { + next: doneResult + }; + } + + runtime.values = values; + function doneResult() { + return { + value: undefined, + done: true + }; + } + + Context.prototype = { + constructor: Context, + reset: function () { + this.prev = 0; + this.next = 0; + this.sent = undefined; + this.done = false; + this.delegate = null; + this.tryEntries.forEach(resetTryEntry); + + for (var tempIndex = 0, tempName; hasOwn.call(this, tempName = "t" + tempIndex) || tempIndex < 20; ++tempIndex) { + this[tempName] = null; + } + }, + stop: function () { + this.done = true; + var rootEntry = this.tryEntries[0]; + var rootRecord = rootEntry.completion; + if (rootRecord.type === "throw") { + throw rootRecord.arg; + } + return this.rval; + }, + dispatchException: function (exception) { + if (this.done) { + throw exception; + } + var context = this; + function handle(loc, caught) { + record.type = "throw"; + record.arg = exception; + context.next = loc; + return !!caught; + } + + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i]; + var record = entry.completion; + if (entry.tryLoc === "root") { + return handle("end"); + } + if (entry.tryLoc <= this.prev) { + var hasCatch = hasOwn.call(entry, "catchLoc"); + + var hasFinally = hasOwn.call(entry, "finallyLoc"); + + if (hasCatch && hasFinally) { + if (this.prev < entry.catchLoc) { + return handle(entry.catchLoc, true); + } else if (this.prev < entry.finallyLoc) { + return handle(entry.finallyLoc); + } + } else if (hasCatch) { + if (this.prev < entry.catchLoc) { + return handle(entry.catchLoc, true); + } + } else if (hasFinally) { + if (this.prev < entry.finallyLoc) { + return handle(entry.finallyLoc); + } + } else { + throw new Error("try statement without catch or finally"); + } + } + } + }, + _findFinallyEntry: function (finallyLoc) { + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i]; + if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && (entry.finallyLoc === finallyLoc || this.prev < entry.finallyLoc)) { + return entry; + } + } + }, + abrupt: function (type, arg) { + var entry = this._findFinallyEntry(); + + var record = entry ? entry.completion : {}; + record.type = type; + record.arg = arg; + if (entry) { + this.next = entry.finallyLoc; + } else { + this.complete(record); + } + return ContinueSentinel; + }, + complete: function (record) { + if (record.type === "throw") { + throw record.arg; + } + if (record.type === "break" || record.type === "continue") { + this.next = record.arg; + } else if (record.type === "return") { + this.rval = record.arg; + this.next = "end"; + } + return ContinueSentinel; + }, + finish: function (finallyLoc) { + var entry = this._findFinallyEntry(finallyLoc); + + return this.complete(entry.completion); + }, + "catch": function (tryLoc) { + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i]; + if (entry.tryLoc === tryLoc) { + var record = entry.completion; + if (record.type === "throw") { + var thrown = record.arg; + resetTryEntry(entry, i); + } + return thrown; + } + } + + throw new Error("illegal catch attempt"); + }, + delegateYield: function (iterable, resultName, nextLoc) { + this.delegate = { + iterator: values(iterable), + resultName: resultName, + nextLoc: nextLoc + }; + return ContinueSentinel; + } + }; +})(); +var x = regeneratorRuntime.mark(function x() { + return regeneratorRuntime.wrap(function x$(context$1$0) { + while (1) switch (context$1$0.prev = context$1$0.next) { + case 0: + case "end": + return context$1$0.stop(); + } + }, x, this); +}); diff --git a/test/fixtures/transformation/es6-generators/expected.js b/test/fixtures/transformation/es6-generators/expected.js new file mode 100644 index 0000000000..d82da75f43 --- /dev/null +++ b/test/fixtures/transformation/es6-generators/expected.js @@ -0,0 +1 @@ +function *x() {} diff --git a/test/fixtures/transformation/es6-generators/options.json b/test/fixtures/transformation/es6-generators/options.json new file mode 100644 index 0000000000..a0eb28374e --- /dev/null +++ b/test/fixtures/transformation/es6-generators/options.json @@ -0,0 +1,3 @@ +{ + "includeRegenerator": true +} From 9620f50f22d9af3cc4492e27c5eb4a3f6306808b Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 13 Jan 2015 10:32:39 +1100 Subject: [PATCH 18/51] fix #474 test --- .../es6-generators/{ => include-regenerator}/actual.js | 0 .../es6-generators/{ => include-regenerator}/expected.js | 0 .../es6-generators/{ => include-regenerator}/options.json | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename test/fixtures/transformation/es6-generators/{ => include-regenerator}/actual.js (100%) rename test/fixtures/transformation/es6-generators/{ => include-regenerator}/expected.js (100%) rename test/fixtures/transformation/es6-generators/{ => include-regenerator}/options.json (100%) diff --git a/test/fixtures/transformation/es6-generators/actual.js b/test/fixtures/transformation/es6-generators/include-regenerator/actual.js similarity index 100% rename from test/fixtures/transformation/es6-generators/actual.js rename to test/fixtures/transformation/es6-generators/include-regenerator/actual.js diff --git a/test/fixtures/transformation/es6-generators/expected.js b/test/fixtures/transformation/es6-generators/include-regenerator/expected.js similarity index 100% rename from test/fixtures/transformation/es6-generators/expected.js rename to test/fixtures/transformation/es6-generators/include-regenerator/expected.js diff --git a/test/fixtures/transformation/es6-generators/options.json b/test/fixtures/transformation/es6-generators/include-regenerator/options.json similarity index 100% rename from test/fixtures/transformation/es6-generators/options.json rename to test/fixtures/transformation/es6-generators/include-regenerator/options.json From a66ce5b6ce3f88891ee8d2eaa693dabfb1df6b64 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 13 Jan 2015 10:44:17 +1100 Subject: [PATCH 19/51] add ignore ast check to es6 generators test because regenerator outputs an invalid ast --- .../es6-generators/include-regenerator/options.json | 1 + 1 file changed, 1 insertion(+) diff --git a/test/fixtures/transformation/es6-generators/include-regenerator/options.json b/test/fixtures/transformation/es6-generators/include-regenerator/options.json index a0eb28374e..b61f12c5b9 100644 --- a/test/fixtures/transformation/es6-generators/include-regenerator/options.json +++ b/test/fixtures/transformation/es6-generators/include-regenerator/options.json @@ -1,3 +1,4 @@ { + "noCheckAst": true, "includeRegenerator": true } From 3283991ed0a1a24e3aad383f65d99f25d0d396ce Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 13 Jan 2015 10:56:36 +1100 Subject: [PATCH 20/51] flip es6 geneartors include regenerator tests --- .../include-regenerator/actual.js | 401 +----------------- .../include-regenerator/expected.js | 401 +++++++++++++++++- 2 files changed, 401 insertions(+), 401 deletions(-) diff --git a/test/fixtures/transformation/es6-generators/include-regenerator/actual.js b/test/fixtures/transformation/es6-generators/include-regenerator/actual.js index 3b1d9b0960..d82da75f43 100644 --- a/test/fixtures/transformation/es6-generators/include-regenerator/actual.js +++ b/test/fixtures/transformation/es6-generators/include-regenerator/actual.js @@ -1,400 +1 @@ -"use strict"; - -!(function () { - var hasOwn = Object.prototype.hasOwnProperty; - var undefined; - var iteratorSymbol = typeof Symbol === "function" && Symbol.iterator || "@@iterator"; - if (typeof regeneratorRuntime === "object") { - return; - } - var runtime = regeneratorRuntime = typeof exports === "undefined" ? {} : exports; - function wrap(innerFn, outerFn, self, tryList) { - return new Generator(innerFn, outerFn, self || null, tryList || []); - } - - runtime.wrap = wrap; - var GenStateSuspendedStart = "suspendedStart"; - - var GenStateSuspendedYield = "suspendedYield"; - - var GenStateExecuting = "executing"; - - var GenStateCompleted = "completed"; - - var ContinueSentinel = {}; - - function GeneratorFunction() {} - - function GeneratorFunctionPrototype() {} - - var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype; - GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype; - GeneratorFunctionPrototype.constructor = GeneratorFunction; - GeneratorFunction.displayName = "GeneratorFunction"; - runtime.isGeneratorFunction = function (genFun) { - var ctor = typeof genFun === "function" && genFun.constructor; - return ctor ? ctor === GeneratorFunction || (ctor.displayName || ctor.name) === "GeneratorFunction" : false; - }; - - runtime.mark = function (genFun) { - genFun.__proto__ = GeneratorFunctionPrototype; - genFun.prototype = Object.create(Gp); - return genFun; - }; - - runtime.async = function (innerFn, outerFn, self, tryList) { - return new Promise(function (resolve, reject) { - var generator = wrap(innerFn, outerFn, self, tryList); - - var callNext = step.bind(generator.next); - - var callThrow = step.bind(generator["throw"]); - - function step(arg) { - try { - var info = this(arg); - - var value = info.value; - } catch (error) { - return reject(error); - } - if (info.done) { - resolve(value); - } else { - Promise.resolve(value).then(callNext, callThrow); - } - } - - callNext(); - }); - }; - - function Generator(innerFn, outerFn, self, tryList) { - var generator = outerFn ? Object.create(outerFn.prototype) : this; - var context = new Context(tryList); - var state = GenStateSuspendedStart; - function invoke(method, arg) { - if (state === GenStateExecuting) { - throw new Error("Generator is already running"); - } - if (state === GenStateCompleted) { - return doneResult(); - } - while (true) { - var delegate = context.delegate; - if (delegate) { - try { - var info = delegate.iterator[method](arg); - - method = "next"; - arg = undefined; - } catch (uncaught) { - context.delegate = null; - method = "throw"; - arg = uncaught; - continue; - } - if (info.done) { - context[delegate.resultName] = info.value; - context.next = delegate.nextLoc; - } else { - state = GenStateSuspendedYield; - return info; - } - context.delegate = null; - } - if (method === "next") { - if (state === GenStateSuspendedStart && typeof arg !== "undefined") { - throw new TypeError("attempt to send " + JSON.stringify(arg) + " to newborn generator"); - } - if (state === GenStateSuspendedYield) { - context.sent = arg; - } else { - delete context.sent; - } - } else if (method === "throw") { - if (state === GenStateSuspendedStart) { - state = GenStateCompleted; - throw arg; - } - if (context.dispatchException(arg)) { - method = "next"; - arg = undefined; - } - } else if (method === "return") { - context.abrupt("return", arg); - } - state = GenStateExecuting; - try { - var value = innerFn.call(self, context); - - state = context.done ? GenStateCompleted : GenStateSuspendedYield; - var info = { - value: value, - done: context.done - }; - - if (value === ContinueSentinel) { - if (context.delegate && method === "next") { - arg = undefined; - } - } else { - return info; - } - } catch (thrown) { - state = GenStateCompleted; - if (method === "next") { - context.dispatchException(thrown); - } else { - arg = thrown; - } - } - } - } - - generator.next = invoke.bind(generator, "next"); - generator["throw"] = invoke.bind(generator, "throw"); - generator["return"] = invoke.bind(generator, "return"); - return generator; - } - - Gp[iteratorSymbol] = function () { - return this; - }; - - Gp.toString = function () { - return "[object Generator]"; - }; - - function pushTryEntry(triple) { - var entry = { - tryLoc: triple[0] - }; - - if (1 in triple) { - entry.catchLoc = triple[1]; - } - if (2 in triple) { - entry.finallyLoc = triple[2]; - } - this.tryEntries.push(entry); - } - - function resetTryEntry(entry, i) { - var record = entry.completion || {}; - record.type = i === 0 ? "normal" : "return"; - delete record.arg; - entry.completion = record; - } - - function Context(tryList) { - this.tryEntries = [{ - tryLoc: "root" - }]; - tryList.forEach(pushTryEntry, this); - - this.reset(); - } - - runtime.keys = function (object) { - var keys = []; - - for (var key in object) { - keys.push(key); - } - - keys.reverse(); - - return function next() { - while (keys.length) { - var key = keys.pop(); - - if (key in object) { - next.value = key; - next.done = false; - return next; - } - } - next.done = true; - return next; - }; - }; - - function values(iterable) { - if (iterable) { - var iteratorMethod = iterable[iteratorSymbol]; - if (iteratorMethod) { - return iteratorMethod.call(iterable); - } - if (typeof iterable.next === "function") { - return iterable; - } - if (!isNaN(iterable.length)) { - var i = -1; - function next() { - while (++i < iterable.length) { - if (hasOwn.call(iterable, i)) { - next.value = iterable[i]; - next.done = false; - return next; - } - } - next.value = undefined; - next.done = true; - return next; - } - - return next.next = next; - } - } - return { - next: doneResult - }; - } - - runtime.values = values; - function doneResult() { - return { - value: undefined, - done: true - }; - } - - Context.prototype = { - constructor: Context, - reset: function () { - this.prev = 0; - this.next = 0; - this.sent = undefined; - this.done = false; - this.delegate = null; - this.tryEntries.forEach(resetTryEntry); - - for (var tempIndex = 0, tempName; hasOwn.call(this, tempName = "t" + tempIndex) || tempIndex < 20; ++tempIndex) { - this[tempName] = null; - } - }, - stop: function () { - this.done = true; - var rootEntry = this.tryEntries[0]; - var rootRecord = rootEntry.completion; - if (rootRecord.type === "throw") { - throw rootRecord.arg; - } - return this.rval; - }, - dispatchException: function (exception) { - if (this.done) { - throw exception; - } - var context = this; - function handle(loc, caught) { - record.type = "throw"; - record.arg = exception; - context.next = loc; - return !!caught; - } - - for (var i = this.tryEntries.length - 1; i >= 0; --i) { - var entry = this.tryEntries[i]; - var record = entry.completion; - if (entry.tryLoc === "root") { - return handle("end"); - } - if (entry.tryLoc <= this.prev) { - var hasCatch = hasOwn.call(entry, "catchLoc"); - - var hasFinally = hasOwn.call(entry, "finallyLoc"); - - if (hasCatch && hasFinally) { - if (this.prev < entry.catchLoc) { - return handle(entry.catchLoc, true); - } else if (this.prev < entry.finallyLoc) { - return handle(entry.finallyLoc); - } - } else if (hasCatch) { - if (this.prev < entry.catchLoc) { - return handle(entry.catchLoc, true); - } - } else if (hasFinally) { - if (this.prev < entry.finallyLoc) { - return handle(entry.finallyLoc); - } - } else { - throw new Error("try statement without catch or finally"); - } - } - } - }, - _findFinallyEntry: function (finallyLoc) { - for (var i = this.tryEntries.length - 1; i >= 0; --i) { - var entry = this.tryEntries[i]; - if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && (entry.finallyLoc === finallyLoc || this.prev < entry.finallyLoc)) { - return entry; - } - } - }, - abrupt: function (type, arg) { - var entry = this._findFinallyEntry(); - - var record = entry ? entry.completion : {}; - record.type = type; - record.arg = arg; - if (entry) { - this.next = entry.finallyLoc; - } else { - this.complete(record); - } - return ContinueSentinel; - }, - complete: function (record) { - if (record.type === "throw") { - throw record.arg; - } - if (record.type === "break" || record.type === "continue") { - this.next = record.arg; - } else if (record.type === "return") { - this.rval = record.arg; - this.next = "end"; - } - return ContinueSentinel; - }, - finish: function (finallyLoc) { - var entry = this._findFinallyEntry(finallyLoc); - - return this.complete(entry.completion); - }, - "catch": function (tryLoc) { - for (var i = this.tryEntries.length - 1; i >= 0; --i) { - var entry = this.tryEntries[i]; - if (entry.tryLoc === tryLoc) { - var record = entry.completion; - if (record.type === "throw") { - var thrown = record.arg; - resetTryEntry(entry, i); - } - return thrown; - } - } - - throw new Error("illegal catch attempt"); - }, - delegateYield: function (iterable, resultName, nextLoc) { - this.delegate = { - iterator: values(iterable), - resultName: resultName, - nextLoc: nextLoc - }; - return ContinueSentinel; - } - }; -})(); -var x = regeneratorRuntime.mark(function x() { - return regeneratorRuntime.wrap(function x$(context$1$0) { - while (1) switch (context$1$0.prev = context$1$0.next) { - case 0: - case "end": - return context$1$0.stop(); - } - }, x, this); -}); +function *x() {} diff --git a/test/fixtures/transformation/es6-generators/include-regenerator/expected.js b/test/fixtures/transformation/es6-generators/include-regenerator/expected.js index d82da75f43..3b1d9b0960 100644 --- a/test/fixtures/transformation/es6-generators/include-regenerator/expected.js +++ b/test/fixtures/transformation/es6-generators/include-regenerator/expected.js @@ -1 +1,400 @@ -function *x() {} +"use strict"; + +!(function () { + var hasOwn = Object.prototype.hasOwnProperty; + var undefined; + var iteratorSymbol = typeof Symbol === "function" && Symbol.iterator || "@@iterator"; + if (typeof regeneratorRuntime === "object") { + return; + } + var runtime = regeneratorRuntime = typeof exports === "undefined" ? {} : exports; + function wrap(innerFn, outerFn, self, tryList) { + return new Generator(innerFn, outerFn, self || null, tryList || []); + } + + runtime.wrap = wrap; + var GenStateSuspendedStart = "suspendedStart"; + + var GenStateSuspendedYield = "suspendedYield"; + + var GenStateExecuting = "executing"; + + var GenStateCompleted = "completed"; + + var ContinueSentinel = {}; + + function GeneratorFunction() {} + + function GeneratorFunctionPrototype() {} + + var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype; + GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype; + GeneratorFunctionPrototype.constructor = GeneratorFunction; + GeneratorFunction.displayName = "GeneratorFunction"; + runtime.isGeneratorFunction = function (genFun) { + var ctor = typeof genFun === "function" && genFun.constructor; + return ctor ? ctor === GeneratorFunction || (ctor.displayName || ctor.name) === "GeneratorFunction" : false; + }; + + runtime.mark = function (genFun) { + genFun.__proto__ = GeneratorFunctionPrototype; + genFun.prototype = Object.create(Gp); + return genFun; + }; + + runtime.async = function (innerFn, outerFn, self, tryList) { + return new Promise(function (resolve, reject) { + var generator = wrap(innerFn, outerFn, self, tryList); + + var callNext = step.bind(generator.next); + + var callThrow = step.bind(generator["throw"]); + + function step(arg) { + try { + var info = this(arg); + + var value = info.value; + } catch (error) { + return reject(error); + } + if (info.done) { + resolve(value); + } else { + Promise.resolve(value).then(callNext, callThrow); + } + } + + callNext(); + }); + }; + + function Generator(innerFn, outerFn, self, tryList) { + var generator = outerFn ? Object.create(outerFn.prototype) : this; + var context = new Context(tryList); + var state = GenStateSuspendedStart; + function invoke(method, arg) { + if (state === GenStateExecuting) { + throw new Error("Generator is already running"); + } + if (state === GenStateCompleted) { + return doneResult(); + } + while (true) { + var delegate = context.delegate; + if (delegate) { + try { + var info = delegate.iterator[method](arg); + + method = "next"; + arg = undefined; + } catch (uncaught) { + context.delegate = null; + method = "throw"; + arg = uncaught; + continue; + } + if (info.done) { + context[delegate.resultName] = info.value; + context.next = delegate.nextLoc; + } else { + state = GenStateSuspendedYield; + return info; + } + context.delegate = null; + } + if (method === "next") { + if (state === GenStateSuspendedStart && typeof arg !== "undefined") { + throw new TypeError("attempt to send " + JSON.stringify(arg) + " to newborn generator"); + } + if (state === GenStateSuspendedYield) { + context.sent = arg; + } else { + delete context.sent; + } + } else if (method === "throw") { + if (state === GenStateSuspendedStart) { + state = GenStateCompleted; + throw arg; + } + if (context.dispatchException(arg)) { + method = "next"; + arg = undefined; + } + } else if (method === "return") { + context.abrupt("return", arg); + } + state = GenStateExecuting; + try { + var value = innerFn.call(self, context); + + state = context.done ? GenStateCompleted : GenStateSuspendedYield; + var info = { + value: value, + done: context.done + }; + + if (value === ContinueSentinel) { + if (context.delegate && method === "next") { + arg = undefined; + } + } else { + return info; + } + } catch (thrown) { + state = GenStateCompleted; + if (method === "next") { + context.dispatchException(thrown); + } else { + arg = thrown; + } + } + } + } + + generator.next = invoke.bind(generator, "next"); + generator["throw"] = invoke.bind(generator, "throw"); + generator["return"] = invoke.bind(generator, "return"); + return generator; + } + + Gp[iteratorSymbol] = function () { + return this; + }; + + Gp.toString = function () { + return "[object Generator]"; + }; + + function pushTryEntry(triple) { + var entry = { + tryLoc: triple[0] + }; + + if (1 in triple) { + entry.catchLoc = triple[1]; + } + if (2 in triple) { + entry.finallyLoc = triple[2]; + } + this.tryEntries.push(entry); + } + + function resetTryEntry(entry, i) { + var record = entry.completion || {}; + record.type = i === 0 ? "normal" : "return"; + delete record.arg; + entry.completion = record; + } + + function Context(tryList) { + this.tryEntries = [{ + tryLoc: "root" + }]; + tryList.forEach(pushTryEntry, this); + + this.reset(); + } + + runtime.keys = function (object) { + var keys = []; + + for (var key in object) { + keys.push(key); + } + + keys.reverse(); + + return function next() { + while (keys.length) { + var key = keys.pop(); + + if (key in object) { + next.value = key; + next.done = false; + return next; + } + } + next.done = true; + return next; + }; + }; + + function values(iterable) { + if (iterable) { + var iteratorMethod = iterable[iteratorSymbol]; + if (iteratorMethod) { + return iteratorMethod.call(iterable); + } + if (typeof iterable.next === "function") { + return iterable; + } + if (!isNaN(iterable.length)) { + var i = -1; + function next() { + while (++i < iterable.length) { + if (hasOwn.call(iterable, i)) { + next.value = iterable[i]; + next.done = false; + return next; + } + } + next.value = undefined; + next.done = true; + return next; + } + + return next.next = next; + } + } + return { + next: doneResult + }; + } + + runtime.values = values; + function doneResult() { + return { + value: undefined, + done: true + }; + } + + Context.prototype = { + constructor: Context, + reset: function () { + this.prev = 0; + this.next = 0; + this.sent = undefined; + this.done = false; + this.delegate = null; + this.tryEntries.forEach(resetTryEntry); + + for (var tempIndex = 0, tempName; hasOwn.call(this, tempName = "t" + tempIndex) || tempIndex < 20; ++tempIndex) { + this[tempName] = null; + } + }, + stop: function () { + this.done = true; + var rootEntry = this.tryEntries[0]; + var rootRecord = rootEntry.completion; + if (rootRecord.type === "throw") { + throw rootRecord.arg; + } + return this.rval; + }, + dispatchException: function (exception) { + if (this.done) { + throw exception; + } + var context = this; + function handle(loc, caught) { + record.type = "throw"; + record.arg = exception; + context.next = loc; + return !!caught; + } + + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i]; + var record = entry.completion; + if (entry.tryLoc === "root") { + return handle("end"); + } + if (entry.tryLoc <= this.prev) { + var hasCatch = hasOwn.call(entry, "catchLoc"); + + var hasFinally = hasOwn.call(entry, "finallyLoc"); + + if (hasCatch && hasFinally) { + if (this.prev < entry.catchLoc) { + return handle(entry.catchLoc, true); + } else if (this.prev < entry.finallyLoc) { + return handle(entry.finallyLoc); + } + } else if (hasCatch) { + if (this.prev < entry.catchLoc) { + return handle(entry.catchLoc, true); + } + } else if (hasFinally) { + if (this.prev < entry.finallyLoc) { + return handle(entry.finallyLoc); + } + } else { + throw new Error("try statement without catch or finally"); + } + } + } + }, + _findFinallyEntry: function (finallyLoc) { + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i]; + if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && (entry.finallyLoc === finallyLoc || this.prev < entry.finallyLoc)) { + return entry; + } + } + }, + abrupt: function (type, arg) { + var entry = this._findFinallyEntry(); + + var record = entry ? entry.completion : {}; + record.type = type; + record.arg = arg; + if (entry) { + this.next = entry.finallyLoc; + } else { + this.complete(record); + } + return ContinueSentinel; + }, + complete: function (record) { + if (record.type === "throw") { + throw record.arg; + } + if (record.type === "break" || record.type === "continue") { + this.next = record.arg; + } else if (record.type === "return") { + this.rval = record.arg; + this.next = "end"; + } + return ContinueSentinel; + }, + finish: function (finallyLoc) { + var entry = this._findFinallyEntry(finallyLoc); + + return this.complete(entry.completion); + }, + "catch": function (tryLoc) { + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i]; + if (entry.tryLoc === tryLoc) { + var record = entry.completion; + if (record.type === "throw") { + var thrown = record.arg; + resetTryEntry(entry, i); + } + return thrown; + } + } + + throw new Error("illegal catch attempt"); + }, + delegateYield: function (iterable, resultName, nextLoc) { + this.delegate = { + iterator: values(iterable), + resultName: resultName, + nextLoc: nextLoc + }; + return ContinueSentinel; + } + }; +})(); +var x = regeneratorRuntime.mark(function x() { + return regeneratorRuntime.wrap(function x$(context$1$0) { + while (1) switch (context$1$0.prev = context$1$0.next) { + case 0: + case "end": + return context$1$0.stop(); + } + }, x, this); +}); From 75cd0bab02c7900de871beeee4b5f84fe8e69da0 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 13 Jan 2015 11:26:07 +1100 Subject: [PATCH 21/51] add 2.11.2 changelog --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ab53376bfd..8192090636 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,13 @@ _Note: Gaps between patch versions are faulty/broken releases._ +## 2.11.2 + + * **Bug Fix** + * Support esprima-style catch clause handlers. + * **Polish** + * Don't print a stacktrace for syntax errors in the CLI. + ## 2.11.1 * **Bug Fix** From 010dbe1cceab29b837f8b2c32650cc647d2e2a71 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 13 Jan 2015 11:29:46 +1100 Subject: [PATCH 22/51] v2.11.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 83eefca287..91ac14e22a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "6to5", "description": "Turn ES6 code into readable vanilla ES5 with source maps", - "version": "2.11.1", + "version": "2.11.2", "author": "Sebastian McKenzie ", "homepage": "https://github.com/6to5/6to5", "repository": { From b2dc560a2d4d7062ca60ef76d0232bd094f137de Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 13 Jan 2015 14:33:18 +1100 Subject: [PATCH 23/51] allow a string to be passed as the `optional` option --- CHANGELOG.md | 5 +++++ lib/6to5/file.js | 1 + 2 files changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8192090636..6ccd2fab09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,11 @@ _Note: Gaps between patch versions are faulty/broken releases._ +## 2.11.3 + + * **Bug Fix** + * Allow a string to be passed as the `optional` option. + ## 2.11.2 * **Bug Fix** diff --git a/lib/6to5/file.js b/lib/6to5/file.js index 70a0b900b6..d18a53bdc2 100644 --- a/lib/6to5/file.js +++ b/lib/6to5/file.js @@ -72,6 +72,7 @@ File.normaliseOptions = function (opts) { opts.blacklist = util.arrayify(opts.blacklist); opts.whitelist = util.arrayify(opts.whitelist); + opts.optional = util.arrayify(opts.optional); _.defaults(opts, { moduleRoot: opts.sourceRoot From 7ed7475c468b7e47bc9aa81f165779f8e33681e4 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 13 Jan 2015 14:35:14 +1100 Subject: [PATCH 24/51] v2.11.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 91ac14e22a..b45a75917b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "6to5", "description": "Turn ES6 code into readable vanilla ES5 with source maps", - "version": "2.11.2", + "version": "2.11.3", "author": "Sebastian McKenzie ", "homepage": "https://github.com/6to5/6to5", "repository": { From 4df6d6043e13e148bd3319f64732fd42f838e59e Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 13 Jan 2015 20:07:34 +1100 Subject: [PATCH 25/51] make dependency versions static - fixes #475 --- package.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index b45a75917b..77f8045115 100644 --- a/package.json +++ b/package.json @@ -43,32 +43,32 @@ "ast-types": "~0.6.1", "chokidar": "0.11.1", "commander": "2.5.0", - "core-js": "^0.4.4", + "core-js": "0.4.4", "estraverse": "1.8.0", "esutils": "1.1.6", - "esvalid": "^1.1.0", + "esvalid": "1.1.0", "fs-readdir-recursive": "0.1.0", - "jshint": "^2.5.10", + "jshint": "2.5.10", "lodash": "2.4.1", "mkdirp": "0.5.0", "private": "0.1.6", - "regenerator": "^0.8.3", + "regenerator": "0.8.3", "regexpu": "0.3.0", - "roadrunner": "^1.0.4", + "roadrunner": "1.0.4", "source-map": "0.1.40", "source-map-support": "0.2.8" }, "devDependencies": { "browserify": "6.3.2", - "chai": "^1.9.2", + "chai": "1.9.2", "istanbul": "0.3.2", - "jshint-stylish": "^1.0.0", + "jshint-stylish": "1.0.0", "matcha": "0.6.0", "mocha": "1.21.4", "rimraf": "2.2.8", "uglify-js": "2.4.15" }, "optionalDependencies": { - "kexec": "^0.2.0" + "kexec": "0.2.0" } } From bd179ace86ada88632604a16aa674ebd5d9f1ec8 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 13 Jan 2015 20:08:38 +1100 Subject: [PATCH 26/51] add 2.11.4 changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ccd2fab09..2c4a1f2b33 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,11 @@ _Note: Gaps between patch versions are faulty/broken releases._ +## 2.11.4 + + * **Internal** + * Make all dependency versions fixed. + ## 2.11.3 * **Bug Fix** From 9aa010d987666add5de890fc4b1e44248fb07ee0 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 13 Jan 2015 20:15:35 +1100 Subject: [PATCH 27/51] v2.11.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 77f8045115..46c8a49cb1 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "6to5", "description": "Turn ES6 code into readable vanilla ES5 with source maps", - "version": "2.11.3", + "version": "2.11.4", "author": "Sebastian McKenzie ", "homepage": "https://github.com/6to5/6to5", "repository": { From f14f72b6351cec272d54732b0067c0d150b73e88 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 13 Jan 2015 22:01:37 +1100 Subject: [PATCH 28/51] add --mangle option to uglify --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 120336e372..c392eefc20 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ BROWSERIFY_CMD = node_modules/browserify/bin/cmd.js ISTANBUL_CMD = node_modules/istanbul/lib/cli.js cover -UGLIFY_CMD = node_modules/uglify-js/bin/uglifyjs +UGLIFY_CMD = node_modules/uglify-js/bin/uglifyjs --mangle sort JSHINT_CMD = node_modules/jshint/bin/jshint MOCHA_CMD = node_modules/mocha/bin/_mocha From 0f55a66f5b56a1a3677373c50757575f1ea25ea2 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 13 Jan 2015 22:02:04 +1100 Subject: [PATCH 29/51] add "fast" option for transformers --- bin/6to5/index.js | 2 + lib/6to5/file.js | 18 ++ .../class-super-constructor-call-fast.js | 8 +- lib/6to5/transformation/transform.js | 2 - .../transformers/es6-classes.js | 199 ++++++++++++------ .../transformation/transformers/es6-for-of.js | 70 +++++- .../transformers/optional-for-of-fast.js | 37 ---- .../accessing-super-class/actual.js | 0 .../accessing-super-class/expected.js | 0 .../accessing-super-properties/actual.js | 0 .../accessing-super-properties/expected.js | 0 .../calling-super-properties/actual.js | 0 .../calling-super-properties/expected.js | 0 .../es6-classes-fast/options.json | 3 + .../actual.js | 0 .../expected.js | 8 +- .../super-class/actual.js | 0 .../super-class/expected.js | 0 .../super-function-fallback/actual.js | 0 .../super-function-fallback/expected.js | 0 .../optional-classes-fast-super/options.json | 3 - 21 files changed, 226 insertions(+), 124 deletions(-) delete mode 100644 lib/6to5/transformation/transformers/optional-for-of-fast.js rename test/fixtures/transformation/{optional-classes-fast-super => es6-classes-fast}/accessing-super-class/actual.js (100%) rename test/fixtures/transformation/{optional-classes-fast-super => es6-classes-fast}/accessing-super-class/expected.js (100%) rename test/fixtures/transformation/{optional-classes-fast-super => es6-classes-fast}/accessing-super-properties/actual.js (100%) rename test/fixtures/transformation/{optional-classes-fast-super => es6-classes-fast}/accessing-super-properties/expected.js (100%) rename test/fixtures/transformation/{optional-classes-fast-super => es6-classes-fast}/calling-super-properties/actual.js (100%) rename test/fixtures/transformation/{optional-classes-fast-super => es6-classes-fast}/calling-super-properties/expected.js (100%) create mode 100644 test/fixtures/transformation/es6-classes-fast/options.json rename test/fixtures/transformation/{optional-classes-fast-super => es6-classes-fast}/super-class-id-member-expression/actual.js (100%) rename test/fixtures/transformation/{optional-classes-fast-super => es6-classes-fast}/super-class-id-member-expression/expected.js (82%) rename test/fixtures/transformation/{optional-classes-fast-super => es6-classes-fast}/super-class/actual.js (100%) rename test/fixtures/transformation/{optional-classes-fast-super => es6-classes-fast}/super-class/expected.js (100%) rename test/fixtures/transformation/{optional-classes-fast-super => es6-classes-fast}/super-function-fallback/actual.js (100%) rename test/fixtures/transformation/{optional-classes-fast-super => es6-classes-fast}/super-function-fallback/expected.js (100%) delete mode 100644 test/fixtures/transformation/optional-classes-fast-super/options.json diff --git a/bin/6to5/index.js b/bin/6to5/index.js index ea5cc727d5..b5dd079d29 100755 --- a/bin/6to5/index.js +++ b/bin/6to5/index.js @@ -18,6 +18,7 @@ commander.option("-m, --modules [modules]", "Module formatter type to use [commo commander.option("-l, --whitelist [whitelist]", "Whitelist of transformers to ONLY use", util.list); commander.option("-b, --blacklist [blacklist]", "Blacklist of transformers to NOT use", util.list); commander.option("-i, --optional [list]", "List of optional transformers to enable", util.list); +commander.option("--fast [list]", "List of transformers to enable their fast mode", util.list); commander.option("-o, --out-file [out]", "Compile all input files into a single file"); commander.option("-d, --out-dir [out]", "Compile an input directory of modules into an output directory"); commander.option("-c, --remove-comments", "Remove comments from the compiled code", false); @@ -116,6 +117,7 @@ exports.opts = { comments: !commander.removeComments, runtime: commander.runtime, modules: commander.modules, + fast: commander.fast, format: { indent: { style: util.repeat(parseInt(commander.indent)) diff --git a/lib/6to5/file.js b/lib/6to5/file.js index d18a53bdc2..ef830e1ab6 100644 --- a/lib/6to5/file.js +++ b/lib/6to5/file.js @@ -63,6 +63,7 @@ File.normaliseOptions = function (opts) { filename: "unknown", modules: "common", runtime: false, + fast: [], code: true, ast: true }); @@ -73,6 +74,18 @@ File.normaliseOptions = function (opts) { opts.blacklist = util.arrayify(opts.blacklist); opts.whitelist = util.arrayify(opts.whitelist); opts.optional = util.arrayify(opts.optional); + opts.fast = util.arrayify(opts.fast); + + // todo: remove in 3.0.0 + _.each({ + fastForOf: "forOf", + classesFastSuper: "classes" + }, function (newTransformer, oldTransformer) { + if (_.contains(opts.optional, oldTransformer)) { + _.pull(opts.optional, oldTransformer); + opts.fast.push(newTransformer); + } + }); _.defaults(opts, { moduleRoot: opts.sourceRoot @@ -102,10 +115,15 @@ File.normaliseOptions = function (opts) { transform._ensureTransformerNames("blacklist", opts.blacklist); transform._ensureTransformerNames("whitelist", opts.whitelist); transform._ensureTransformerNames("optional", opts.optional); + transform._ensureTransformerNames("fast", opts.fast); return opts; }; +File.prototype.isFast = function (key) { + return _.contains(this.opts.fast, key); +}; + File.prototype.getTransformers = function () { var file = this; var transformers = []; diff --git a/lib/6to5/transformation/templates/class-super-constructor-call-fast.js b/lib/6to5/transformation/templates/class-super-constructor-call-fast.js index dceab5e75b..ab957160f2 100644 --- a/lib/6to5/transformation/templates/class-super-constructor-call-fast.js +++ b/lib/6to5/transformation/templates/class-super-constructor-call-fast.js @@ -1,5 +1,3 @@ -(function () { - if (SUPER_NAME != null) { - SUPER_NAME.apply(this, arguments); - } -}); +if (SUPER_NAME != null) { + SUPER_NAME.apply(this, arguments); +} diff --git a/lib/6to5/transformation/transform.js b/lib/6to5/transformation/transform.js index cd3a10669b..a3399e7b97 100644 --- a/lib/6to5/transformation/transform.js +++ b/lib/6to5/transformation/transform.js @@ -59,7 +59,6 @@ _.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"), @@ -70,7 +69,6 @@ _.each({ computedPropertyNames: require("./transformers/es6-computed-property-names"), destructuring: require("./transformers/es6-destructuring"), defaultParameters: require("./transformers/es6-default-parameters"), - forOfFast: require("./transformers/optional-for-of-fast"), forOf: require("./transformers/es6-for-of"), unicodeRegex: require("./transformers/es6-unicode-regex"), abstractReferences: require("./transformers/es7-abstract-references"), diff --git a/lib/6to5/transformation/transformers/es6-classes.js b/lib/6to5/transformation/transformers/es6-classes.js index 8fcf90c7ba..d736dfcd5d 100644 --- a/lib/6to5/transformation/transformers/es6-classes.js +++ b/lib/6to5/transformation/transformers/es6-classes.js @@ -33,6 +33,7 @@ function Class(node, file, scope, isStatement) { this.hasConstructor = false; this.className = node.id || file.generateUidIdentifier("class", scope); this.superName = node.superClass; + this.isFast = file.isFast("classes"); } /** @@ -117,27 +118,31 @@ Class.prototype.buildBody = function () { var superName = this.superName; var classBody = this.node.body.body; var body = this.body; - var self = this; for (var i in classBody) { var node = classBody[i]; if (t.isMethodDefinition(node)) { - self.replaceInstanceSuperReferences(node); + this.replaceInstanceSuperReferences(node); if (node.key.name === "constructor") { - self.pushConstructor(node); + this.pushConstructor(node); } else { - self.pushMethod(node); + this.pushMethod(node); } } else if (t.isPrivateDeclaration(node)) { - self.closure = true; + this.closure = true; body.unshift(node); } } + // we have no constructor, we have a super, and the super doesn't appear to be falsy if (!this.hasConstructor && superName && !t.isFalsyExpression(superName)) { - constructor.body.body.push(util.template("class-super-constructor-call", { - CLASS_NAME: className + var defaultConstructorTemplate = "class-super-constructor-call"; + if (this.isFast) defaultConstructorTemplate += "-fast"; + + constructor.body.body.push(util.template(defaultConstructorTemplate, { + CLASS_NAME: className, + SUPER_NAME: this.superName }, true)); } @@ -219,6 +224,47 @@ Class.prototype.superProperty = function (property, isStatic, isComputed, thisEx ); }; +/** + * Description + * + * @param {Object} node + * @param {Object} id + * @param {Object} parent + * @returns {Object} + */ + +Class.prototype.fastSuperProperty = function (methodNode, id, parent) { + var methodName = methodNode.key; + var superName = this.superName || t.identifier("Function"); + + 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(superName, 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(id, 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; + } +}; + /** * Replace all `super` references with a reference to our `superClass`. * @@ -231,7 +277,7 @@ Class.prototype.replaceInstanceSuperReferences = function (methodNode) { var topLevelThisReference; - traverse2(method, true); + traverseLevel(method, true); if (topLevelThisReference) { method.body.body.unshift(t.variableDeclaration("var", [ @@ -239,75 +285,100 @@ Class.prototype.replaceInstanceSuperReferences = function (methodNode) { ])); } - function traverse2(node, topLevel) { + function traverseLevel(node, topLevel) { traverse(node, { enter: function (node, parent) { if (t.isFunction(node) && !t.isArrowFunctionExpression(node)) { - traverse2(node, false); + // we need to call traverseLevel again so we're context aware + traverseLevel(node, false); return this.skip(); } - 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; - } - - if (property) { - var thisReference; + var getThisReference = function () { if (topLevel) { - thisReference = t.thisExpression(); + // top level so `this` is the instance + return t.thisExpression(); } else { - topLevelThisReference = thisReference = topLevelThisReference || self.file.generateUidIdentifier("this"); + // not in the top level so we need to create a reference + return topLevelThisReference = topLevelThisReference || self.file.generateUidIdentifier("this"); } + }; - var superProperty = self.superProperty(property, methodNode.static, computed, thisReference); - if (args) { - if (args.length === 1 && t.isSpreadElement(args[0])) { - // super(...arguments); - return t.callExpression( - t.memberExpression(superProperty, t.identifier("apply"), false), - [thisReference, args[0].argument] - ); - } else { - return t.callExpression( - t.memberExpression(superProperty, t.identifier("call"), false), - [thisReference].concat(args) - ); - } - } else { - return superProperty; - } - } + var callback = specHandle; + if (self.isFast) callback = fastHandle; + return callback(getThisReference, node, parent); } }); } + + function fastHandle(getThisReference, node, parent) { + if (t.isIdentifier(node, { name: "super" })) { + return self.fastSuperProperty(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(getThisReference()); + } + } + + function specHandle(getThisReference, node, parent) { + 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; + } + + if (!property) return; + + var thisReference = getThisReference(); + var superProperty = self.superProperty(property, methodNode.static, computed, thisReference); + if (args) { + if (args.length === 1 && t.isSpreadElement(args[0])) { + // super(...arguments); + return t.callExpression( + t.memberExpression(superProperty, t.identifier("apply")), + [thisReference, args[0].argument] + ); + } else { + return t.callExpression( + t.memberExpression(superProperty, t.identifier("call")), + [thisReference].concat(args) + ); + } + } else { + return superProperty; + } + } }; /** diff --git a/lib/6to5/transformation/transformers/es6-for-of.js b/lib/6to5/transformation/transformers/es6-for-of.js index 737bf36b14..f24987a2c1 100644 --- a/lib/6to5/transformation/transformers/es6-for-of.js +++ b/lib/6to5/transformation/transformers/es6-for-of.js @@ -2,6 +2,60 @@ var util = require("../../util"); var t = require("../../types"); exports.ForOfStatement = function (node, parent, file, scope) { + var callback = spec; + if (file.isFast("forOf")) callback = fast; + + var build = callback(node, parent, file, scope); + var loop = build.loop; + var block = loop.body; + + // inherit comments from the original loop + t.inheritsComments(loop, node); + + // ensure that it's a block so we can take all it's statemetns + t.ensureBlock(node); + + // push the value declaration to the new loop body + if (build.declar) block.body.push(build.declar); + + // push the rest of the original loop body onto our new body + block.body = block.body.concat(node.body.body); + + return loop; +}; + +var fast = function (node, parent, file, scope) { + var left = node.left; + var declar, id; + + if (t.isIdentifier(left) || t.isPattern(left)) { + // for (i of test), for ({ i } of test) + id = left; + } else if (t.isVariableDeclaration(left)) { + // for (var i of test) + id = left.declarations[0].id; + declar = t.variableDeclaration(left.kind, [ + t.variableDeclarator(id) + ]); + } else { + throw file.errorWithNode(left, "Unknown node type " + left.type + " in ForOfStatement"); + } + + var loop = util.template("for-of-fast", { + LOOP_OBJECT: file.generateUidIdentifier("loopObject", scope), + IS_ARRAY: file.generateUidIdentifier("isArray", scope), + OBJECT: node.right, + INDEX: file.generateUidIdentifier("i", scope), + ID: id + }); + + return { + declar: declar, + loop: loop + }; +}; + +var spec = function (node, parent, file, scope) { var left = node.left; var declar; @@ -9,8 +63,10 @@ exports.ForOfStatement = function (node, parent, file, scope) { var stepValue = t.memberExpression(stepKey, t.identifier("value")); if (t.isIdentifier(left) || t.isPattern(left)) { + // for (i of test), for ({ i } of test) declar = t.expressionStatement(t.assignmentExpression("=", left, stepValue)); } else if (t.isVariableDeclaration(left)) { + // for (var i of test) declar = t.variableDeclaration(left.kind, [ t.variableDeclarator(left.declarations[0].id, stepValue) ]); @@ -18,18 +74,14 @@ exports.ForOfStatement = function (node, parent, file, scope) { throw file.errorWithNode(left, "Unknown node type " + left.type + " in ForOfStatement"); } - var node2 = util.template("for-of", { + var loop = util.template("for-of", { ITERATOR_KEY: file.generateUidIdentifier("iterator", scope), STEP_KEY: stepKey, OBJECT: node.right }); - t.inheritsComments(node2, node); - t.ensureBlock(node); - - var block = node2.body; - block.body.push(declar); - block.body = block.body.concat(node.body.body); - - return node2; + return { + declar: declar, + loop: loop + }; }; diff --git a/lib/6to5/transformation/transformers/optional-for-of-fast.js b/lib/6to5/transformation/transformers/optional-for-of-fast.js deleted file mode 100644 index c2d0f1e148..0000000000 --- a/lib/6to5/transformation/transformers/optional-for-of-fast.js +++ /dev/null @@ -1,37 +0,0 @@ -var util = require("../../util"); -var t = require("../../types"); - -exports.optional = true; - -exports.ForOfStatement = function (node, parent, file, scope) { - var left = node.left; - var declar, id; - - if (t.isIdentifier(left) || t.isPattern(left)) { - id = left; - } else if (t.isVariableDeclaration(left)) { - id = left.declarations[0].id; - declar = t.variableDeclaration(left.kind, [ - t.variableDeclarator(id) - ]); - } else { - throw file.errorWithNode(left, "Unknown node type " + left.type + " in ForOfStatement"); - } - - var node2 = util.template("for-of-fast", { - LOOP_OBJECT: file.generateUidIdentifier("loopObject", scope), - IS_ARRAY: file.generateUidIdentifier("isArray", scope), - OBJECT: node.right, - INDEX: file.generateUidIdentifier("i", scope), - ID: id - }); - - t.inheritsComments(node2, node); - t.ensureBlock(node); - - var block = node2.body; - if (declar) block.body.unshift(declar); - block.body = block.body.concat(node.body.body); - - return node2; -}; diff --git a/test/fixtures/transformation/optional-classes-fast-super/accessing-super-class/actual.js b/test/fixtures/transformation/es6-classes-fast/accessing-super-class/actual.js similarity index 100% rename from test/fixtures/transformation/optional-classes-fast-super/accessing-super-class/actual.js rename to test/fixtures/transformation/es6-classes-fast/accessing-super-class/actual.js diff --git a/test/fixtures/transformation/optional-classes-fast-super/accessing-super-class/expected.js b/test/fixtures/transformation/es6-classes-fast/accessing-super-class/expected.js similarity index 100% rename from test/fixtures/transformation/optional-classes-fast-super/accessing-super-class/expected.js rename to test/fixtures/transformation/es6-classes-fast/accessing-super-class/expected.js diff --git a/test/fixtures/transformation/optional-classes-fast-super/accessing-super-properties/actual.js b/test/fixtures/transformation/es6-classes-fast/accessing-super-properties/actual.js similarity index 100% rename from test/fixtures/transformation/optional-classes-fast-super/accessing-super-properties/actual.js rename to test/fixtures/transformation/es6-classes-fast/accessing-super-properties/actual.js diff --git a/test/fixtures/transformation/optional-classes-fast-super/accessing-super-properties/expected.js b/test/fixtures/transformation/es6-classes-fast/accessing-super-properties/expected.js similarity index 100% rename from test/fixtures/transformation/optional-classes-fast-super/accessing-super-properties/expected.js rename to test/fixtures/transformation/es6-classes-fast/accessing-super-properties/expected.js diff --git a/test/fixtures/transformation/optional-classes-fast-super/calling-super-properties/actual.js b/test/fixtures/transformation/es6-classes-fast/calling-super-properties/actual.js similarity index 100% rename from test/fixtures/transformation/optional-classes-fast-super/calling-super-properties/actual.js rename to test/fixtures/transformation/es6-classes-fast/calling-super-properties/actual.js diff --git a/test/fixtures/transformation/optional-classes-fast-super/calling-super-properties/expected.js b/test/fixtures/transformation/es6-classes-fast/calling-super-properties/expected.js similarity index 100% rename from test/fixtures/transformation/optional-classes-fast-super/calling-super-properties/expected.js rename to test/fixtures/transformation/es6-classes-fast/calling-super-properties/expected.js diff --git a/test/fixtures/transformation/es6-classes-fast/options.json b/test/fixtures/transformation/es6-classes-fast/options.json new file mode 100644 index 0000000000..1777a323e1 --- /dev/null +++ b/test/fixtures/transformation/es6-classes-fast/options.json @@ -0,0 +1,3 @@ +{ + "fast": ["classes"] +} diff --git a/test/fixtures/transformation/optional-classes-fast-super/super-class-id-member-expression/actual.js b/test/fixtures/transformation/es6-classes-fast/super-class-id-member-expression/actual.js similarity index 100% rename from test/fixtures/transformation/optional-classes-fast-super/super-class-id-member-expression/actual.js rename to test/fixtures/transformation/es6-classes-fast/super-class-id-member-expression/actual.js diff --git a/test/fixtures/transformation/optional-classes-fast-super/super-class-id-member-expression/expected.js b/test/fixtures/transformation/es6-classes-fast/super-class-id-member-expression/expected.js similarity index 82% rename from test/fixtures/transformation/optional-classes-fast-super/super-class-id-member-expression/expected.js rename to test/fixtures/transformation/es6-classes-fast/super-class-id-member-expression/expected.js index 0101e0778e..f8b4bc49e2 100644 --- a/test/fixtures/transformation/optional-classes-fast-super/super-class-id-member-expression/expected.js +++ b/test/fixtures/transformation/es6-classes-fast/super-class-id-member-expression/expected.js @@ -17,8 +17,8 @@ var _inherits = function (subClass, superClass) { var BaseController = (function (_Chaplin$Controller) { function BaseController() { - if (Chaplin.Controller != null) { - Chaplin.Controller.apply(this, arguments); + if (_Chaplin$Controller != null) { + _Chaplin$Controller.apply(this, arguments); } } @@ -29,8 +29,8 @@ var BaseController = (function (_Chaplin$Controller) { var BaseController2 = (function (_Chaplin$Controller$Another) { function BaseController2() { - if (Chaplin.Controller.Another != null) { - Chaplin.Controller.Another.apply(this, arguments); + if (_Chaplin$Controller$Another != null) { + _Chaplin$Controller$Another.apply(this, arguments); } } diff --git a/test/fixtures/transformation/optional-classes-fast-super/super-class/actual.js b/test/fixtures/transformation/es6-classes-fast/super-class/actual.js similarity index 100% rename from test/fixtures/transformation/optional-classes-fast-super/super-class/actual.js rename to test/fixtures/transformation/es6-classes-fast/super-class/actual.js diff --git a/test/fixtures/transformation/optional-classes-fast-super/super-class/expected.js b/test/fixtures/transformation/es6-classes-fast/super-class/expected.js similarity index 100% rename from test/fixtures/transformation/optional-classes-fast-super/super-class/expected.js rename to test/fixtures/transformation/es6-classes-fast/super-class/expected.js diff --git a/test/fixtures/transformation/optional-classes-fast-super/super-function-fallback/actual.js b/test/fixtures/transformation/es6-classes-fast/super-function-fallback/actual.js similarity index 100% rename from test/fixtures/transformation/optional-classes-fast-super/super-function-fallback/actual.js rename to test/fixtures/transformation/es6-classes-fast/super-function-fallback/actual.js diff --git a/test/fixtures/transformation/optional-classes-fast-super/super-function-fallback/expected.js b/test/fixtures/transformation/es6-classes-fast/super-function-fallback/expected.js similarity index 100% rename from test/fixtures/transformation/optional-classes-fast-super/super-function-fallback/expected.js rename to test/fixtures/transformation/es6-classes-fast/super-function-fallback/expected.js diff --git a/test/fixtures/transformation/optional-classes-fast-super/options.json b/test/fixtures/transformation/optional-classes-fast-super/options.json deleted file mode 100644 index a1ebbb1755..0000000000 --- a/test/fixtures/transformation/optional-classes-fast-super/options.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "optional": ["classesFastSuper"] -} From f560062d8269ae61eefd8ad348e12f82e29444e4 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 13 Jan 2015 22:02:30 +1100 Subject: [PATCH 30/51] remove loopfunc: false from jshint - thanks @dcousens... --- .jshintrc | 1 - 1 file changed, 1 deletion(-) diff --git a/.jshintrc b/.jshintrc index 9e68224789..9337f7e7ea 100644 --- a/.jshintrc +++ b/.jshintrc @@ -14,7 +14,6 @@ "boss": true, "expr": true, "undef": true, - "loopfunc": true, "white": true, "maxparams": 5, "maxdepth": 4, From 70eae9f6ce12061da2b3abaf7badce2ac37dc1d4 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 13 Jan 2015 22:18:58 +1100 Subject: [PATCH 31/51] remove functions inside of loops --- .../transformers/es6-default-parameters.js | 38 +++++----- .../transformers/es6-let-scoping.js | 7 +- .../optional-classes-fast-super.js | 74 ------------------- 3 files changed, 25 insertions(+), 94 deletions(-) delete mode 100644 lib/6to5/transformation/transformers/optional-classes-fast-super.js diff --git a/lib/6to5/transformation/transformers/es6-default-parameters.js b/lib/6to5/transformation/transformers/es6-default-parameters.js index eb7b6fc1b3..db82d8e2d4 100644 --- a/lib/6to5/transformation/transformers/es6-default-parameters.js +++ b/lib/6to5/transformation/transformers/es6-default-parameters.js @@ -1,7 +1,6 @@ var traverse = require("../../traverse"); var util = require("../../util"); var t = require("../../types"); -var _ = require("lodash"); exports.Function = function (node, parent, file, scope) { if (!node.defaults || !node.defaults.length) return; @@ -15,6 +14,23 @@ exports.Function = function (node, parent, file, scope) { var i; var def; + var checkTDZ = function (ids) { + var check = function (node, parent) { + if (!t.isIdentifier(node) || !t.isReferenced(node, parent)) return; + + if (ids.indexOf(node.name) >= 0) { + throw file.errorWithNode(node, "Temporal dead zone - accessing a variable before it's initialized"); + } + + if (scope.has(node.name, true)) { + iife = true; + } + }; + + check(def, node); + traverse(def, { enter: check }); + }; + for (i in node.defaults) { def = node.defaults[i]; if (!def) continue; @@ -23,22 +39,10 @@ exports.Function = function (node, parent, file, scope) { // temporal dead zone check - here we prevent accessing of params that // are to the right - ie. uninitialized parameters - _.each(ids.slice(i), function (ids) { - var check = function (node, parent) { - if (!t.isIdentifier(node) || !t.isReferenced(node, parent)) return; - - if (ids.indexOf(node.name) >= 0) { - throw file.errorWithNode(node, "Temporal dead zone - accessing a variable before it's initialized"); - } - - if (scope.has(node.name, true)) { - iife = true; - } - }; - - check(def, node); - traverse(def, { enter: check }); - }); + var rightIds = ids.slice(i); + for (i in rightIds) { + checkTDZ(rightIds[i]); + } // we're accessing a variable that's already defined within this function var has = scope.get(param.name); diff --git a/lib/6to5/transformation/transformers/es6-let-scoping.js b/lib/6to5/transformation/transformers/es6-let-scoping.js index 44151d58b8..a95c1b3a30 100644 --- a/lib/6to5/transformation/transformers/es6-let-scoping.js +++ b/lib/6to5/transformation/transformers/es6-let-scoping.js @@ -250,10 +250,11 @@ LetScoping.prototype.getInfo = function () { declar = block.body[i]; if (!isLet(declar, block)) continue; - _.each(t.getIds(declar, true), function (id, key) { - duplicates(id, key); + var declars = t.getIds(declar, true); + for (var key in declars) { + duplicates(declars[key], key); opts.keys.push(key); - }); + } } return opts; diff --git a/lib/6to5/transformation/transformers/optional-classes-fast-super.js b/lib/6to5/transformation/transformers/optional-classes-fast-super.js deleted file mode 100644 index 7f65c08c93..0000000000 --- a/lib/6to5/transformation/transformers/optional-classes-fast-super.js +++ /dev/null @@ -1,74 +0,0 @@ -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; - } -}; From 2a97a4233d3004afd6236bdda1957ca3d360afe8 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 13 Jan 2015 22:26:33 +1100 Subject: [PATCH 32/51] remove invalid jshint options --- .jshintrc | 2 -- 1 file changed, 2 deletions(-) diff --git a/.jshintrc b/.jshintrc index 9337f7e7ea..f6a65273be 100644 --- a/.jshintrc +++ b/.jshintrc @@ -5,7 +5,6 @@ "camelcase": true, "unused": true, "eqnull": true, - "proto": true, "newcap": true, "supernew": true, "noyield": true, @@ -14,7 +13,6 @@ "boss": true, "expr": true, "undef": true, - "white": true, "maxparams": 5, "maxdepth": 4, From f8275adc6fdfc7948f432bc16ddb4d424b3280e7 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 13 Jan 2015 22:44:06 +1100 Subject: [PATCH 33/51] upgrade acorn-6to5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 46c8a49cb1..74203aed6d 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "test": "make test" }, "dependencies": { - "acorn-6to5": "0.11.1-13", + "acorn-6to5": "0.11.1-14", "ast-types": "~0.6.1", "chokidar": "0.11.1", "commander": "2.5.0", From f8915333b0fed643ab9256b7039a7278d7bb63f4 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 13 Jan 2015 22:44:26 +1100 Subject: [PATCH 34/51] remove double spaces in version read in makefile --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c392eefc20..1acfc5281f 100644 --- a/Makefile +++ b/Makefile @@ -71,7 +71,7 @@ publish: make test - read -p "Version: " version; \ + read -p "Version: " version; \ npm version $$version --message "v%s" make build From 1c2bafe0e1fa2333c3a3a17030952f7a27b61574 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 13 Jan 2015 23:18:38 +1100 Subject: [PATCH 35/51] use assignment instead of define for fast classes --- .../transformers/es6-classes.js | 13 ++++++ .../accessing-super-class/expected.js | 40 +++++++------------ .../calling-super-properties/expected.js | 15 +++---- 3 files changed, 33 insertions(+), 35 deletions(-) diff --git a/lib/6to5/transformation/transformers/es6-classes.js b/lib/6to5/transformation/transformers/es6-classes.js index d736dfcd5d..2e7fb8b06f 100644 --- a/lib/6to5/transformation/transformers/es6-classes.js +++ b/lib/6to5/transformation/transformers/es6-classes.js @@ -188,6 +188,19 @@ Class.prototype.pushMethod = function (node) { } if (kind === "") { + if (this.isFast) { + // use assignments instead of define properties for fast classes + + var className = this.className; + if (!node.static) className = t.memberExpression(className, t.identifier("prototype")); + methodName = t.memberExpression(className, methodName, node.computed); + + var expr = t.expressionStatement(t.assignmentExpression("=", methodName, node.value)); + t.inheritsComments(expr, node); + this.body.push(expr); + return; + } + kind = "value"; } diff --git a/test/fixtures/transformation/es6-classes-fast/accessing-super-class/expected.js b/test/fixtures/transformation/es6-classes-fast/accessing-super-class/expected.js index a0dce8e571..6c9bd8d668 100644 --- a/test/fixtures/transformation/es6-classes-fast/accessing-super-class/expected.js +++ b/test/fixtures/transformation/es6-classes-fast/accessing-super-class/expected.js @@ -37,31 +37,21 @@ var Test = (function (Foo) { _inherits(Test, Foo); - _prototypeProperties(Test, { - foo: { - value: 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))); - }, - writable: true, - enumerable: true, - configurable: true - } - }, { - test: { - value: 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))); - }, - writable: true, - enumerable: true, - configurable: true - } - }); + 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))); + }; + + 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))); + }; + + _prototypeProperties(Test, {}, {}); return Test; })(Foo); diff --git a/test/fixtures/transformation/es6-classes-fast/calling-super-properties/expected.js b/test/fixtures/transformation/es6-classes-fast/calling-super-properties/expected.js index 7891b464e4..529795221c 100644 --- a/test/fixtures/transformation/es6-classes-fast/calling-super-properties/expected.js +++ b/test/fixtures/transformation/es6-classes-fast/calling-super-properties/expected.js @@ -28,16 +28,11 @@ var Test = (function (Foo) { _inherits(Test, Foo); - _prototypeProperties(Test, { - test: { - value: function () { - return Foo.wow.call(this); - }, - writable: true, - enumerable: true, - configurable: true - } - }); + Test.test = function () { + return Foo.wow.call(this); + }; + + _prototypeProperties(Test, {}); return Test; })(Foo); From bd2fa77446a5389ca10bf87671fd474e36845dd7 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 13 Jan 2015 23:18:46 +1100 Subject: [PATCH 36/51] fix fast forOf and add tests --- .../transformation/transformers/es6-for-of.js | 24 +++++++++----- .../es6-for-of-fast/identifier/actual.js | 3 ++ .../es6-for-of-fast/identifier/expected.js | 15 +++++++++ .../es6-for-of-fast/let/actual.js | 3 ++ .../es6-for-of-fast/let/expected.js | 16 ++++++++++ .../es6-for-of-fast/multiple/actual.js | 7 +++++ .../es6-for-of-fast/multiple/expected.js | 31 +++++++++++++++++++ .../es6-for-of-fast/options.json | 3 ++ .../es6-for-of-fast/var/actual.js | 3 ++ .../es6-for-of-fast/var/expected.js | 16 ++++++++++ 10 files changed, 113 insertions(+), 8 deletions(-) create mode 100644 test/fixtures/transformation/es6-for-of-fast/identifier/actual.js create mode 100644 test/fixtures/transformation/es6-for-of-fast/identifier/expected.js create mode 100644 test/fixtures/transformation/es6-for-of-fast/let/actual.js create mode 100644 test/fixtures/transformation/es6-for-of-fast/let/expected.js create mode 100644 test/fixtures/transformation/es6-for-of-fast/multiple/actual.js create mode 100644 test/fixtures/transformation/es6-for-of-fast/multiple/expected.js create mode 100644 test/fixtures/transformation/es6-for-of-fast/options.json create mode 100644 test/fixtures/transformation/es6-for-of-fast/var/actual.js create mode 100644 test/fixtures/transformation/es6-for-of-fast/var/expected.js diff --git a/lib/6to5/transformation/transformers/es6-for-of.js b/lib/6to5/transformation/transformers/es6-for-of.js index f24987a2c1..b0ab43a191 100644 --- a/lib/6to5/transformation/transformers/es6-for-of.js +++ b/lib/6to5/transformation/transformers/es6-for-of.js @@ -5,9 +5,10 @@ exports.ForOfStatement = function (node, parent, file, scope) { var callback = spec; if (file.isFast("forOf")) callback = fast; - var build = callback(node, parent, file, scope); - var loop = build.loop; - var block = loop.body; + var build = callback(node, parent, file, scope); + var declar = build.declar; + var loop = build.loop; + var block = loop.body; // inherit comments from the original loop t.inheritsComments(loop, node); @@ -15,8 +16,14 @@ exports.ForOfStatement = function (node, parent, file, scope) { // ensure that it's a block so we can take all it's statemetns t.ensureBlock(node); - // push the value declaration to the new loop body - if (build.declar) block.body.push(build.declar); + // add the value declaration to the new loop body + if (declar){ + if (build.shouldUnshift) { + block.body.unshift(declar); + } else { + block.body.push(declar); + } + } // push the rest of the original loop body onto our new body block.body = block.body.concat(node.body.body); @@ -42,7 +49,7 @@ var fast = function (node, parent, file, scope) { } var loop = util.template("for-of-fast", { - LOOP_OBJECT: file.generateUidIdentifier("loopObject", scope), + LOOP_OBJECT: file.generateUidIdentifier("iterator", scope), IS_ARRAY: file.generateUidIdentifier("isArray", scope), OBJECT: node.right, INDEX: file.generateUidIdentifier("i", scope), @@ -50,8 +57,9 @@ var fast = function (node, parent, file, scope) { }); return { - declar: declar, - loop: loop + shouldUnshift: true, + declar: declar, + loop: loop }; }; diff --git a/test/fixtures/transformation/es6-for-of-fast/identifier/actual.js b/test/fixtures/transformation/es6-for-of-fast/identifier/actual.js new file mode 100644 index 0000000000..ddd15051ba --- /dev/null +++ b/test/fixtures/transformation/es6-for-of-fast/identifier/actual.js @@ -0,0 +1,3 @@ +for (i of arr) { + +} diff --git a/test/fixtures/transformation/es6-for-of-fast/identifier/expected.js b/test/fixtures/transformation/es6-for-of-fast/identifier/expected.js new file mode 100644 index 0000000000..4a7ea3a6a5 --- /dev/null +++ b/test/fixtures/transformation/es6-for-of-fast/identifier/expected.js @@ -0,0 +1,15 @@ +"use strict"; + +for (var _iterator = arr, + _isArray = Array.isArray(_iterator), + _i = 0, + _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { + if (_isArray) { + if (_i >= _iterator.length) break; + i = _iterator[_i++]; + } else { + _i = _iterator.next(); + if (_i.done) break; + i = _i.value; + } +} diff --git a/test/fixtures/transformation/es6-for-of-fast/let/actual.js b/test/fixtures/transformation/es6-for-of-fast/let/actual.js new file mode 100644 index 0000000000..f1e32392de --- /dev/null +++ b/test/fixtures/transformation/es6-for-of-fast/let/actual.js @@ -0,0 +1,3 @@ +for (let i of arr) { + +} diff --git a/test/fixtures/transformation/es6-for-of-fast/let/expected.js b/test/fixtures/transformation/es6-for-of-fast/let/expected.js new file mode 100644 index 0000000000..94848fe0c1 --- /dev/null +++ b/test/fixtures/transformation/es6-for-of-fast/let/expected.js @@ -0,0 +1,16 @@ +"use strict"; + +for (var _iterator = arr, + _isArray = Array.isArray(_iterator), + _i = 0, + _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { + var i = undefined; + if (_isArray) { + if (_i >= _iterator.length) break; + i = _iterator[_i++]; + } else { + _i = _iterator.next(); + if (_i.done) break; + i = _i.value; + } +} diff --git a/test/fixtures/transformation/es6-for-of-fast/multiple/actual.js b/test/fixtures/transformation/es6-for-of-fast/multiple/actual.js new file mode 100644 index 0000000000..d9c969b809 --- /dev/null +++ b/test/fixtures/transformation/es6-for-of-fast/multiple/actual.js @@ -0,0 +1,7 @@ +for (var i of arr) { + +} + +for (var i of numbers) { + +} diff --git a/test/fixtures/transformation/es6-for-of-fast/multiple/expected.js b/test/fixtures/transformation/es6-for-of-fast/multiple/expected.js new file mode 100644 index 0000000000..a20dee268b --- /dev/null +++ b/test/fixtures/transformation/es6-for-of-fast/multiple/expected.js @@ -0,0 +1,31 @@ +"use strict"; + +for (var _iterator = arr, + _isArray = Array.isArray(_iterator), + _i = 0, + _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { + var i; + if (_isArray) { + if (_i >= _iterator.length) break; + i = _iterator[_i++]; + } else { + _i = _iterator.next(); + if (_i.done) break; + i = _i.value; + } +} + +for (var _iterator2 = numbers, + _isArray2 = Array.isArray(_iterator2), + _i2 = 0, + _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { + var i; + if (_isArray2) { + if (_i2 >= _iterator2.length) break; + i = _iterator2[_i2++]; + } else { + _i2 = _iterator2.next(); + if (_i2.done) break; + i = _i2.value; + } +} diff --git a/test/fixtures/transformation/es6-for-of-fast/options.json b/test/fixtures/transformation/es6-for-of-fast/options.json new file mode 100644 index 0000000000..20a82b96e0 --- /dev/null +++ b/test/fixtures/transformation/es6-for-of-fast/options.json @@ -0,0 +1,3 @@ +{ + "fast": ["forOf"] +} diff --git a/test/fixtures/transformation/es6-for-of-fast/var/actual.js b/test/fixtures/transformation/es6-for-of-fast/var/actual.js new file mode 100644 index 0000000000..48e5f59b2c --- /dev/null +++ b/test/fixtures/transformation/es6-for-of-fast/var/actual.js @@ -0,0 +1,3 @@ +for (var i of arr) { + +} diff --git a/test/fixtures/transformation/es6-for-of-fast/var/expected.js b/test/fixtures/transformation/es6-for-of-fast/var/expected.js new file mode 100644 index 0000000000..3695bf3454 --- /dev/null +++ b/test/fixtures/transformation/es6-for-of-fast/var/expected.js @@ -0,0 +1,16 @@ +"use strict"; + +for (var _iterator = arr, + _isArray = Array.isArray(_iterator), + _i = 0, + _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { + var i; + if (_isArray) { + if (_i >= _iterator.length) break; + i = _iterator[_i++]; + } else { + _i = _iterator.next(); + if (_i.done) break; + i = _i.value; + } +} From 4898770d60530c58a2302578601727b25ff98785 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 13 Jan 2015 23:27:26 +1100 Subject: [PATCH 37/51] ignore test262 in istanbul --- test/bin.js | 3 +-- test/test262.js | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/test/bin.js b/test/bin.js index 8930fdf05f..e8bd33b22e 100644 --- a/test/bin.js +++ b/test/bin.js @@ -1,5 +1,4 @@ -// skip these tests under instanbul since they're useless -if (process.env.running_under_istanbul === '1') return; +if (process.env.running_under_istanbul) return; var readdir = require("fs-readdir-recursive"); var helper = require("./_helper"); diff --git a/test/test262.js b/test/test262.js index b8b8f8cb3d..12e31a8927 100644 --- a/test/test262.js +++ b/test/test262.js @@ -1,4 +1,4 @@ -if (process.env.SIMPLE_6TO5_TESTS) return; +if (process.env.SIMPLE_6TO5_TESTS || process.env.running_under_istanbul) return; var transform = require("../lib/6to5/transformation/transform"); var readdir = require("fs-readdir-recursive"); From f25ed0b5dead670f0de16e0c96251a8b3ba45700 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 13 Jan 2015 23:27:52 +1100 Subject: [PATCH 38/51] add minimum of 1 newline after line comments - fixes #442 and fixes #477 --- lib/6to5/generation/whitespace.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/6to5/generation/whitespace.js b/lib/6to5/generation/whitespace.js index aba4628493..c7dda860da 100644 --- a/lib/6to5/generation/whitespace.js +++ b/lib/6to5/generation/whitespace.js @@ -47,7 +47,13 @@ Whitespace.prototype.getNewlinesAfter = function (node) { if (endToken.type.type === "eof") { return 1; } else { - return this.getNewlinesBetween(startToken, endToken); + var lines = this.getNewlinesBetween(startToken, endToken); + if (node.type === "Line" && !lines) { + // line comment + return 1; + } else { + return lines; + } } }; From 8afec8b12ac65f3d82a3c19395b7047a427a1465 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Wed, 14 Jan 2015 00:24:34 +1100 Subject: [PATCH 39/51] rename fast mode to loose #465 --- bin/6to5/index.js | 4 ++-- lib/6to5/file.js | 12 ++++++------ ....js => class-super-constructor-call-loose.js} | 0 .../{for-of-fast.js => for-of-loose.js} | 0 .../transformation/transformers/es6-classes.js | 16 ++++++++-------- .../transformation/transformers/es6-for-of.js | 6 +++--- .../transformation/es6-classes-fast/options.json | 3 --- .../accessing-super-class/actual.js | 0 .../accessing-super-class/expected.js | 0 .../accessing-super-properties/actual.js | 0 .../accessing-super-properties/expected.js | 0 .../calling-super-properties/actual.js | 0 .../calling-super-properties/expected.js | 0 .../es6-classes-loose/options.json | 3 +++ .../super-class-id-member-expression/actual.js | 0 .../super-class-id-member-expression/expected.js | 0 .../super-class/actual.js | 0 .../super-class/expected.js | 0 .../super-function-fallback/actual.js | 0 .../super-function-fallback/expected.js | 0 .../transformation/es6-for-of-fast/options.json | 3 --- .../identifier/actual.js | 0 .../identifier/expected.js | 0 .../let/actual.js | 0 .../let/expected.js | 0 .../multiple/actual.js | 0 .../multiple/expected.js | 0 .../transformation/es6-for-of-loose/options.json | 3 +++ .../var/actual.js | 0 .../var/expected.js | 0 30 files changed, 25 insertions(+), 25 deletions(-) rename lib/6to5/transformation/templates/{class-super-constructor-call-fast.js => class-super-constructor-call-loose.js} (100%) rename lib/6to5/transformation/templates/{for-of-fast.js => for-of-loose.js} (100%) delete mode 100644 test/fixtures/transformation/es6-classes-fast/options.json rename test/fixtures/transformation/{es6-classes-fast => es6-classes-loose}/accessing-super-class/actual.js (100%) rename test/fixtures/transformation/{es6-classes-fast => es6-classes-loose}/accessing-super-class/expected.js (100%) rename test/fixtures/transformation/{es6-classes-fast => es6-classes-loose}/accessing-super-properties/actual.js (100%) rename test/fixtures/transformation/{es6-classes-fast => es6-classes-loose}/accessing-super-properties/expected.js (100%) rename test/fixtures/transformation/{es6-classes-fast => es6-classes-loose}/calling-super-properties/actual.js (100%) rename test/fixtures/transformation/{es6-classes-fast => es6-classes-loose}/calling-super-properties/expected.js (100%) create mode 100644 test/fixtures/transformation/es6-classes-loose/options.json rename test/fixtures/transformation/{es6-classes-fast => es6-classes-loose}/super-class-id-member-expression/actual.js (100%) rename test/fixtures/transformation/{es6-classes-fast => es6-classes-loose}/super-class-id-member-expression/expected.js (100%) rename test/fixtures/transformation/{es6-classes-fast => es6-classes-loose}/super-class/actual.js (100%) rename test/fixtures/transformation/{es6-classes-fast => es6-classes-loose}/super-class/expected.js (100%) rename test/fixtures/transformation/{es6-classes-fast => es6-classes-loose}/super-function-fallback/actual.js (100%) rename test/fixtures/transformation/{es6-classes-fast => es6-classes-loose}/super-function-fallback/expected.js (100%) delete mode 100644 test/fixtures/transformation/es6-for-of-fast/options.json rename test/fixtures/transformation/{es6-for-of-fast => es6-for-of-loose}/identifier/actual.js (100%) rename test/fixtures/transformation/{es6-for-of-fast => es6-for-of-loose}/identifier/expected.js (100%) rename test/fixtures/transformation/{es6-for-of-fast => es6-for-of-loose}/let/actual.js (100%) rename test/fixtures/transformation/{es6-for-of-fast => es6-for-of-loose}/let/expected.js (100%) rename test/fixtures/transformation/{es6-for-of-fast => es6-for-of-loose}/multiple/actual.js (100%) rename test/fixtures/transformation/{es6-for-of-fast => es6-for-of-loose}/multiple/expected.js (100%) create mode 100644 test/fixtures/transformation/es6-for-of-loose/options.json rename test/fixtures/transformation/{es6-for-of-fast => es6-for-of-loose}/var/actual.js (100%) rename test/fixtures/transformation/{es6-for-of-fast => es6-for-of-loose}/var/expected.js (100%) diff --git a/bin/6to5/index.js b/bin/6to5/index.js index b5dd079d29..955671555d 100755 --- a/bin/6to5/index.js +++ b/bin/6to5/index.js @@ -18,7 +18,7 @@ commander.option("-m, --modules [modules]", "Module formatter type to use [commo commander.option("-l, --whitelist [whitelist]", "Whitelist of transformers to ONLY use", util.list); commander.option("-b, --blacklist [blacklist]", "Blacklist of transformers to NOT use", util.list); commander.option("-i, --optional [list]", "List of optional transformers to enable", util.list); -commander.option("--fast [list]", "List of transformers to enable their fast mode", util.list); +commander.option("--loose [list]", "List of transformers to enable their loose mode", util.list); commander.option("-o, --out-file [out]", "Compile all input files into a single file"); commander.option("-d, --out-dir [out]", "Compile an input directory of modules into an output directory"); commander.option("-c, --remove-comments", "Remove comments from the compiled code", false); @@ -117,7 +117,7 @@ exports.opts = { comments: !commander.removeComments, runtime: commander.runtime, modules: commander.modules, - fast: commander.fast, + loose: commander.loose, format: { indent: { style: util.repeat(parseInt(commander.indent)) diff --git a/lib/6to5/file.js b/lib/6to5/file.js index ef830e1ab6..2757dcb1e2 100644 --- a/lib/6to5/file.js +++ b/lib/6to5/file.js @@ -63,7 +63,7 @@ File.normaliseOptions = function (opts) { filename: "unknown", modules: "common", runtime: false, - fast: [], + loose: [], code: true, ast: true }); @@ -74,7 +74,7 @@ File.normaliseOptions = function (opts) { opts.blacklist = util.arrayify(opts.blacklist); opts.whitelist = util.arrayify(opts.whitelist); opts.optional = util.arrayify(opts.optional); - opts.fast = util.arrayify(opts.fast); + opts.loose = util.arrayify(opts.loose); // todo: remove in 3.0.0 _.each({ @@ -83,7 +83,7 @@ File.normaliseOptions = function (opts) { }, function (newTransformer, oldTransformer) { if (_.contains(opts.optional, oldTransformer)) { _.pull(opts.optional, oldTransformer); - opts.fast.push(newTransformer); + opts.loose.push(newTransformer); } }); @@ -115,13 +115,13 @@ File.normaliseOptions = function (opts) { transform._ensureTransformerNames("blacklist", opts.blacklist); transform._ensureTransformerNames("whitelist", opts.whitelist); transform._ensureTransformerNames("optional", opts.optional); - transform._ensureTransformerNames("fast", opts.fast); + transform._ensureTransformerNames("loose", opts.loose); return opts; }; -File.prototype.isFast = function (key) { - return _.contains(this.opts.fast, key); +File.prototype.isLoose = function (key) { + return _.contains(this.opts.loose, key); }; File.prototype.getTransformers = function () { diff --git a/lib/6to5/transformation/templates/class-super-constructor-call-fast.js b/lib/6to5/transformation/templates/class-super-constructor-call-loose.js similarity index 100% rename from lib/6to5/transformation/templates/class-super-constructor-call-fast.js rename to lib/6to5/transformation/templates/class-super-constructor-call-loose.js diff --git a/lib/6to5/transformation/templates/for-of-fast.js b/lib/6to5/transformation/templates/for-of-loose.js similarity index 100% rename from lib/6to5/transformation/templates/for-of-fast.js rename to lib/6to5/transformation/templates/for-of-loose.js diff --git a/lib/6to5/transformation/transformers/es6-classes.js b/lib/6to5/transformation/transformers/es6-classes.js index 2e7fb8b06f..c31d1787b9 100644 --- a/lib/6to5/transformation/transformers/es6-classes.js +++ b/lib/6to5/transformation/transformers/es6-classes.js @@ -33,7 +33,7 @@ function Class(node, file, scope, isStatement) { this.hasConstructor = false; this.className = node.id || file.generateUidIdentifier("class", scope); this.superName = node.superClass; - this.isFast = file.isFast("classes"); + this.isLoose = file.isLoose("classes"); } /** @@ -138,7 +138,7 @@ Class.prototype.buildBody = function () { // we have no constructor, we have a super, and the super doesn't appear to be falsy if (!this.hasConstructor && superName && !t.isFalsyExpression(superName)) { var defaultConstructorTemplate = "class-super-constructor-call"; - if (this.isFast) defaultConstructorTemplate += "-fast"; + if (this.isLoose) defaultConstructorTemplate += "-loose"; constructor.body.body.push(util.template(defaultConstructorTemplate, { CLASS_NAME: className, @@ -188,8 +188,8 @@ Class.prototype.pushMethod = function (node) { } if (kind === "") { - if (this.isFast) { - // use assignments instead of define properties for fast classes + if (this.isLoose) { + // use assignments instead of define properties for loose classes var className = this.className; if (!node.static) className = t.memberExpression(className, t.identifier("prototype")); @@ -246,7 +246,7 @@ Class.prototype.superProperty = function (property, isStatic, isComputed, thisEx * @returns {Object} */ -Class.prototype.fastSuperProperty = function (methodNode, id, parent) { +Class.prototype.looseSuperProperty = function (methodNode, id, parent) { var methodName = methodNode.key; var superName = this.superName || t.identifier("Function"); @@ -318,15 +318,15 @@ Class.prototype.replaceInstanceSuperReferences = function (methodNode) { }; var callback = specHandle; - if (self.isFast) callback = fastHandle; + if (self.isLoose) callback = looseHandle; return callback(getThisReference, node, parent); } }); } - function fastHandle(getThisReference, node, parent) { + function looseHandle(getThisReference, node, parent) { if (t.isIdentifier(node, { name: "super" })) { - return self.fastSuperProperty(methodNode, node, parent); + return self.looseSuperProperty(methodNode, node, parent); } else if (t.isCallExpression(node)) { var callee = node.callee; if (!t.isMemberExpression(callee)) return; diff --git a/lib/6to5/transformation/transformers/es6-for-of.js b/lib/6to5/transformation/transformers/es6-for-of.js index b0ab43a191..61357cfbad 100644 --- a/lib/6to5/transformation/transformers/es6-for-of.js +++ b/lib/6to5/transformation/transformers/es6-for-of.js @@ -3,7 +3,7 @@ var t = require("../../types"); exports.ForOfStatement = function (node, parent, file, scope) { var callback = spec; - if (file.isFast("forOf")) callback = fast; + if (file.isLoose("forOf")) callback = loose; var build = callback(node, parent, file, scope); var declar = build.declar; @@ -31,7 +31,7 @@ exports.ForOfStatement = function (node, parent, file, scope) { return loop; }; -var fast = function (node, parent, file, scope) { +var loose = function (node, parent, file, scope) { var left = node.left; var declar, id; @@ -48,7 +48,7 @@ var fast = function (node, parent, file, scope) { throw file.errorWithNode(left, "Unknown node type " + left.type + " in ForOfStatement"); } - var loop = util.template("for-of-fast", { + var loop = util.template("for-of-loose", { LOOP_OBJECT: file.generateUidIdentifier("iterator", scope), IS_ARRAY: file.generateUidIdentifier("isArray", scope), OBJECT: node.right, diff --git a/test/fixtures/transformation/es6-classes-fast/options.json b/test/fixtures/transformation/es6-classes-fast/options.json deleted file mode 100644 index 1777a323e1..0000000000 --- a/test/fixtures/transformation/es6-classes-fast/options.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "fast": ["classes"] -} diff --git a/test/fixtures/transformation/es6-classes-fast/accessing-super-class/actual.js b/test/fixtures/transformation/es6-classes-loose/accessing-super-class/actual.js similarity index 100% rename from test/fixtures/transformation/es6-classes-fast/accessing-super-class/actual.js rename to test/fixtures/transformation/es6-classes-loose/accessing-super-class/actual.js diff --git a/test/fixtures/transformation/es6-classes-fast/accessing-super-class/expected.js b/test/fixtures/transformation/es6-classes-loose/accessing-super-class/expected.js similarity index 100% rename from test/fixtures/transformation/es6-classes-fast/accessing-super-class/expected.js rename to test/fixtures/transformation/es6-classes-loose/accessing-super-class/expected.js diff --git a/test/fixtures/transformation/es6-classes-fast/accessing-super-properties/actual.js b/test/fixtures/transformation/es6-classes-loose/accessing-super-properties/actual.js similarity index 100% rename from test/fixtures/transformation/es6-classes-fast/accessing-super-properties/actual.js rename to test/fixtures/transformation/es6-classes-loose/accessing-super-properties/actual.js diff --git a/test/fixtures/transformation/es6-classes-fast/accessing-super-properties/expected.js b/test/fixtures/transformation/es6-classes-loose/accessing-super-properties/expected.js similarity index 100% rename from test/fixtures/transformation/es6-classes-fast/accessing-super-properties/expected.js rename to test/fixtures/transformation/es6-classes-loose/accessing-super-properties/expected.js diff --git a/test/fixtures/transformation/es6-classes-fast/calling-super-properties/actual.js b/test/fixtures/transformation/es6-classes-loose/calling-super-properties/actual.js similarity index 100% rename from test/fixtures/transformation/es6-classes-fast/calling-super-properties/actual.js rename to test/fixtures/transformation/es6-classes-loose/calling-super-properties/actual.js diff --git a/test/fixtures/transformation/es6-classes-fast/calling-super-properties/expected.js b/test/fixtures/transformation/es6-classes-loose/calling-super-properties/expected.js similarity index 100% rename from test/fixtures/transformation/es6-classes-fast/calling-super-properties/expected.js rename to test/fixtures/transformation/es6-classes-loose/calling-super-properties/expected.js diff --git a/test/fixtures/transformation/es6-classes-loose/options.json b/test/fixtures/transformation/es6-classes-loose/options.json new file mode 100644 index 0000000000..b928f940e6 --- /dev/null +++ b/test/fixtures/transformation/es6-classes-loose/options.json @@ -0,0 +1,3 @@ +{ + "loose": ["classes"] +} diff --git a/test/fixtures/transformation/es6-classes-fast/super-class-id-member-expression/actual.js b/test/fixtures/transformation/es6-classes-loose/super-class-id-member-expression/actual.js similarity index 100% rename from test/fixtures/transformation/es6-classes-fast/super-class-id-member-expression/actual.js rename to test/fixtures/transformation/es6-classes-loose/super-class-id-member-expression/actual.js diff --git a/test/fixtures/transformation/es6-classes-fast/super-class-id-member-expression/expected.js b/test/fixtures/transformation/es6-classes-loose/super-class-id-member-expression/expected.js similarity index 100% rename from test/fixtures/transformation/es6-classes-fast/super-class-id-member-expression/expected.js rename to test/fixtures/transformation/es6-classes-loose/super-class-id-member-expression/expected.js diff --git a/test/fixtures/transformation/es6-classes-fast/super-class/actual.js b/test/fixtures/transformation/es6-classes-loose/super-class/actual.js similarity index 100% rename from test/fixtures/transformation/es6-classes-fast/super-class/actual.js rename to test/fixtures/transformation/es6-classes-loose/super-class/actual.js diff --git a/test/fixtures/transformation/es6-classes-fast/super-class/expected.js b/test/fixtures/transformation/es6-classes-loose/super-class/expected.js similarity index 100% rename from test/fixtures/transformation/es6-classes-fast/super-class/expected.js rename to test/fixtures/transformation/es6-classes-loose/super-class/expected.js diff --git a/test/fixtures/transformation/es6-classes-fast/super-function-fallback/actual.js b/test/fixtures/transformation/es6-classes-loose/super-function-fallback/actual.js similarity index 100% rename from test/fixtures/transformation/es6-classes-fast/super-function-fallback/actual.js rename to test/fixtures/transformation/es6-classes-loose/super-function-fallback/actual.js diff --git a/test/fixtures/transformation/es6-classes-fast/super-function-fallback/expected.js b/test/fixtures/transformation/es6-classes-loose/super-function-fallback/expected.js similarity index 100% rename from test/fixtures/transformation/es6-classes-fast/super-function-fallback/expected.js rename to test/fixtures/transformation/es6-classes-loose/super-function-fallback/expected.js diff --git a/test/fixtures/transformation/es6-for-of-fast/options.json b/test/fixtures/transformation/es6-for-of-fast/options.json deleted file mode 100644 index 20a82b96e0..0000000000 --- a/test/fixtures/transformation/es6-for-of-fast/options.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "fast": ["forOf"] -} diff --git a/test/fixtures/transformation/es6-for-of-fast/identifier/actual.js b/test/fixtures/transformation/es6-for-of-loose/identifier/actual.js similarity index 100% rename from test/fixtures/transformation/es6-for-of-fast/identifier/actual.js rename to test/fixtures/transformation/es6-for-of-loose/identifier/actual.js diff --git a/test/fixtures/transformation/es6-for-of-fast/identifier/expected.js b/test/fixtures/transformation/es6-for-of-loose/identifier/expected.js similarity index 100% rename from test/fixtures/transformation/es6-for-of-fast/identifier/expected.js rename to test/fixtures/transformation/es6-for-of-loose/identifier/expected.js diff --git a/test/fixtures/transformation/es6-for-of-fast/let/actual.js b/test/fixtures/transformation/es6-for-of-loose/let/actual.js similarity index 100% rename from test/fixtures/transformation/es6-for-of-fast/let/actual.js rename to test/fixtures/transformation/es6-for-of-loose/let/actual.js diff --git a/test/fixtures/transformation/es6-for-of-fast/let/expected.js b/test/fixtures/transformation/es6-for-of-loose/let/expected.js similarity index 100% rename from test/fixtures/transformation/es6-for-of-fast/let/expected.js rename to test/fixtures/transformation/es6-for-of-loose/let/expected.js diff --git a/test/fixtures/transformation/es6-for-of-fast/multiple/actual.js b/test/fixtures/transformation/es6-for-of-loose/multiple/actual.js similarity index 100% rename from test/fixtures/transformation/es6-for-of-fast/multiple/actual.js rename to test/fixtures/transformation/es6-for-of-loose/multiple/actual.js diff --git a/test/fixtures/transformation/es6-for-of-fast/multiple/expected.js b/test/fixtures/transformation/es6-for-of-loose/multiple/expected.js similarity index 100% rename from test/fixtures/transformation/es6-for-of-fast/multiple/expected.js rename to test/fixtures/transformation/es6-for-of-loose/multiple/expected.js diff --git a/test/fixtures/transformation/es6-for-of-loose/options.json b/test/fixtures/transformation/es6-for-of-loose/options.json new file mode 100644 index 0000000000..c2821829bf --- /dev/null +++ b/test/fixtures/transformation/es6-for-of-loose/options.json @@ -0,0 +1,3 @@ +{ + "loose": ["forOf"] +} diff --git a/test/fixtures/transformation/es6-for-of-fast/var/actual.js b/test/fixtures/transformation/es6-for-of-loose/var/actual.js similarity index 100% rename from test/fixtures/transformation/es6-for-of-fast/var/actual.js rename to test/fixtures/transformation/es6-for-of-loose/var/actual.js diff --git a/test/fixtures/transformation/es6-for-of-fast/var/expected.js b/test/fixtures/transformation/es6-for-of-loose/var/expected.js similarity index 100% rename from test/fixtures/transformation/es6-for-of-fast/var/expected.js rename to test/fixtures/transformation/es6-for-of-loose/var/expected.js From afd3af834dfe8b0609c1c148c44ed67fe5df7b14 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Wed, 14 Jan 2015 00:35:45 +1100 Subject: [PATCH 40/51] add loose option to computed property names --- .../es6-computed-property-names.js | 53 ++++++++++++++----- .../argument/actual.js | 3 ++ .../argument/expected.js | 8 +++ .../assignment/actual.js | 3 ++ .../assignment/expected.js | 8 +++ .../ignore-symbol/actual.js | 3 ++ .../ignore-symbol/expected.js | 8 +++ .../method/actual.js | 5 ++ .../method/expected.js | 11 ++++ .../mixed/actual.js | 6 +++ .../mixed/expected.js | 11 ++++ .../multiple/actual.js | 4 ++ .../multiple/expected.js | 9 ++++ .../options.json | 3 ++ .../single/actual.js | 3 ++ .../single/expected.js | 8 +++ .../this/actual.js | 3 ++ .../this/expected.js | 9 ++++ .../two/actual.js | 4 ++ .../two/expected.js | 9 ++++ .../variable/actual.js | 3 ++ .../variable/expected.js | 8 +++ 22 files changed, 168 insertions(+), 14 deletions(-) create mode 100644 test/fixtures/transformation/es6-computed-property-names-loose/argument/actual.js create mode 100644 test/fixtures/transformation/es6-computed-property-names-loose/argument/expected.js create mode 100644 test/fixtures/transformation/es6-computed-property-names-loose/assignment/actual.js create mode 100644 test/fixtures/transformation/es6-computed-property-names-loose/assignment/expected.js create mode 100644 test/fixtures/transformation/es6-computed-property-names-loose/ignore-symbol/actual.js create mode 100644 test/fixtures/transformation/es6-computed-property-names-loose/ignore-symbol/expected.js create mode 100644 test/fixtures/transformation/es6-computed-property-names-loose/method/actual.js create mode 100644 test/fixtures/transformation/es6-computed-property-names-loose/method/expected.js create mode 100644 test/fixtures/transformation/es6-computed-property-names-loose/mixed/actual.js create mode 100644 test/fixtures/transformation/es6-computed-property-names-loose/mixed/expected.js create mode 100644 test/fixtures/transformation/es6-computed-property-names-loose/multiple/actual.js create mode 100644 test/fixtures/transformation/es6-computed-property-names-loose/multiple/expected.js create mode 100644 test/fixtures/transformation/es6-computed-property-names-loose/options.json create mode 100644 test/fixtures/transformation/es6-computed-property-names-loose/single/actual.js create mode 100644 test/fixtures/transformation/es6-computed-property-names-loose/single/expected.js create mode 100644 test/fixtures/transformation/es6-computed-property-names-loose/this/actual.js create mode 100644 test/fixtures/transformation/es6-computed-property-names-loose/this/expected.js create mode 100644 test/fixtures/transformation/es6-computed-property-names-loose/two/actual.js create mode 100644 test/fixtures/transformation/es6-computed-property-names-loose/two/expected.js create mode 100644 test/fixtures/transformation/es6-computed-property-names-loose/variable/actual.js create mode 100644 test/fixtures/transformation/es6-computed-property-names-loose/variable/expected.js diff --git a/lib/6to5/transformation/transformers/es6-computed-property-names.js b/lib/6to5/transformation/transformers/es6-computed-property-names.js index 3a559177df..bc3c9091f2 100644 --- a/lib/6to5/transformation/transformers/es6-computed-property-names.js +++ b/lib/6to5/transformation/transformers/es6-computed-property-names.js @@ -4,26 +4,62 @@ exports.ObjectExpression = function (node, parent, file, scope) { var hasComputed = false; var prop; var key; - var i; - for (i in node.properties) { + for (var i in node.properties) { hasComputed = t.isProperty(node.properties[i], { computed: true, kind: "init" }); if (hasComputed) break; } if (!hasComputed) return; + var initProps = []; var objId = scope.generateUidBasedOnNode(parent, file); + // + var body = []; var container = t.functionExpression(null, [], t.blockStatement(body)); container._aliasFunction = true; + // + + var callback = spec; + if (file.isLoose("computedPropertyNames")) callback = loose; + + var result = callback(node, body, objId, initProps, file); + if (result) return result; + + // + + body.unshift(t.variableDeclaration("var", [ + t.variableDeclarator(objId, t.objectExpression(initProps)) + ])); + + body.push(t.returnStatement(objId)); + + return t.callExpression(container, []); +}; + +var loose = function (node, body, objId) { + for (var i in node.properties) { + var prop = node.properties[i]; + + body.push(t.expressionStatement( + t.assignmentExpression( + "=", + t.memberExpression(objId, prop.key, prop.computed), + prop.value + ) + )); + } +}; + +var spec = function (node, body, objId, initProps, file) { var props = node.properties; // normalise key - for (i in props) { + for (var i in props) { prop = props[i]; if (prop.kind !== "init") continue; @@ -36,7 +72,6 @@ exports.ObjectExpression = function (node, parent, file, scope) { // add all non-computed properties and `__proto__` properties to the initializer - var initProps = []; var broken = false; for (i in props) { @@ -86,14 +121,4 @@ exports.ObjectExpression = function (node, parent, file, scope) { return first; } } - - // - - body.unshift(t.variableDeclaration("var", [ - t.variableDeclarator(objId, t.objectExpression(initProps)) - ])); - - body.push(t.returnStatement(objId)); - - return t.callExpression(container, []); }; diff --git a/test/fixtures/transformation/es6-computed-property-names-loose/argument/actual.js b/test/fixtures/transformation/es6-computed-property-names-loose/argument/actual.js new file mode 100644 index 0000000000..fc50c41c49 --- /dev/null +++ b/test/fixtures/transformation/es6-computed-property-names-loose/argument/actual.js @@ -0,0 +1,3 @@ +foo({ + [bar]: "foobar" +}); diff --git a/test/fixtures/transformation/es6-computed-property-names-loose/argument/expected.js b/test/fixtures/transformation/es6-computed-property-names-loose/argument/expected.js new file mode 100644 index 0000000000..8a544ec30e --- /dev/null +++ b/test/fixtures/transformation/es6-computed-property-names-loose/argument/expected.js @@ -0,0 +1,8 @@ +"use strict"; + +foo((function () { + var _foo = {}; + + _foo[bar] = "foobar"; + return _foo; +})()); \ No newline at end of file diff --git a/test/fixtures/transformation/es6-computed-property-names-loose/assignment/actual.js b/test/fixtures/transformation/es6-computed-property-names-loose/assignment/actual.js new file mode 100644 index 0000000000..dd74ed9f04 --- /dev/null +++ b/test/fixtures/transformation/es6-computed-property-names-loose/assignment/actual.js @@ -0,0 +1,3 @@ +foo = { + [bar]: "foobar" +}; diff --git a/test/fixtures/transformation/es6-computed-property-names-loose/assignment/expected.js b/test/fixtures/transformation/es6-computed-property-names-loose/assignment/expected.js new file mode 100644 index 0000000000..2b1f23d706 --- /dev/null +++ b/test/fixtures/transformation/es6-computed-property-names-loose/assignment/expected.js @@ -0,0 +1,8 @@ +"use strict"; + +foo = (function () { + var _foo = {}; + + _foo[bar] = "foobar"; + return _foo; +})(); \ No newline at end of file diff --git a/test/fixtures/transformation/es6-computed-property-names-loose/ignore-symbol/actual.js b/test/fixtures/transformation/es6-computed-property-names-loose/ignore-symbol/actual.js new file mode 100644 index 0000000000..fce8293ed4 --- /dev/null +++ b/test/fixtures/transformation/es6-computed-property-names-loose/ignore-symbol/actual.js @@ -0,0 +1,3 @@ +var foo = { + [Symbol.iterator]: "foobar" +}; diff --git a/test/fixtures/transformation/es6-computed-property-names-loose/ignore-symbol/expected.js b/test/fixtures/transformation/es6-computed-property-names-loose/ignore-symbol/expected.js new file mode 100644 index 0000000000..852e2b4e6c --- /dev/null +++ b/test/fixtures/transformation/es6-computed-property-names-loose/ignore-symbol/expected.js @@ -0,0 +1,8 @@ +"use strict"; + +var foo = (function () { + var _foo = {}; + + _foo[Symbol.iterator] = "foobar"; + return _foo; +})(); diff --git a/test/fixtures/transformation/es6-computed-property-names-loose/method/actual.js b/test/fixtures/transformation/es6-computed-property-names-loose/method/actual.js new file mode 100644 index 0000000000..068edebd55 --- /dev/null +++ b/test/fixtures/transformation/es6-computed-property-names-loose/method/actual.js @@ -0,0 +1,5 @@ +var obj = { + [foobar]() { + return "foobar"; + } +}; diff --git a/test/fixtures/transformation/es6-computed-property-names-loose/method/expected.js b/test/fixtures/transformation/es6-computed-property-names-loose/method/expected.js new file mode 100644 index 0000000000..da3d3d08e2 --- /dev/null +++ b/test/fixtures/transformation/es6-computed-property-names-loose/method/expected.js @@ -0,0 +1,11 @@ +"use strict"; + +var obj = (function () { + var _obj = {}; + + _obj[foobar] = function () { + return "foobar"; + }; + + return _obj; +})(); \ No newline at end of file diff --git a/test/fixtures/transformation/es6-computed-property-names-loose/mixed/actual.js b/test/fixtures/transformation/es6-computed-property-names-loose/mixed/actual.js new file mode 100644 index 0000000000..17e110ad3d --- /dev/null +++ b/test/fixtures/transformation/es6-computed-property-names-loose/mixed/actual.js @@ -0,0 +1,6 @@ +var obj = { + ["x" + foo]: "heh", + ["y" + bar]: "noo", + foo: "foo", + bar: "bar" +}; diff --git a/test/fixtures/transformation/es6-computed-property-names-loose/mixed/expected.js b/test/fixtures/transformation/es6-computed-property-names-loose/mixed/expected.js new file mode 100644 index 0000000000..7728ebd72c --- /dev/null +++ b/test/fixtures/transformation/es6-computed-property-names-loose/mixed/expected.js @@ -0,0 +1,11 @@ +"use strict"; + +var obj = (function () { + var _obj = {}; + + _obj["x" + foo] = "heh"; + _obj["y" + bar] = "noo"; + _obj.foo = "foo"; + _obj.bar = "bar"; + return _obj; +})(); \ No newline at end of file diff --git a/test/fixtures/transformation/es6-computed-property-names-loose/multiple/actual.js b/test/fixtures/transformation/es6-computed-property-names-loose/multiple/actual.js new file mode 100644 index 0000000000..02d4195fa7 --- /dev/null +++ b/test/fixtures/transformation/es6-computed-property-names-loose/multiple/actual.js @@ -0,0 +1,4 @@ +var obj = { + ["x" + foo]: "heh", + ["y" + bar]: "noo" +}; diff --git a/test/fixtures/transformation/es6-computed-property-names-loose/multiple/expected.js b/test/fixtures/transformation/es6-computed-property-names-loose/multiple/expected.js new file mode 100644 index 0000000000..fb1c4ceb31 --- /dev/null +++ b/test/fixtures/transformation/es6-computed-property-names-loose/multiple/expected.js @@ -0,0 +1,9 @@ +"use strict"; + +var obj = (function () { + var _obj = {}; + + _obj["x" + foo] = "heh"; + _obj["y" + bar] = "noo"; + return _obj; +})(); \ No newline at end of file diff --git a/test/fixtures/transformation/es6-computed-property-names-loose/options.json b/test/fixtures/transformation/es6-computed-property-names-loose/options.json new file mode 100644 index 0000000000..422293bd82 --- /dev/null +++ b/test/fixtures/transformation/es6-computed-property-names-loose/options.json @@ -0,0 +1,3 @@ +{ + "loose": ["computedPropertyNames"] +} diff --git a/test/fixtures/transformation/es6-computed-property-names-loose/single/actual.js b/test/fixtures/transformation/es6-computed-property-names-loose/single/actual.js new file mode 100644 index 0000000000..04ec89b5ce --- /dev/null +++ b/test/fixtures/transformation/es6-computed-property-names-loose/single/actual.js @@ -0,0 +1,3 @@ +var obj = { + ["x" + foo]: "heh" +}; diff --git a/test/fixtures/transformation/es6-computed-property-names-loose/single/expected.js b/test/fixtures/transformation/es6-computed-property-names-loose/single/expected.js new file mode 100644 index 0000000000..627faff494 --- /dev/null +++ b/test/fixtures/transformation/es6-computed-property-names-loose/single/expected.js @@ -0,0 +1,8 @@ +"use strict"; + +var obj = (function () { + var _obj = {}; + + _obj["x" + foo] = "heh"; + return _obj; +})(); \ No newline at end of file diff --git a/test/fixtures/transformation/es6-computed-property-names-loose/this/actual.js b/test/fixtures/transformation/es6-computed-property-names-loose/this/actual.js new file mode 100644 index 0000000000..3e3a34ef12 --- /dev/null +++ b/test/fixtures/transformation/es6-computed-property-names-loose/this/actual.js @@ -0,0 +1,3 @@ +var obj = { + ["x" + this.foo]: "heh" +}; diff --git a/test/fixtures/transformation/es6-computed-property-names-loose/this/expected.js b/test/fixtures/transformation/es6-computed-property-names-loose/this/expected.js new file mode 100644 index 0000000000..23b5ee17e4 --- /dev/null +++ b/test/fixtures/transformation/es6-computed-property-names-loose/this/expected.js @@ -0,0 +1,9 @@ +"use strict"; + +var _this = this; +var obj = (function () { + var _obj = {}; + + _obj["x" + _this.foo] = "heh"; + return _obj; +})(); \ No newline at end of file diff --git a/test/fixtures/transformation/es6-computed-property-names-loose/two/actual.js b/test/fixtures/transformation/es6-computed-property-names-loose/two/actual.js new file mode 100644 index 0000000000..c63046dd19 --- /dev/null +++ b/test/fixtures/transformation/es6-computed-property-names-loose/two/actual.js @@ -0,0 +1,4 @@ +var obj = { + first: "first", + ["second"]: "second", +}; diff --git a/test/fixtures/transformation/es6-computed-property-names-loose/two/expected.js b/test/fixtures/transformation/es6-computed-property-names-loose/two/expected.js new file mode 100644 index 0000000000..42ef0c1e64 --- /dev/null +++ b/test/fixtures/transformation/es6-computed-property-names-loose/two/expected.js @@ -0,0 +1,9 @@ +"use strict"; + +var obj = (function () { + var _obj = {}; + + _obj.first = "first"; + _obj.second = "second"; + return _obj; +})(); diff --git a/test/fixtures/transformation/es6-computed-property-names-loose/variable/actual.js b/test/fixtures/transformation/es6-computed-property-names-loose/variable/actual.js new file mode 100644 index 0000000000..13d8e7f24a --- /dev/null +++ b/test/fixtures/transformation/es6-computed-property-names-loose/variable/actual.js @@ -0,0 +1,3 @@ +var foo = { + [bar]: "foobar" +}; diff --git a/test/fixtures/transformation/es6-computed-property-names-loose/variable/expected.js b/test/fixtures/transformation/es6-computed-property-names-loose/variable/expected.js new file mode 100644 index 0000000000..6f691f0fd6 --- /dev/null +++ b/test/fixtures/transformation/es6-computed-property-names-loose/variable/expected.js @@ -0,0 +1,8 @@ +"use strict"; + +var foo = (function () { + var _foo = {}; + + _foo[bar] = "foobar"; + return _foo; +})(); From 4fdcf685d3d6d4164d5e8556beb7bda5ea468682 Mon Sep 17 00:00:00 2001 From: Christopher Monsanto Date: Tue, 13 Jan 2015 14:48:31 -0500 Subject: [PATCH 41/51] add loose transform for tagged template literals --- lib/6to5/file.js | 1 + .../templates/tagged-template-literal-loose.js | 4 ++++ .../transformers/es6-template-literals.js | 11 +++++++---- 3 files changed, 12 insertions(+), 4 deletions(-) create mode 100644 lib/6to5/transformation/templates/tagged-template-literal-loose.js diff --git a/lib/6to5/file.js b/lib/6to5/file.js index 2757dcb1e2..66c86d7fce 100644 --- a/lib/6to5/file.js +++ b/lib/6to5/file.js @@ -24,6 +24,7 @@ File.helpers = [ "prototype-properties", "apply-constructor", "tagged-template-literal", + "tagged-template-literal-loose", "interop-require", "to-array", "sliced-to-array", diff --git a/lib/6to5/transformation/templates/tagged-template-literal-loose.js b/lib/6to5/transformation/templates/tagged-template-literal-loose.js new file mode 100644 index 0000000000..d8dd44bb7a --- /dev/null +++ b/lib/6to5/transformation/templates/tagged-template-literal-loose.js @@ -0,0 +1,4 @@ +(function (strings, raw) { + strings.raw = raw; + return strings; +}); diff --git a/lib/6to5/transformation/transformers/es6-template-literals.js b/lib/6to5/transformation/transformers/es6-template-literals.js index 4be21d4269..81872a7766 100644 --- a/lib/6to5/transformation/transformers/es6-template-literals.js +++ b/lib/6to5/transformation/transformers/es6-template-literals.js @@ -17,11 +17,14 @@ exports.TaggedTemplateExpression = function (node, parent, file) { raw.push(t.literal(elem.value.raw)); } - args.push(t.callExpression(file.addHelper("tagged-template-literal"), [ - t.arrayExpression(strings), - t.arrayExpression(raw) - ])); + strings = t.arrayExpression(strings); + raw = t.arrayExpression(raw); + var template = file.isLoose("templateLiterals") ? + "tagged-template-literal-loose" : + "tagged-template-literal"; + + args.push(t.callExpression(file.addHelper(template), [strings, raw])); args = args.concat(quasi.expressions); return t.callExpression(node.tag, args); From 2005df3fa22756042a464f2a6b6230dc29fbb40b Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Wed, 14 Jan 2015 07:31:28 +1100 Subject: [PATCH 42/51] support non-string jsx literals - fixes #479 --- lib/6to5/transformation/transformers/react.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/6to5/transformation/transformers/react.js b/lib/6to5/transformation/transformers/react.js index 2842560fc4..341d6b1492 100644 --- a/lib/6to5/transformation/transformers/react.js +++ b/lib/6to5/transformation/transformers/react.js @@ -5,6 +5,7 @@ var esutils = require("esutils"); var t = require("../../types"); +var _ = require("lodash"); exports.XJSIdentifier = function (node) { if (esutils.keyword.isIdentifierName(node.name)) { @@ -138,7 +139,7 @@ exports.XJSElement = { for (i in node.children) { var child = node.children[i]; - if (t.isLiteral(child)) { + if (t.isLiteral(child) && _.isString(child.value)) { var lines = child.value.split(/\r\n|\n|\r/); for (i in lines) { From 3b259c6b1ebe5b5f5d0ec5d4ed58970dcd95014c Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Wed, 14 Jan 2015 07:31:51 +1100 Subject: [PATCH 43/51] clean up 6to5 register-browser --- lib/6to5/register-browser.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/6to5/register-browser.js b/lib/6to5/register-browser.js index 44ab2f5a39..7f7ab7a552 100644 --- a/lib/6to5/register-browser.js +++ b/lib/6to5/register-browser.js @@ -1,4 +1,5 @@ -// Required to safely use 6to5/register within a browserify codebase. +// required to safely use 6to5/register within a browserify codebase + module.exports = function () {}; require("./polyfill"); From 6b836de3068708ce0b83a9b517c842d89960fd25 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Wed, 14 Jan 2015 07:56:45 +1100 Subject: [PATCH 44/51] add #480 test --- .../es6-template-literals/tag-loose/actual.js | 1 + .../es6-template-literals/tag-loose/expected.js | 8 ++++++++ .../es6-template-literals/tag-loose/options.json | 3 +++ 3 files changed, 12 insertions(+) create mode 100644 test/fixtures/transformation/es6-template-literals/tag-loose/actual.js create mode 100644 test/fixtures/transformation/es6-template-literals/tag-loose/expected.js create mode 100644 test/fixtures/transformation/es6-template-literals/tag-loose/options.json diff --git a/test/fixtures/transformation/es6-template-literals/tag-loose/actual.js b/test/fixtures/transformation/es6-template-literals/tag-loose/actual.js new file mode 100644 index 0000000000..7fe1864736 --- /dev/null +++ b/test/fixtures/transformation/es6-template-literals/tag-loose/actual.js @@ -0,0 +1 @@ +var foo = bar`wow\na${ 42 }b ${_.foobar()}`; diff --git a/test/fixtures/transformation/es6-template-literals/tag-loose/expected.js b/test/fixtures/transformation/es6-template-literals/tag-loose/expected.js new file mode 100644 index 0000000000..7be77f1baa --- /dev/null +++ b/test/fixtures/transformation/es6-template-literals/tag-loose/expected.js @@ -0,0 +1,8 @@ +"use strict"; + +var _taggedTemplateLiteralLoose = function (strings, raw) { + strings.raw = raw; + return strings; +}; + +var foo = bar(_taggedTemplateLiteralLoose(["wow\na", "b ", ""], ["wow\\na", "b ", ""]), 42, _.foobar()); diff --git a/test/fixtures/transformation/es6-template-literals/tag-loose/options.json b/test/fixtures/transformation/es6-template-literals/tag-loose/options.json new file mode 100644 index 0000000000..fe669cb1d4 --- /dev/null +++ b/test/fixtures/transformation/es6-template-literals/tag-loose/options.json @@ -0,0 +1,3 @@ +{ + "loose": ["templateLiterals"] +} From e258b85420a738cca4120a7019b83cbbc068584c Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Wed, 14 Jan 2015 08:55:24 +1100 Subject: [PATCH 45/51] clean up loose template literals --- lib/6to5/file.js | 3 ++- .../transformation/transformers/es6-template-literals.js | 7 +++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/6to5/file.js b/lib/6to5/file.js index 66c86d7fce..fa2967e3d2 100644 --- a/lib/6to5/file.js +++ b/lib/6to5/file.js @@ -42,7 +42,8 @@ File.helpers = [ File.excludeHelpersFromRuntime = [ "async-to-generator", - "typeof" + "typeof", + "tagged-template-literal-loose" ]; File.normaliseOptions = function (opts) { diff --git a/lib/6to5/transformation/transformers/es6-template-literals.js b/lib/6to5/transformation/transformers/es6-template-literals.js index 81872a7766..5e4f824cf3 100644 --- a/lib/6to5/transformation/transformers/es6-template-literals.js +++ b/lib/6to5/transformation/transformers/es6-template-literals.js @@ -20,11 +20,10 @@ exports.TaggedTemplateExpression = function (node, parent, file) { strings = t.arrayExpression(strings); raw = t.arrayExpression(raw); - var template = file.isLoose("templateLiterals") ? - "tagged-template-literal-loose" : - "tagged-template-literal"; + var templateName = "tagged-template-literal"; + if (file.isLoose("templateLiterals")) templateName += "-loose"; + args.push(t.callExpression(file.addHelper(templateName), [strings, raw])); - args.push(t.callExpression(file.addHelper(template), [strings, raw])); args = args.concat(quasi.expressions); return t.callExpression(node.tag, args); From fc3a5f25fb9d15746c489343649f25f9d7fb952d Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Wed, 14 Jan 2015 10:09:47 +1100 Subject: [PATCH 46/51] add 2.12.0 changelog --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c4a1f2b33..9e6ffb0938 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,15 @@ _Note: Gaps between patch versions are faulty/broken releases._ +## 2.12.0 + + * **Bug Fix** + * Support non-string JSX literals. + * **New Feature** + * Loose mode for some transformers that enables non-spec behaviour. + * **Internal** + * Uglify `--mangle sort` has been added to the build script, cutting minified scripts in half. + ## 2.11.4 * **Internal** From 6a57a4e565f82e302002eb2a5492fed7aa4ece5c Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Wed, 14 Jan 2015 10:11:07 +1100 Subject: [PATCH 47/51] fix linting errors --- .../transformers/es6-computed-property-names.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/6to5/transformation/transformers/es6-computed-property-names.js b/lib/6to5/transformation/transformers/es6-computed-property-names.js index bc3c9091f2..f84a522086 100644 --- a/lib/6to5/transformation/transformers/es6-computed-property-names.js +++ b/lib/6to5/transformation/transformers/es6-computed-property-names.js @@ -60,10 +60,10 @@ var spec = function (node, body, objId, initProps, file) { // normalise key for (var i in props) { - prop = props[i]; + var prop = props[i]; if (prop.kind !== "init") continue; - key = prop.key; + var key = prop.key; if (!prop.computed && t.isIdentifier(key)) { prop.key = t.literal(key.name); From 313e932e7c08ad239a97095f05a7416f6044763a Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Wed, 14 Jan 2015 10:11:41 +1100 Subject: [PATCH 48/51] fix linting errors --- .../transformers/es6-computed-property-names.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/6to5/transformation/transformers/es6-computed-property-names.js b/lib/6to5/transformation/transformers/es6-computed-property-names.js index f84a522086..c6f85be62f 100644 --- a/lib/6to5/transformation/transformers/es6-computed-property-names.js +++ b/lib/6to5/transformation/transformers/es6-computed-property-names.js @@ -56,14 +56,15 @@ var loose = function (node, body, objId) { var spec = function (node, body, objId, initProps, file) { var props = node.properties; + var prop, key; // normalise key for (var i in props) { - var prop = props[i]; + prop = props[i]; if (prop.kind !== "init") continue; - var key = prop.key; + key = prop.key; if (!prop.computed && t.isIdentifier(key)) { prop.key = t.literal(key.name); From 99ca9b7e9a94add09b68042d9ebe68d99e0ed564 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Wed, 14 Jan 2015 10:12:11 +1100 Subject: [PATCH 49/51] fix linting errors --- .../transformation/transformers/es6-computed-property-names.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/6to5/transformation/transformers/es6-computed-property-names.js b/lib/6to5/transformation/transformers/es6-computed-property-names.js index c6f85be62f..94d4bd9e86 100644 --- a/lib/6to5/transformation/transformers/es6-computed-property-names.js +++ b/lib/6to5/transformation/transformers/es6-computed-property-names.js @@ -2,8 +2,6 @@ var t = require("../../types"); exports.ObjectExpression = function (node, parent, file, scope) { var hasComputed = false; - var prop; - var key; for (var i in node.properties) { hasComputed = t.isProperty(node.properties[i], { computed: true, kind: "init" }); From a4e528e2b3f6ca79fc4589733b44b842c8a2c9bb Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Wed, 14 Jan 2015 10:14:14 +1100 Subject: [PATCH 50/51] v2.12.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 74203aed6d..a76b3beabe 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "6to5", "description": "Turn ES6 code into readable vanilla ES5 with source maps", - "version": "2.11.4", + "version": "2.12.0", "author": "Sebastian McKenzie ", "homepage": "https://github.com/6to5/6to5", "repository": { From 0dfea1a51b8e4db5048bb31e2f98a79af3417f5d Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Wed, 14 Jan 2015 14:54:31 +1100 Subject: [PATCH 51/51] update notes --- NOTES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NOTES.md b/NOTES.md index fcb68ebe86..a973eaafdf 100644 --- a/NOTES.md +++ b/NOTES.md @@ -10,4 +10,4 @@ * Split up ES5 getter/setter transforming and ES6 property methods into separate transformers. * Add autoindentation. * Move `super` transformation from classes into a separate transformer that also supports object expressions. - * Prefix all fast transformers with `fast`, make them declare that they're a fast transformer similar to optional transformers and add a `--fast` flag to enable them all. + * Remove fast transformer backwards compatibility.