From 36c16a02279ecf031e85d3ee51edfaa1be7bae5f Mon Sep 17 00:00:00 2001 From: James Kyle Date: Sat, 6 Dec 2014 15:31:02 -0800 Subject: [PATCH 001/139] Center everything in README --- README.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d1f2e07244..772f7abb6c 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,11 @@

-**6to5** turns ES6+ code into vanilla ES5, so you can use next generation features **today.** +

+ 6to5 turns ES6+ code into vanilla ES5, so you can use next generation features today. +

-For more information view the [documentation](https://6to5.github.io). For -support visit the [gitter room](https://gitter.im/6to5/6to5). +

+ For more information view the documentation. For + support visit the gitter room. +

From 88a85c0ca8e44575dea7c6a74b89d7553dec70bc Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Sun, 7 Dec 2014 11:19:17 +1100 Subject: [PATCH 002/139] fix files only containg comments not being output - fixes #259 --- CHANGELOG.md | 4 ++++ lib/6to5/generation/generator.js | 8 ++++++++ .../{.comment-only/expected.js => comment-only/actual.js} | 0 .../{.comment-only/actual.js => comment-only/expected.js} | 4 ++-- 4 files changed, 14 insertions(+), 2 deletions(-) rename test/fixtures/generation/comments/{.comment-only/expected.js => comment-only/actual.js} (100%) rename test/fixtures/generation/comments/{.comment-only/actual.js => comment-only/expected.js} (63%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 93935fa179..76a09da17b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.14.18 + + * Fix files only containg comments not being output. + # 1.14.17 * Add default initializer to let variables within loop bodies. diff --git a/lib/6to5/generation/generator.js b/lib/6to5/generation/generator.js index 18fa9b00a3..6c0274a7b8 100644 --- a/lib/6to5/generation/generator.js +++ b/lib/6to5/generation/generator.js @@ -71,6 +71,12 @@ CodeGenerator.prototype.generate = function () { this.print(ast); + var comments = []; + _.each(ast.comments, function (comment) { + if (!comment._displayed) comments.push(comment); + }); + if (comments.length) this._printComments(comments); + return { map: this.map.get(), code: this.buffer.get() @@ -259,6 +265,8 @@ CodeGenerator.prototype._printComments = function (comments) { var self = this; _.each(comments, function (comment) { + comment._displayed = true; + // whitespace before self.newline(self.whitespace.getNewlinesBefore(comment)); diff --git a/test/fixtures/generation/comments/.comment-only/expected.js b/test/fixtures/generation/comments/comment-only/actual.js similarity index 100% rename from test/fixtures/generation/comments/.comment-only/expected.js rename to test/fixtures/generation/comments/comment-only/actual.js diff --git a/test/fixtures/generation/comments/.comment-only/actual.js b/test/fixtures/generation/comments/comment-only/expected.js similarity index 63% rename from test/fixtures/generation/comments/.comment-only/actual.js rename to test/fixtures/generation/comments/comment-only/expected.js index 2cc6cab81c..b30266f9e6 100644 --- a/test/fixtures/generation/comments/.comment-only/actual.js +++ b/test/fixtures/generation/comments/comment-only/expected.js @@ -1,6 +1,6 @@ +"use strict"; + // from #23 /**/ /* */ - -test From eef0344cb27dd823ecbc73d0eb1cf2b1e8092ddb Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Sun, 7 Dec 2014 11:30:50 +1100 Subject: [PATCH 003/139] fix comments-only rendering --- lib/6to5/generation/generator.js | 10 ++++++++-- .../generation/comments/comment-only/expected.js | 2 -- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/6to5/generation/generator.js b/lib/6to5/generation/generator.js index 6c0274a7b8..842e397899 100644 --- a/lib/6to5/generation/generator.js +++ b/lib/6to5/generation/generator.js @@ -75,7 +75,7 @@ CodeGenerator.prototype.generate = function () { _.each(ast.comments, function (comment) { if (!comment._displayed) comments.push(comment); }); - if (comments.length) this._printComments(comments); + this._printComments(comments); return { map: this.map.get(), @@ -265,7 +265,13 @@ CodeGenerator.prototype._printComments = function (comments) { var self = this; _.each(comments, function (comment) { - comment._displayed = true; + // find the original comment in the ast and set it as displayed + _.each(self.ast.comments, function (origComment) { + if (origComment.start === comment.start) { + origComment._displayed = true; + return false; + } + }); // whitespace before self.newline(self.whitespace.getNewlinesBefore(comment)); diff --git a/test/fixtures/generation/comments/comment-only/expected.js b/test/fixtures/generation/comments/comment-only/expected.js index b30266f9e6..acfb1b9a7b 100644 --- a/test/fixtures/generation/comments/comment-only/expected.js +++ b/test/fixtures/generation/comments/comment-only/expected.js @@ -1,5 +1,3 @@ -"use strict"; - // from #23 /**/ /* From bf07f54e5749f5ab3a9fa60d28b6095c6c2eb4e8 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Sun, 7 Dec 2014 11:31:08 +1100 Subject: [PATCH 004/139] add note about inline functions to docs/differences --- doc/differences.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/differences.md b/doc/differences.md index 73f5babd0c..7a6189a84c 100644 --- a/doc/differences.md +++ b/doc/differences.md @@ -51,7 +51,11 @@ As you can tell, it's not very pretty, unreadable even. Instead of mapping directly to a runtime, like other transpilers, 6to5 maps directly to the equivalent ES5. -Sometimes there are little things that 6to5 needs +Sometimes there are little inline functions that 6to5 needs. These are +placed at the top of your file much like coffee-script does. If these +are bother you then you can use the [optional runtime](optional-runtime.md). +We promise that these inline functions will never be significant and will +always be used as little as possible. ## Comparison to other transpilers From c1c22ed5f742691efd6f6e7c9efd9d4b397335ac Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Sun, 7 Dec 2014 11:43:51 +1100 Subject: [PATCH 005/139] fix duplicate comments on property key shorthands - fixes #234 --- CHANGELOG.md | 1 + .../transformers/es6-property-name-shorthand.js | 4 ++++ lib/6to5/types/index.js | 5 ----- .../es6-property-name-shorthand/comments/actual.js | 4 ++++ .../es6-property-name-shorthand/comments/expected.js | 4 ++++ 5 files changed, 13 insertions(+), 5 deletions(-) create mode 100644 test/fixtures/transformation/es6-property-name-shorthand/comments/actual.js create mode 100644 test/fixtures/transformation/es6-property-name-shorthand/comments/expected.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 76a09da17b..5aad5189fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # 1.14.18 * Fix files only containg comments not being output. + * Fix duplicate comments on property key shorthands. # 1.14.17 diff --git a/lib/6to5/transformation/transformers/es6-property-name-shorthand.js b/lib/6to5/transformation/transformers/es6-property-name-shorthand.js index 747cbbd9ec..8614d69c84 100644 --- a/lib/6to5/transformation/transformers/es6-property-name-shorthand.js +++ b/lib/6to5/transformation/transformers/es6-property-name-shorthand.js @@ -1,4 +1,8 @@ +var t = require("../../types"); +var _ = require("lodash"); + exports.Property = function (node) { if (!node.shorthand) return; node.shorthand = false; + node.key = t.removeComments(_.clone(node.key)); }; diff --git a/lib/6to5/types/index.js b/lib/6to5/types/index.js index f741debaff..96cceddb6b 100644 --- a/lib/6to5/types/index.js +++ b/lib/6to5/types/index.js @@ -295,11 +295,6 @@ t.inheritsComments = function (child, parent) { return child; }; -t.removeComments = function (node) { - delete node.leadingComments; - delete node.trailingComments; -}; - t.inherits = function (child, parent) { child.loc = parent.loc; child.end = parent.end; diff --git a/test/fixtures/transformation/es6-property-name-shorthand/comments/actual.js b/test/fixtures/transformation/es6-property-name-shorthand/comments/actual.js new file mode 100644 index 0000000000..a6a10d4689 --- /dev/null +++ b/test/fixtures/transformation/es6-property-name-shorthand/comments/actual.js @@ -0,0 +1,4 @@ +const A = 'a'; +const o = { + A // comment +}; diff --git a/test/fixtures/transformation/es6-property-name-shorthand/comments/expected.js b/test/fixtures/transformation/es6-property-name-shorthand/comments/expected.js new file mode 100644 index 0000000000..1368b53247 --- /dev/null +++ b/test/fixtures/transformation/es6-property-name-shorthand/comments/expected.js @@ -0,0 +1,4 @@ +const A = 'a'; +const o = { + A: A // comment +}; From e17d5bdb13c58c8ef42db26832928c002a91df16 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Sun, 7 Dec 2014 11:46:59 +1100 Subject: [PATCH 006/139] fix comments test in property name shorthand --- .../es6-property-name-shorthand/comments/expected.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/fixtures/transformation/es6-property-name-shorthand/comments/expected.js b/test/fixtures/transformation/es6-property-name-shorthand/comments/expected.js index 1368b53247..bb002dfed6 100644 --- a/test/fixtures/transformation/es6-property-name-shorthand/comments/expected.js +++ b/test/fixtures/transformation/es6-property-name-shorthand/comments/expected.js @@ -1,4 +1,6 @@ -const A = 'a'; -const o = { +"use strict"; + +var A = "a"; +var o = { A: A // comment }; From 2e0cd0f3491c010704a47f14aaca67e9d685208d Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Sun, 7 Dec 2014 02:06:41 -0800 Subject: [PATCH 007/139] Add tests for newlines before comments --- .../2-space-multi-comment-with-space/actual.js | 10 ++++++++++ .../2-space-multi-comment-with-space/expected.js | 10 ++++++++++ .../comments/comment-only-with-space/actual.js | 7 +++++++ .../comments/comment-only-with-space/expected.js | 7 +++++++ 4 files changed, 34 insertions(+) create mode 100644 test/fixtures/generation/comments/2-space-multi-comment-with-space/actual.js create mode 100644 test/fixtures/generation/comments/2-space-multi-comment-with-space/expected.js create mode 100644 test/fixtures/generation/comments/comment-only-with-space/actual.js create mode 100644 test/fixtures/generation/comments/comment-only-with-space/expected.js diff --git a/test/fixtures/generation/comments/2-space-multi-comment-with-space/actual.js b/test/fixtures/generation/comments/2-space-multi-comment-with-space/actual.js new file mode 100644 index 0000000000..aa61a9c8fe --- /dev/null +++ b/test/fixtures/generation/comments/2-space-multi-comment-with-space/actual.js @@ -0,0 +1,10 @@ +function test() { + + + /* + * this is comment + */ + + + var i = 20; +} diff --git a/test/fixtures/generation/comments/2-space-multi-comment-with-space/expected.js b/test/fixtures/generation/comments/2-space-multi-comment-with-space/expected.js new file mode 100644 index 0000000000..aa61a9c8fe --- /dev/null +++ b/test/fixtures/generation/comments/2-space-multi-comment-with-space/expected.js @@ -0,0 +1,10 @@ +function test() { + + + /* + * this is comment + */ + + + var i = 20; +} diff --git a/test/fixtures/generation/comments/comment-only-with-space/actual.js b/test/fixtures/generation/comments/comment-only-with-space/actual.js new file mode 100644 index 0000000000..befcf38bfa --- /dev/null +++ b/test/fixtures/generation/comments/comment-only-with-space/actual.js @@ -0,0 +1,7 @@ + +// from #23 + +/**/ + +/* +*/ diff --git a/test/fixtures/generation/comments/comment-only-with-space/expected.js b/test/fixtures/generation/comments/comment-only-with-space/expected.js new file mode 100644 index 0000000000..befcf38bfa --- /dev/null +++ b/test/fixtures/generation/comments/comment-only-with-space/expected.js @@ -0,0 +1,7 @@ + +// from #23 + +/**/ + +/* +*/ From f592f95a68f5923f1acacbc8ef43fa09ae29c71e Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Sun, 7 Dec 2014 02:06:54 -0800 Subject: [PATCH 008/139] Subtract one if line already ends with "{\n" --- lib/6to5/generation/buffer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/6to5/generation/buffer.js b/lib/6to5/generation/buffer.js index a3f4756653..ae6e174400 100644 --- a/lib/6to5/generation/buffer.js +++ b/lib/6to5/generation/buffer.js @@ -68,7 +68,6 @@ Buffer.prototype.removeLast = function (cha) { Buffer.prototype.newline = function (i, removeLast) { if (!this.buf) return; if (this.format.compact) return; - if (this.endsWith("{\n")) return; if (_.isBoolean(i)) { removeLast = i; @@ -76,6 +75,7 @@ Buffer.prototype.newline = function (i, removeLast) { } if (_.isNumber(i)) { + if (this.endsWith("{\n")) i--; if (this.endsWith(util.repeat(i, "\n"))) return; var self = this; From ce9a82c194cad3c89c13928fa6ff82fdeddcba04 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Sun, 7 Dec 2014 21:58:36 +1100 Subject: [PATCH 009/139] add docs for `ast` and `code` option --- doc/usage.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/doc/usage.md b/doc/usage.md index 4a474def03..7db7c636fc 100644 --- a/doc/usage.md +++ b/doc/usage.md @@ -159,7 +159,17 @@ to5.transformFile("filename.js", options, function (err, result) { // Enable support for experimental ES7 features // Default: false - experimental: true + experimental: true, + + // Set this to `false` if you don't want the transformed AST in the returned + // result + // Default: true + ast: true, + + // Set this to `false` if you don't want the transformed code in the returned + // result + // Default: true + code: true } ``` From f9f48620de32355d6aa6364041e9220ecbd0c433 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Sun, 7 Dec 2014 21:59:01 +1100 Subject: [PATCH 010/139] remove unused test transformation whitespace option --- test/transformation.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/transformation.js b/test/transformation.js index 388097e447..03418d0f83 100644 --- a/test/transformation.js +++ b/test/transformation.js @@ -15,8 +15,7 @@ var run = function (task, done) { var getOpts = function (self) { return _.merge({ - whtiespace: true, - filename: self.loc + filename: self.loc }, opts); }; From bd876f7a4d3eb28e281905ca3e1a181e1e32437b Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Sun, 7 Dec 2014 21:59:22 +1100 Subject: [PATCH 011/139] fix starting file newlines --- lib/6to5/generation/buffer.js | 4 +++- lib/6to5/generation/generator.js | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/6to5/generation/buffer.js b/lib/6to5/generation/buffer.js index ae6e174400..9bfa757816 100644 --- a/lib/6to5/generation/buffer.js +++ b/lib/6to5/generation/buffer.js @@ -66,7 +66,6 @@ Buffer.prototype.removeLast = function (cha) { }; Buffer.prototype.newline = function (i, removeLast) { - if (!this.buf) return; if (this.format.compact) return; if (_.isBoolean(i)) { @@ -88,7 +87,10 @@ Buffer.prototype.newline = function (i, removeLast) { if (removeLast && this.isLast("\n")) this.removeLast("\n"); this.removeLast(" "); + + // remove whitespace if last character was a newline this.buf = this.buf.replace(/\n +$/, "\n"); + this._push("\n"); }; diff --git a/lib/6to5/generation/generator.js b/lib/6to5/generation/generator.js index 842e397899..63919c94d3 100644 --- a/lib/6to5/generation/generator.js +++ b/lib/6to5/generation/generator.js @@ -138,6 +138,9 @@ CodeGenerator.prototype.print = function (node, parent, opts) { var needs = n.needsWhitespaceAfter; if (leading) needs = n.needsWhitespaceBefore; lines += needs(node, parent); + + // generated nodes can't add starting file whitespace + if (!self.buffer.get()) lines = 0; } self.newline(lines); From d11d0d321666612fd3a5a234299055dd31b6f03f Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Sun, 7 Dec 2014 21:59:52 +1100 Subject: [PATCH 012/139] split up plugins into sections and change some community plugin urls to official ones --- doc/plugins.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/doc/plugins.md b/doc/plugins.md index 3c4fa70137..53180bd449 100644 --- a/doc/plugins.md +++ b/doc/plugins.md @@ -1,18 +1,23 @@ # Plugins +## Build systems + - [Broccoli](https://github.com/very-geek/broccoli-6to5-transpiler) - [Browserify](https://github.com/6to5/6to5-browserify) - [Brunch](https://github.com/es128/6to5-brunch) - [Duo](https://github.com/bdo-labs/duo6to5) - [Connect](https://github.com/6to5/6to5-connect) - - [Gobble](https://github.com/gobblejs/gobble-6to5) + - [Gobble](https://github.com/6to5/gobble-6to5) - [Gulp](https://github.com/sindresorhus/gulp-6to5) - [Grunt](https://github.com/sindresorhus/grunt-6to5) - - [Isparta](https://github.com/douglasduteil/isparta) - Code coverage with `karma` and `instanbul` using 6to5 - [Jade](https://github.com/Apoxx/jade-6to5) - [Jest](https://github.com/6to5/6to5-jest) - - [JSXHint](https://github.com/STRML/JSXHint) - A wrapper around JSHint to allow linting of JSX files - [Karma](https://github.com/shuhei/karma-6to5-preprocessor) - [Mocha](https://github.com/6to5/6to5-mocha) - [Rails](https://github.com/josh/sprockets-es6) or via [browserify-rails](https://github.com/6to5/6to5-rails) - - [webpack](https://github.com/Couto/6to5-loader) + - [webpack](https://github.com/6to5/6to5-loader) + +## Integrations + + - [Isparta](https://github.com/douglasduteil/isparta) - Code coverage with `karma` and `instanbul` using 6to5 + - [JSXHint](https://github.com/STRML/JSXHint) - A wrapper around JSHint to allow linting of JSX files From 61b9c28ce648ce052b07407f748f75b40564884c Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Mon, 8 Dec 2014 12:11:39 +1100 Subject: [PATCH 013/139] update plugins to reflect 6to5 org migrations --- doc/plugins.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/doc/plugins.md b/doc/plugins.md index 53180bd449..388582e2d5 100644 --- a/doc/plugins.md +++ b/doc/plugins.md @@ -4,20 +4,24 @@ - [Broccoli](https://github.com/very-geek/broccoli-6to5-transpiler) - [Browserify](https://github.com/6to5/6to5-browserify) - - [Brunch](https://github.com/es128/6to5-brunch) + - [Brunch](https://github.com/6to5/6to5-brunch) - [Duo](https://github.com/bdo-labs/duo6to5) - [Connect](https://github.com/6to5/6to5-connect) - [Gobble](https://github.com/6to5/gobble-6to5) - - [Gulp](https://github.com/sindresorhus/gulp-6to5) - - [Grunt](https://github.com/sindresorhus/grunt-6to5) + - [Gulp](https://github.com/6to5/gulp-6to5) + - [Grunt](https://github.com/6to5/grunt-6to5) - [Jade](https://github.com/Apoxx/jade-6to5) - [Jest](https://github.com/6to5/6to5-jest) - - [Karma](https://github.com/shuhei/karma-6to5-preprocessor) + - [Karma](https://github.com/6to5/karma-6to5-preprocessor) - [Mocha](https://github.com/6to5/6to5-mocha) - - [Rails](https://github.com/josh/sprockets-es6) or via [browserify-rails](https://github.com/6to5/6to5-rails) + - [Sprockets](https://github.com/josh/sprockets-es6) or via [Browserify](https://github.com/6to5/6to5-rails) - [webpack](https://github.com/6to5/6to5-loader) ## Integrations - [Isparta](https://github.com/douglasduteil/isparta) - Code coverage with `karma` and `instanbul` using 6to5 - [JSXHint](https://github.com/STRML/JSXHint) - A wrapper around JSHint to allow linting of JSX files + +## Bridges + + - [Ruby](https://github.com/6to5/6to5-ruby) From 6f6d9bd5a8f79a42d3893d179c6eefe734d3f679 Mon Sep 17 00:00:00 2001 From: Elan Shanker Date: Mon, 8 Dec 2014 17:17:31 -0500 Subject: [PATCH 014/139] Simplify chokidar event handler --- bin/6to5/file.js | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/bin/6to5/file.js b/bin/6to5/file.js index 73c0f19a7f..67db8e8264 100644 --- a/bin/6to5/file.js +++ b/bin/6to5/file.js @@ -116,13 +116,9 @@ module.exports = function (commander, filenames) { var watcher = chokidar.watch(filenames, { persistent: true, ignoreInitial: true - }); - - _.each(["add", "change", "unlink"], function (type) { - watcher.on(type, function (filename) { - console.log(type, filename); - walk(); - }); + }).on("all", function (type, filename) { + console.log(type, filename); + walk(); }); } }; From 5e67dfbd9e8ace962cf02ac28539170eda7d685f Mon Sep 17 00:00:00 2001 From: Elan Shanker Date: Mon, 8 Dec 2014 17:55:54 -0500 Subject: [PATCH 015/139] Ensure only file events are acted upon --- bin/6to5/file.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/bin/6to5/file.js b/bin/6to5/file.js index 67db8e8264..a118389437 100644 --- a/bin/6to5/file.js +++ b/bin/6to5/file.js @@ -117,8 +117,10 @@ module.exports = function (commander, filenames) { persistent: true, ignoreInitial: true }).on("all", function (type, filename) { - console.log(type, filename); - walk(); + if (type === "add" || type === "change" || type === "unlink" ) { + console.log(type, filename); + walk(); + } }); } }; From b688154aee951218687a21456cf12070840ef9e5 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 9 Dec 2014 23:15:05 +1100 Subject: [PATCH 016/139] reformat CHANGELOG --- CHANGELOG.md | 120 ++++++++++++++++++++++++++------------------------- 1 file changed, 62 insertions(+), 58 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5aad5189fd..efe737e84e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,272 +1,276 @@ -# 1.14.18 +# Changelog + +Gaps between patch versions are faulty/broken releases. + +## 1.14.18 * Fix files only containg comments not being output. * Fix duplicate comments on property key shorthands. -# 1.14.17 +## 1.14.17 * Add default initializer to let variables within loop bodies. * Fix excessive `break` replacement inside of switches in let scoping. -# 1.14.16 +## 1.14.16 * Add object getter memos and this shorthand to playground. * Fix while loops in let scoping. * Upgrade `acorn-6to5`. -# 1.14.14 +## 1.14.14 * Fix template literals escaping. -# 1.14.13 +## 1.14.13 * Fix let scoping of `while` loops. * Make class methods enumerable. -# 1.14.12 +## 1.14.12 * Fix duplicate dynamic expressions in call spread. -# 1.14.10 +## 1.14.10 * Fix let scoping unneccesary override. -# 1.14.6 +## 1.14.6 * Avoid ensuring a block on non-array node replacements. -# 1.14.5 +## 1.14.5 * Upgrade `acorn-6to5`. * Fix JSON recursion error for unknown code generator node types. * Ensure that a statement is a block on block/statement types when replacing them with multiple nodes. -# 1.14.4 +## 1.14.4 * Merge pretzel maps and method binding. -# 1.14.3 +## 1.14.3 * Add playground pretzel maps. -# 1.14.2 +## 1.14.2 * Fix `commonInterop` default export handling. * Fix keyworded property key identifiers being turned into computed property key literals. -# 1.14.1 +## 1.14.1 * Inherit comments from `ClassDeclaration`. -# 1.14.0 +## 1.14.0 * Add [playground](https://6to5.github.io/playground.html). -# 1.13.13 +## 1.13.13 * Fix `--debug` in `bin/6to5-node`. Thanks [@timoxley](https://github.com/timoxley). -# 1.13.12 +## 1.13.12 * Ignore `XJSEmptyExpression`s in `react` transformer output. -# 1.13.11 +## 1.13.11 * Fix `util.regexify` on falsy values. * Fix `_aliasFunction` with rest parameters. * Export as `module.exports` instead of `exports.default` if there are no other `ExportDeclaration`s in `commonInterop` module formatter. * Add `system` module formatter. Thanks [@douglasduteil](https://github.com/douglasduteil). -# 1.13.10 +## 1.13.10 * Add support for `AssignmentExpression` destructuring outside of `ExpressionStatement`. -# 1.13.9 +## 1.13.9 * Fix `VirtualPropertyExpression` visitor keys. -# 1.13.8 +## 1.13.8 * Only use a single reference in abstract references. -# 1.13.7 +## 1.13.7 * Upgrade `acorn-6to5`. * Add experimental exponentiation operator support. -# 1.13.6 +## 1.13.6 * Fix experimental object spread/rest helper. -# 1.13.5 +## 1.13.5 * Upgrade `acorn-6to5`. * Add experimental support for object spread/rest. * Change `arguments` to array to an additional helper method. -# 1.13.4 +## 1.13.4 * Fix single spread element returning itself. -# 1.13.3 +## 1.13.3 * Upgrade `acorn-6to5`. * Add experimental support for abstract references. -# 1.13.2 +## 1.13.2 * Optimise `Array.from` usage by adding a helper method. * Upgrade `acorn-6to5`. -# 1.13.1 +## 1.13.1 * Fix constructor spread optimisation. Thanks [@zloirock](https://github.com/zloirock). -# 1.13.0 +## 1.13.0 * Put experimental ES7 features behind a flag `--experimental` and `experimental` option. * Constructor spread performance increase. Thanks [@RReverser](https://github.com/RReverser). * Use `self` instead of `window` in the optional 6to5 runtime. Thanks [@RReverser](https://github.com/RReverser). -# 1.12.26 +## 1.12.26 * Support computed property destructuring. -# 1.12.25 +## 1.12.25 * Update `acorn-6to5`, `ast-types`, `es6-shim`, `chokidar`, `estraverse` and `private`. -# 1.12.24 +## 1.12.24 * Collect references that haven't been declared in scope. -# 1.12.23 +## 1.12.23 * Fix generator function export hoisting. -# 1.12.22 +## 1.12.22 * Update `fs-readdir-recursive` and `chokidar`. * Support array destructuring on iterables. * Make amd module id optional. Thanks [@webpro](https://github.com/webpro). -# 1.12.21 +## 1.12.21 * Fix unneccesary let scoping replacement. * Add `commonInterop` module formatter. Thanks [@Naddiseo](https://github.com/Naddiseo). * Fix `return` outside of function body bug. Thanks [@brentburg](https://github.com/brentburg). * Add more flexible option types. -# 1.12.20 +## 1.12.20 * Append `sourceMappingURL` when using `bin/6to5` and output sourcemaps. -# 1.12.19 +## 1.12.19 * Add `comments` option and `--remove-comments` flag. Thanks [@webpro](htps://github.com/webpro). * Embed `regenerator`. -# 1.12.18 +## 1.12.18 * Use `global` reference instead of `window`. -# 1.12.17 +## 1.12.17 * Add `moduleName`, `sourceRoot` and `filenameRelative` options. Thanks [@darvelo](https://github.com/darvelo). * Traversal optimisations. -# 1.12.16 +## 1.12.16 * Fix comments not being retained from `MethodDefinition` in classes. * Add temporal dead zone in default parameters. -# 1.12.15 +## 1.12.15 * Update `acorn-6to5`. -# 1.12.14 +## 1.12.14 * Fix duplicate let scoping in functions. * Make JSX whitespace more React-compliant. * Add `_memberExpressionKeywords` transformer that turns keyword identifiers to computed literals. * Upgrade `regenerator-6to5`. -# 1.12.13 +## 1.12.13 * Support duplicate constants within different block scopes. * Fix for-head duplication testing and replacement. * Support `raw` property on tagged template literals. -# 1.12.12 +## 1.12.12 * Make scope tracker more reliable to handle all edgecases. -# 1.12.11 +## 1.12.11 * Block scope classes. * Fix generation of integer `Literal`s in `MemberExpression`. -# 1.12.10 +## 1.12.10 * Fix let scoping var hoisting. -# 1.12.9 +## 1.12.9 * Escape unicode characters when generating string `Literal`s. * Fix semicolons being output for statements in `ExportDeclaration`. * Fix `WithStatement` missing parenthesis. -# 1.12.8 +## 1.12.8 * Temporarily forbid `AssignmentExpression` destructuring outside of `ExpressionStatement`. -# 1.12.7 +## 1.12.7 * Update to latest `acorn-6to5`. -# 1.12.6 +## 1.12.6 * Update to latest `acorn-6to5`. -# 1.12.5 +## 1.12.5 * Fix excessive whitespace trimming resulting in innaccurate sourcemap line. -# 1.12.4 +## 1.12.4 * Add `doc` folder for documentation. -# 1.12.3 +## 1.12.3 * Support generator comprehensions. * Use `Array.from` instead of `Array.prototype.slice` in spread transformer. * Support spread in `NewExpression`s. -# 1.12.2 +## 1.12.2 * Upgrade `matcha` to `0.6.0` and `browserify` to `6.3.2`. * Add own `trimRight` helper instead of relying on the string instance method. * Support JSX spreads that aren't the first. -# 1.12.1 +## 1.12.1 * Fix `this` and `arguments` mapping in the `_aliasFunctions` transformer. -# 1.12.0 +## 1.12.0 * Combine `jsx` and `react` transformers to `react`. * Update `react` syntax output to React v0.12. -# 1.11.15 +## 1.11.15 * Fix JSX literal whitespace generation. -# 1.11.14 +## 1.11.14 * Avoid using a switch for let-scoping continue and break statements and use an if statement instead. * Remove excess whitespace and newlines from JSX literals. -# 1.11.13 +## 1.11.13 * Update regenerator-6to5 * Add support for most escodegen formatting options From e97e916b5c6d56819b926ec7f19a40e2bf87ab37 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 9 Dec 2014 23:15:43 +1100 Subject: [PATCH 017/139] module export variable declaration initializer default - fixes #264 --- lib/6to5/transformation/modules/common.js | 12 +++++------- lib/6to5/transformation/transformers/es6-modules.js | 8 ++++++++ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/lib/6to5/transformation/modules/common.js b/lib/6to5/transformation/modules/common.js index 267c4ca677..8ab054cf5d 100644 --- a/lib/6to5/transformation/modules/common.js +++ b/lib/6to5/transformation/modules/common.js @@ -98,14 +98,12 @@ CommonJSFormatter.prototype.export = function (node, nodes) { if (t.isVariableDeclaration(declar)) { var decl = declar.declarations[0]; - if (decl.init) { - decl.init = util.template("exports-assign", { - //inherits: node, + decl.init = util.template("exports-assign", { + //inherits: node, - VALUE: decl.init, - KEY: decl.id - }); - } + VALUE: decl.init, + KEY: decl.id + }); nodes.push(declar); } else { diff --git a/lib/6to5/transformation/transformers/es6-modules.js b/lib/6to5/transformation/transformers/es6-modules.js index cfcd991f5c..3b7148cf67 100644 --- a/lib/6to5/transformation/transformers/es6-modules.js +++ b/lib/6to5/transformation/transformers/es6-modules.js @@ -1,3 +1,4 @@ +var t = require("../../types"); var _ = require("lodash"); exports.ImportDeclaration = function (node, parent, file) { @@ -18,6 +19,13 @@ exports.ExportDeclaration = function (node, parent, file) { var nodes = []; if (node.declaration) { + // make sure variable exports have an initialiser + // this is done here to avoid duplicating it in the module formatters + if (t.isVariableDeclaration(node.declaration)) { + var declar = node.declaration.declarations[0]; + declar.init = declar.init || t.identifier("undefined"); + } + file.moduleFormatter.export(node, nodes, parent); } else { _.each(node.specifiers, function (specifier) { From b8d61f152886f8e128e294c24bab5c0af84a2104 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 9 Dec 2014 23:15:57 +1100 Subject: [PATCH 018/139] update github urls and regroup plugins --- doc/plugins.md | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/doc/plugins.md b/doc/plugins.md index 388582e2d5..020de40f7d 100644 --- a/doc/plugins.md +++ b/doc/plugins.md @@ -2,18 +2,13 @@ ## Build systems - - [Broccoli](https://github.com/very-geek/broccoli-6to5-transpiler) + - [Broccoli](https://github.com/6to5/broccoli-6to5-transpiler) - [Browserify](https://github.com/6to5/6to5-browserify) - [Brunch](https://github.com/6to5/6to5-brunch) - - [Duo](https://github.com/bdo-labs/duo6to5) - - [Connect](https://github.com/6to5/6to5-connect) + - [Duo](https://github.com/6to5/duo6to5) - [Gobble](https://github.com/6to5/gobble-6to5) - [Gulp](https://github.com/6to5/gulp-6to5) - [Grunt](https://github.com/6to5/grunt-6to5) - - [Jade](https://github.com/Apoxx/jade-6to5) - - [Jest](https://github.com/6to5/6to5-jest) - - [Karma](https://github.com/6to5/karma-6to5-preprocessor) - - [Mocha](https://github.com/6to5/6to5-mocha) - [Sprockets](https://github.com/josh/sprockets-es6) or via [Browserify](https://github.com/6to5/6to5-rails) - [webpack](https://github.com/6to5/6to5-loader) @@ -25,3 +20,14 @@ ## Bridges - [Ruby](https://github.com/6to5/6to5-ruby) + +## Testing + + - [Jest](https://github.com/6to5/6to5-jest) + - [Karma](https://github.com/6to5/karma-6to5-preprocessor) + - [Mocha](https://github.com/6to5/6to5-mocha) + +## Misc + + - [Connect](https://github.com/6to5/6to5-connect) + - [Jade](https://github.com/6to5/jade-6to5) From 2245bbc6c43ea2fec9bf373710fcd466a47a5d66 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 9 Dec 2014 23:18:38 +1100 Subject: [PATCH 019/139] make bin/6to5-node more node bin compliant --- bin/_6to5-node | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/bin/_6to5-node b/bin/_6to5-node index 2133bf156e..7d8b14a304 100644 --- a/bin/_6to5-node +++ b/bin/_6to5-node @@ -1,6 +1,7 @@ #!/usr/bin/env node var commander = require("commander"); +var Module = require("module"); var path = require("path"); var repl = require("repl"); var to5 = require("../lib/6to5"); @@ -44,16 +45,15 @@ if (commander.eval) { var result = _eval(commander.eval, "eval"); if (commander.print) console.log(result); } else { - var filenames = commander.args; + if (commander.args.length) { + process.argv.splice(0, 1); // remove 6to5-node directive - if (filenames.length) { - _.each(filenames, function (filename) { - if (!util.isAbsolute(filename)) { - filename = path.join(process.cwd(), filename); - } + var filename = process.argv[1]; + if (!util.isAbsolute(filename)) { + process.argv[1] = path.join(process.cwd(), filename); + } - require(require.resolve(filename)); - }); + Module.runMain(); } else { replStart(); } From 5f26a0c5cc7e29bfed40d8e4233ad8318816cd82 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 9 Dec 2014 23:28:07 +1100 Subject: [PATCH 020/139] update modules tests --- .../es6-modules-amd/exports-variable/expected.js | 4 ++-- .../es6-modules-common-interop/exports-variable/expected.js | 4 ++-- .../es6-modules-common/exports-variable/expected.js | 4 ++-- .../es6-modules-ignore/exports-variable/expected.js | 4 ++-- .../es6-modules-umd/exports-variable/expected.js | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/test/fixtures/transformation/es6-modules-amd/exports-variable/expected.js b/test/fixtures/transformation/es6-modules-amd/exports-variable/expected.js index b94e1dd338..b959a86bd0 100644 --- a/test/fixtures/transformation/es6-modules-amd/exports-variable/expected.js +++ b/test/fixtures/transformation/es6-modules-amd/exports-variable/expected.js @@ -4,9 +4,9 @@ define(["exports"], function (exports) { exports.foo7 = foo7; var foo = exports.foo = 1; var foo2 = exports.foo2 = function () {}; - var foo3; + var foo3 = exports.foo3 = undefined; var foo4 = exports.foo4 = 2; - var foo5; + var foo5 = exports.foo5 = undefined; var foo6 = exports.foo6 = 3; function foo7() {} var foo8 = function foo8() {}; diff --git a/test/fixtures/transformation/es6-modules-common-interop/exports-variable/expected.js b/test/fixtures/transformation/es6-modules-common-interop/exports-variable/expected.js index 886cf61824..42e6fdf913 100644 --- a/test/fixtures/transformation/es6-modules-common-interop/exports-variable/expected.js +++ b/test/fixtures/transformation/es6-modules-common-interop/exports-variable/expected.js @@ -3,9 +3,9 @@ exports.foo7 = foo7; var foo = exports.foo = 1; var foo2 = exports.foo2 = function () {}; -var foo3; +var foo3 = exports.foo3 = undefined; var foo4 = exports.foo4 = 2; -var foo5; +var foo5 = exports.foo5 = undefined; var foo6 = exports.foo6 = 3; function foo7() {} var foo8 = function foo8() {}; diff --git a/test/fixtures/transformation/es6-modules-common/exports-variable/expected.js b/test/fixtures/transformation/es6-modules-common/exports-variable/expected.js index 886cf61824..42e6fdf913 100644 --- a/test/fixtures/transformation/es6-modules-common/exports-variable/expected.js +++ b/test/fixtures/transformation/es6-modules-common/exports-variable/expected.js @@ -3,9 +3,9 @@ exports.foo7 = foo7; var foo = exports.foo = 1; var foo2 = exports.foo2 = function () {}; -var foo3; +var foo3 = exports.foo3 = undefined; var foo4 = exports.foo4 = 2; -var foo5; +var foo5 = exports.foo5 = undefined; var foo6 = exports.foo6 = 3; function foo7() {} var foo8 = function foo8() {}; diff --git a/test/fixtures/transformation/es6-modules-ignore/exports-variable/expected.js b/test/fixtures/transformation/es6-modules-ignore/exports-variable/expected.js index b9c8a5d690..ecf4bd267a 100644 --- a/test/fixtures/transformation/es6-modules-ignore/exports-variable/expected.js +++ b/test/fixtures/transformation/es6-modules-ignore/exports-variable/expected.js @@ -2,9 +2,9 @@ var foo = 1; var foo2 = function () {}; -var foo3; +var foo3 = undefined; var foo4 = 2; -var foo5; +var foo5 = undefined; var foo6 = 3; function foo7() {} var foo8 = function foo8() {}; diff --git a/test/fixtures/transformation/es6-modules-umd/exports-variable/expected.js b/test/fixtures/transformation/es6-modules-umd/exports-variable/expected.js index d381823150..989b8d476b 100644 --- a/test/fixtures/transformation/es6-modules-umd/exports-variable/expected.js +++ b/test/fixtures/transformation/es6-modules-umd/exports-variable/expected.js @@ -10,9 +10,9 @@ exports.foo7 = foo7; var foo = exports.foo = 1; var foo2 = exports.foo2 = function () {}; - var foo3; + var foo3 = exports.foo3 = undefined; var foo4 = exports.foo4 = 2; - var foo5; + var foo5 = exports.foo5 = undefined; var foo6 = exports.foo6 = 3; function foo7() {} var foo8 = function foo8() {}; From b32d56a168a5e8f5c2c50b6d405b94dbfcf24c63 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 9 Dec 2014 23:32:25 +1100 Subject: [PATCH 021/139] remove 6to5-node filenames test --- test/fixtures/bin/6to5-node/filenames/in-files/bar.js | 2 -- test/fixtures/bin/6to5-node/filenames/in-files/foo.js | 2 -- test/fixtures/bin/6to5-node/filenames/options.json | 3 --- test/fixtures/bin/6to5-node/filenames/stdout.txt | 2 -- 4 files changed, 9 deletions(-) delete mode 100644 test/fixtures/bin/6to5-node/filenames/in-files/bar.js delete mode 100644 test/fixtures/bin/6to5-node/filenames/in-files/foo.js delete mode 100644 test/fixtures/bin/6to5-node/filenames/options.json delete mode 100644 test/fixtures/bin/6to5-node/filenames/stdout.txt diff --git a/test/fixtures/bin/6to5-node/filenames/in-files/bar.js b/test/fixtures/bin/6to5-node/filenames/in-files/bar.js deleted file mode 100644 index 5e0f4fd877..0000000000 --- a/test/fixtures/bin/6to5-node/filenames/in-files/bar.js +++ /dev/null @@ -1,2 +0,0 @@ -var bar = () => console.log("bar"); -bar(); diff --git a/test/fixtures/bin/6to5-node/filenames/in-files/foo.js b/test/fixtures/bin/6to5-node/filenames/in-files/foo.js deleted file mode 100644 index 6cbc6fbcfb..0000000000 --- a/test/fixtures/bin/6to5-node/filenames/in-files/foo.js +++ /dev/null @@ -1,2 +0,0 @@ -var foo = () => console.log("foo"); -foo(); diff --git a/test/fixtures/bin/6to5-node/filenames/options.json b/test/fixtures/bin/6to5-node/filenames/options.json deleted file mode 100644 index 4caf67b360..0000000000 --- a/test/fixtures/bin/6to5-node/filenames/options.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "args": ["foo", "bar"] -} diff --git a/test/fixtures/bin/6to5-node/filenames/stdout.txt b/test/fixtures/bin/6to5-node/filenames/stdout.txt deleted file mode 100644 index 3bd1f0e297..0000000000 --- a/test/fixtures/bin/6to5-node/filenames/stdout.txt +++ /dev/null @@ -1,2 +0,0 @@ -foo -bar From 0f47814b4178213662508f044da4cbe17d23a6ad Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Wed, 10 Dec 2014 21:08:00 +1100 Subject: [PATCH 022/139] separate experimental page in docs --- doc/caveats.md | 8 ++++---- doc/experimental.md | 8 ++++++++ doc/features.md | 12 ++++++------ doc/index.md | 12 ++++++------ doc/playground.md | 2 +- doc/usage.md | 9 --------- 6 files changed, 25 insertions(+), 26 deletions(-) create mode 100644 doc/experimental.md diff --git a/doc/caveats.md b/doc/caveats.md index 32049b2f98..097edfc781 100644 --- a/doc/caveats.md +++ b/doc/caveats.md @@ -6,12 +6,12 @@ satisfy **all** 6to5 feature requirements by using the included | Feature | Requirements | | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | -| Abstract References | [experimental](usage.md#experimental), `Symbol` | +| Abstract References | [experimental](experimental.md), `Symbol` | | Array destructuring | `Array.isArray`, `Array.from` | -| Async functions, Generators | [experimental](usage.md#experimental), [regenerator runtime](https://github.com/facebook/regenerator/blob/master/runtime.js) | -| Comprehensions | [experimental](usage.md#experimental), `Array.isArray`, `Array.from` | +| Async functions, Generators | [experimental](experimental.md), [regenerator runtime](https://github.com/facebook/regenerator/blob/master/runtime.js) | +| Comprehensions | [experimental](experimental.md), `Array.isArray`, `Array.from` | | For Of | `Symbol`, `prototype[Symbol.iterator]` | -| Object spread/rest | [experimental](usage.md#experimental), `Object.assign` | +| Object spread/rest | [experimental](experimental.md), `Object.assign` | | Spread | `Array.isArray`, `Array.from` | ## Classes diff --git a/doc/experimental.md b/doc/experimental.md new file mode 100644 index 0000000000..3546d0cb82 --- /dev/null +++ b/doc/experimental.md @@ -0,0 +1,8 @@ +## Experimental + +6to5 also has experimental support for ES7 proposals. You can enable this with +the `experimental: true` option when using the [Node API](#node) or +`--experimental` when using the [CLI](#cli). + +**WARNING:** These proposals are subject to change so use with +**extreme caution**. diff --git a/doc/features.md b/doc/features.md index d23e891620..0efa77c58f 100644 --- a/doc/features.md +++ b/doc/features.md @@ -1,6 +1,6 @@ # Features -## Abstract references ([experimental](usage.md#experimental)) ([spec](https://github.com/zenparsing/es-abstract-refs)) +## Abstract references ([experimental](experimental.md)) ([spec](https://github.com/zenparsing/es-abstract-refs)) ```javascript foo::bar; @@ -8,7 +8,7 @@ foo::bar = baz; delete foo::bar; ``` -## Array comprehensions ([experimental](usage.md#experimental)) +## Array comprehensions ([experimental](experimental.md)) ```javascript var results = [for (c of customers) if (c.city == "Seattle") { name: c.name, age: c.age }] @@ -39,7 +39,7 @@ var bob = { }; ``` -## Async functions ([experimental](usage.md#experimental)) ([spec](https://github.com/lukehoban/ecmascript-asyncawait)) +## Async functions ([experimental](experimental.md)) ([spec](https://github.com/lukehoban/ecmascript-asyncawait)) ```javascript async function chainAnimationsAsync(elem, animations) { @@ -130,7 +130,7 @@ var [a] = []; a === undefined; ``` -## Exponentiation operator ([experimental](usage.md#experimental)) ([spec](https://github.com/rwaldron/exponentiation-operator)) +## Exponentiation operator ([experimental](experimental.md)) ([spec](https://github.com/rwaldron/exponentiation-operator)) ```javascript var a = 2; @@ -167,7 +167,7 @@ for (var n of fibonacci()) { } ``` -## Generator comprehensions ([experimental](usage.md#experimental)) +## Generator comprehensions ([experimental](experimental.md)) ```javascript var nums = [1, 2, 3, 4, 5, 6]; @@ -208,7 +208,7 @@ export default test; 0o767 === 503; // true ``` -## Object spread/rest ([experimental](usage.md#experimental)) ([spec](https://github.com/sebmarkbage/ecmascript-rest-spread)) +## Object spread/rest ([experimental](experimental.md)) ([spec](https://github.com/sebmarkbage/ecmascript-rest-spread)) ```javascript var n = { x, y, ...z }; diff --git a/doc/index.md b/doc/index.md index 507cf6435d..7280935055 100644 --- a/doc/index.md +++ b/doc/index.md @@ -35,23 +35,23 @@ And it doesn't end here! To see all the ways you can use 6to5, check out the ## [Features](features.md) - - [Abstract references](features.md#abstract-references) ([experimental](usage.md#experimental)) - - [Array comprehension](features.md#array-comprehension) ([experimental](usage.md#experimental)) - - [Async functions](features.md#async-functions) ([experimental](usage.md#experimental)) + - [Abstract references](features.md#abstract-references) ([experimental](experimental.md)) + - [Array comprehension](features.md#array-comprehension) ([experimental](experimental.md)) + - [Async functions](features.md#async-functions) ([experimental](experimental.md)) - [Arrow functions](features.md#arrow-functions) - [Classes](features.md#classes) - [Computed property names](features.md#computed-property-names) - [Constants](features.md#constants) - [Default parameters](features.md#default-parameters) - [Destructuring](features.md#destructuring) - - [Exponentiation operator](features.md#exponentiation-operator) ([experimental](usage.md#experimental)) + - [Exponentiation operator](features.md#exponentiation-operator) ([experimental](experimental.md)) - [For-of](features.md#for-of) - [Generators](features.md#generators) - - [Generator comprehension](features.md#generator-comprehension) ([experimental](usage.md#experimental)) + - [Generator comprehension](features.md#generator-comprehension) ([experimental](experimental.md)) - [Let scoping](features.md#let-scoping) - [Modules](features.md#modules) - [Numeric literals](features.md#numeric-literals) - - [Object Rest/Spread](features.md#object-rest-spread) ([experimental](usage.md#experimental)) + - [Object Rest/Spread](features.md#object-rest-spread) ([experimental](experimental.md)) - [Property method assignment](features.md#property-method-assignment) - [Property name shorthand](features.md#property-name-shorthand) - [React/JSX](react.md) diff --git a/doc/playground.md b/doc/playground.md index c1f143f0ad..5ad1ad5738 100644 --- a/doc/playground.md +++ b/doc/playground.md @@ -12,7 +12,7 @@ Playground is a proving ground for **possible** ES7 proposals. to5.transform("code", { playground: true }); ``` -**NOTE:** Enabling `playground` also enables [experimental support](usage.md#experimental). +**NOTE:** Enabling `playground` also enables [experimental support](experimental.md). ## Features diff --git a/doc/usage.md b/doc/usage.md index 7db7c636fc..f9daf47ff2 100644 --- a/doc/usage.md +++ b/doc/usage.md @@ -215,12 +215,3 @@ require("6to5/register")({ extensions: [".js", ".es6"] }); ``` - -## Experimental - -6to5 also has experimental support for ES7 proposals. You can enable this with -the `experimental: true` option when using the [Node API](#node) or -`--experimental` when using the [CLI](#cli). - -**WARNING:** These proposals are subject to change so use with -**extreme caution**. From 8e96130bc05baf3fe5a32c9dae3cdf0f8751500d Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Wed, 10 Dec 2014 21:08:54 +1100 Subject: [PATCH 023/139] rename common to commonStrict and commonInterop to common --- doc/modules.md | 118 +++++------- .../exports-default-module-override.js | 1 + lib/6to5/transformation/modules/_default.js | 153 +++++++++++++++ lib/6to5/transformation/modules/amd.js | 19 +- .../transformation/modules/common-interop.js | 56 ------ .../transformation/modules/common-strict.js | 46 +++++ lib/6to5/transformation/modules/common.js | 178 ++++-------------- .../exports-default/expected.js | 15 -- .../imports-default/expected.js | 9 - .../imports-mixing/expected.js | 9 - .../es6-modules-common-interop/options.json | 3 - .../exports-default/actual.js | 0 .../exports-default/expected.js | 15 ++ .../exports-from/actual.js | 0 .../exports-from/expected.js | 0 .../exports-named/actual.js | 0 .../exports-named/expected.js | 0 .../exports-variable/actual.js | 0 .../exports-variable/expected.js | 0 .../hoist-function-exports/actual.js | 0 .../hoist-function-exports/expected.js | 0 .../imports-default/actual.js | 0 .../imports-default/expected.js | 4 + .../imports-glob/actual.js | 0 .../imports-glob/expected.js | 0 .../imports-mixing/actual.js | 0 .../imports-mixing/expected.js | 4 + .../imports-named/actual.js | 0 .../imports-named/expected.js | 0 .../imports/actual.js | 0 .../imports/expected.js | 0 .../es6-modules-common-strict/options.json | 3 + .../overview/actual.js | 0 .../overview/expected.js | 7 +- .../exports-default/expected.js | 16 +- .../imports-default/expected.js | 9 +- .../imports-mixing/expected.js | 7 +- .../es6-modules-common/overview/expected.js | 9 +- 38 files changed, 355 insertions(+), 326 deletions(-) create mode 100644 lib/6to5/templates/exports-default-module-override.js create mode 100644 lib/6to5/transformation/modules/_default.js delete mode 100644 lib/6to5/transformation/modules/common-interop.js create mode 100644 lib/6to5/transformation/modules/common-strict.js delete mode 100644 test/fixtures/transformation/es6-modules-common-interop/exports-default/expected.js delete mode 100644 test/fixtures/transformation/es6-modules-common-interop/imports-default/expected.js delete mode 100644 test/fixtures/transformation/es6-modules-common-interop/imports-mixing/expected.js delete mode 100644 test/fixtures/transformation/es6-modules-common-interop/options.json rename test/fixtures/transformation/{es6-modules-common-interop => es6-modules-common-strict}/exports-default/actual.js (100%) create mode 100644 test/fixtures/transformation/es6-modules-common-strict/exports-default/expected.js rename test/fixtures/transformation/{es6-modules-common-interop => es6-modules-common-strict}/exports-from/actual.js (100%) rename test/fixtures/transformation/{es6-modules-common-interop => es6-modules-common-strict}/exports-from/expected.js (100%) rename test/fixtures/transformation/{es6-modules-common-interop => es6-modules-common-strict}/exports-named/actual.js (100%) rename test/fixtures/transformation/{es6-modules-common-interop => es6-modules-common-strict}/exports-named/expected.js (100%) rename test/fixtures/transformation/{es6-modules-common-interop => es6-modules-common-strict}/exports-variable/actual.js (100%) rename test/fixtures/transformation/{es6-modules-common-interop => es6-modules-common-strict}/exports-variable/expected.js (100%) rename test/fixtures/transformation/{es6-modules-common-interop => es6-modules-common-strict}/hoist-function-exports/actual.js (100%) rename test/fixtures/transformation/{es6-modules-common-interop => es6-modules-common-strict}/hoist-function-exports/expected.js (100%) rename test/fixtures/transformation/{es6-modules-common-interop => es6-modules-common-strict}/imports-default/actual.js (100%) create mode 100644 test/fixtures/transformation/es6-modules-common-strict/imports-default/expected.js rename test/fixtures/transformation/{es6-modules-common-interop => es6-modules-common-strict}/imports-glob/actual.js (100%) rename test/fixtures/transformation/{es6-modules-common-interop => es6-modules-common-strict}/imports-glob/expected.js (100%) rename test/fixtures/transformation/{es6-modules-common-interop => es6-modules-common-strict}/imports-mixing/actual.js (100%) create mode 100644 test/fixtures/transformation/es6-modules-common-strict/imports-mixing/expected.js rename test/fixtures/transformation/{es6-modules-common-interop => es6-modules-common-strict}/imports-named/actual.js (100%) rename test/fixtures/transformation/{es6-modules-common-interop => es6-modules-common-strict}/imports-named/expected.js (100%) rename test/fixtures/transformation/{es6-modules-common-interop => es6-modules-common-strict}/imports/actual.js (100%) rename test/fixtures/transformation/{es6-modules-common-interop => es6-modules-common-strict}/imports/expected.js (100%) create mode 100644 test/fixtures/transformation/es6-modules-common-strict/options.json rename test/fixtures/transformation/{es6-modules-common-interop => es6-modules-common-strict}/overview/actual.js (100%) rename test/fixtures/transformation/{es6-modules-common-interop => es6-modules-common-strict}/overview/expected.js (66%) diff --git a/doc/modules.md b/doc/modules.md index 5fcba15868..7ce8b20d07 100644 --- a/doc/modules.md +++ b/doc/modules.md @@ -19,12 +19,12 @@ to5.transform('import "foo";', { modules: "common" }); * [AMD](#amd) * [Common (Default)](#common-default) - * [Common Interop](#common-interop) + * [Common Strict](#common-strict) * [Ignore](#ignore) * [System](#system) * [UMD](#umd) -### Common (Default) +### Common ```sh $ 6to5 --modules common @@ -32,6 +32,53 @@ $ 6to5 --modules common **In** +```javascript +export default test; + +export {test}; +export var test = 5; + +import "foo"; + +import foo from "foo"; +import * as foo from "foo"; + +import {bar} from "foo"; +import {foo as bar} from "foo"; +``` + +**Out** + +```javascript +"use strict"; + +var _interopRequire = function (obj) { + return obj && (obj["default"] || obj); +}; + +exports = module.exports = test; + +exports.test = test; +var test = exports.test = 5; + +require("foo"); + +var foo = _interopRequire(require("foo")); + +var foo = require("foo"); + +var bar = require("foo").bar; +var bar = require("foo").foo; +``` + +### Common Strict + +```sh +$ 6to5 --modules commonStrict +``` + +**In** + ```javascript import "foo"; @@ -64,73 +111,6 @@ var test = 5; exports.test = test; exports.default = test; ``` -### Common interop - -```sh -$ 6to5 --modules commonInterop -``` - -**In** - -```javascript -import "foo"; - -import foo from "foo"; -import * as foo from "foo"; - -import {bar} from "foo"; -import {foo as bar} from "foo"; - -export {test}; -export var test = 5; - -export default test; -``` - -**Out** - -```javascript -var _interopRequire = function (obj) { - return obj && (obj["default"] || obj); -}; - -require("foo"); - -var foo = _interopRequire(require("foo")); -var foo = require("foo"); - -var bar = require("foo").bar; -var bar = require("foo").foo; - -exports.test = test; -var test = exports.test = 5; - -exports["default"] = test; -``` - -#### module.exports behaviour - -If there exist no other non-default `export`s then `default exports` are -exported as `module.exports` instead of `exports.default`. - -**In** - -```javascript -export default function foo() { - -} -``` - -**Out** - -```javascript -module.exports = foo; - -function foo() { - -} -``` - ### AMD ```sh diff --git a/lib/6to5/templates/exports-default-module-override.js b/lib/6to5/templates/exports-default-module-override.js new file mode 100644 index 0000000000..4ce92a4fd1 --- /dev/null +++ b/lib/6to5/templates/exports-default-module-override.js @@ -0,0 +1 @@ +exports = module.exports = VALUE; diff --git a/lib/6to5/transformation/modules/_default.js b/lib/6to5/transformation/modules/_default.js new file mode 100644 index 0000000000..7d3f06c345 --- /dev/null +++ b/lib/6to5/transformation/modules/_default.js @@ -0,0 +1,153 @@ +module.exports = DefaultFormatter; + +var traverse = require("../../traverse"); +var util = require("../../util"); +var t = require("../../types"); +var _ = require("lodash"); + +function DefaultFormatter(file) { + this.exports = []; + this.file = file; + + var localExports = []; + _.each(file.ast.program.body, function (node) { + var declar = node.declaration; + if (t.isExportDeclaration(node) && declar && t.isStatement(declar)) { + localExports = localExports.concat(t.getIds(declar)); + } + }); + this.localExports = localExports; + + this.remapAssignments(); +} + +DefaultFormatter.prototype.remapAssignments = function () { + var localExports = this.localExports; + + traverse(this.file.ast, function (node) { + if (t.isExportDeclaration(node)) return false; + + if (t.isAssignmentExpression(node)) { + var left = node.left; + if (t.isIdentifier(left) && _.contains(localExports, left.name)) { + return t.assignmentExpression( + "=", + left, + t.assignmentExpression( + node.operator, + t.memberExpression(t.identifier("exports"), left), + node.right + ) + ); + } + } + }); +}; + +DefaultFormatter.prototype.getModuleName = function () { + var opts = this.file.opts; + var filenameRelative = opts.filenameRelative; + var moduleName = ""; + + if (opts.moduleRoot) { + moduleName = opts.moduleRoot + "/"; + } + + if (!opts.filenameRelative) { + return moduleName + opts.filename.replace(/^\//, ""); + } + + if (opts.sourceRoot) { + // remove sourceRoot from filename + var sourceRootRegEx = new RegExp("^" + opts.sourceRoot + "\/?"); + filenameRelative = filenameRelative.replace(sourceRootRegEx, ""); + } + + // remove extension + filenameRelative = filenameRelative.replace(/\.(.*?)$/, ""); + + moduleName += filenameRelative; + + return moduleName; +}; + +DefaultFormatter.prototype._pushStatement = function (ref, nodes) { + if (t.isClass(ref) || t.isFunction(ref)) { + if (ref.id) { + nodes.push(t.toStatement(ref)); + ref = ref.id; + } + } + + return ref; +}; + +DefaultFormatter.prototype._hoistExport = function (declar, assign) { + if (t.isFunctionDeclaration(declar)) { + assign._blockHoist = true; + } + + return assign; +}; + +DefaultFormatter.prototype._exportSpecifier = function (getRef, specifier, node, nodes) { + var variableName = t.getSpecifierName(specifier); + + var inherits = false; + if (node.specifiers.length === 1) inherits = node; + + if (node.source) { + if (t.isExportBatchSpecifier(specifier)) { + // export * from "foo"; + nodes.push(util.template("exports-wildcard", { + OBJECT: getRef() + }, true)); + } else { + // export { foo } from "test"; + nodes.push(util.template("exports-assign-key", { + VARIABLE_NAME: variableName.name, + OBJECT: getRef(), + KEY: specifier.id + }, true)); + } + } else { + // export { foo }; + nodes.push(util.template("exports-assign", { + VALUE: specifier.id, + KEY: variableName + }, true)); + } +}; + +DefaultFormatter.prototype.export = function (node, nodes) { + var declar = node.declaration; + + if (node.default) { + nodes.push(util.template("exports-default", { + VALUE: this._pushStatement(declar, nodes) + }, true)); + } else { + var assign; + + if (t.isVariableDeclaration(declar)) { + var decl = declar.declarations[0]; + + decl.init = util.template("exports-assign", { + VALUE: decl.init, + KEY: decl.id + }); + + nodes.push(declar); + } else { + assign = util.template("exports-assign", { + VALUE: declar.id, + KEY: declar.id + }, true); + + nodes.push(t.toStatement(declar)); + nodes.push(assign); + + this._hoistExport(declar, assign); + } + } +}; diff --git a/lib/6to5/transformation/modules/amd.js b/lib/6to5/transformation/modules/amd.js index 3a0469cd7e..23566148a8 100644 --- a/lib/6to5/transformation/modules/amd.js +++ b/lib/6to5/transformation/modules/amd.js @@ -1,16 +1,20 @@ module.exports = AMDFormatter; -var CommonJSFormatter = require("./common"); -var util = require("../../util"); -var t = require("../../types"); -var _ = require("lodash"); +var DefaultFormatter = require("./_default"); +var util = require("../../util"); +var t = require("../../types"); +var _ = require("lodash"); function AMDFormatter(file) { this.file = file; this.ids = {}; } -util.inherits(AMDFormatter, CommonJSFormatter); +util.inherits(AMDFormatter, DefaultFormatter); + +/** + * Wrap the entire body in a `define` wrapper. + */ AMDFormatter.prototype.transform = function (ast) { var program = ast.program; @@ -40,6 +44,11 @@ AMDFormatter.prototype.transform = function (ast) { program.body = [t.expressionStatement(call)]; }; +/** + * Get the AMD module name that we'll prepend to the wrapper + * to define this module + */ + AMDFormatter.prototype.getModuleName = function () { if (this.file.opts.amdModuleIds) { return CommonJSFormatter.prototype.getModuleName.apply(this, arguments); diff --git a/lib/6to5/transformation/modules/common-interop.js b/lib/6to5/transformation/modules/common-interop.js deleted file mode 100644 index 9cc4d4bd37..0000000000 --- a/lib/6to5/transformation/modules/common-interop.js +++ /dev/null @@ -1,56 +0,0 @@ -module.exports = CommonJSInteropFormatter; - -var CommonJSFormatter = require("./common"); -var util = require("../../util"); -var t = require("../../types"); -var _ = require("lodash"); - -function CommonJSInteropFormatter(file) { - CommonJSFormatter.apply(this, arguments); - - var has = false; - _.each(file.ast.program.body, function (node) { - if (t.isExportDeclaration(node) && !node.default) has = true; - }); - this.has = has; -} - -util.inherits(CommonJSInteropFormatter, CommonJSFormatter); - -CommonJSInteropFormatter.prototype.importSpecifier = function (specifier, node, nodes) { - var variableName = t.getSpecifierName(specifier); - - // import foo from "foo"; - if (specifier.default) { - nodes.push(t.variableDeclaration("var", [ - t.variableDeclarator(variableName, - t.callExpression(this.file.addDeclaration("interop-require"), [util.template("require", { - MODULE_NAME: node.source.raw - })]) - ) - ])); - } else { - CommonJSFormatter.prototype.importSpecifier.apply(this, arguments); - } -}; - -CommonJSInteropFormatter.prototype.export = function (node, nodes) { - if (node.default && !this.has) { - var declar = node.declaration; - - // module.exports = VALUE; - var assign = util.template("exports-default-module", { - VALUE: this._pushStatement(declar, nodes) - }, true); - - // hoist to the top if this default is a function - nodes.push(this._hoistExport(declar, assign)); - return; - } - - CommonJSFormatter.prototype.export.apply(this, arguments); -}; - -CommonJSInteropFormatter.prototype.exportSpecifier = function () { - CommonJSFormatter.prototype.exportSpecifier.apply(this, arguments); -}; diff --git a/lib/6to5/transformation/modules/common-strict.js b/lib/6to5/transformation/modules/common-strict.js new file mode 100644 index 0000000000..eb58cb6d75 --- /dev/null +++ b/lib/6to5/transformation/modules/common-strict.js @@ -0,0 +1,46 @@ +module.exports = CommonJSStrictFormatter; + +var DefaultFormatter = require("./_default"); +var util = require("../../util"); +var t = require("../../types"); + +function CommonJSStrictFormatter() { + DefaultFormatter.apply(this, arguments); +} + +util.inherits(CommonJSStrictFormatter, DefaultFormatter); + +CommonJSStrictFormatter.prototype.import = function (node, nodes) { + // import "foo"; + nodes.push(util.template("require", { + //inherits: node, + + MODULE_NAME: node.source.raw + }, true)); +}; + +CommonJSStrictFormatter.prototype.importSpecifier = function (specifier, node, nodes) { + var variableName = t.getSpecifierName(specifier); + + // import foo from "foo"; + if (specifier.default) { + specifier.id = t.identifier("default"); + } + + var templateName = "require-assign"; + + // import * as bar from "foo"; + if (specifier.type !== "ImportBatchSpecifier") templateName += "-key"; + + nodes.push(util.template(templateName, { + VARIABLE_NAME: variableName, + MODULE_NAME: node.source.raw, + KEY: specifier.id + })); +}; + +CommonJSStrictFormatter.prototype.exportSpecifier = function (specifier, node, nodes) { + this._exportSpecifier(function () { + return t.callExpression(t.identifier("require"), [node.source]); + }, specifier, node, nodes); +}; diff --git a/lib/6to5/transformation/modules/common.js b/lib/6to5/transformation/modules/common.js index 8ab054cf5d..1feb646d61 100644 --- a/lib/6to5/transformation/modules/common.js +++ b/lib/6to5/transformation/modules/common.js @@ -1,164 +1,60 @@ module.exports = CommonJSFormatter; -var util = require("../../util"); -var t = require("../../types"); +var CommonJSStrictFormatter = require("./common-strict"); +var util = require("../../util"); +var t = require("../../types"); +var _ = require("lodash"); function CommonJSFormatter(file) { - this.file = file; + CommonJSStrictFormatter.apply(this, arguments); + + var hasNonDefaultExports = false; + _.each(file.ast.program.body, function (node) { + if (t.isExportDeclaration(node) && !node.default) hasNonDefaultExports = true; + }); + this.hasNonDefaultExports = hasNonDefaultExports; } -CommonJSFormatter.prototype.getModuleName = function () { - var opts = this.file.opts; - var filenameRelative = opts.filenameRelative; - var moduleName = ""; - - if (opts.moduleRoot) { - moduleName = opts.moduleRoot + "/"; - } - - if (!opts.filenameRelative) { - return moduleName + opts.filename.replace(/^\//, ""); - } - - if (opts.sourceRoot) { - // remove sourceRoot from filename - var sourceRootRegEx = new RegExp("^" + opts.sourceRoot + "\/?"); - filenameRelative = filenameRelative.replace(sourceRootRegEx, ""); - } - - // remove extension - filenameRelative = filenameRelative.replace(/\.(.*?)$/, ""); - - moduleName += filenameRelative; - - return moduleName; -}; - -CommonJSFormatter.prototype.import = function (node, nodes) { - // import "foo"; - nodes.push(util.template("require", { - //inherits: node, - - MODULE_NAME: node.source.raw - }, true)); -}; +util.inherits(CommonJSFormatter, CommonJSStrictFormatter); CommonJSFormatter.prototype.importSpecifier = function (specifier, node, nodes) { var variableName = t.getSpecifierName(specifier); // import foo from "foo"; - if (specifier.default) { - specifier.id = t.identifier("default"); + if (t.isIdentifier(specifier.id) && specifier.id.name === "default") { + nodes.push(t.variableDeclaration("var", [ + t.variableDeclarator(variableName, + t.callExpression(this.file.addDeclaration("interop-require"), [util.template("require", { + MODULE_NAME: node.source.raw + })]) + ) + ])); + } else { + CommonJSStrictFormatter.prototype.importSpecifier.apply(this, arguments); } - - var templateName = "require-assign"; - - // import * as bar from "foo"; - if (specifier.type !== "ImportBatchSpecifier") templateName += "-key"; - - nodes.push(util.template(templateName, { - //inherits: node.specifiers.length === 1 && node, - - VARIABLE_NAME: variableName, - MODULE_NAME: node.source.raw, - KEY: specifier.id - })); -}; - -CommonJSFormatter.prototype._hoistExport = function (declar, assign) { - if (t.isFunctionDeclaration(declar)) { - assign._blockHoist = true; - } - - return assign; -}; - -CommonJSFormatter.prototype._pushStatement = function (ref, nodes) { - if (t.isClass(ref) || t.isFunction(ref)) { - if (ref.id) { - nodes.push(t.toStatement(ref)); - ref = ref.id; - } - } - return ref; }; CommonJSFormatter.prototype.export = function (node, nodes) { - var declar = node.declaration; - if (node.default) { - nodes.push(util.template("exports-default", { - //inherits: node, + var declar = node.declaration; + // module.exports = VALUE; + var templateName = "exports-default-module"; + + // exports = module.exports = VALUE; + if (this.hasNonDefaultExports) templateName = "exports-default-module-override" + + var assign = util.template(templateName, { VALUE: this._pushStatement(declar, nodes) - }, true)); + }, true); + + // hoist to the top if this default is a function + nodes.push(this._hoistExport(declar, assign)); } else { - var assign; - - if (t.isVariableDeclaration(declar)) { - var decl = declar.declarations[0]; - - decl.init = util.template("exports-assign", { - //inherits: node, - - VALUE: decl.init, - KEY: decl.id - }); - - nodes.push(declar); - } else { - assign = util.template("exports-assign", { - //inherits: node, - - VALUE: declar.id, - KEY: declar.id - }, true); - - nodes.push(t.toStatement(declar)); - nodes.push(assign); - - this._hoistExport(declar, assign); - } + CommonJSStrictFormatter.prototype.export.apply(this, arguments); } }; -CommonJSFormatter.prototype._exportSpecifier = function (getRef, specifier, node, nodes) { - var variableName = t.getSpecifierName(specifier); - - var inherits = false; - if (node.specifiers.length === 1) inherits = node; - - if (node.source) { - if (t.isExportBatchSpecifier(specifier)) { - // export * from "foo"; - nodes.push(util.template("exports-wildcard", { - //inherits: inherits, - - OBJECT: getRef() - }, true)); - } else { - // export { foo } from "test"; - nodes.push(util.template("exports-assign-key", { - //inherits: inherits, - - VARIABLE_NAME: variableName.name, - OBJECT: getRef(), - KEY: specifier.id - }, true)); - } - } else { - // export { foo }; - nodes.push(util.template("exports-assign", { - //inherits: inherits, - - VALUE: specifier.id, - KEY: variableName - }, true)); - } -}; - -CommonJSFormatter.prototype.exportSpecifier = function (specifier, node, nodes) { - this._exportSpecifier(function () { - return t.callExpression(t.identifier("require"), [node.source]); - }, specifier, node, nodes); +CommonJSFormatter.prototype.exportSpecifier = function () { + CommonJSStrictFormatter.prototype.exportSpecifier.apply(this, arguments); }; diff --git a/test/fixtures/transformation/es6-modules-common-interop/exports-default/expected.js b/test/fixtures/transformation/es6-modules-common-interop/exports-default/expected.js deleted file mode 100644 index ef8ba56786..0000000000 --- a/test/fixtures/transformation/es6-modules-common-interop/exports-default/expected.js +++ /dev/null @@ -1,15 +0,0 @@ -"use strict"; - -module.exports = foo; -module.exports = 42; -module.exports = {}; -module.exports = []; -module.exports = foo; -module.exports = function () {}; - -module.exports = function () {}; - -function foo() {} -var Foo = function Foo() {}; - -module.exports = Foo; diff --git a/test/fixtures/transformation/es6-modules-common-interop/imports-default/expected.js b/test/fixtures/transformation/es6-modules-common-interop/imports-default/expected.js deleted file mode 100644 index a93b2668f9..0000000000 --- a/test/fixtures/transformation/es6-modules-common-interop/imports-default/expected.js +++ /dev/null @@ -1,9 +0,0 @@ -"use strict"; - -var _interopRequire = function (obj) { - return obj && (obj["default"] || obj); -}; - -var foo = _interopRequire(require("foo")); - -var foo = require("foo")["default"]; diff --git a/test/fixtures/transformation/es6-modules-common-interop/imports-mixing/expected.js b/test/fixtures/transformation/es6-modules-common-interop/imports-mixing/expected.js deleted file mode 100644 index 09ea4cec86..0000000000 --- a/test/fixtures/transformation/es6-modules-common-interop/imports-mixing/expected.js +++ /dev/null @@ -1,9 +0,0 @@ -"use strict"; - -var _interopRequire = function (obj) { - return obj && (obj["default"] || obj); -}; - -var foo = _interopRequire(require("foo")); - -var xyz = require("foo").baz; diff --git a/test/fixtures/transformation/es6-modules-common-interop/options.json b/test/fixtures/transformation/es6-modules-common-interop/options.json deleted file mode 100644 index d5e2792eed..0000000000 --- a/test/fixtures/transformation/es6-modules-common-interop/options.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "modules": "commonInterop" -} diff --git a/test/fixtures/transformation/es6-modules-common-interop/exports-default/actual.js b/test/fixtures/transformation/es6-modules-common-strict/exports-default/actual.js similarity index 100% rename from test/fixtures/transformation/es6-modules-common-interop/exports-default/actual.js rename to test/fixtures/transformation/es6-modules-common-strict/exports-default/actual.js diff --git a/test/fixtures/transformation/es6-modules-common-strict/exports-default/expected.js b/test/fixtures/transformation/es6-modules-common-strict/exports-default/expected.js new file mode 100644 index 0000000000..8c68ab4224 --- /dev/null +++ b/test/fixtures/transformation/es6-modules-common-strict/exports-default/expected.js @@ -0,0 +1,15 @@ +"use strict"; + +exports["default"] = 42; +exports["default"] = {}; +exports["default"] = []; +exports["default"] = foo; +exports["default"] = function () {}; + +exports["default"] = function () {}; + +function foo() {} +exports["default"] = foo; +var Foo = function Foo() {}; + +exports["default"] = Foo; diff --git a/test/fixtures/transformation/es6-modules-common-interop/exports-from/actual.js b/test/fixtures/transformation/es6-modules-common-strict/exports-from/actual.js similarity index 100% rename from test/fixtures/transformation/es6-modules-common-interop/exports-from/actual.js rename to test/fixtures/transformation/es6-modules-common-strict/exports-from/actual.js diff --git a/test/fixtures/transformation/es6-modules-common-interop/exports-from/expected.js b/test/fixtures/transformation/es6-modules-common-strict/exports-from/expected.js similarity index 100% rename from test/fixtures/transformation/es6-modules-common-interop/exports-from/expected.js rename to test/fixtures/transformation/es6-modules-common-strict/exports-from/expected.js diff --git a/test/fixtures/transformation/es6-modules-common-interop/exports-named/actual.js b/test/fixtures/transformation/es6-modules-common-strict/exports-named/actual.js similarity index 100% rename from test/fixtures/transformation/es6-modules-common-interop/exports-named/actual.js rename to test/fixtures/transformation/es6-modules-common-strict/exports-named/actual.js diff --git a/test/fixtures/transformation/es6-modules-common-interop/exports-named/expected.js b/test/fixtures/transformation/es6-modules-common-strict/exports-named/expected.js similarity index 100% rename from test/fixtures/transformation/es6-modules-common-interop/exports-named/expected.js rename to test/fixtures/transformation/es6-modules-common-strict/exports-named/expected.js diff --git a/test/fixtures/transformation/es6-modules-common-interop/exports-variable/actual.js b/test/fixtures/transformation/es6-modules-common-strict/exports-variable/actual.js similarity index 100% rename from test/fixtures/transformation/es6-modules-common-interop/exports-variable/actual.js rename to test/fixtures/transformation/es6-modules-common-strict/exports-variable/actual.js diff --git a/test/fixtures/transformation/es6-modules-common-interop/exports-variable/expected.js b/test/fixtures/transformation/es6-modules-common-strict/exports-variable/expected.js similarity index 100% rename from test/fixtures/transformation/es6-modules-common-interop/exports-variable/expected.js rename to test/fixtures/transformation/es6-modules-common-strict/exports-variable/expected.js diff --git a/test/fixtures/transformation/es6-modules-common-interop/hoist-function-exports/actual.js b/test/fixtures/transformation/es6-modules-common-strict/hoist-function-exports/actual.js similarity index 100% rename from test/fixtures/transformation/es6-modules-common-interop/hoist-function-exports/actual.js rename to test/fixtures/transformation/es6-modules-common-strict/hoist-function-exports/actual.js diff --git a/test/fixtures/transformation/es6-modules-common-interop/hoist-function-exports/expected.js b/test/fixtures/transformation/es6-modules-common-strict/hoist-function-exports/expected.js similarity index 100% rename from test/fixtures/transformation/es6-modules-common-interop/hoist-function-exports/expected.js rename to test/fixtures/transformation/es6-modules-common-strict/hoist-function-exports/expected.js diff --git a/test/fixtures/transformation/es6-modules-common-interop/imports-default/actual.js b/test/fixtures/transformation/es6-modules-common-strict/imports-default/actual.js similarity index 100% rename from test/fixtures/transformation/es6-modules-common-interop/imports-default/actual.js rename to test/fixtures/transformation/es6-modules-common-strict/imports-default/actual.js diff --git a/test/fixtures/transformation/es6-modules-common-strict/imports-default/expected.js b/test/fixtures/transformation/es6-modules-common-strict/imports-default/expected.js new file mode 100644 index 0000000000..32db9b239c --- /dev/null +++ b/test/fixtures/transformation/es6-modules-common-strict/imports-default/expected.js @@ -0,0 +1,4 @@ +"use strict"; + +var foo = require("foo")["default"]; +var foo = require("foo")["default"]; diff --git a/test/fixtures/transformation/es6-modules-common-interop/imports-glob/actual.js b/test/fixtures/transformation/es6-modules-common-strict/imports-glob/actual.js similarity index 100% rename from test/fixtures/transformation/es6-modules-common-interop/imports-glob/actual.js rename to test/fixtures/transformation/es6-modules-common-strict/imports-glob/actual.js diff --git a/test/fixtures/transformation/es6-modules-common-interop/imports-glob/expected.js b/test/fixtures/transformation/es6-modules-common-strict/imports-glob/expected.js similarity index 100% rename from test/fixtures/transformation/es6-modules-common-interop/imports-glob/expected.js rename to test/fixtures/transformation/es6-modules-common-strict/imports-glob/expected.js diff --git a/test/fixtures/transformation/es6-modules-common-interop/imports-mixing/actual.js b/test/fixtures/transformation/es6-modules-common-strict/imports-mixing/actual.js similarity index 100% rename from test/fixtures/transformation/es6-modules-common-interop/imports-mixing/actual.js rename to test/fixtures/transformation/es6-modules-common-strict/imports-mixing/actual.js diff --git a/test/fixtures/transformation/es6-modules-common-strict/imports-mixing/expected.js b/test/fixtures/transformation/es6-modules-common-strict/imports-mixing/expected.js new file mode 100644 index 0000000000..57bcfd38fc --- /dev/null +++ b/test/fixtures/transformation/es6-modules-common-strict/imports-mixing/expected.js @@ -0,0 +1,4 @@ +"use strict"; + +var foo = require("foo")["default"]; +var xyz = require("foo").baz; diff --git a/test/fixtures/transformation/es6-modules-common-interop/imports-named/actual.js b/test/fixtures/transformation/es6-modules-common-strict/imports-named/actual.js similarity index 100% rename from test/fixtures/transformation/es6-modules-common-interop/imports-named/actual.js rename to test/fixtures/transformation/es6-modules-common-strict/imports-named/actual.js diff --git a/test/fixtures/transformation/es6-modules-common-interop/imports-named/expected.js b/test/fixtures/transformation/es6-modules-common-strict/imports-named/expected.js similarity index 100% rename from test/fixtures/transformation/es6-modules-common-interop/imports-named/expected.js rename to test/fixtures/transformation/es6-modules-common-strict/imports-named/expected.js diff --git a/test/fixtures/transformation/es6-modules-common-interop/imports/actual.js b/test/fixtures/transformation/es6-modules-common-strict/imports/actual.js similarity index 100% rename from test/fixtures/transformation/es6-modules-common-interop/imports/actual.js rename to test/fixtures/transformation/es6-modules-common-strict/imports/actual.js diff --git a/test/fixtures/transformation/es6-modules-common-interop/imports/expected.js b/test/fixtures/transformation/es6-modules-common-strict/imports/expected.js similarity index 100% rename from test/fixtures/transformation/es6-modules-common-interop/imports/expected.js rename to test/fixtures/transformation/es6-modules-common-strict/imports/expected.js diff --git a/test/fixtures/transformation/es6-modules-common-strict/options.json b/test/fixtures/transformation/es6-modules-common-strict/options.json new file mode 100644 index 0000000000..42fca89301 --- /dev/null +++ b/test/fixtures/transformation/es6-modules-common-strict/options.json @@ -0,0 +1,3 @@ +{ + "modules": "commonStrict" +} diff --git a/test/fixtures/transformation/es6-modules-common-interop/overview/actual.js b/test/fixtures/transformation/es6-modules-common-strict/overview/actual.js similarity index 100% rename from test/fixtures/transformation/es6-modules-common-interop/overview/actual.js rename to test/fixtures/transformation/es6-modules-common-strict/overview/actual.js diff --git a/test/fixtures/transformation/es6-modules-common-interop/overview/expected.js b/test/fixtures/transformation/es6-modules-common-strict/overview/expected.js similarity index 66% rename from test/fixtures/transformation/es6-modules-common-interop/overview/expected.js rename to test/fixtures/transformation/es6-modules-common-strict/overview/expected.js index 208d3a3d3b..614b23e905 100644 --- a/test/fixtures/transformation/es6-modules-common-interop/overview/expected.js +++ b/test/fixtures/transformation/es6-modules-common-strict/overview/expected.js @@ -1,17 +1,12 @@ "use strict"; -var _interopRequire = function (obj) { - return obj && (obj["default"] || obj); -}; - require("foo"); require("foo-bar"); require("./directory/foo-bar"); -var foo = _interopRequire(require("foo")); - +var foo = require("foo")["default"]; var foo = require("foo"); var bar = require("foo").bar; diff --git a/test/fixtures/transformation/es6-modules-common/exports-default/expected.js b/test/fixtures/transformation/es6-modules-common/exports-default/expected.js index 8c68ab4224..ef8ba56786 100644 --- a/test/fixtures/transformation/es6-modules-common/exports-default/expected.js +++ b/test/fixtures/transformation/es6-modules-common/exports-default/expected.js @@ -1,15 +1,15 @@ "use strict"; -exports["default"] = 42; -exports["default"] = {}; -exports["default"] = []; -exports["default"] = foo; -exports["default"] = function () {}; +module.exports = foo; +module.exports = 42; +module.exports = {}; +module.exports = []; +module.exports = foo; +module.exports = function () {}; -exports["default"] = function () {}; +module.exports = function () {}; function foo() {} -exports["default"] = foo; var Foo = function Foo() {}; -exports["default"] = Foo; +module.exports = Foo; diff --git a/test/fixtures/transformation/es6-modules-common/imports-default/expected.js b/test/fixtures/transformation/es6-modules-common/imports-default/expected.js index 32db9b239c..2a84fb6d1e 100644 --- a/test/fixtures/transformation/es6-modules-common/imports-default/expected.js +++ b/test/fixtures/transformation/es6-modules-common/imports-default/expected.js @@ -1,4 +1,9 @@ "use strict"; -var foo = require("foo")["default"]; -var foo = require("foo")["default"]; +var _interopRequire = function (obj) { + return obj && (obj["default"] || obj); +}; + +var foo = _interopRequire(require("foo")); + +var foo = _interopRequire(require("foo")); diff --git a/test/fixtures/transformation/es6-modules-common/imports-mixing/expected.js b/test/fixtures/transformation/es6-modules-common/imports-mixing/expected.js index 57bcfd38fc..09ea4cec86 100644 --- a/test/fixtures/transformation/es6-modules-common/imports-mixing/expected.js +++ b/test/fixtures/transformation/es6-modules-common/imports-mixing/expected.js @@ -1,4 +1,9 @@ "use strict"; -var foo = require("foo")["default"]; +var _interopRequire = function (obj) { + return obj && (obj["default"] || obj); +}; + +var foo = _interopRequire(require("foo")); + var xyz = require("foo").baz; diff --git a/test/fixtures/transformation/es6-modules-common/overview/expected.js b/test/fixtures/transformation/es6-modules-common/overview/expected.js index 614b23e905..f0d7868fc9 100644 --- a/test/fixtures/transformation/es6-modules-common/overview/expected.js +++ b/test/fixtures/transformation/es6-modules-common/overview/expected.js @@ -1,12 +1,17 @@ "use strict"; +var _interopRequire = function (obj) { + return obj && (obj["default"] || obj); +}; + require("foo"); require("foo-bar"); require("./directory/foo-bar"); -var foo = require("foo")["default"]; +var foo = _interopRequire(require("foo")); + var foo = require("foo"); var bar = require("foo").bar; @@ -14,4 +19,4 @@ var bar = require("foo").foo; exports.test = test; var test = exports.test = 5; -exports["default"] = test; +exports = module.exports = test; From 1c22c608a970600aeef58784cad7013b77bb02da Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Wed, 10 Dec 2014 21:09:09 +1100 Subject: [PATCH 024/139] make bin/6to5-node usage more inline with node --- bin/_6to5-node | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/bin/_6to5-node b/bin/_6to5-node index 7d8b14a304..98a6563c63 100644 --- a/bin/_6to5-node +++ b/bin/_6to5-node @@ -46,12 +46,24 @@ if (commander.eval) { if (commander.print) console.log(result); } else { if (commander.args.length) { - process.argv.splice(0, 1); // remove 6to5-node directive + // slice all arguments up to the first filename since they're 6to5 args that we handle + var args = process.argv.slice(2); - var filename = process.argv[1]; - if (!util.isAbsolute(filename)) { - process.argv[1] = path.join(process.cwd(), filename); - } + var i = 0; + _.each(args, function (arg, i2) { + if (arg[0] !== "-") { + i = i2; + return false; + } + }); + args = args.slice(i); + + // make the filename absolute + var filename = args[0] + if (!util.isAbsolute(filename)) args[0] = path.join(process.cwd(), filename); + + // add back on node and concat the sliced args + process.argv = ["node"].concat(args); Module.runMain(); } else { From e6da342e8bf6fc226e82d1f7cf06d9e483c799a4 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Wed, 10 Dec 2014 21:09:58 +1100 Subject: [PATCH 025/139] add a "spec" transformer namespace for transformers that nicen up code and make it well, more spec compliant --- lib/6to5/transformation/transform.js | 33 +++++++++++-------- .../spec-block-hoist-functions.js | 19 +++++++++++ ....js => spec-member-expression-literals.js} | 0 .../spec-no-duplicate-properties.js | 25 ++++++++++++++ .../spec-no-for-in-of-assignment.js | 10 ++++++ ...-literals.js => spec-property-literals.js} | 0 .../misc/property-literals/actual.js | 3 -- .../misc/property-literals/expected.js | 5 --- .../identifiers/actual.js | 1 + .../literals/actual.js | 1 + .../mixed/actual.js | 1 + .../spec-no-duplicate-properties/options.json | 3 ++ .../spec-no-for-in-of-assignment/in/actual.js | 3 ++ .../spec-no-for-in-of-assignment/of/actual.js | 3 ++ .../spec-no-for-in-of-assignment/options.json | 3 ++ .../spec/block-hoist-functions/exec.js | 5 +++ .../member-expression-literals}/actual.js | 0 .../member-expression-literals}/expected.js | 0 .../property-literals}/actual.js | 0 .../property-literals}/expected.js | 0 20 files changed, 94 insertions(+), 21 deletions(-) create mode 100644 lib/6to5/transformation/transformers/spec-block-hoist-functions.js rename lib/6to5/transformation/transformers/{_member-expression-literals.js => spec-member-expression-literals.js} (100%) create mode 100644 lib/6to5/transformation/transformers/spec-no-duplicate-properties.js create mode 100644 lib/6to5/transformation/transformers/spec-no-for-in-of-assignment.js rename lib/6to5/transformation/transformers/{_property-literals.js => spec-property-literals.js} (100%) delete mode 100644 test/fixtures/transformation/misc/property-literals/actual.js delete mode 100644 test/fixtures/transformation/misc/property-literals/expected.js create mode 100644 test/fixtures/transformation/spec-no-duplicate-properties/identifiers/actual.js create mode 100644 test/fixtures/transformation/spec-no-duplicate-properties/literals/actual.js create mode 100644 test/fixtures/transformation/spec-no-duplicate-properties/mixed/actual.js create mode 100644 test/fixtures/transformation/spec-no-duplicate-properties/options.json create mode 100644 test/fixtures/transformation/spec-no-for-in-of-assignment/in/actual.js create mode 100644 test/fixtures/transformation/spec-no-for-in-of-assignment/of/actual.js create mode 100644 test/fixtures/transformation/spec-no-for-in-of-assignment/options.json create mode 100644 test/fixtures/transformation/spec/block-hoist-functions/exec.js rename test/fixtures/transformation/{misc/_member-expression-literals => spec/member-expression-literals}/actual.js (100%) rename test/fixtures/transformation/{misc/_member-expression-literals => spec/member-expression-literals}/expected.js (100%) rename test/fixtures/transformation/{misc/_property-literals => spec/property-literals}/actual.js (100%) rename test/fixtures/transformation/{misc/_property-literals => spec/property-literals}/expected.js (100%) diff --git a/lib/6to5/transformation/transform.js b/lib/6to5/transformation/transform.js index 4824e44548..497d65d376 100644 --- a/lib/6to5/transformation/transform.js +++ b/lib/6to5/transformation/transform.js @@ -20,16 +20,21 @@ transform._ensureTransformerNames = function (type, keys) { transform.transformers = {}; transform.moduleFormatters = { - common: require("./modules/common"), - commonInterop: require("./modules/common-interop"), - system: require("./modules/system"), - ignore: require("./modules/ignore"), - amd: require("./modules/amd"), - umd: require("./modules/umd") + commonStrict: require("./modules/common-strict"), + common: require("./modules/common"), + system: require("./modules/system"), + ignore: require("./modules/ignore"), + amd: require("./modules/amd"), + umd: require("./modules/umd") }; _.each({ - // plyground + // spec + _blockHoistFunctions: require("./transformers/spec-block-hoist-functions"), + _noForInOfAssignment: require("./transformers/spec-no-for-in-of-assignment"), + _noDuplicateProperties: require("./transformers/spec-no-duplicate-properties"), + + // playground methodBinding: require("./transformers/playground-method-binding"), memoizationOperator: require("./transformers/playground-memoization-operator"), objectGetterMemoization: require("./transformers/playground-object-getter-memoization"), @@ -59,16 +64,18 @@ _.each({ constants: require("./transformers/es6-constants"), letScoping: require("./transformers/es6-let-scoping"), - generators: require("./transformers/es6-generators"), - _blockHoist: require("./transformers/_block-hoist"), _declarations: require("./transformers/_declarations"), + + generators: require("./transformers/es6-generators"), + + // spec + _propertyLiterals: require("./transformers/spec-property-literals"), + _memberExpressioLiterals: require("./transformers/spec-member-expression-literals"), + + // wrap up _aliasFunctions: require("./transformers/_alias-functions"), - useStrict: require("./transformers/use-strict"), - - _propertyLiterals: require("./transformers/_property-literals"), - _memberExpressioLiterals: require("./transformers/_member-expression-literals"), _moduleFormatter: require("./transformers/_module-formatter") }, function (transformer, key) { transform.transformers[key] = new Transformer(key, transformer); diff --git a/lib/6to5/transformation/transformers/spec-block-hoist-functions.js b/lib/6to5/transformation/transformers/spec-block-hoist-functions.js new file mode 100644 index 0000000000..8dae49c00c --- /dev/null +++ b/lib/6to5/transformation/transformers/spec-block-hoist-functions.js @@ -0,0 +1,19 @@ +var t = require("../../types"); +var _ = require("lodash"); + +exports.BlockStatement = function (node, parent) { + if (t.isFunction(parent)) return; + + node.body = node.body.map(function (node) { + if (t.isFunction(node)) { + node.type = "FunctionExpression"; + var declar = t.variableDeclaration("let", [ + t.variableDeclarator(node.id, node) + ]); + declar._blockHoist = true; + return declar; + } else { + return node; + } + }); +}; diff --git a/lib/6to5/transformation/transformers/_member-expression-literals.js b/lib/6to5/transformation/transformers/spec-member-expression-literals.js similarity index 100% rename from lib/6to5/transformation/transformers/_member-expression-literals.js rename to lib/6to5/transformation/transformers/spec-member-expression-literals.js diff --git a/lib/6to5/transformation/transformers/spec-no-duplicate-properties.js b/lib/6to5/transformation/transformers/spec-no-duplicate-properties.js new file mode 100644 index 0000000000..6bbfb3b2f9 --- /dev/null +++ b/lib/6to5/transformation/transformers/spec-no-duplicate-properties.js @@ -0,0 +1,25 @@ +var t = require("../../types"); +var _ = require("lodash"); + +exports.ObjectExpression = function (node, parent, file) { + var keys = []; + + _.each(node.properties, function (prop) { + if (prop.computed || prop.kind !== "init") return; + + var key = prop.key; + if (t.isIdentifier(key)) { + key = key.name; + } else if (t.isLiteral(key)) { + key = key.value; + } else { + return; + } + + if (_.contains(keys, key)) { + throw file.errorWithNode(prop.key, "Duplicate property key"); + } else { + keys.push(key); + } + }); +}; diff --git a/lib/6to5/transformation/transformers/spec-no-for-in-of-assignment.js b/lib/6to5/transformation/transformers/spec-no-for-in-of-assignment.js new file mode 100644 index 0000000000..5af12108f1 --- /dev/null +++ b/lib/6to5/transformation/transformers/spec-no-for-in-of-assignment.js @@ -0,0 +1,10 @@ +var t = require("../../types"); + +exports.ForInStatement = +exports.ForOfStatement = function (node, parent, file) { + var left = node.left; + if (t.isVariableDeclaration(left)) { + var declar = left.declarations[0]; + if (declar.init) throw file.errorWithNode(declar, "No assignments allowed in for-in/of head"); + } +}; diff --git a/lib/6to5/transformation/transformers/_property-literals.js b/lib/6to5/transformation/transformers/spec-property-literals.js similarity index 100% rename from lib/6to5/transformation/transformers/_property-literals.js rename to lib/6to5/transformation/transformers/spec-property-literals.js diff --git a/test/fixtures/transformation/misc/property-literals/actual.js b/test/fixtures/transformation/misc/property-literals/actual.js deleted file mode 100644 index 229c4e0f42..0000000000 --- a/test/fixtures/transformation/misc/property-literals/actual.js +++ /dev/null @@ -1,3 +0,0 @@ -var obj = { - "foobar": "lol" -}; diff --git a/test/fixtures/transformation/misc/property-literals/expected.js b/test/fixtures/transformation/misc/property-literals/expected.js deleted file mode 100644 index 5222f9aedf..0000000000 --- a/test/fixtures/transformation/misc/property-literals/expected.js +++ /dev/null @@ -1,5 +0,0 @@ -"use strict"; - -var obj = { - foobar: "lol" -}; diff --git a/test/fixtures/transformation/spec-no-duplicate-properties/identifiers/actual.js b/test/fixtures/transformation/spec-no-duplicate-properties/identifiers/actual.js new file mode 100644 index 0000000000..7dd5168e50 --- /dev/null +++ b/test/fixtures/transformation/spec-no-duplicate-properties/identifiers/actual.js @@ -0,0 +1 @@ +var obj = { a: 1, a: 2 }; diff --git a/test/fixtures/transformation/spec-no-duplicate-properties/literals/actual.js b/test/fixtures/transformation/spec-no-duplicate-properties/literals/actual.js new file mode 100644 index 0000000000..85b7f9f02a --- /dev/null +++ b/test/fixtures/transformation/spec-no-duplicate-properties/literals/actual.js @@ -0,0 +1 @@ +var obj = { "a": 1, "a": 2 }; diff --git a/test/fixtures/transformation/spec-no-duplicate-properties/mixed/actual.js b/test/fixtures/transformation/spec-no-duplicate-properties/mixed/actual.js new file mode 100644 index 0000000000..eace9c1b04 --- /dev/null +++ b/test/fixtures/transformation/spec-no-duplicate-properties/mixed/actual.js @@ -0,0 +1 @@ +var obj = { a: 1, "a": 2 }; diff --git a/test/fixtures/transformation/spec-no-duplicate-properties/options.json b/test/fixtures/transformation/spec-no-duplicate-properties/options.json new file mode 100644 index 0000000000..32dce7785e --- /dev/null +++ b/test/fixtures/transformation/spec-no-duplicate-properties/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Duplicate property key" +} diff --git a/test/fixtures/transformation/spec-no-for-in-of-assignment/in/actual.js b/test/fixtures/transformation/spec-no-for-in-of-assignment/in/actual.js new file mode 100644 index 0000000000..167407a7da --- /dev/null +++ b/test/fixtures/transformation/spec-no-for-in-of-assignment/in/actual.js @@ -0,0 +1,3 @@ +for (var i = 0 in obj) { + +} diff --git a/test/fixtures/transformation/spec-no-for-in-of-assignment/of/actual.js b/test/fixtures/transformation/spec-no-for-in-of-assignment/of/actual.js new file mode 100644 index 0000000000..56e4dfef82 --- /dev/null +++ b/test/fixtures/transformation/spec-no-for-in-of-assignment/of/actual.js @@ -0,0 +1,3 @@ +for (var i = 0 of obj) { + +} diff --git a/test/fixtures/transformation/spec-no-for-in-of-assignment/options.json b/test/fixtures/transformation/spec-no-for-in-of-assignment/options.json new file mode 100644 index 0000000000..c7ae9b8aa4 --- /dev/null +++ b/test/fixtures/transformation/spec-no-for-in-of-assignment/options.json @@ -0,0 +1,3 @@ +{ + "throws": "No assignments allowed in for-in/of head" +} diff --git a/test/fixtures/transformation/spec/block-hoist-functions/exec.js b/test/fixtures/transformation/spec/block-hoist-functions/exec.js new file mode 100644 index 0000000000..f3475e0a9e --- /dev/null +++ b/test/fixtures/transformation/spec/block-hoist-functions/exec.js @@ -0,0 +1,5 @@ +function f() { return 1; } +{ + function f() { return 2; } +} +assert.equal(f(), 1); diff --git a/test/fixtures/transformation/misc/_member-expression-literals/actual.js b/test/fixtures/transformation/spec/member-expression-literals/actual.js similarity index 100% rename from test/fixtures/transformation/misc/_member-expression-literals/actual.js rename to test/fixtures/transformation/spec/member-expression-literals/actual.js diff --git a/test/fixtures/transformation/misc/_member-expression-literals/expected.js b/test/fixtures/transformation/spec/member-expression-literals/expected.js similarity index 100% rename from test/fixtures/transformation/misc/_member-expression-literals/expected.js rename to test/fixtures/transformation/spec/member-expression-literals/expected.js diff --git a/test/fixtures/transformation/misc/_property-literals/actual.js b/test/fixtures/transformation/spec/property-literals/actual.js similarity index 100% rename from test/fixtures/transformation/misc/_property-literals/actual.js rename to test/fixtures/transformation/spec/property-literals/actual.js diff --git a/test/fixtures/transformation/misc/_property-literals/expected.js b/test/fixtures/transformation/spec/property-literals/expected.js similarity index 100% rename from test/fixtures/transformation/misc/_property-literals/expected.js rename to test/fixtures/transformation/spec/property-literals/expected.js From 187f7ba01e061aa41584c20087af61fd55091ec3 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Wed, 10 Dec 2014 21:10:59 +1100 Subject: [PATCH 026/139] Remove regenerator finished generator error --- .../transformers/es6-generators/runtime.js | 11 +++++++---- test/_generator-helpers.js | 12 ++---------- .../exec.js | 12 ++---------- 3 files changed, 11 insertions(+), 24 deletions(-) diff --git a/lib/6to5/transformation/transformers/es6-generators/runtime.js b/lib/6to5/transformation/transformers/es6-generators/runtime.js index 2adc60afdd..bdfd846382 100644 --- a/lib/6to5/transformation/transformers/es6-generators/runtime.js +++ b/lib/6to5/transformation/transformers/es6-generators/runtime.js @@ -87,9 +87,7 @@ function Generator(innerFn, outerFn, self, tryList) { throw new Error("Generator is already running"); } - if (state === GenStateCompleted) { - throw new Error("Generator has already finished"); - } + var alreadyFinished = state === GenStateCompleted; while (true) { var delegate = context.delegate; @@ -162,7 +160,8 @@ function Generator(innerFn, outerFn, self, tryList) { state = GenStateExecuting; try { - var value = innerFn.call(self, context); + var value; + if (!alreadyFinished) value = innerFn.call(self, context); // If an exception is thrown from innerFn, we leave state === // GenStateExecuting and loop back for another invocation. @@ -267,6 +266,10 @@ runtime.keys = function (object) { }; }; +function isIn(key, obj) { + return typeof obj !== "string" && typeof obj !== "number" && key in obj; +} + function values(iterable) { var iterator = iterable; if (iteratorSymbol in iterable) { diff --git a/test/_generator-helpers.js b/test/_generator-helpers.js index 4d1a390058..4eef535ee0 100644 --- a/test/_generator-helpers.js +++ b/test/_generator-helpers.js @@ -20,14 +20,6 @@ exports.raise = function raise(argument) { }; exports.assertAlreadyFinished = function assertAlreadyFinished(generator) { - try { - generator.next(); - assert.ok(false, "should have thrown an exception"); - } catch (err) { - assert.ok(err instanceof Error); - assert.strictEqual( - err.message, - "Generator has already finished" - ); - } + var item = generator.next(); + assert.ok(item.done && item.value === undefined, "not finished"); }; diff --git a/test/fixtures/transformation/es6-generators/function-declaration-hoisting-should-work-even-if-the-declarations-are-out-of-order/exec.js b/test/fixtures/transformation/es6-generators/function-declaration-hoisting-should-work-even-if-the-declarations-are-out-of-order/exec.js index 202b84a0d1..1b1de7c33b 100644 --- a/test/fixtures/transformation/es6-generators/function-declaration-hoisting-should-work-even-if-the-declarations-are-out-of-order/exec.js +++ b/test/fixtures/transformation/es6-generators/function-declaration-hoisting-should-work-even-if-the-declarations-are-out-of-order/exec.js @@ -15,18 +15,10 @@ function *gen(n) { function decrement(x) { return x - 1; } - } else { - // The behavior of function declarations nested inside conditional - // blocks is notoriously underspecified, and in V8 it appears the - // halve function is still defined when we take this branch, so - // "undefine" it for consistency with regenerator semantics. - halve = void 0; } - yield typeof halve; - yield increment(increment(n)); } -genHelpers.check(gen(3), [4, 1, "function", 5]); -genHelpers.check(gen(4), [5, "undefined", 6]); +genHelpers.check(gen(3), [4, 1, 5]); +genHelpers.check(gen(4), [5, 6]); From 4a439857d2915555d0a8d23c3513c5a80ca9562c Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Wed, 10 Dec 2014 21:11:13 +1100 Subject: [PATCH 027/139] make mutators enumerable --- lib/6to5/util.js | 2 ++ .../getter-and-setter/expected.js | 3 ++- .../es5-property-methods-assignment/getter/expected.js | 3 ++- .../es5-property-methods-assignment/setter/expected.js | 3 ++- .../es6-classes/instance-getter-and-setter/expected.js | 3 ++- .../es6-classes/instance-getter/expected.js | 3 ++- .../es6-classes/instance-setter/expected.js | 3 ++- .../transformation/es6-classes/static/expected.js | 3 ++- .../playground/object-getter-memoization/expected.js | 9 ++++++--- .../transformation/source-maps/class/expected.js | 3 ++- 10 files changed, 24 insertions(+), 11 deletions(-) diff --git a/lib/6to5/util.js b/lib/6to5/util.js index 244ab28cab..7bfe4e5ac3 100644 --- a/lib/6to5/util.js +++ b/lib/6to5/util.js @@ -117,6 +117,8 @@ exports.buildDefineProperties = function (mutatorMap) { var propNode = t.property("init", map._key, mapNode, map._computed); + map.enumerable = t.literal(true); + _.each(map, function (node, key) { if (key[0] === "_") return; diff --git a/test/fixtures/transformation/es5-property-methods-assignment/getter-and-setter/expected.js b/test/fixtures/transformation/es5-property-methods-assignment/getter-and-setter/expected.js index 23467f3675..9ef3d3265d 100644 --- a/test/fixtures/transformation/es5-property-methods-assignment/getter-and-setter/expected.js +++ b/test/fixtures/transformation/es5-property-methods-assignment/getter-and-setter/expected.js @@ -8,7 +8,8 @@ var obj = (function (_obj) { }, set: function (value) { this._foo = value; - } + }, + enumerable: true } }); diff --git a/test/fixtures/transformation/es5-property-methods-assignment/getter/expected.js b/test/fixtures/transformation/es5-property-methods-assignment/getter/expected.js index fda0188e6e..c519a4ee8d 100644 --- a/test/fixtures/transformation/es5-property-methods-assignment/getter/expected.js +++ b/test/fixtures/transformation/es5-property-methods-assignment/getter/expected.js @@ -5,7 +5,8 @@ var obj = (function (_obj) { foo: { get: function () { return 5 + 5; - } + }, + enumerable: true } }); diff --git a/test/fixtures/transformation/es5-property-methods-assignment/setter/expected.js b/test/fixtures/transformation/es5-property-methods-assignment/setter/expected.js index 3320d6ee41..780fb983a8 100644 --- a/test/fixtures/transformation/es5-property-methods-assignment/setter/expected.js +++ b/test/fixtures/transformation/es5-property-methods-assignment/setter/expected.js @@ -5,7 +5,8 @@ var obj = (function (_obj) { foo: { set: function (value) { this._foo = value; - } + }, + enumerable: true } }); diff --git a/test/fixtures/transformation/es6-classes/instance-getter-and-setter/expected.js b/test/fixtures/transformation/es6-classes/instance-getter-and-setter/expected.js index 0fb4c995d3..1ca4e4bc91 100644 --- a/test/fixtures/transformation/es6-classes/instance-getter-and-setter/expected.js +++ b/test/fixtures/transformation/es6-classes/instance-getter-and-setter/expected.js @@ -15,7 +15,8 @@ var Test = (function () { }, set: function (val) { this._test = val; - } + }, + enumerable: true } }); diff --git a/test/fixtures/transformation/es6-classes/instance-getter/expected.js b/test/fixtures/transformation/es6-classes/instance-getter/expected.js index 0d50b8e732..b980afd00a 100644 --- a/test/fixtures/transformation/es6-classes/instance-getter/expected.js +++ b/test/fixtures/transformation/es6-classes/instance-getter/expected.js @@ -12,7 +12,8 @@ var Test = (function () { test: { get: function () { return 5 + 5; - } + }, + enumerable: true } }); diff --git a/test/fixtures/transformation/es6-classes/instance-setter/expected.js b/test/fixtures/transformation/es6-classes/instance-setter/expected.js index 87f8e40dde..5a181cc25c 100644 --- a/test/fixtures/transformation/es6-classes/instance-setter/expected.js +++ b/test/fixtures/transformation/es6-classes/instance-setter/expected.js @@ -12,7 +12,8 @@ var Test = (function () { test: { set: function (val) { this._test = val; - } + }, + enumerable: true } }); diff --git a/test/fixtures/transformation/es6-classes/static/expected.js b/test/fixtures/transformation/es6-classes/static/expected.js index 1ef2108334..26ef9d30f1 100644 --- a/test/fixtures/transformation/es6-classes/static/expected.js +++ b/test/fixtures/transformation/es6-classes/static/expected.js @@ -13,7 +13,8 @@ var A = (function () { _classProps(A, { b: { get: function () {}, - set: function (b) {} + set: function (b) {}, + enumerable: true } }); diff --git a/test/fixtures/transformation/playground/object-getter-memoization/expected.js b/test/fixtures/transformation/playground/object-getter-memoization/expected.js index 83441a35f4..c8886b8b37 100644 --- a/test/fixtures/transformation/playground/object-getter-memoization/expected.js +++ b/test/fixtures/transformation/playground/object-getter-memoization/expected.js @@ -14,7 +14,8 @@ var Foo = (function () { if (this._memoDone) return this._memo; this._memoDone = true; return this._memo = complex(); - } + }, + enumerable: true }; return _ref; })({ @@ -23,7 +24,8 @@ var Foo = (function () { if (this._barDone) return this._bar; this._barDone = true; return this._bar = complex(); - } + }, + enumerable: true } })); @@ -45,7 +47,8 @@ var foo = (function (_foo) { if (this._barDone) return this._bar; this._barDone = true; return this._bar = complex(); - } + }, + enumerable: true } }); diff --git a/test/fixtures/transformation/source-maps/class/expected.js b/test/fixtures/transformation/source-maps/class/expected.js index 7a04a39640..aa5136a46f 100644 --- a/test/fixtures/transformation/source-maps/class/expected.js +++ b/test/fixtures/transformation/source-maps/class/expected.js @@ -12,7 +12,8 @@ var Test = (function () { bar: { get: function () { throw new Error("wow"); - } + }, + enumerable: true } }); From 59b81b389a2ab5537bcf1314e493b495bf63ea92 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Wed, 10 Dec 2014 21:11:26 +1100 Subject: [PATCH 028/139] Fix up checkLoop method comment --- lib/6to5/transformation/transformers/es6-let-scoping.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/6to5/transformation/transformers/es6-let-scoping.js b/lib/6to5/transformation/transformers/es6-let-scoping.js index ce11cde375..194be693be 100644 --- a/lib/6to5/transformation/transformers/es6-let-scoping.js +++ b/lib/6to5/transformation/transformers/es6-let-scoping.js @@ -272,8 +272,8 @@ LetScoping.prototype.initialiseLoopLets = function () { }; /** - * If we're inside of a `For*Statement` then traverse it and check if it has one - * of the following node types `ReturnStatement`, `BreakStatement`, + * If we're inside of a loop then traverse it and check if it has one of + * the following node types `ReturnStatement`, `BreakStatement`, * `ContinueStatement` and replace it with a return value that we can track * later on. * From 072fff0f4c681b4d2c880fcc311fcd77e39c7761 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Wed, 10 Dec 2014 21:11:43 +1100 Subject: [PATCH 029/139] clean up system modules formatter --- .../exports-from/expected.js | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/test/fixtures/transformation/.es6-modules-system/exports-from/expected.js b/test/fixtures/transformation/.es6-modules-system/exports-from/expected.js index 680bae3c9f..9f6c8d743d 100644 --- a/test/fixtures/transformation/.es6-modules-system/exports-from/expected.js +++ b/test/fixtures/transformation/.es6-modules-system/exports-from/expected.js @@ -7,28 +7,27 @@ System.register("actual", ["foo"], function (_export) { return { setters: [ - function(m) { - _export("foo", m.foo); + function(m) { + _export("foo", m.foo); - _export("foo", m.foo); + _export("foo", m.foo); - _export("bar", m.bar); + _export("bar", m.bar); - _export("bar", m.foo); + _export("bar", m.foo); - _export("default", m.foo); + _export("default", m.foo); - _export("default", m.foo); + _export("default", m.foo); - _export("bar", m.bar); + _export("bar", m.bar); - for (var p in m) { - if (_localExports.indexOf(i) == -1) - _export(p, m[p]); + for (var p in m) { + if (_localExports.indexOf(i) == -1) + _export(p, m[p]); + } } - } ], - execute: function () { - } + execute: function () {} }; }); From c4a0f62eef5e2482cc2c1604ee295f28f32372c4 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Wed, 10 Dec 2014 21:12:01 +1100 Subject: [PATCH 030/139] add global symbol registry to polyfill --- lib/6to5/polyfill.js | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/6to5/polyfill.js b/lib/6to5/polyfill.js index 9e98ba264a..e9f7342924 100644 --- a/lib/6to5/polyfill.js +++ b/lib/6to5/polyfill.js @@ -1,7 +1,7 @@ /* jshint newcap: false */ var ensureSymbol = function (key) { - Symbol[key] = Symbol[key] || Symbol(); + Symbol[key] = Symbol[key] || Symbol(key); }; var ensureProto = function (Constructor, key, val) { @@ -13,11 +13,25 @@ var ensureProto = function (Constructor, key, val) { if (typeof Symbol === "undefined") { require("es6-symbol/implement"); + + var globSymbols = {}; + + Symbol.for = function (key) { + return globSymbols[key] = globSymbols[key] || Symbol(key); + }; + + Symbol.keyFor = function (sym) { + return sym.__description__; + }; } require("es6-shim"); require("./transformation/transformers/es6-generators/runtime"); +ensureSymbol("species"); + +String.prototype.includes = String.prototype.includes || String.prototype.contains; + // Abstract references ensureSymbol("referenceGet"); From f11f364d2c0bd115d259c4fb0a187a0c30b8ef4c Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Wed, 10 Dec 2014 21:28:49 +1100 Subject: [PATCH 031/139] add _aliasFunction to generator comprehension container - fixes #278 --- .../transformation/transformers/es7-generator-comprehension.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/6to5/transformation/transformers/es7-generator-comprehension.js b/lib/6to5/transformation/transformers/es7-generator-comprehension.js index 3a102474c4..cb469ef1ce 100644 --- a/lib/6to5/transformation/transformers/es7-generator-comprehension.js +++ b/lib/6to5/transformation/transformers/es7-generator-comprehension.js @@ -6,6 +6,7 @@ exports.ComprehensionExpression = function (node) { var body = []; var container = t.functionExpression(null, [], t.blockStatement(body), true); + container._aliasFunction = true body.push(arrayComprehension._build(node, function () { return t.expressionStatement(t.yieldExpression(node.body)); From b986a4e4828aa35463e37f5a07871e04c7ddd5b4 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Wed, 10 Dec 2014 21:31:27 +1100 Subject: [PATCH 032/139] expose ast transformer - fixes #263 --- doc/usage.md | 9 +++++++++ lib/6to5/file.js | 10 ++++++---- lib/6to5/transformation/transform.js | 20 +++++++++++++++----- lib/6to5/util.js | 20 +++++++++++++++----- 4 files changed, 45 insertions(+), 14 deletions(-) diff --git a/doc/usage.md b/doc/usage.md index f9daf47ff2..46baecce82 100644 --- a/doc/usage.md +++ b/doc/usage.md @@ -95,6 +95,15 @@ to5.transformFile("filename.js", options, function (err, result) { }); ``` +### to5.transform.fromAst(ast, [code], [opts]) + +```javascript +var result = to5.transform(ast, "var a = 2;", opts); +result.code; +result.map; +result.ast; +``` + #### Options ```javascript diff --git a/lib/6to5/file.js b/lib/6to5/file.js index de9957fe79..0e1207b023 100644 --- a/lib/6to5/file.js +++ b/lib/6to5/file.js @@ -156,14 +156,16 @@ File.prototype.errorWithNode = function (node, msg, Error) { return err; }; -File.prototype.parse = function (code) { +File.prototype.addCode = function (code) { code = (code || "") + ""; + this.code = code; + return this.parseShebang(code); +}; +File.prototype.parse = function (code) { var self = this; - this.code = code; - - code = this.parseShebang(code); + this.addCode(code); return util.parse(this.opts, code, function (tree) { self.transform(tree); diff --git a/lib/6to5/transformation/transform.js b/lib/6to5/transformation/transform.js index 497d65d376..94afc696c4 100644 --- a/lib/6to5/transformation/transform.js +++ b/lib/6to5/transformation/transform.js @@ -2,6 +2,7 @@ module.exports = transform; var Transformer = require("./transformer"); var File = require("../file"); +var util = require("../util"); var _ = require("lodash"); function transform(code, opts) { @@ -9,6 +10,15 @@ function transform(code, opts) { return file.parse(code); } +transform.fromAst = function (ast, code, opts) { + ast = util.normaliseAst(ast); + + var file = new File(opts); + file.addCode(code); + file.transform(); + return file.generate(); +}; + transform._ensureTransformerNames = function (type, keys) { _.each(keys, function (key) { if (!_.has(transform.transformers, key)) { @@ -30,9 +40,9 @@ transform.moduleFormatters = { _.each({ // spec - _blockHoistFunctions: require("./transformers/spec-block-hoist-functions"), - _noForInOfAssignment: require("./transformers/spec-no-for-in-of-assignment"), - _noDuplicateProperties: require("./transformers/spec-no-duplicate-properties"), + specBlockHoistFunctions: require("./transformers/spec-block-hoist-functions"), + specNoForInOfAssignment: require("./transformers/spec-no-for-in-of-assignment"), + specNoDuplicateProperties: require("./transformers/spec-no-duplicate-properties"), // playground methodBinding: require("./transformers/playground-method-binding"), @@ -70,8 +80,8 @@ _.each({ generators: require("./transformers/es6-generators"), // spec - _propertyLiterals: require("./transformers/spec-property-literals"), - _memberExpressioLiterals: require("./transformers/spec-member-expression-literals"), + specPropertyLiterals: require("./transformers/spec-property-literals"), + specMemberExpressioLiterals: require("./transformers/spec-member-expression-literals"), // wrap up _aliasFunctions: require("./transformers/_alias-functions"), diff --git a/lib/6to5/util.js b/lib/6to5/util.js index 7bfe4e5ac3..ab43d7a30e 100644 --- a/lib/6to5/util.js +++ b/lib/6to5/util.js @@ -212,6 +212,20 @@ exports.repeat = function (width, cha) { return new Array(width + 1).join(cha); }; +exports.normaliseAst = function (ast, comments, tokens) { + if (ast && ast.type === "Program") { + ast = t.file(ast, comments || [], tokens || []); + + traverse(ast, function (node, parent) { + node._parent = parent; + }); + + return ast; + } else { + throw new Error("Not a valid ast?"); + } +}; + exports.parse = function (opts, code, callback) { try { var comments = []; @@ -231,11 +245,7 @@ exports.parse = function (opts, code, callback) { estraverse.attachComments(ast, comments, tokens); - ast = t.file(ast, comments, tokens); - - traverse(ast, function (node, parent) { - node._parent = parent; - }); + ast = exports.normaliseAst(ast, comments, tokens); if (callback) { return callback(ast); From d00faf4a72848f7a0b86a5fc84d65373c9cca81c Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Wed, 10 Dec 2014 21:33:30 +1100 Subject: [PATCH 033/139] remove commonInterop option from register --- lib/6to5/register.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/6to5/register.js b/lib/6to5/register.js index efdec2ad90..b8203ae462 100644 --- a/lib/6to5/register.js +++ b/lib/6to5/register.js @@ -89,7 +89,6 @@ var loader = function (m, filename) { whitelist: whitelist, blacklist: blacklist, sourceMap: true, - modules: "commonInterop", ast: false }, transformOpts)); From bac87583691c81cdfd44d8034983bef48c0d2e78 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Wed, 10 Dec 2014 21:37:07 +1100 Subject: [PATCH 034/139] remove other commonInterop reference --- bin/_6to5-node | 1 - 1 file changed, 1 deletion(-) diff --git a/bin/_6to5-node b/bin/_6to5-node index 98a6563c63..cc02ae170a 100644 --- a/bin/_6to5-node +++ b/bin/_6to5-node @@ -33,7 +33,6 @@ to5.register({ var _eval = function (code, filename) { code = to5.transform(code, { - modules: "commonInterop", filename: filename, blacklist: ["useStrict"], experimental: commander.experimental From 30a90d255482aa0671e5b8eeafe51ffb67377e63 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Wed, 10 Dec 2014 21:54:38 +1100 Subject: [PATCH 035/139] fix hash bang support --- lib/6to5/file.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/6to5/file.js b/lib/6to5/file.js index 0e1207b023..d8d9c4ba24 100644 --- a/lib/6to5/file.js +++ b/lib/6to5/file.js @@ -165,7 +165,7 @@ File.prototype.addCode = function (code) { File.prototype.parse = function (code) { var self = this; - this.addCode(code); + code = this.addCode(code); return util.parse(this.opts, code, function (tree) { self.transform(tree); From 79b4207b4458397d4c90f07e7575ed16d6a79b9a Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Wed, 10 Dec 2014 21:54:43 +1100 Subject: [PATCH 036/139] upgrade acorn-6to5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8d4b342188..465b34f832 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "test": "make test" }, "dependencies": { - "acorn-6to5": "0.9.1-12", + "acorn-6to5": "0.9.1-13", "ast-types": "0.6.5", "chokidar": "0.11.1", "commander": "2.5.0", From 6d68b3da4dcfac342f8f36e30864fc95135bdf39 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Wed, 10 Dec 2014 21:54:54 +1100 Subject: [PATCH 037/139] fix fromAst usage --- doc/usage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/usage.md b/doc/usage.md index 46baecce82..3e81e93a21 100644 --- a/doc/usage.md +++ b/doc/usage.md @@ -98,7 +98,7 @@ to5.transformFile("filename.js", options, function (err, result) { ### to5.transform.fromAst(ast, [code], [opts]) ```javascript -var result = to5.transform(ast, "var a = 2;", opts); +var result = to5.transform.fromAst(ast, "var a = 2;", opts); result.code; result.map; result.ast; From 8ffd2e843f06ddb932693395f7830aa36762f594 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Wed, 10 Dec 2014 22:34:58 +1100 Subject: [PATCH 038/139] fix fromAst not passing ast to transform --- lib/6to5/transformation/transform.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/6to5/transformation/transform.js b/lib/6to5/transformation/transform.js index 94afc696c4..bd0361ae58 100644 --- a/lib/6to5/transformation/transform.js +++ b/lib/6to5/transformation/transform.js @@ -15,7 +15,7 @@ transform.fromAst = function (ast, code, opts) { var file = new File(opts); file.addCode(code); - file.transform(); + file.transform(ast); return file.generate(); }; From 01934b69601c23e8c2384d0ba9d2c6acd7cbaf39 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Wed, 10 Dec 2014 23:18:23 +1100 Subject: [PATCH 039/139] fix default import generation --- lib/6to5/generation/generators/modules.js | 13 +++++++++++-- .../expected.js | 2 +- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/6to5/generation/generators/modules.js b/lib/6to5/generation/generators/modules.js index 871afe085f..16f6a01d83 100644 --- a/lib/6to5/generation/generators/modules.js +++ b/lib/6to5/generation/generators/modules.js @@ -1,7 +1,14 @@ var t = require("../../types"); var _ = require("lodash"); -exports.ImportSpecifier = +exports.ImportSpecifier = function (node, print) { + if (node.id && node.id.name === "default") { + print(node.name); + } else { + return exports.ExportSpecifier.apply(this, arguments); + } +}; + exports.ExportSpecifier = function (node, print) { print(node.id); if (node.name) { @@ -62,7 +69,9 @@ exports.ImportDeclaration = function (node, print) { self.push(", "); } - if (!spec.default && spec.type !== "ImportBatchSpecifier" && !foundImportSpecifier) { + var isDefault = spec.id && spec.id.name === "default"; + + if (!isDefault && spec.type !== "ImportBatchSpecifier" && !foundImportSpecifier) { foundImportSpecifier = true; self.push("{ "); } diff --git a/test/fixtures/generation/types/ImportDeclaration-ImportSpecifier-ImportBatchSpecifier/expected.js b/test/fixtures/generation/types/ImportDeclaration-ImportSpecifier-ImportBatchSpecifier/expected.js index b7a4a4b9fd..ed9cfef590 100644 --- a/test/fixtures/generation/types/ImportDeclaration-ImportSpecifier-ImportBatchSpecifier/expected.js +++ b/test/fixtures/generation/types/ImportDeclaration-ImportSpecifier-ImportBatchSpecifier/expected.js @@ -1,6 +1,6 @@ import "foo"; import foo from "foo"; -import { default as foo } from "foo"; +import foo from "foo"; import * as foo from "foo"; import foo, { baz as xyz } from "foo"; import { bar } from "foo"; From 2a0b63f3bbca83b6e5ef92ad136c643cf2b066d4 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Wed, 10 Dec 2014 23:28:50 +1100 Subject: [PATCH 040/139] better symbol iterator check in regenerator runtime --- .../transformation/transformers/es6-generators/runtime.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/6to5/transformation/transformers/es6-generators/runtime.js b/lib/6to5/transformation/transformers/es6-generators/runtime.js index bdfd846382..ee4ab898c8 100644 --- a/lib/6to5/transformation/transformers/es6-generators/runtime.js +++ b/lib/6to5/transformation/transformers/es6-generators/runtime.js @@ -266,13 +266,9 @@ runtime.keys = function (object) { }; }; -function isIn(key, obj) { - return typeof obj !== "string" && typeof obj !== "number" && key in obj; -} - function values(iterable) { var iterator = iterable; - if (iteratorSymbol in iterable) { + if (iterable[iteratorSymbol]) { iterator = iterable[iteratorSymbol](); } else if (!isNaN(iterable.length)) { var i = -1; From c7d69b2f92cf9aa26cafc2ace3cdf29acaee0bba Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Wed, 10 Dec 2014 23:49:13 +1100 Subject: [PATCH 041/139] block scope constants --- .../transformers/es6-constants.js | 20 ++++++++++++++++--- lib/6to5/traverse/scope.js | 17 +++++++++------- .../es6-constants/block-scoped/exec.js | 3 +++ 3 files changed, 30 insertions(+), 10 deletions(-) create mode 100644 test/fixtures/transformation/es6-constants/block-scoped/exec.js diff --git a/lib/6to5/transformation/transformers/es6-constants.js b/lib/6to5/transformation/transformers/es6-constants.js index 15f2c8c45b..2996974c37 100644 --- a/lib/6to5/transformation/transformers/es6-constants.js +++ b/lib/6to5/transformation/transformers/es6-constants.js @@ -9,11 +9,21 @@ exports.ForOfStatement = exports.ForStatement = function (node, parent, file) { var constants = {}; - var check = function (parent, names) { + /** + * Check the results of `util.getIds` as `names` generated from a + * node against it's parent. + */ + + var check = function (parent, names, scope) { _.each(names, function (nameNode, name) { if (!_.has(constants, name)) return; if (parent && t.isBlockStatement(parent) && parent !== constants[name]) return; + if (scope) { + var defined = scope.get(name); + if (defined && defined === nameNode) return; + } + throw file.errorWithNode(nameNode, name + " is read-only"); }); }; @@ -22,6 +32,10 @@ exports.ForStatement = function (node, parent, file) { return t.getIds(node, true, ["MemberExpression"]); }; + /** + * Collect all constants in this scope. + */ + _.each(node.body, function (child, parent) { if (child && t.isVariableDeclaration(child, { kind: "const" })) { _.each(child.declarations, function (declar) { @@ -43,12 +57,12 @@ exports.ForStatement = function (node, parent, file) { if (_.isEmpty(constants)) return; - traverse(node, function (child, parent) { + traverse(node, function (child, parent, scope) { if (child._ignoreConstant) return; if (t.isVariableDeclaration(child)) return; if (t.isVariableDeclarator(child) || t.isDeclaration(child) || t.isAssignmentExpression(child)) { - check(parent, getIds(child)); + check(parent, getIds(child), scope); } }); }; diff --git a/lib/6to5/traverse/scope.js b/lib/6to5/traverse/scope.js index 50bb67243c..b2faeab838 100644 --- a/lib/6to5/traverse/scope.js +++ b/lib/6to5/traverse/scope.js @@ -27,12 +27,12 @@ Scope.add = function (node, references) { }; Scope.prototype.generateTemp = function (file, name) { - var id = file.generateUidIdentifier(name || "temp", this); - this.push({ - key: id.name, - id: id - }); - return id; + var id = file.generateUidIdentifier(name || "temp", this); + this.push({ + key: id.name, + id: id + }); + return id; }; Scope.prototype.getReferences = function () { @@ -86,12 +86,15 @@ Scope.prototype.getReferences = function () { // declared within are accessible if (t.isFunction(node)) return false; + // function identifier doesn't belong to this scope + if (block.id && node === block.id) return; + if (t.isIdentifier(node) && t.isReferenced(node, parent) && !scope.has(node.name)) { add(node); } // we've ran into a declaration! - // we'll let the BlockStatement scope deal with `let` declarations + // we'll let the BlockStatement scope deal with `let` declarations unless if (t.isDeclaration(node) && !t.isLet(node)) { add(node); } diff --git a/test/fixtures/transformation/es6-constants/block-scoped/exec.js b/test/fixtures/transformation/es6-constants/block-scoped/exec.js new file mode 100644 index 0000000000..c46d684d19 --- /dev/null +++ b/test/fixtures/transformation/es6-constants/block-scoped/exec.js @@ -0,0 +1,3 @@ +const bar = 123; +{ const bar = 456; } +assert.equal(bar, 123); From ad923cf8fa476a9039923aa089bbf82f7bca4457 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Thu, 11 Dec 2014 09:52:29 +1100 Subject: [PATCH 042/139] add playground support to 6to5-node --- bin/_6to5-node | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bin/_6to5-node b/bin/_6to5-node index cc02ae170a..d31d93a46e 100644 --- a/bin/_6to5-node +++ b/bin/_6to5-node @@ -26,6 +26,7 @@ commander.parse(process.argv); to5.register({ experimental: commander.experimental, extensions: commander.extensions, + playground: commander.playground, ignore: commander.ignore }); @@ -35,7 +36,8 @@ var _eval = function (code, filename) { code = to5.transform(code, { filename: filename, blacklist: ["useStrict"], - experimental: commander.experimental + experimental: commander.experimental, + playground: commander.playground }).code; return vm.runInThisContext(code, filename); }; From 74614e712e1952e55ece697d80b9aec3c7ce81c6 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Thu, 11 Dec 2014 09:52:50 +1100 Subject: [PATCH 043/139] make rest parameters work inside of aliasFunction --- lib/6to5/transformation/transformers/es6-rest-parameters.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/6to5/transformation/transformers/es6-rest-parameters.js b/lib/6to5/transformation/transformers/es6-rest-parameters.js index 37a32657dd..060259a94b 100644 --- a/lib/6to5/transformation/transformers/es6-rest-parameters.js +++ b/lib/6to5/transformation/transformers/es6-rest-parameters.js @@ -14,7 +14,7 @@ exports.Function = function (node, parent, file) { call.arguments.push(t.literal(node.params.length)); } - call._ignoreAliasFunctions = true; + if (!node._aliasFunction) call._ignoreAliasFunctions = true; node.body.body.unshift(t.variableDeclaration("var", [ t.variableDeclarator(rest, call) From 8af05634faaa3688ac82929c64fc992859dfed81 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Thu, 11 Dec 2014 10:10:07 +1100 Subject: [PATCH 044/139] fix rest parameters on arrow functions --- lib/6to5/transformation/transformers/es6-arrow-functions.js | 2 +- lib/6to5/transformation/transformers/es6-rest-parameters.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/6to5/transformation/transformers/es6-arrow-functions.js b/lib/6to5/transformation/transformers/es6-arrow-functions.js index 80a45e573b..40f9ab9906 100644 --- a/lib/6to5/transformation/transformers/es6-arrow-functions.js +++ b/lib/6to5/transformation/transformers/es6-arrow-functions.js @@ -3,7 +3,7 @@ var t = require("../../types"); exports.ArrowFunctionExpression = function (node) { t.ensureBlock(node); - node._aliasFunction = true; + node._aliasFunction = "arrow"; node.expression = false; node.type = "FunctionExpression"; diff --git a/lib/6to5/transformation/transformers/es6-rest-parameters.js b/lib/6to5/transformation/transformers/es6-rest-parameters.js index 060259a94b..0d67a8b261 100644 --- a/lib/6to5/transformation/transformers/es6-rest-parameters.js +++ b/lib/6to5/transformation/transformers/es6-rest-parameters.js @@ -14,7 +14,7 @@ exports.Function = function (node, parent, file) { call.arguments.push(t.literal(node.params.length)); } - if (!node._aliasFunction) call._ignoreAliasFunctions = true; + if (!node._aliasFunction || node._aliasFunction === "arrow") call._ignoreAliasFunctions = true; node.body.body.unshift(t.variableDeclaration("var", [ t.variableDeclarator(rest, call) From 253776877273fbef2013aba6f0c7e987b52afe93 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Thu, 11 Dec 2014 10:13:40 +1100 Subject: [PATCH 045/139] inherit comments in modules transformer - fixes #280 --- lib/6to5/transformation/transformers/es6-modules.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/6to5/transformation/transformers/es6-modules.js b/lib/6to5/transformation/transformers/es6-modules.js index 3b7148cf67..97abf7fe16 100644 --- a/lib/6to5/transformation/transformers/es6-modules.js +++ b/lib/6to5/transformation/transformers/es6-modules.js @@ -1,6 +1,12 @@ var t = require("../../types"); var _ = require("lodash"); +var inheritsComments = function (node, nodes) { + if (nodes.length) { + t.inheritsComments(nodes[0], node); + } +}; + exports.ImportDeclaration = function (node, parent, file) { var nodes = []; @@ -12,6 +18,8 @@ exports.ImportDeclaration = function (node, parent, file) { file.moduleFormatter.import(node, nodes, parent); } + inheritsComments(node, nodes); + return nodes; }; @@ -33,5 +41,7 @@ exports.ExportDeclaration = function (node, parent, file) { }); } + inheritsComments(node, nodes); + return nodes; }; From c26ce1c1142831ea661c7352a016cdd5ffc98a23 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Thu, 11 Dec 2014 10:14:08 +1100 Subject: [PATCH 046/139] abstract away astRun from transformer --- lib/6to5/transformation/transformer.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/lib/6to5/transformation/transformer.js b/lib/6to5/transformation/transformer.js index 9def8f1912..ff5693dfe4 100644 --- a/lib/6to5/transformation/transformer.js +++ b/lib/6to5/transformation/transformer.js @@ -23,19 +23,22 @@ Transformer.normalise = function (transformer) { return transformer; }; +Transformer.prototype.astRun = function (file, key) { + var transformer = this.transformer; + var ast = file.ast; + + if (transformer.ast && transformer.ast[key]) { + transformer.ast[key](ast, file); + } +}; + Transformer.prototype.transform = function (file) { if (!this.canRun(file)) return; var transformer = this.transformer; var ast = file.ast; - var astRun = function (key) { - if (transformer.ast && transformer.ast[key]) { - transformer.ast[key](ast, file); - } - }; - - astRun("enter"); + this.astRun(file, "enter"); var build = function (exit) { return function (node, parent, scope) { @@ -64,7 +67,7 @@ Transformer.prototype.transform = function (file) { exit: build(true) }); - astRun("exit"); + this.astRun(file, "exit"); }; Transformer.prototype.canRun = function (file) { From 74f40c282442f755b334d99676c155b491565490 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Thu, 11 Dec 2014 11:02:55 +1100 Subject: [PATCH 047/139] fix generator rest parameters --- lib/6to5/transformation/transform.js | 5 +++-- lib/6to5/transformation/transformers/es6-rest-parameters.js | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/6to5/transformation/transform.js b/lib/6to5/transformation/transform.js index bd0361ae58..1279608cf1 100644 --- a/lib/6to5/transformation/transform.js +++ b/lib/6to5/transformation/transform.js @@ -64,7 +64,6 @@ _.each({ templateLiterals: require("./transformers/es6-template-literals"), propertyMethodAssignment: require("./transformers/es5-property-method-assignment"), defaultParameters: require("./transformers/es6-default-parameters"), - restParameters: require("./transformers/es6-rest-parameters"), destructuring: require("./transformers/es6-destructuring"), forOf: require("./transformers/es6-for-of"), unicodeRegex: require("./transformers/es6-unicode-regex"), @@ -75,9 +74,11 @@ _.each({ letScoping: require("./transformers/es6-let-scoping"), _blockHoist: require("./transformers/_block-hoist"), - _declarations: require("./transformers/_declarations"), generators: require("./transformers/es6-generators"), + restParameters: require("./transformers/es6-rest-parameters"), + + _declarations: require("./transformers/_declarations"), // spec specPropertyLiterals: require("./transformers/spec-property-literals"), diff --git a/lib/6to5/transformation/transformers/es6-rest-parameters.js b/lib/6to5/transformation/transformers/es6-rest-parameters.js index 0d67a8b261..37a32657dd 100644 --- a/lib/6to5/transformation/transformers/es6-rest-parameters.js +++ b/lib/6to5/transformation/transformers/es6-rest-parameters.js @@ -14,7 +14,7 @@ exports.Function = function (node, parent, file) { call.arguments.push(t.literal(node.params.length)); } - if (!node._aliasFunction || node._aliasFunction === "arrow") call._ignoreAliasFunctions = true; + call._ignoreAliasFunctions = true; node.body.body.unshift(t.variableDeclaration("var", [ t.variableDeclarator(rest, call) From 55e2010311906a05e56b8c9ecd4e11d497b5e9f8 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Thu, 11 Dec 2014 23:12:15 +1100 Subject: [PATCH 048/139] comment out broken esnext --- benchmark/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/benchmark/index.js b/benchmark/index.js index c7d04b1b65..176142818c 100644 --- a/benchmark/index.js +++ b/benchmark/index.js @@ -4,7 +4,7 @@ var jsTrans = require("jstransform"); var traceur = require("traceur"); var es6tr = require("es6-transpiler"); var es6now = require("es6now"); -var esnext = require("esnext"); +//var esnext = require("esnext"); var to5 = require("../lib/6to5"); //var uglify = require("uglify-js"); @@ -56,12 +56,12 @@ var compilers = { } }, - esnext: { + /*esnext: { runtime: readResolve("esnext/node_modules/regenerator/runtime.js") || readResolve("regenerator/runtime.js"), compile: function (code) { return esnext.compile(code).code; } - }, + },*/ es6now: { runtime: readResolve("es6now/runtime/ES6.js"), From 615425c8085455dfa5c28613d47e3467eef7caa5 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Fri, 12 Dec 2014 12:14:02 +1100 Subject: [PATCH 049/139] fix linting errors --- bin/6to5/file.js | 2 +- lib/6to5/polyfill.js | 2 +- lib/6to5/transformation/modules/amd.js | 2 +- lib/6to5/transformation/modules/common.js | 2 +- .../transformation/transformers/es7-generator-comprehension.js | 2 +- .../transformation/transformers/spec-block-hoist-functions.js | 1 - 6 files changed, 5 insertions(+), 6 deletions(-) diff --git a/bin/6to5/file.js b/bin/6to5/file.js index a118389437..a06bf304ea 100644 --- a/bin/6to5/file.js +++ b/bin/6to5/file.js @@ -113,7 +113,7 @@ module.exports = function (commander, filenames) { walk(); if (commander.watch) { - var watcher = chokidar.watch(filenames, { + chokidar.watch(filenames, { persistent: true, ignoreInitial: true }).on("all", function (type, filename) { diff --git a/lib/6to5/polyfill.js b/lib/6to5/polyfill.js index e9f7342924..5d945d16e8 100644 --- a/lib/6to5/polyfill.js +++ b/lib/6to5/polyfill.js @@ -1,4 +1,4 @@ -/* jshint newcap: false */ +/* jshint newcap: false, freeze: false */ var ensureSymbol = function (key) { Symbol[key] = Symbol[key] || Symbol(key); diff --git a/lib/6to5/transformation/modules/amd.js b/lib/6to5/transformation/modules/amd.js index 23566148a8..49185c5a40 100644 --- a/lib/6to5/transformation/modules/amd.js +++ b/lib/6to5/transformation/modules/amd.js @@ -51,7 +51,7 @@ AMDFormatter.prototype.transform = function (ast) { AMDFormatter.prototype.getModuleName = function () { if (this.file.opts.amdModuleIds) { - return CommonJSFormatter.prototype.getModuleName.apply(this, arguments); + return DefaultFormatter.prototype.getModuleName.apply(this, arguments); } else { return null; } diff --git a/lib/6to5/transformation/modules/common.js b/lib/6to5/transformation/modules/common.js index 1feb646d61..6676511919 100644 --- a/lib/6to5/transformation/modules/common.js +++ b/lib/6to5/transformation/modules/common.js @@ -42,7 +42,7 @@ CommonJSFormatter.prototype.export = function (node, nodes) { var templateName = "exports-default-module"; // exports = module.exports = VALUE; - if (this.hasNonDefaultExports) templateName = "exports-default-module-override" + if (this.hasNonDefaultExports) templateName = "exports-default-module-override"; var assign = util.template(templateName, { VALUE: this._pushStatement(declar, nodes) diff --git a/lib/6to5/transformation/transformers/es7-generator-comprehension.js b/lib/6to5/transformation/transformers/es7-generator-comprehension.js index cb469ef1ce..2034beef85 100644 --- a/lib/6to5/transformation/transformers/es7-generator-comprehension.js +++ b/lib/6to5/transformation/transformers/es7-generator-comprehension.js @@ -6,7 +6,7 @@ exports.ComprehensionExpression = function (node) { var body = []; var container = t.functionExpression(null, [], t.blockStatement(body), true); - container._aliasFunction = true + container._aliasFunction = true; body.push(arrayComprehension._build(node, function () { return t.expressionStatement(t.yieldExpression(node.body)); diff --git a/lib/6to5/transformation/transformers/spec-block-hoist-functions.js b/lib/6to5/transformation/transformers/spec-block-hoist-functions.js index 8dae49c00c..8d18464de0 100644 --- a/lib/6to5/transformation/transformers/spec-block-hoist-functions.js +++ b/lib/6to5/transformation/transformers/spec-block-hoist-functions.js @@ -1,5 +1,4 @@ var t = require("../../types"); -var _ = require("lodash"); exports.BlockStatement = function (node, parent) { if (t.isFunction(parent)) return; From e563783a1e7c30faaa64d23a87e3590103ed547d Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Fri, 12 Dec 2014 12:14:07 +1100 Subject: [PATCH 050/139] add gratipay to readme --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 772f7abb6c..eb4bb860c0 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,10 @@

+ + Gratipay + + Travis Status From 593e4ca670ec32e14e05c2af0bbcdbf21b8181f4 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Fri, 12 Dec 2014 12:14:24 +1100 Subject: [PATCH 051/139] remove useless GeneratorFunction aliasing causing issues #283 --- .../transformers/es6-generators/runtime.js | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/lib/6to5/transformation/transformers/es6-generators/runtime.js b/lib/6to5/transformation/transformers/es6-generators/runtime.js index ee4ab898c8..9fe09b03cb 100644 --- a/lib/6to5/transformation/transformers/es6-generators/runtime.js +++ b/lib/6to5/transformation/transformers/es6-generators/runtime.js @@ -27,20 +27,14 @@ var ContinueSentinel = {}; // Dummy constructor that we use as the .constructor property for // functions that return Generator objects. -var GF = function GeneratorFunction() {}; +function GeneratorFunction() {} var GFp = function GeneratorFunctionPrototype() {}; var Gp = GFp.prototype = Generator.prototype; -(GFp.constructor = GF).prototype = - Gp.constructor = GFp; - -// Ensure isGeneratorFunction works when Function#name not supported. -var GFName = "GeneratorFunction"; -if (GF.name !== GFName) GF.name = GFName; -if (GF.name !== GFName) throw new Error(GFName + " renamed?"); +(GFp.constructor = GeneratorFunction).prototype = Gp.constructor = GFp; runtime.isGeneratorFunction = function (genFun) { var ctor = genFun && genFun.constructor; - return ctor ? GF.name === ctor.name : false; + return ctor ? GeneratorFunction.name === ctor.name : false; }; runtime.mark = function (genFun) { From 226734447151c08ca49c6904c244b508aaa4e303 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Sat, 13 Dec 2014 04:37:00 +1100 Subject: [PATCH 052/139] use # operator instead of : for playground method binding to remove ambiguous syntax --- doc/playground.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/playground.md b/doc/playground.md index 5ad1ad5738..e02e89c163 100644 --- a/doc/playground.md +++ b/doc/playground.md @@ -52,11 +52,11 @@ if (!Object.prototype.hasOwnProperty.call(obj, "x")) obj.x = 2; ### Method binding ```javascript -var fn = obj:method; -var fn = obj:method("foob"); +var fn = obj#method; +var fn = obj#method("foob"); -["foo", "bar"].map(:toUpperCase); // ["FOO", "BAR"] -[1.1234, 23.53245, 3].map(:toFixed(2)); // ["1.12", "23.53", "3.00"] +["foo", "bar"].map(#toUpperCase); // ["FOO", "BAR"] +[1.1234, 23.53245, 3].map(#toFixed(2)); // ["1.12", "23.53", "3.00"] ``` equivalent to: From aae7d8190b26b12486a6e225cc026abca6d5d91b Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Sat, 13 Dec 2014 12:40:43 +1100 Subject: [PATCH 053/139] fix up tests to work with the new method binding operator --- .../bin/6to5/stdin --filename/stderr.txt | 2 +- .../fixtures/bin/6to5/stdin --filename/stdin.txt | 4 ++-- .../transformation/errors/syntax/actual.js | 2 +- .../transformation/errors/syntax/options.json | 2 +- .../playground/method-binding/actual.js | 16 ++++++++-------- .../playground/method-binding/exec.js | 12 ++++++------ test/transformation.js | 4 +++- 7 files changed, 22 insertions(+), 20 deletions(-) diff --git a/test/fixtures/bin/6to5/stdin --filename/stderr.txt b/test/fixtures/bin/6to5/stdin --filename/stderr.txt index 40674d06f1..70be01b6f3 100644 --- a/test/fixtures/bin/6to5/stdin --filename/stderr.txt +++ b/test/fixtures/bin/6to5/stdin --filename/stderr.txt @@ -1 +1 @@ -SyntaxError: test.js: Unexpected character '#' +SyntaxError: test.js: Unexpected token (2:10) diff --git a/test/fixtures/bin/6to5/stdin --filename/stdin.txt b/test/fixtures/bin/6to5/stdin --filename/stdin.txt index 6b84913768..1d931c7e85 100644 --- a/test/fixtures/bin/6to5/stdin --filename/stdin.txt +++ b/test/fixtures/bin/6to5/stdin --filename/stdin.txt @@ -1,3 +1,3 @@ -arr.map(x => { - $#! +arr.map(function () { + return $]!; }); diff --git a/test/fixtures/transformation/errors/syntax/actual.js b/test/fixtures/transformation/errors/syntax/actual.js index 1ef7cb5d40..1d931c7e85 100644 --- a/test/fixtures/transformation/errors/syntax/actual.js +++ b/test/fixtures/transformation/errors/syntax/actual.js @@ -1,3 +1,3 @@ arr.map(function () { - return $#!; + return $]!; }); diff --git a/test/fixtures/transformation/errors/syntax/options.json b/test/fixtures/transformation/errors/syntax/options.json index 72ad0f0daf..7c05159f45 100644 --- a/test/fixtures/transformation/errors/syntax/options.json +++ b/test/fixtures/transformation/errors/syntax/options.json @@ -1,3 +1,3 @@ { - "throws": "Unexpected character '#'" + "throws": "Unexpected token (2:10)" } diff --git a/test/fixtures/transformation/playground/method-binding/actual.js b/test/fixtures/transformation/playground/method-binding/actual.js index 1457513da0..12185e1a7c 100644 --- a/test/fixtures/transformation/playground/method-binding/actual.js +++ b/test/fixtures/transformation/playground/method-binding/actual.js @@ -1,13 +1,13 @@ -var fn = obj:method; -var fn = obj:method("foob"); -var fn = obj[foo]:method; -var fn = obj.foo:method; -var fn = obj[foo()]:method; +var fn = obj#method; +var fn = obj#method("foob"); +var fn = obj[foo]#method; +var fn = obj.foo#method; +var fn = obj[foo()]#method; -["foo", "bar"].map(:toUpperCase); -[1.1234, 23.53245, 3].map(:toFixed(2)); +["foo", "bar"].map(#toUpperCase); +[1.1234, 23.53245, 3].map(#toFixed(2)); var get = function () { return 2; }; -[1.1234, 23.53245, 3].map(:toFixed(get())); +[1.1234, 23.53245, 3].map(#toFixed(get())); diff --git a/test/fixtures/transformation/playground/method-binding/exec.js b/test/fixtures/transformation/playground/method-binding/exec.js index 77a2949ab4..b83e4b49aa 100644 --- a/test/fixtures/transformation/playground/method-binding/exec.js +++ b/test/fixtures/transformation/playground/method-binding/exec.js @@ -12,19 +12,19 @@ var obj = { } }; -var foo = obj:getFoo; +var foo = obj#getFoo; assert.equal(foo(), "foo"); -var bar = obj:getBar("foo"); +var bar = obj#getBar("foo"); assert.equal(bar(), "foo bar"); -var zoo = obj:getZoo("foo"); +var zoo = obj#getZoo("foo"); assert.equal(zoo("bar"), "foo bar foo bar"); -assert.deepEqual(["foo", "bar"].map(:toUpperCase), ["FOO", "BAR"]); -assert.deepEqual([1.1234, 23.53245, 3].map(:toFixed(2)), ["1.12", "23.53", "3.00"]); +assert.deepEqual(["foo", "bar"].map(#toUpperCase), ["FOO", "BAR"]); +assert.deepEqual([1.1234, 23.53245, 3].map(#toFixed(2)), ["1.12", "23.53", "3.00"]); var get = function () { return 2; } -assert.deepEqual([1.1234, 23.53245, 3].map(:toFixed(get())), ["1.12", "23.53", "3.00"]); +assert.deepEqual([1.1234, 23.53245, 3].map(#toFixed(get())), ["1.12", "23.53", "3.00"]); diff --git a/test/transformation.js b/test/transformation.js index 03418d0f83..ca03b78af1 100644 --- a/test/transformation.js +++ b/test/transformation.js @@ -77,7 +77,9 @@ _.each(helper.get("transformation"), function (testSuite) { // the options object with useless options delete task.options.throws; - assert.throws(runTask, new RegExp(throwMsg)); + assert.throws(runTask, function (err) { + return err.message.indexOf(throwMsg) >= 0; + }); } else { runTask(); } From 84332da399bbfabbe1c00d51a0c4749de8790800 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Sat, 13 Dec 2014 12:52:31 +1100 Subject: [PATCH 054/139] document format options --- doc/usage.md | 30 +++++++++++++++++++++++++----- lib/6to5/generation/buffer.js | 2 +- lib/6to5/generation/generator.js | 2 -- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/doc/usage.md b/doc/usage.md index 3e81e93a21..801f544db3 100644 --- a/doc/usage.md +++ b/doc/usage.md @@ -162,10 +162,6 @@ result.ast; // Default: false runtime: true, - // Output comments in generated output - // Default: true - comments: false, - // Enable support for experimental ES7 features // Default: false experimental: true, @@ -178,7 +174,31 @@ result.ast; // Set this to `false` if you don't want the transformed code in the returned // result // Default: true - code: true + code: true, + + format: { + // Output comments in generated output + // Default: true + comments: true, + + // Do not include superfluous whitespace characters and line terminators + // Default: false + compact: false, + + indent: { + // Adjust the indentation of multiline comments to keep asterisks vertically aligned + // Default: true + adjustMultilineComment: true, + + // Indent string + // Default: " " + style: " ", + + // Base indent level + // Default: 0 + base: 0 + } + } } ``` diff --git a/lib/6to5/generation/buffer.js b/lib/6to5/generation/buffer.js index 9bfa757816..afd9c4dd23 100644 --- a/lib/6to5/generation/buffer.js +++ b/lib/6to5/generation/buffer.js @@ -35,7 +35,7 @@ Buffer.prototype.dedent = function () { }; Buffer.prototype.semicolon = function () { - if (this.format.semicolons) this.push(";"); + this.push(";"); }; Buffer.prototype.ensureSemicolon = function () { diff --git a/lib/6to5/generation/generator.js b/lib/6to5/generation/generator.js index 63919c94d3..f10e729ec4 100644 --- a/lib/6to5/generation/generator.js +++ b/lib/6to5/generation/generator.js @@ -36,8 +36,6 @@ _.each(Buffer.prototype, function (fn, key) { CodeGenerator.normaliseOptions = function (opts) { return _.merge({ - parentheses: true, - semicolons: true, comments: opts.comments == null || opts.comments, compact: false, indent: { From 13785bddb0c8726b427f45a06dff09504d898ece Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Sat, 13 Dec 2014 14:14:47 +1100 Subject: [PATCH 055/139] escape illegal js but valid json unicode characters - fixes #247 --- lib/6to5/generation/generators/types.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/6to5/generation/generators/types.js b/lib/6to5/generation/generators/types.js index b9fa822ce3..4a58375a8d 100644 --- a/lib/6to5/generation/generators/types.js +++ b/lib/6to5/generation/generators/types.js @@ -84,8 +84,8 @@ exports.Literal = function (node) { if (type === "string") { val = JSON.stringify(val); - // escape unicode characters - val = val.replace(/[\u007f-\uffff]/g, function (c) { + // escape illegal js but valid json unicode characters + val = val.replace(/[\u000A\u000D\u2028\u2029]/g, function (c) { return "\\u" + ("0000" + c.charCodeAt(0).toString(16)).slice(-4); }); From 525169460a23c653cf525e36be625c7cc543efa8 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Sat, 13 Dec 2014 17:32:58 +1100 Subject: [PATCH 056/139] add back parentheses generator option --- doc/usage.md | 4 ++++ lib/6to5/generation/generator.js | 1 + 2 files changed, 5 insertions(+) diff --git a/doc/usage.md b/doc/usage.md index 801f544db3..08c19eef05 100644 --- a/doc/usage.md +++ b/doc/usage.md @@ -186,6 +186,10 @@ result.ast; compact: false, indent: { + // Preserve parentheses in new expressions that have no arguments + // Default: true + parentheses: true, + // Adjust the indentation of multiline comments to keep asterisks vertically aligned // Default: true adjustMultilineComment: true, diff --git a/lib/6to5/generation/generator.js b/lib/6to5/generation/generator.js index f10e729ec4..7f2ce983de 100644 --- a/lib/6to5/generation/generator.js +++ b/lib/6to5/generation/generator.js @@ -36,6 +36,7 @@ _.each(Buffer.prototype, function (fn, key) { CodeGenerator.normaliseOptions = function (opts) { return _.merge({ + parentheses: true, comments: opts.comments == null || opts.comments, compact: false, indent: { From 833a4900dab0d4f8b58f51eb4ea29d4d6d74c4bb Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Sat, 13 Dec 2014 17:33:35 +1100 Subject: [PATCH 057/139] remove IIFE on class declarations #288 --- lib/6to5/templates/class.js | 7 -- .../transformers/es6-classes.js | 98 +++++++++---------- .../accessing-super-class/expected.js | 46 ++++----- .../accessing-super-properties/expected.js | 14 +-- .../calling-super-properties/expected.js | 20 ++-- .../es6-classes/constructor/expected.js | 12 +-- .../instance-getter-and-setter/expected.js | 28 +++--- .../es6-classes/instance-getter/expected.js | 22 ++--- .../es6-classes/instance-method/expected.js | 12 +-- .../es6-classes/instance-setter/expected.js | 22 ++--- .../es6-classes/static/expected.js | 22 ++--- .../expected.js | 24 ++--- .../expected.js | 12 +-- .../es6-classes/super-class/expected.js | 12 +-- .../es6-unicode-regex/basic/expected.js | 2 +- .../ignore-non-unicode/expected.js | 2 +- .../object-getter-memoization/expected.js | 46 ++++----- .../source-maps/class/expected.js | 22 ++--- .../source-maps/class/source-mappings.json | 4 +- 19 files changed, 180 insertions(+), 247 deletions(-) delete mode 100644 lib/6to5/templates/class.js diff --git a/lib/6to5/templates/class.js b/lib/6to5/templates/class.js deleted file mode 100644 index b644463235..0000000000 --- a/lib/6to5/templates/class.js +++ /dev/null @@ -1,7 +0,0 @@ -(function () { - var CLASS_NAME = function () { - - }; - - return CLASS_NAME; -})() diff --git a/lib/6to5/transformation/transformers/es6-classes.js b/lib/6to5/transformation/transformers/es6-classes.js index d44d6c6f25..98ac4d59d6 100644 --- a/lib/6to5/transformation/transformers/es6-classes.js +++ b/lib/6to5/transformation/transformers/es6-classes.js @@ -4,24 +4,11 @@ var t = require("../../types"); var _ = require("lodash"); exports.ClassDeclaration = function (node, parent, file, scope) { - var built = new Class(node, file, scope).run(); - - var declar = t.variableDeclaration("let", [ - t.variableDeclarator(node.id, built) - ]); - t.inheritsComments(declar, node); - return declar; + return new Class(node, file, scope, true).run(); }; exports.ClassExpression = function (node, parent, file, scope) { - return new Class(node, file, scope).run(); -}; - -var getMemberExpressionObject = function (node) { - while (t.isMemberExpression(node)) { - node = node.object; - } - return node; + return new Class(node, file, scope, false).run(); }; /** @@ -30,12 +17,14 @@ var getMemberExpressionObject = function (node) { * @param {Node} node * @param {File} file * @param {Scope} scope + * @param {Boolean} isStatement */ -function Class(node, file, scope) { - this.scope = scope; - this.node = node; - this.file = file; +function Class(node, file, scope, isStatement) { + this.isStatement = isStatement; + this.scope = scope; + this.node = node; + this.file = file; this.instanceMutatorMap = {}; this.staticMutatorMap = {}; @@ -51,50 +40,59 @@ function Class(node, file, scope) { */ Class.prototype.run = function () { - var superClassArgument = this.superName; - var superClassCallee = this.superName; - var superName = this.superName; - var className = this.className; - var file = this.file; + var superName = this.superName; + var className = this.className; + var file = this.file; - if (superName) { - if (t.isMemberExpression(superName)) { - superClassArgument = superClassCallee = getMemberExpressionObject(superName); - } else if (!t.isIdentifier(superName)) { - superClassArgument = superName; - superClassCallee = superName = file.generateUidIdentifier("ref", this.scope); - } + // + + var body = this.body = []; + + var constructor = t.functionExpression(null, [], t.blockStatement([])); + if (this.node.id) constructor.id = className; + this.constructor = constructor; + + body.push(t.variableDeclaration("let", [ + t.variableDeclarator(className, constructor) + ])); + + // + + if (superName && t.isDynamic(superName)) { + // so we're only evaluating it once + var superRefName = "super"; + if (className) superRefName = className.name + "Super"; + + var superRef = file.generateUidIdentifier(superRefName, this.scope); + body.unshift(t.variableDeclaration("var", [ + t.variableDeclarator(superRef, superName) + ])); + superName = superRef; } this.superName = superName; - var container = util.template("class", { - CLASS_NAME: className - }); - - var block = container.callee.expression.body; - var body = this.body = block.body; - var constructor = this.constructor = body[0].declarations[0].init; - - if (this.node.id) constructor.id = className; - - var returnStatement = body.pop(); + // if (superName) { body.push(t.expressionStatement(t.callExpression(file.addDeclaration("extends"), [className, superName]))); - - container.arguments.push(superClassArgument); - container.callee.expression.params.push(superClassCallee); } this.buildBody(); - if (body.length === 1) { - // only a constructor so no need for a closure container - return constructor; + if (this.isStatement) { + return body; } else { - body.push(returnStatement); - return container; + if (body.length === 1) { + // only a constructor so no need for a closure container + return constructor; + } else { + body.push(t.returnStatement(className)); + return t.callExpression( + t.functionExpression(null, [], t.blockStatement(body)), + [] + ); + } } }; 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 0c54fbc4e6..ad8532015c 100644 --- a/test/fixtures/transformation/es6-classes/accessing-super-class/expected.js +++ b/test/fixtures/transformation/es6-classes/accessing-super-class/expected.js @@ -13,33 +13,29 @@ var _extends = function (child, parent) { child.__proto__ = parent; }; -var Test = (function (Foo) { - var Test = function Test() { - woops["super"].test(); - Foo.call(this); - Foo.prototype.test.call(this); - foob(Foo); +var Test = function Test() { + woops["super"].test(); + Foo.call(this); + Foo.prototype.test.call(this); + foob(Foo); - Foo.call.apply(Foo, [this].concat(_slice.call(arguments))); - Foo.call.apply(Foo, [this, "test"].concat(_slice.call(arguments))); + Foo.call.apply(Foo, [this].concat(_slice.call(arguments))); + Foo.call.apply(Foo, [this, "test"].concat(_slice.call(arguments))); - Foo.prototype.test.call.apply(Foo.prototype, [this].concat(_slice.call(arguments))); - Foo.prototype.test.call.apply(Foo.prototype, [this, "test"].concat(_slice.call(arguments))); - }; + Foo.prototype.test.call.apply(Foo.prototype, [this].concat(_slice.call(arguments))); + Foo.prototype.test.call.apply(Foo.prototype, [this, "test"].concat(_slice.call(arguments))); +}; - _extends(Test, Foo); +_extends(Test, Foo); - Test.prototype.test = function () { - Foo.prototype.test.call(this); - Foo.prototype.test.call.apply(Foo.prototype.test, [this].concat(_slice.call(arguments))); - Foo.prototype.test.call.apply(Foo.prototype.test, [this, "test"].concat(_slice.call(arguments))); - }; +Test.prototype.test = function () { + Foo.prototype.test.call(this); + Foo.prototype.test.call.apply(Foo.prototype.test, [this].concat(_slice.call(arguments))); + Foo.prototype.test.call.apply(Foo.prototype.test, [this, "test"].concat(_slice.call(arguments))); +}; - Test.foo = function () { - Foo.foo.call(this); - Foo.foo.call.apply(Foo.foo, [this].concat(_slice.call(arguments))); - Foo.foo.call.apply(Foo.foo, [this, "test"].concat(_slice.call(arguments))); - }; - - return Test; -})(Foo); +Test.foo = function () { + Foo.foo.call(this); + Foo.foo.call.apply(Foo.foo, [this].concat(_slice.call(arguments))); + Foo.foo.call.apply(Foo.foo, [this, "test"].concat(_slice.call(arguments))); +}; diff --git a/test/fixtures/transformation/es6-classes/accessing-super-properties/expected.js b/test/fixtures/transformation/es6-classes/accessing-super-properties/expected.js index dec479103b..5ffb26c5c6 100644 --- a/test/fixtures/transformation/es6-classes/accessing-super-properties/expected.js +++ b/test/fixtures/transformation/es6-classes/accessing-super-properties/expected.js @@ -12,13 +12,9 @@ var _extends = function (child, parent) { child.__proto__ = parent; }; -var Test = (function (Foo) { - var Test = function Test() { - Foo.prototype.test; - Foo.prototype.test.whatever; - }; +var Test = function Test() { + Foo.prototype.test; + Foo.prototype.test.whatever; +}; - _extends(Test, Foo); - - return Test; -})(Foo); +_extends(Test, Foo); diff --git a/test/fixtures/transformation/es6-classes/calling-super-properties/expected.js b/test/fixtures/transformation/es6-classes/calling-super-properties/expected.js index 28aa2cb0ea..8387489528 100644 --- a/test/fixtures/transformation/es6-classes/calling-super-properties/expected.js +++ b/test/fixtures/transformation/es6-classes/calling-super-properties/expected.js @@ -12,17 +12,13 @@ var _extends = function (child, parent) { child.__proto__ = parent; }; -var Test = (function (Foo) { - var Test = function Test() { - Foo.prototype.test.whatever(); - Foo.prototype.test.call(this); - }; +var Test = function Test() { + Foo.prototype.test.whatever(); + Foo.prototype.test.call(this); +}; - _extends(Test, Foo); +_extends(Test, Foo); - Test.test = function () { - return Foo.wow.call(this); - }; - - return Test; -})(Foo); +Test.test = function () { + return Foo.wow.call(this); +}; diff --git a/test/fixtures/transformation/es6-classes/constructor/expected.js b/test/fixtures/transformation/es6-classes/constructor/expected.js index 200e36b4c5..47eb5a927e 100644 --- a/test/fixtures/transformation/es6-classes/constructor/expected.js +++ b/test/fixtures/transformation/es6-classes/constructor/expected.js @@ -16,12 +16,8 @@ var Test = function Test() { this.state = "test"; }; -var Foo = (function (Bar) { - var Foo = function Foo() { - this.state = "test"; - }; +var Foo = function Foo() { + this.state = "test"; +}; - _extends(Foo, Bar); - - return Foo; -})(Bar); +_extends(Foo, Bar); diff --git a/test/fixtures/transformation/es6-classes/instance-getter-and-setter/expected.js b/test/fixtures/transformation/es6-classes/instance-getter-and-setter/expected.js index 1ca4e4bc91..fed43faa63 100644 --- a/test/fixtures/transformation/es6-classes/instance-getter-and-setter/expected.js +++ b/test/fixtures/transformation/es6-classes/instance-getter-and-setter/expected.js @@ -5,20 +5,16 @@ var _classProps = function (child, staticProps, instanceProps) { if (instanceProps) Object.defineProperties(child.prototype, instanceProps); }; -var Test = (function () { - var Test = function Test() {}; +var Test = function Test() {}; - _classProps(Test, null, { - test: { - get: function () { - return 5 + 5; - }, - set: function (val) { - this._test = val; - }, - enumerable: true - } - }); - - return Test; -})(); +_classProps(Test, null, { + test: { + get: function () { + return 5 + 5; + }, + set: function (val) { + this._test = val; + }, + enumerable: true + } +}); diff --git a/test/fixtures/transformation/es6-classes/instance-getter/expected.js b/test/fixtures/transformation/es6-classes/instance-getter/expected.js index b980afd00a..4b52e5a6e2 100644 --- a/test/fixtures/transformation/es6-classes/instance-getter/expected.js +++ b/test/fixtures/transformation/es6-classes/instance-getter/expected.js @@ -5,17 +5,13 @@ var _classProps = function (child, staticProps, instanceProps) { if (instanceProps) Object.defineProperties(child.prototype, instanceProps); }; -var Test = (function () { - var Test = function Test() {}; +var Test = function Test() {}; - _classProps(Test, null, { - test: { - get: function () { - return 5 + 5; - }, - enumerable: true - } - }); - - return Test; -})(); +_classProps(Test, null, { + test: { + get: function () { + return 5 + 5; + }, + enumerable: true + } +}); diff --git a/test/fixtures/transformation/es6-classes/instance-method/expected.js b/test/fixtures/transformation/es6-classes/instance-method/expected.js index bedd164fe5..8e4305baca 100644 --- a/test/fixtures/transformation/es6-classes/instance-method/expected.js +++ b/test/fixtures/transformation/es6-classes/instance-method/expected.js @@ -1,11 +1,7 @@ "use strict"; -var Test = (function () { - var Test = function Test() {}; +var Test = function Test() {}; - Test.prototype.test = function () { - return 5 + 5; - }; - - return Test; -})(); +Test.prototype.test = function () { + return 5 + 5; +}; diff --git a/test/fixtures/transformation/es6-classes/instance-setter/expected.js b/test/fixtures/transformation/es6-classes/instance-setter/expected.js index 5a181cc25c..0f47c5db71 100644 --- a/test/fixtures/transformation/es6-classes/instance-setter/expected.js +++ b/test/fixtures/transformation/es6-classes/instance-setter/expected.js @@ -5,17 +5,13 @@ var _classProps = function (child, staticProps, instanceProps) { if (instanceProps) Object.defineProperties(child.prototype, instanceProps); }; -var Test = (function () { - var Test = function Test() {}; +var Test = function Test() {}; - _classProps(Test, null, { - test: { - set: function (val) { - this._test = val; - }, - enumerable: true - } - }); - - return Test; -})(); +_classProps(Test, null, { + test: { + set: function (val) { + this._test = val; + }, + enumerable: true + } +}); diff --git a/test/fixtures/transformation/es6-classes/static/expected.js b/test/fixtures/transformation/es6-classes/static/expected.js index 26ef9d30f1..5898b4e35d 100644 --- a/test/fixtures/transformation/es6-classes/static/expected.js +++ b/test/fixtures/transformation/es6-classes/static/expected.js @@ -5,18 +5,14 @@ var _classProps = function (child, staticProps, instanceProps) { if (instanceProps) Object.defineProperties(child.prototype, instanceProps); }; -var A = (function () { - var A = function A() {}; +var A = function A() {}; - A.a = function () {}; +A.a = function () {}; - _classProps(A, { - b: { - get: function () {}, - set: function (b) {}, - enumerable: true - } - }); - - return A; -})(); +_classProps(A, { + b: { + get: function () {}, + set: function (b) {}, + enumerable: true + } +}); diff --git a/test/fixtures/transformation/es6-classes/super-class-id-member-expression/expected.js b/test/fixtures/transformation/es6-classes/super-class-id-member-expression/expected.js index bce35e1528..5108133980 100644 --- a/test/fixtures/transformation/es6-classes/super-class-id-member-expression/expected.js +++ b/test/fixtures/transformation/es6-classes/super-class-id-member-expression/expected.js @@ -12,22 +12,14 @@ var _extends = function (child, parent) { child.__proto__ = parent; }; -var BaseController = (function (Chaplin) { - var BaseController = function BaseController() { - Chaplin.Controller.apply(this, arguments); - }; +var BaseController = function BaseController() { + Chaplin.Controller.apply(this, arguments); +}; - _extends(BaseController, Chaplin.Controller); +_extends(BaseController, Chaplin.Controller); - return BaseController; -})(Chaplin); +var BaseController2 = function BaseController2() { + Chaplin.Controller.Another.apply(this, arguments); +}; -var BaseController2 = (function (Chaplin) { - var BaseController2 = function BaseController2() { - Chaplin.Controller.Another.apply(this, arguments); - }; - - _extends(BaseController2, Chaplin.Controller.Another); - - return BaseController2; -})(Chaplin); +_extends(BaseController2, Chaplin.Controller.Another); diff --git a/test/fixtures/transformation/es6-classes/super-class-id-non-identifiers/expected.js b/test/fixtures/transformation/es6-classes/super-class-id-non-identifiers/expected.js index 353a8c289b..aa3f6fdfc2 100644 --- a/test/fixtures/transformation/es6-classes/super-class-id-non-identifiers/expected.js +++ b/test/fixtures/transformation/es6-classes/super-class-id-non-identifiers/expected.js @@ -12,12 +12,10 @@ var _extends = function (child, parent) { child.__proto__ = parent; }; -var Q = (function (_ref) { - var Q = function Q() { - _ref.apply(this, arguments); - }; +var _QSuper = function () {}; - _extends(Q, _ref); +var Q = function Q() { + _QSuper.apply(this, arguments); +}; - return Q; -})(function () {}); +_extends(Q, _QSuper); diff --git a/test/fixtures/transformation/es6-classes/super-class/expected.js b/test/fixtures/transformation/es6-classes/super-class/expected.js index c8c1fb516f..82b40d6a4a 100644 --- a/test/fixtures/transformation/es6-classes/super-class/expected.js +++ b/test/fixtures/transformation/es6-classes/super-class/expected.js @@ -12,12 +12,8 @@ var _extends = function (child, parent) { child.__proto__ = parent; }; -var Test = (function (Foo) { - var Test = function Test() { - Foo.apply(this, arguments); - }; +var Test = function Test() { + Foo.apply(this, arguments); +}; - _extends(Test, Foo); - - return Test; -})(Foo); +_extends(Test, Foo); diff --git a/test/fixtures/transformation/es6-unicode-regex/basic/expected.js b/test/fixtures/transformation/es6-unicode-regex/basic/expected.js index d4f30f3911..eb24a69373 100644 --- a/test/fixtures/transformation/es6-unicode-regex/basic/expected.js +++ b/test/fixtures/transformation/es6-unicode-regex/basic/expected.js @@ -1,4 +1,4 @@ "use strict"; -var string = "foo\ud83d\udca9bar"; +var string = "foo💩bar"; var match = string.match(/foo((?:[\0-\t\x0B\f\x0E-\u2027\u202A-\uD7FF\uDC00-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF]))bar/); diff --git a/test/fixtures/transformation/es6-unicode-regex/ignore-non-unicode/expected.js b/test/fixtures/transformation/es6-unicode-regex/ignore-non-unicode/expected.js index ab57a7f88e..2a77fc0b65 100644 --- a/test/fixtures/transformation/es6-unicode-regex/ignore-non-unicode/expected.js +++ b/test/fixtures/transformation/es6-unicode-regex/ignore-non-unicode/expected.js @@ -1,4 +1,4 @@ "use strict"; -var string = "foo\ud83d\udca9bar"; +var string = "foo💩bar"; var match = string.match(/foo(.)bar/); diff --git a/test/fixtures/transformation/playground/object-getter-memoization/expected.js b/test/fixtures/transformation/playground/object-getter-memoization/expected.js index c8886b8b37..68a1265fd0 100644 --- a/test/fixtures/transformation/playground/object-getter-memoization/expected.js +++ b/test/fixtures/transformation/playground/object-getter-memoization/expected.js @@ -5,32 +5,28 @@ var _classProps = function (child, staticProps, instanceProps) { if (instanceProps) Object.defineProperties(child.prototype, instanceProps); }; -var Foo = (function () { - var Foo = function Foo() {}; +var Foo = function Foo() {}; - _classProps(Foo, null, (function (_ref) { - _ref[bar] = { - get: function () { - if (this._memoDone) return this._memo; - this._memoDone = true; - return this._memo = complex(); - }, - enumerable: true - }; - return _ref; - })({ - bar: { - get: function () { - if (this._barDone) return this._bar; - this._barDone = true; - return this._bar = complex(); - }, - enumerable: true - } - })); - - return Foo; -})(); +_classProps(Foo, null, (function (_ref) { + _ref[bar] = { + get: function () { + if (this._memoDone) return this._memo; + this._memoDone = true; + return this._memo = complex(); + }, + enumerable: true + }; + return _ref; +})({ + bar: { + get: function () { + if (this._barDone) return this._bar; + this._barDone = true; + return this._bar = complex(); + }, + enumerable: true + } +})); var foo = (function (_foo) { _foo[bar] = function () { diff --git a/test/fixtures/transformation/source-maps/class/expected.js b/test/fixtures/transformation/source-maps/class/expected.js index aa5136a46f..8d4a322398 100644 --- a/test/fixtures/transformation/source-maps/class/expected.js +++ b/test/fixtures/transformation/source-maps/class/expected.js @@ -5,20 +5,16 @@ var _classProps = function (child, staticProps, instanceProps) { if (instanceProps) Object.defineProperties(child.prototype, instanceProps); }; -var Test = (function () { - var Test = function Test() {}; +var Test = function Test() {}; - _classProps(Test, null, { - bar: { - get: function () { - throw new Error("wow"); - }, - enumerable: true - } - }); - - return Test; -})(); +_classProps(Test, null, { + bar: { + get: function () { + throw new Error("wow"); + }, + enumerable: true + } +}); var test = new Test(); test.bar; diff --git a/test/fixtures/transformation/source-maps/class/source-mappings.json b/test/fixtures/transformation/source-maps/class/source-mappings.json index 8b95905776..1fe92711b8 100644 --- a/test/fixtures/transformation/source-maps/class/source-mappings.json +++ b/test/fixtures/transformation/source-maps/class/source-mappings.json @@ -4,7 +4,7 @@ "column": 10 }, "generated": { - "line": 14, - "column": 15 + "line": 13, + "column": 13 } }] From ceb8e812b6b30a706f1930671e74e11a936b5abf Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Sun, 14 Dec 2014 12:17:16 +1100 Subject: [PATCH 058/139] expose transformers and types --- lib/6to5/file.js | 30 +++++++++++++++++++++++------- lib/6to5/index.js | 4 ++++ 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/lib/6to5/file.js b/lib/6to5/file.js index d8d9c4ba24..c5763f991f 100644 --- a/lib/6to5/file.js +++ b/lib/6to5/file.js @@ -2,12 +2,13 @@ module.exports = File; var SHEBANG_REGEX = /^\#\!.*/; -var transform = require("./transformation/transform"); -var generate = require("./generation/generator"); -var Scope = require("./traverse/scope"); -var util = require("./util"); -var t = require("./types"); -var _ = require("lodash"); +var Transformer = require("./transformation/transformer"); +var transform = require("./transformation/transform"); +var generate = require("./generation/generator"); +var Scope = require("./traverse/scope"); +var util = require("./util"); +var t = require("./types"); +var _ = require("lodash"); function File(opts) { this.opts = File.normaliseOptions(opts); @@ -28,10 +29,21 @@ File.declarations = [ ]; File.normaliseOptions = function (opts) { - opts = _.cloneDeep(opts || {}); + opts = opts || {}; + + _.each(opts.transformers, function (transformer, i) { + if (!(transformer instanceof Transformer)) { + throw new TypeError("opts.transformers[" + i + "] isn't an instance of Transformer"); + } + }); + + opts = _.cloneDeep(opts, function (value) { + return value instanceof Transformer ? value : undefined; + }); _.defaults(opts, { experimental: false, + transformers: [], playground: false, whitespace: true, blacklist: [], @@ -180,6 +192,10 @@ File.prototype.transform = function (ast) { var self = this; + _.each(this.opts.transformers, function (transformer) { + transformer.transform(self); + }); + _.each(transform.transformers, function (transformer) { transformer.transform(self); }); diff --git a/lib/6to5/index.js b/lib/6to5/index.js index 924e08acb3..d60d457322 100644 --- a/lib/6to5/index.js +++ b/lib/6to5/index.js @@ -3,6 +3,10 @@ var util = require("./util"); var fs = require("fs"); var _ = require("lodash"); +exports.Transformer = require("./transformation/transformer"); + +exports.types = require("./types"); + exports.runtime = require("./runtime"); exports.register = function (opts) { From 194fb77b9c4492da4f0369585759fd73e0259c5d Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Sun, 14 Dec 2014 12:17:28 +1100 Subject: [PATCH 059/139] add WithStatement buider keys --- lib/6to5/types/builder-keys.json | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/6to5/types/builder-keys.json b/lib/6to5/types/builder-keys.json index 45c315a50b..1d7484b568 100644 --- a/lib/6to5/types/builder-keys.json +++ b/lib/6to5/types/builder-keys.json @@ -24,5 +24,6 @@ "UnaryExpression": ["operator", "argument", "prefix"], "VariableDeclaration": ["kind", "declarations"], "VariableDeclarator": ["id", "init"], + "WithStatement": ["object", "body"], "YieldExpression": ["argument", "delegate"] } From bf40849e35558fe565c098b4293bec82ad97c757 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Sun, 14 Dec 2014 12:18:03 +1100 Subject: [PATCH 060/139] make ensureProto methods non-enumerable --- lib/6to5/polyfill.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/6to5/polyfill.js b/lib/6to5/polyfill.js index 5d945d16e8..9c2cf47317 100644 --- a/lib/6to5/polyfill.js +++ b/lib/6to5/polyfill.js @@ -6,7 +6,11 @@ var ensureSymbol = function (key) { var ensureProto = function (Constructor, key, val) { var proto = Constructor.prototype; - proto[key] = proto[key] || val; + if (!proto[key]) { + Object.defineProperty(proto, key, { + value: val + }); + } }; // From c38428c536307e2f5d205b881e59ecc4e30aeec1 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Sun, 14 Dec 2014 12:18:14 +1100 Subject: [PATCH 061/139] make react transformer first --- lib/6to5/transformation/transform.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/6to5/transformation/transform.js b/lib/6to5/transformation/transform.js index 1279608cf1..14364f76c6 100644 --- a/lib/6to5/transformation/transform.js +++ b/lib/6to5/transformation/transform.js @@ -49,6 +49,7 @@ _.each({ memoizationOperator: require("./transformers/playground-memoization-operator"), objectGetterMemoization: require("./transformers/playground-object-getter-memoization"), + react: require("./transformers/react"), modules: require("./transformers/es6-modules"), propertyNameShorthand: require("./transformers/es6-property-name-shorthand"), arrayComprehension: require("./transformers/es7-array-comprehension"), @@ -68,7 +69,6 @@ _.each({ forOf: require("./transformers/es6-for-of"), unicodeRegex: require("./transformers/es6-unicode-regex"), abstractReferences: require("./transformers/es7-abstract-references"), - react: require("./transformers/react"), constants: require("./transformers/es6-constants"), letScoping: require("./transformers/es6-let-scoping"), From 11fc7cd0ce81ba8043b87c05201c82687e232830 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Sun, 14 Dec 2014 12:18:33 +1100 Subject: [PATCH 062/139] rename 6to5-browserify to 6to5ify --- doc/plugins.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/plugins.md b/doc/plugins.md index 020de40f7d..3785d31575 100644 --- a/doc/plugins.md +++ b/doc/plugins.md @@ -3,7 +3,7 @@ ## Build systems - [Broccoli](https://github.com/6to5/broccoli-6to5-transpiler) - - [Browserify](https://github.com/6to5/6to5-browserify) + - [Browserify](https://github.com/6to5/6to5ify) - [Brunch](https://github.com/6to5/6to5-brunch) - [Duo](https://github.com/6to5/duo6to5) - [Gobble](https://github.com/6to5/gobble-6to5) From d26f441a5cb5361e626f57c0c57dc1fd16d8f3ec Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Sun, 14 Dec 2014 12:19:24 +1100 Subject: [PATCH 063/139] support falsy and null super classes - fixes #284 --- lib/6to5/templates/extends.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/6to5/templates/extends.js b/lib/6to5/templates/extends.js index bc950dfd9a..1e8f6b5e8f 100644 --- a/lib/6to5/templates/extends.js +++ b/lib/6to5/templates/extends.js @@ -1,5 +1,5 @@ (function (child, parent) { - child.prototype = Object.create(parent.prototype, { + child.prototype = Object.create(parent && parent.prototype, { constructor: { value: child, enumerable: false, @@ -7,5 +7,5 @@ configurable: true } }); - child.__proto__ = parent; + if (parent) child.__proto__ = parent; }) From 00cb90541a7fdb2ad7fba76d3aef239173bb09c3 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Sun, 14 Dec 2014 14:49:25 +1100 Subject: [PATCH 064/139] add support for experimental private abstract references syntax - closes #291 --- lib/6to5/generation/generator.js | 1 + lib/6to5/generation/generators/flow.js | 3 ++ lib/6to5/generation/generators/statements.js | 6 +++ lib/6to5/patch.js | 5 +++ .../transformers/es6-classes.js | 37 +++++++++++-------- .../transformers/es7-abstract-references.js | 6 +++ lib/6to5/types/visitor-keys.json | 4 +- .../types/PrivateDeclaration/actual.js | 7 ++++ .../types/PrivateDeclaration/expected.js | 7 ++++ .../es7-abstract-references/private/actual.js | 12 ++++++ .../private/expected.js | 19 ++++++++++ 11 files changed, 90 insertions(+), 17 deletions(-) create mode 100644 lib/6to5/generation/generators/flow.js create mode 100644 test/fixtures/generation/types/PrivateDeclaration/actual.js create mode 100644 test/fixtures/generation/types/PrivateDeclaration/expected.js create mode 100644 test/fixtures/transformation/es7-abstract-references/private/actual.js create mode 100644 test/fixtures/transformation/es7-abstract-references/private/expected.js diff --git a/lib/6to5/generation/generator.js b/lib/6to5/generation/generator.js index 7f2ce983de..4406a84f46 100644 --- a/lib/6to5/generation/generator.js +++ b/lib/6to5/generation/generator.js @@ -57,6 +57,7 @@ CodeGenerator.generators = { methods: require("./generators/methods"), modules: require("./generators/modules"), types: require("./generators/types"), + flow: require("./generators/flow"), base: require("./generators/base"), jsx: require("./generators/jsx") }; diff --git a/lib/6to5/generation/generators/flow.js b/lib/6to5/generation/generators/flow.js new file mode 100644 index 0000000000..f96e45bde0 --- /dev/null +++ b/lib/6to5/generation/generators/flow.js @@ -0,0 +1,3 @@ +exports.ClassProperty = function () { + throw new Error("not implemented"); +}; diff --git a/lib/6to5/generation/generators/statements.js b/lib/6to5/generation/generators/statements.js index f96ecb29fa..c6c471b638 100644 --- a/lib/6to5/generation/generators/statements.js +++ b/lib/6to5/generation/generators/statements.js @@ -164,6 +164,12 @@ exports.VariableDeclaration = function (node, print, parent) { } }; +exports.PrivateDeclaration = function (node, print) { + this.push("private "); + print.join(node.declarations, { separator: ", " }); + this.semicolon(); +}; + exports.VariableDeclarator = function (node, print) { if (node.init) { print(node.id); diff --git a/lib/6to5/patch.js b/lib/6to5/patch.js index b50b96718a..f846fdf2f0 100644 --- a/lib/6to5/patch.js +++ b/lib/6to5/patch.js @@ -30,6 +30,11 @@ def("VirtualPropertyExpression") .field("object", def("Expression")) .field("property", or(def("Identifier"), def("Expression"))); +def("PrivateDeclaration") + .bases("Declaration") + .build("declarations") + .field("declarations", [def("Identifier")]); + // Playground def("BindMemberExpression") .bases("Expression") diff --git a/lib/6to5/transformation/transformers/es6-classes.js b/lib/6to5/transformation/transformers/es6-classes.js index 98ac4d59d6..9292aba0ea 100644 --- a/lib/6to5/transformation/transformers/es6-classes.js +++ b/lib/6to5/transformation/transformers/es6-classes.js @@ -4,11 +4,11 @@ var t = require("../../types"); var _ = require("lodash"); exports.ClassDeclaration = function (node, parent, file, scope) { - return new Class(node, file, scope, true).run(); + return new Class(node, file, scope, false).run(); }; exports.ClassExpression = function (node, parent, file, scope) { - return new Class(node, file, scope, false).run(); + return new Class(node, file, scope, true).run(); }; /** @@ -17,14 +17,14 @@ exports.ClassExpression = function (node, parent, file, scope) { * @param {Node} node * @param {File} file * @param {Scope} scope - * @param {Boolean} isStatement + * @param {Boolean} closure */ -function Class(node, file, scope, isStatement) { - this.isStatement = isStatement; - this.scope = scope; - this.node = node; - this.file = file; +function Class(node, file, scope, closure) { + this.closure = closure; + this.scope = scope; + this.node = node; + this.file = file; this.instanceMutatorMap = {}; this.staticMutatorMap = {}; @@ -80,9 +80,7 @@ Class.prototype.run = function () { this.buildBody(); - if (this.isStatement) { - return body; - } else { + if (this.closure) { if (body.length === 1) { // only a constructor so no need for a closure container return constructor; @@ -93,6 +91,8 @@ Class.prototype.run = function () { [] ); } + } else { + return body; } }; @@ -109,12 +109,17 @@ Class.prototype.buildBody = function () { var self = this; _.each(classBody, function (node) { - self.replaceInstanceSuperReferences(node); + if (t.isMethodDefinition(node)) { + self.replaceInstanceSuperReferences(node); - if (node.key.name === "constructor") { - self.pushConstructor(node); - } else { - self.pushMethod(node); + if (node.key.name === "constructor") { + self.pushConstructor(node); + } else { + self.pushMethod(node); + } + } else if (t.isPrivateDeclaration(node)) { + self.closure = true; + body.unshift(node); } }); diff --git a/lib/6to5/transformation/transformers/es7-abstract-references.js b/lib/6to5/transformation/transformers/es7-abstract-references.js index 266aa9d09b..73d86adb7f 100644 --- a/lib/6to5/transformation/transformers/es7-abstract-references.js +++ b/lib/6to5/transformation/transformers/es7-abstract-references.js @@ -96,3 +96,9 @@ exports.VirtualPropertyExpression = function (node) { OBJECT: node.object }); }; + +exports.PrivateDeclaration = function (node) { + return t.variableDeclaration("const", node.declarations.map(function (id) { + return t.variableDeclarator(id, t.newExpression(t.identifier("WeakMap"), [])); + })); +}; diff --git a/lib/6to5/types/visitor-keys.json b/lib/6to5/types/visitor-keys.json index fc78a716e5..b90e63942f 100644 --- a/lib/6to5/types/visitor-keys.json +++ b/lib/6to5/types/visitor-keys.json @@ -5,6 +5,7 @@ "AssignmentExpression": ["left", "right"], "AwaitExpression": ["argument"], "BinaryExpression": ["left", "right"], + "BindFunctionExpression": ["callee", "arguments"], "BindMemberExpression": ["object", "property", "arguments"], "BlockStatement": ["body"], "BreakStatement": ["label"], @@ -13,6 +14,7 @@ "ClassBody": ["body"], "ClassDeclaration": ["id", "body", "superClass"], "ClassExpression": ["id", "body", "superClass"], + "ClassProperty": ["key"], "ComprehensionBlock": ["left", "right", "body"], "ComprehensionExpression": ["filter", "blocks", "body"], "ConditionalExpression": ["test", "consequent", "alternate"], @@ -44,7 +46,7 @@ "ObjectExpression": ["properties"], "ObjectPattern": ["properties"], "ParenthesizedExpression": ["expression"], - "BindFunctionExpression": ["callee", "arguments"], + "PrivateDeclaration": ["declarations"], "Program": ["body"], "Property": ["key", "value"], "ReturnStatement": ["argument"], diff --git a/test/fixtures/generation/types/PrivateDeclaration/actual.js b/test/fixtures/generation/types/PrivateDeclaration/actual.js new file mode 100644 index 0000000000..c9c6b03ef6 --- /dev/null +++ b/test/fixtures/generation/types/PrivateDeclaration/actual.js @@ -0,0 +1,7 @@ +private A; +private B, C; + +class Test { + private A; + private B, C; +} diff --git a/test/fixtures/generation/types/PrivateDeclaration/expected.js b/test/fixtures/generation/types/PrivateDeclaration/expected.js new file mode 100644 index 0000000000..c9c6b03ef6 --- /dev/null +++ b/test/fixtures/generation/types/PrivateDeclaration/expected.js @@ -0,0 +1,7 @@ +private A; +private B, C; + +class Test { + private A; + private B, C; +} diff --git a/test/fixtures/transformation/es7-abstract-references/private/actual.js b/test/fixtures/transformation/es7-abstract-references/private/actual.js new file mode 100644 index 0000000000..9643ff19c2 --- /dev/null +++ b/test/fixtures/transformation/es7-abstract-references/private/actual.js @@ -0,0 +1,12 @@ +private A; +private B, C; + +class D { + private E; + private F, G; +} + +var H = class { + private I; + private J, K; +}; diff --git a/test/fixtures/transformation/es7-abstract-references/private/expected.js b/test/fixtures/transformation/es7-abstract-references/private/expected.js new file mode 100644 index 0000000000..91d4b390d1 --- /dev/null +++ b/test/fixtures/transformation/es7-abstract-references/private/expected.js @@ -0,0 +1,19 @@ +"use strict"; + +var A = new WeakMap(); +var B = new WeakMap(), C = new WeakMap(); +(function () { + var F = new WeakMap(), G = new WeakMap(); + var E = new WeakMap(); + var D = function D() {}; + + return D; +})() + +var H = (function () { + var J = new WeakMap(), K = new WeakMap(); + var I = new WeakMap(); + var _class = function () {}; + + return _class; +})(); From 77f959668205ced6b144e00ec3c51b8ef65ff985 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Sun, 14 Dec 2014 14:49:37 +1100 Subject: [PATCH 065/139] update classes tests to work with new _extends method --- .../es6-classes/accessing-super-class/expected.js | 4 ++-- .../es6-classes/accessing-super-properties/expected.js | 4 ++-- .../es6-classes/calling-super-properties/expected.js | 4 ++-- .../transformation/es6-classes/constructor/expected.js | 4 ++-- .../es6-classes/super-class-id-member-expression/expected.js | 4 ++-- .../es6-classes/super-class-id-non-identifiers/expected.js | 4 ++-- .../transformation/es6-classes/super-class/expected.js | 4 ++-- 7 files changed, 14 insertions(+), 14 deletions(-) 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 ad8532015c..14523f5053 100644 --- a/test/fixtures/transformation/es6-classes/accessing-super-class/expected.js +++ b/test/fixtures/transformation/es6-classes/accessing-super-class/expected.js @@ -2,7 +2,7 @@ var _slice = Array.prototype.slice; var _extends = function (child, parent) { - child.prototype = Object.create(parent.prototype, { + child.prototype = Object.create(parent && parent.prototype, { constructor: { value: child, enumerable: false, @@ -10,7 +10,7 @@ var _extends = function (child, parent) { configurable: true } }); - child.__proto__ = parent; + if (parent) child.__proto__ = parent; }; var Test = function Test() { diff --git a/test/fixtures/transformation/es6-classes/accessing-super-properties/expected.js b/test/fixtures/transformation/es6-classes/accessing-super-properties/expected.js index 5ffb26c5c6..b04502c5e3 100644 --- a/test/fixtures/transformation/es6-classes/accessing-super-properties/expected.js +++ b/test/fixtures/transformation/es6-classes/accessing-super-properties/expected.js @@ -1,7 +1,7 @@ "use strict"; var _extends = function (child, parent) { - child.prototype = Object.create(parent.prototype, { + child.prototype = Object.create(parent && parent.prototype, { constructor: { value: child, enumerable: false, @@ -9,7 +9,7 @@ var _extends = function (child, parent) { configurable: true } }); - child.__proto__ = parent; + if (parent) child.__proto__ = parent; }; var Test = function Test() { diff --git a/test/fixtures/transformation/es6-classes/calling-super-properties/expected.js b/test/fixtures/transformation/es6-classes/calling-super-properties/expected.js index 8387489528..424555b3f4 100644 --- a/test/fixtures/transformation/es6-classes/calling-super-properties/expected.js +++ b/test/fixtures/transformation/es6-classes/calling-super-properties/expected.js @@ -1,7 +1,7 @@ "use strict"; var _extends = function (child, parent) { - child.prototype = Object.create(parent.prototype, { + child.prototype = Object.create(parent && parent.prototype, { constructor: { value: child, enumerable: false, @@ -9,7 +9,7 @@ var _extends = function (child, parent) { configurable: true } }); - child.__proto__ = parent; + if (parent) child.__proto__ = parent; }; var Test = function Test() { diff --git a/test/fixtures/transformation/es6-classes/constructor/expected.js b/test/fixtures/transformation/es6-classes/constructor/expected.js index 47eb5a927e..5771cc0767 100644 --- a/test/fixtures/transformation/es6-classes/constructor/expected.js +++ b/test/fixtures/transformation/es6-classes/constructor/expected.js @@ -1,7 +1,7 @@ "use strict"; var _extends = function (child, parent) { - child.prototype = Object.create(parent.prototype, { + child.prototype = Object.create(parent && parent.prototype, { constructor: { value: child, enumerable: false, @@ -9,7 +9,7 @@ var _extends = function (child, parent) { configurable: true } }); - child.__proto__ = parent; + if (parent) child.__proto__ = parent; }; var Test = function Test() { diff --git a/test/fixtures/transformation/es6-classes/super-class-id-member-expression/expected.js b/test/fixtures/transformation/es6-classes/super-class-id-member-expression/expected.js index 5108133980..27635243a2 100644 --- a/test/fixtures/transformation/es6-classes/super-class-id-member-expression/expected.js +++ b/test/fixtures/transformation/es6-classes/super-class-id-member-expression/expected.js @@ -1,7 +1,7 @@ "use strict"; var _extends = function (child, parent) { - child.prototype = Object.create(parent.prototype, { + child.prototype = Object.create(parent && parent.prototype, { constructor: { value: child, enumerable: false, @@ -9,7 +9,7 @@ var _extends = function (child, parent) { configurable: true } }); - child.__proto__ = parent; + if (parent) child.__proto__ = parent; }; var BaseController = function BaseController() { diff --git a/test/fixtures/transformation/es6-classes/super-class-id-non-identifiers/expected.js b/test/fixtures/transformation/es6-classes/super-class-id-non-identifiers/expected.js index aa3f6fdfc2..83a25652fb 100644 --- a/test/fixtures/transformation/es6-classes/super-class-id-non-identifiers/expected.js +++ b/test/fixtures/transformation/es6-classes/super-class-id-non-identifiers/expected.js @@ -1,7 +1,7 @@ "use strict"; var _extends = function (child, parent) { - child.prototype = Object.create(parent.prototype, { + child.prototype = Object.create(parent && parent.prototype, { constructor: { value: child, enumerable: false, @@ -9,7 +9,7 @@ var _extends = function (child, parent) { configurable: true } }); - child.__proto__ = parent; + if (parent) child.__proto__ = parent; }; var _QSuper = function () {}; diff --git a/test/fixtures/transformation/es6-classes/super-class/expected.js b/test/fixtures/transformation/es6-classes/super-class/expected.js index 82b40d6a4a..a4e3858bd8 100644 --- a/test/fixtures/transformation/es6-classes/super-class/expected.js +++ b/test/fixtures/transformation/es6-classes/super-class/expected.js @@ -1,7 +1,7 @@ "use strict"; var _extends = function (child, parent) { - child.prototype = Object.create(parent.prototype, { + child.prototype = Object.create(parent && parent.prototype, { constructor: { value: child, enumerable: false, @@ -9,7 +9,7 @@ var _extends = function (child, parent) { configurable: true } }); - child.__proto__ = parent; + if (parent) child.__proto__ = parent; }; var Test = function Test() { From 319ed09407c084037531207cd80ad790b6519f78 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Sun, 14 Dec 2014 14:49:48 +1100 Subject: [PATCH 066/139] remove string includes polyfill --- lib/6to5/polyfill.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/6to5/polyfill.js b/lib/6to5/polyfill.js index 9c2cf47317..f6253cf6e9 100644 --- a/lib/6to5/polyfill.js +++ b/lib/6to5/polyfill.js @@ -34,8 +34,6 @@ require("./transformation/transformers/es6-generators/runtime"); ensureSymbol("species"); -String.prototype.includes = String.prototype.includes || String.prototype.contains; - // Abstract references ensureSymbol("referenceGet"); From 3dd6eb120261cc82c524387eb664ecc437b78e4b Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Sun, 14 Dec 2014 14:53:00 +1100 Subject: [PATCH 067/139] update acorn-6to5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 392e638e0d..18179d8fce 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "test": "make test" }, "dependencies": { - "acorn-6to5": "0.9.1-13", + "acorn-6to5": "0.9.1-14", "ast-types": "0.6.5", "chokidar": "0.11.1", "commander": "2.5.0", From 37b2e747d59a057ac6c51e1361fd02d9f75a08dc Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Sun, 14 Dec 2014 23:58:31 +1100 Subject: [PATCH 068/139] switch to core-js from es6-symbol and es6-shim --- doc/polyfill.md | 9 ++++---- lib/6to5/polyfill.js | 55 ++++++++------------------------------------ 2 files changed, 13 insertions(+), 51 deletions(-) diff --git a/doc/polyfill.md b/doc/polyfill.md index 631f9adb73..47bbbcd521 100644 --- a/doc/polyfill.md +++ b/doc/polyfill.md @@ -1,12 +1,11 @@ # Polyfill -6to5 includes a polyfill that includes the -[regenerator runtime](https://github.com/facebook/regenerator/blob/master/runtime.js) and the -[es6-shim](https://github.com/paulmillr/es6-shim) and -[es6-symbol](https://github.com/medikoo/es6-symbol) polyfills. +6to5 includes a polyfill that includes a custom +[regenerator runtime](https://github.com/facebook/regenerator/blob/master/runtime.js) and +[core.js](https://github.com/zloirock/core-js). This will emulate a full ES6 environment. This polyfill is automatically loaded -when using [6to5-node](usage.md#node). +when using [6to5-node](usage.md#node) and [6to5/register](usage.md#register-hook). ## Usage diff --git a/lib/6to5/polyfill.js b/lib/6to5/polyfill.js index f6253cf6e9..7fe5f07da6 100644 --- a/lib/6to5/polyfill.js +++ b/lib/6to5/polyfill.js @@ -1,53 +1,16 @@ /* jshint newcap: false, freeze: false */ +require("core-js/shim"); +require("./transformation/transformers/es6-generators/runtime"); + var ensureSymbol = function (key) { Symbol[key] = Symbol[key] || Symbol(key); }; -var ensureProto = function (Constructor, key, val) { - var proto = Constructor.prototype; - if (!proto[key]) { - Object.defineProperty(proto, key, { - value: val - }); - } -}; - -// - -if (typeof Symbol === "undefined") { - require("es6-symbol/implement"); - - var globSymbols = {}; - - Symbol.for = function (key) { - return globSymbols[key] = globSymbols[key] || Symbol(key); - }; - - Symbol.keyFor = function (sym) { - return sym.__description__; - }; -} - -require("es6-shim"); -require("./transformation/transformers/es6-generators/runtime"); - ensureSymbol("species"); - -// Abstract references - -ensureSymbol("referenceGet"); -ensureSymbol("referenceSet"); -ensureSymbol("referenceDelete"); - -ensureProto(Function, Symbol.referenceGet, function () { return this; }); - -ensureProto(Map, Symbol.referenceGet, Map.prototype.get); -ensureProto(Map, Symbol.referenceSet, Map.prototype.set); -ensureProto(Map, Symbol.referenceDelete, Map.prototype.delete); - -if (global.WeakMap) { - ensureProto(WeakMap, Symbol.referenceGet, WeakMap.prototype.get); - ensureProto(WeakMap, Symbol.referenceSet, WeakMap.prototype.set); - ensureProto(WeakMap, Symbol.referenceDelete, WeakMap.prototype.delete); -} +ensureSymbol("hasInstance"); +ensureSymbol("isConcatSpreadable"); +ensureSymbol("isRegExp"); +ensureSymbol("toPrimitive"); +ensureSymbol("toStringTag"); +ensureSymbol("unscopables"); From ea5954121e8b9682ecf36c425d08231db15d2a8e Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Sun, 14 Dec 2014 23:58:42 +1100 Subject: [PATCH 069/139] disable es6-transpiler --- benchmark/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/benchmark/index.js b/benchmark/index.js index 176142818c..f0f820081d 100644 --- a/benchmark/index.js +++ b/benchmark/index.js @@ -2,7 +2,7 @@ Error.stackTraceLimit = Infinity; var jsTrans = require("jstransform"); var traceur = require("traceur"); -var es6tr = require("es6-transpiler"); +//var es6tr = require("es6-transpiler"); var es6now = require("es6now"); //var esnext = require("esnext"); var to5 = require("../lib/6to5"); @@ -70,13 +70,13 @@ var compilers = { } }, - "es6-transpiler": { + /*"es6-transpiler": { compile: function (code) { var result = es6tr.run({ src: code }); if (result.errors.length) throw new Error(result.join("; ")); return result.src; } - }, + },*/ jstransform: { compile: function (code) { From 1b16ff3a0be7023dde0b4e8e0f289a370b105e3d Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Mon, 15 Dec 2014 13:54:45 +1100 Subject: [PATCH 070/139] Revert "switch to core-js from es6-symbol and es6-shim" This reverts commit 37b2e747d59a057ac6c51e1361fd02d9f75a08dc. --- doc/polyfill.md | 9 ++++---- lib/6to5/polyfill.js | 55 ++++++++++++++++++++++++++++++++++++-------- 2 files changed, 51 insertions(+), 13 deletions(-) diff --git a/doc/polyfill.md b/doc/polyfill.md index 47bbbcd521..631f9adb73 100644 --- a/doc/polyfill.md +++ b/doc/polyfill.md @@ -1,11 +1,12 @@ # Polyfill -6to5 includes a polyfill that includes a custom -[regenerator runtime](https://github.com/facebook/regenerator/blob/master/runtime.js) and -[core.js](https://github.com/zloirock/core-js). +6to5 includes a polyfill that includes the +[regenerator runtime](https://github.com/facebook/regenerator/blob/master/runtime.js) and the +[es6-shim](https://github.com/paulmillr/es6-shim) and +[es6-symbol](https://github.com/medikoo/es6-symbol) polyfills. This will emulate a full ES6 environment. This polyfill is automatically loaded -when using [6to5-node](usage.md#node) and [6to5/register](usage.md#register-hook). +when using [6to5-node](usage.md#node). ## Usage diff --git a/lib/6to5/polyfill.js b/lib/6to5/polyfill.js index 7fe5f07da6..f6253cf6e9 100644 --- a/lib/6to5/polyfill.js +++ b/lib/6to5/polyfill.js @@ -1,16 +1,53 @@ /* jshint newcap: false, freeze: false */ -require("core-js/shim"); -require("./transformation/transformers/es6-generators/runtime"); - var ensureSymbol = function (key) { Symbol[key] = Symbol[key] || Symbol(key); }; +var ensureProto = function (Constructor, key, val) { + var proto = Constructor.prototype; + if (!proto[key]) { + Object.defineProperty(proto, key, { + value: val + }); + } +}; + +// + +if (typeof Symbol === "undefined") { + require("es6-symbol/implement"); + + var globSymbols = {}; + + Symbol.for = function (key) { + return globSymbols[key] = globSymbols[key] || Symbol(key); + }; + + Symbol.keyFor = function (sym) { + return sym.__description__; + }; +} + +require("es6-shim"); +require("./transformation/transformers/es6-generators/runtime"); + ensureSymbol("species"); -ensureSymbol("hasInstance"); -ensureSymbol("isConcatSpreadable"); -ensureSymbol("isRegExp"); -ensureSymbol("toPrimitive"); -ensureSymbol("toStringTag"); -ensureSymbol("unscopables"); + +// Abstract references + +ensureSymbol("referenceGet"); +ensureSymbol("referenceSet"); +ensureSymbol("referenceDelete"); + +ensureProto(Function, Symbol.referenceGet, function () { return this; }); + +ensureProto(Map, Symbol.referenceGet, Map.prototype.get); +ensureProto(Map, Symbol.referenceSet, Map.prototype.set); +ensureProto(Map, Symbol.referenceDelete, Map.prototype.delete); + +if (global.WeakMap) { + ensureProto(WeakMap, Symbol.referenceGet, WeakMap.prototype.get); + ensureProto(WeakMap, Symbol.referenceSet, WeakMap.prototype.set); + ensureProto(WeakMap, Symbol.referenceDelete, WeakMap.prototype.delete); +} From 2cd49b08ec176bcaa923c24244f12f96c1bd0239 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Mon, 15 Dec 2014 13:56:22 +1100 Subject: [PATCH 071/139] add async generator functions to docs --- doc/differences.md | 4 ++++ doc/features.md | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/doc/differences.md b/doc/differences.md index 7a6189a84c..3694acfdff 100644 --- a/doc/differences.md +++ b/doc/differences.md @@ -76,21 +76,25 @@ always be used as little as possible. | Array comprehension | ✓ | ✓ | ✓ | | | | | Arrow functions | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | Async functions | ✓ | ✓ | | ✓ | | | +| Async generator functions | ✓ | ✓ | | | | | | Classes | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | Computed property names | ✓ | ✓ | ✓ | ✓ | ✓ | | | Constants | ✓ | ✓ | ✓ | | | | | Default parameters | ✓ | ✓ | ✓ | ✓ | ✓ | | | Destructuring | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | Exponentiation operator | ✓ | ✓ | | | | | +| Flow types | ✓ | | | | | | | For-of | ✓ | ✓ | ✓ | ✓ | ✓ | | | Generators | ✓ | ✓ | | ✓ | | | | Generator comprehension | ✓ | ✓ | | | | | +| JSX | ✓ | | | | | | | Let scoping | ✓ | ✓ | ✓ | | | | | Modules | ✓ | ✓ | | | ✓ | | | Object rest/spread | ✓ | | | | | ✓ | | Property method assignment | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | Property name shorthand | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | Rest parameters | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| React | ✓ | | | | | | | Spread | ✓ | ✓ | ✓ | ✓ | ✓ | | | Template literals | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | Unicode regex | ✓ | ✓ | ✓ | | | | diff --git a/doc/features.md b/doc/features.md index 0efa77c58f..a5c55fda81 100644 --- a/doc/features.md +++ b/doc/features.md @@ -49,6 +49,12 @@ async function chainAnimationsAsync(elem, animations) { } ``` +## Async generator functions ([experimental](experimental.md)) ([spec](https://github.com/jhusain/asyncgenerator)) + +```javascript + +``` + ## Classes ```javascript From 2fb6c7820cce109fdf432352c85125046e569a27 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Mon, 15 Dec 2014 13:59:54 +1100 Subject: [PATCH 072/139] microoptimizations --- lib/6to5/transformation/transform.js | 4 +- lib/6to5/transformation/transformer.js | 18 ++++---- .../transformers/_declarations.js | 13 +++--- .../es5-property-method-assignment.js | 5 ++- .../transformers/es6-classes.js | 25 ++++++++--- .../es6-computed-property-names.js | 6 +-- .../transformers/es6-constants.js | 28 +++++++----- .../transformers/es6-default-parameters.js | 15 ++++--- .../transformers/es6-destructuring.js | 45 +++++++++++-------- .../transformers/es6-generators/index.js | 4 +- .../transformers/es6-let-scoping.js | 33 ++++++++------ .../transformers/es6-modules.js | 13 +++--- .../transformation/transformers/es6-spread.js | 18 ++++---- .../transformers/es6-template-literals.js | 20 +++++---- .../transformers/es6-unicode-regex.js | 2 +- .../transformers/es7-array-comprehension.js | 7 +-- .../transformers/es7-object-spread.js | 13 +++--- lib/6to5/transformation/transformers/react.js | 31 +++++++------ .../spec-no-duplicate-properties.js | 12 ++--- lib/6to5/types/builder-keys.json | 1 + lib/6to5/types/index.js | 8 ++-- 21 files changed, 184 insertions(+), 137 deletions(-) diff --git a/lib/6to5/transformation/transform.js b/lib/6to5/transformation/transform.js index 14364f76c6..87a8edfa7c 100644 --- a/lib/6to5/transformation/transform.js +++ b/lib/6to5/transformation/transform.js @@ -81,8 +81,8 @@ _.each({ _declarations: require("./transformers/_declarations"), // spec - specPropertyLiterals: require("./transformers/spec-property-literals"), - specMemberExpressioLiterals: require("./transformers/spec-member-expression-literals"), + specPropertyLiterals: require("./transformers/spec-property-literals"), + specMemberExpressionLiterals: require("./transformers/spec-member-expression-literals"), // wrap up _aliasFunctions: require("./transformers/_alias-functions"), diff --git a/lib/6to5/transformation/transformer.js b/lib/6to5/transformation/transformer.js index ff5693dfe4..fdac3442e9 100644 --- a/lib/6to5/transformation/transformer.js +++ b/lib/6to5/transformation/transformer.js @@ -18,6 +18,13 @@ Transformer.normalise = function (transformer) { if (type[0] === "_") return; if (_.isFunction(fns)) fns = { enter: fns }; transformer[type] = fns; + + var aliases = t.FLIPPED_ALIAS_KEYS[type]; + if (aliases) { + _.each(aliases, function (alias) { + transformer[alias] = fns; + }); + } }); return transformer; @@ -42,16 +49,7 @@ Transformer.prototype.transform = function (file) { var build = function (exit) { return function (node, parent, scope) { - // add any node type aliases that exist - var types = [node.type].concat(t.ALIAS_KEYS[node.type] || []); - - var fns = transformer.all; - - _.each(types, function (type) { - fns = transformer[type] || fns; - }); - - // this transformer cannot deal with this node type + var fns = transformer[node.type]; if (!fns) return; var fn = fns.enter; diff --git a/lib/6to5/transformation/transformers/_declarations.js b/lib/6to5/transformation/transformers/_declarations.js index 6ccda90a1c..3ceee04780 100644 --- a/lib/6to5/transformation/transformers/_declarations.js +++ b/lib/6to5/transformation/transformers/_declarations.js @@ -1,11 +1,12 @@ var t = require("../../types"); -var _ = require("lodash"); exports.BlockStatement = exports.Program = function (node) { var kinds = {}; - _.each(node._declarations, function (declar) { + for (var i in node._declarations) { + var declar = node._declarations[i]; + var kind = declar.kind || "var"; var declarNode = t.variableDeclarator(declar.id, declar.init); @@ -15,9 +16,9 @@ exports.Program = function (node) { } else { node.body.unshift(t.variableDeclaration(kind, [declarNode])); } - }); + } - _.each(kinds, function (declars, kind) { - node.body.unshift(t.variableDeclaration(kind, declars)); - }); + for (var kind in kinds) { + node.body.unshift(t.variableDeclaration(kind, kinds[kind])); + } }; diff --git a/lib/6to5/transformation/transformers/es5-property-method-assignment.js b/lib/6to5/transformation/transformers/es5-property-method-assignment.js index a6712b6375..0bfe57584c 100644 --- a/lib/6to5/transformation/transformers/es5-property-method-assignment.js +++ b/lib/6to5/transformation/transformers/es5-property-method-assignment.js @@ -1,5 +1,4 @@ var util = require("../../util"); -var _ = require("lodash"); exports.Property = function (node) { if (node.method) node.method = false; @@ -7,9 +6,11 @@ exports.Property = function (node) { exports.ObjectExpression = function (node, parent, file) { var mutatorMap = {}; + var hasAny = false; node.properties = node.properties.filter(function (prop) { if (prop.kind === "get" || prop.kind === "set") { + hasAny = true; util.pushMutatorMap(mutatorMap, prop.key, prop.kind, prop.value); return false; } else { @@ -17,7 +18,7 @@ exports.ObjectExpression = function (node, parent, file) { } }); - if (_.isEmpty(mutatorMap)) return; + if (!hasAny) return; var objId = util.getUid(parent, file); diff --git a/lib/6to5/transformation/transformers/es6-classes.js b/lib/6to5/transformation/transformers/es6-classes.js index 9292aba0ea..6363138079 100644 --- a/lib/6to5/transformation/transformers/es6-classes.js +++ b/lib/6to5/transformation/transformers/es6-classes.js @@ -1,7 +1,6 @@ var traverse = require("../../traverse"); var util = require("../../util"); var t = require("../../types"); -var _ = require("lodash"); exports.ClassDeclaration = function (node, parent, file, scope) { return new Class(node, file, scope, false).run(); @@ -26,6 +25,9 @@ function Class(node, file, scope, closure) { this.node = node; this.file = file; + this.hasInstanceMutators = false; + this.hasStaticMutators = false; + this.instanceMutatorMap = {}; this.staticMutatorMap = {}; this.hasConstructor = false; @@ -108,7 +110,8 @@ Class.prototype.buildBody = function () { var body = this.body; var self = this; - _.each(classBody, function (node) { + for (var i in classBody) { + var node = classBody[i]; if (t.isMethodDefinition(node)) { self.replaceInstanceSuperReferences(node); @@ -121,7 +124,7 @@ Class.prototype.buildBody = function () { self.closure = true; body.unshift(node); } - }); + } if (!this.hasConstructor && superName) { constructor.body.body.push(util.template("class-super-constructor-call", { @@ -132,7 +135,7 @@ Class.prototype.buildBody = function () { var instanceProps; var staticProps; - if (!_.isEmpty(this.instanceMutatorMap)) { + if (this.hasInstanceMutators) { var protoId = util.template("prototype-identifier", { CLASS_NAME: className }); @@ -140,7 +143,7 @@ Class.prototype.buildBody = function () { instanceProps = util.buildDefineProperties(this.instanceMutatorMap, protoId); } - if (!_.isEmpty(this.staticMutatorMap)) { + if (this.hasStaticMutators) { staticProps = util.buildDefineProperties(this.staticMutatorMap, className); } @@ -174,11 +177,18 @@ Class.prototype.pushMethod = function (node) { if (!node.static) className = t.memberExpression(className, t.identifier("prototype")); methodName = t.memberExpression(className, methodName, node.computed); - this.body.push(t.expressionStatement(t.assignmentExpression("=", methodName, node.value))); + var expr = t.expressionStatement(t.assignmentExpression("=", methodName, node.value)); + t.inheritsComments(expr, node); + this.body.push(expr); } else { // mutator var mutatorMap = this.instanceMutatorMap; - if (node.static) mutatorMap = this.staticMutatorMap; + if (node.static) { + this.hasStaticMutators = true; + mutatorMap = this.staticMutatorMap; + } else { + this.hasInstanceMutators = true; + } util.pushMutatorMap(mutatorMap, methodName, kind, node); } }; @@ -265,6 +275,7 @@ Class.prototype.pushConstructor = function (method) { var fn = method.value; this.hasConstructor = true; + t.inherits(construct, fn); t.inheritsComments(construct, method); diff --git a/lib/6to5/transformation/transformers/es6-computed-property-names.js b/lib/6to5/transformation/transformers/es6-computed-property-names.js index 8a8dee808d..91242d4947 100644 --- a/lib/6to5/transformation/transformers/es6-computed-property-names.js +++ b/lib/6to5/transformation/transformers/es6-computed-property-names.js @@ -1,6 +1,5 @@ var util = require("../../util"); var t = require("../../types"); -var _ = require("lodash"); exports.ObjectExpression = function (node, parent, file) { var hasComputed = false; @@ -31,7 +30,8 @@ exports.ObjectExpression = function (node, parent, file) { containerCallee._aliasFunction = true; - _.each(computed, function (prop) { + for (var i in computed) { + var prop = computed[i]; containerBody.unshift( t.expressionStatement( t.assignmentExpression( @@ -41,7 +41,7 @@ exports.ObjectExpression = function (node, parent, file) { ) ) ); - }); + } return container; }; diff --git a/lib/6to5/transformation/transformers/es6-constants.js b/lib/6to5/transformation/transformers/es6-constants.js index 2996974c37..d20812a51c 100644 --- a/lib/6to5/transformation/transformers/es6-constants.js +++ b/lib/6to5/transformation/transformers/es6-constants.js @@ -7,6 +7,7 @@ exports.BlockStatement = exports.ForInStatement = exports.ForOfStatement = exports.ForStatement = function (node, parent, file) { + var hasConstants = false; var constants = {}; /** @@ -15,17 +16,18 @@ exports.ForStatement = function (node, parent, file) { */ var check = function (parent, names, scope) { - _.each(names, function (nameNode, name) { - if (!_.has(constants, name)) return; - if (parent && t.isBlockStatement(parent) && parent !== constants[name]) return; + for (var name in names) { + var nameNode = names[name]; + if (!_.has(constants, name)) continue; + if (parent && t.isBlockStatement(parent) && parent !== constants[name]) continue; if (scope) { var defined = scope.get(name); - if (defined && defined === nameNode) return; + if (defined && defined === nameNode) continue; } throw file.errorWithNode(nameNode, name + " is read-only"); - }); + } }; var getIds = function (node) { @@ -38,24 +40,30 @@ exports.ForStatement = function (node, parent, file) { _.each(node.body, function (child, parent) { if (child && t.isVariableDeclaration(child, { kind: "const" })) { - _.each(child.declarations, function (declar) { - _.each(getIds(declar), function (nameNode, name) { + for (var i in child.declarations) { + var declar = child.declarations[i]; + + var ids = getIds(declar); + for (var name in ids) { + var nameNode = ids[name]; + var names = {}; names[name] = nameNode; check(parent, names); constants[name] = parent; - }); + hasConstants = true; + } declar._ignoreConstant = true; - }); + } child._ignoreConstant = true; child.kind = "let"; } }); - if (_.isEmpty(constants)) return; + if (!hasConstants) return; traverse(node, function (child, parent, scope) { if (child._ignoreConstant) return; diff --git a/lib/6to5/transformation/transformers/es6-default-parameters.js b/lib/6to5/transformation/transformers/es6-default-parameters.js index 3901f6defa..304061943e 100644 --- a/lib/6to5/transformation/transformers/es6-default-parameters.js +++ b/lib/6to5/transformation/transformers/es6-default-parameters.js @@ -1,4 +1,5 @@ var traverse = require("../../traverse"); +var Scope = require("../../traverse/scope"); var util = require("../../util"); var t = require("../../types"); var _ = require("lodash"); @@ -13,8 +14,9 @@ exports.Function = function (node, parent, file, scope) { var iife = false; - _.each(node.defaults, function (def, i) { - if (!def) return; + for (var i in node.defaults) { + var def = node.defaults[i]; + if (!def) continue; var param = node.params[i]; @@ -42,18 +44,19 @@ exports.Function = function (node, parent, file, scope) { if (has && !_.contains(node.params, has)) { iife = true; } - }); + } var body = []; - _.each(node.defaults, function (def, i) { - if (!def) return; + for (var i in node.defaults) { + var def = node.defaults[i]; + if (!def) continue; body.push(util.template("if-undefined-set-to", { VARIABLE: node.params[i], DEFAULT: def }, true)); - }); + } if (iife) { var container = t.functionExpression(null, [], node.body, node.generator); diff --git a/lib/6to5/transformation/transformers/es6-destructuring.js b/lib/6to5/transformation/transformers/es6-destructuring.js index 29d81afc97..3e7db9894a 100644 --- a/lib/6to5/transformation/transformers/es6-destructuring.js +++ b/lib/6to5/transformation/transformers/es6-destructuring.js @@ -1,7 +1,6 @@ // TODO: Clean up var t = require("../../types"); -var _ = require("lodash"); var buildVariableAssign = function (opts, id, init) { var op = opts.operator; @@ -27,20 +26,23 @@ var push = function (opts, nodes, elem, parentId) { }; var pushObjectPattern = function (opts, nodes, pattern, parentId) { - _.each(pattern.properties, function (prop, i) { + for (var i in pattern.properties) { + var prop = pattern.properties[i]; if (t.isSpreadProperty(prop)) { // get all the keys that appear in this object before the current spread var keys = []; - _.each(pattern.properties, function (prop2, i2) { - if (i2 >= i) return false; - if (t.isSpreadProperty(prop2)) return; + for (var i2 in pattern.properties) { + var prop2 = pattern.properties[i2]; + + if (i2 >= i) break; + if (t.isSpreadProperty(prop2)) continue; var key = prop2.key; if (t.isIdentifier(key)) { key = t.literal(prop2.key.name); } keys.push(key); - }); + } keys = t.arrayExpression(keys); var value = t.callExpression(opts.file.addDeclaration("object-spread"), [parentId, keys]); @@ -55,7 +57,7 @@ var pushObjectPattern = function (opts, nodes, pattern, parentId) { nodes.push(buildVariableAssign(opts, pattern2, patternId2)); } } - }); + } }; var pushArrayPattern = function (opts, nodes, pattern, parentId) { @@ -65,15 +67,18 @@ var pushArrayPattern = function (opts, nodes, pattern, parentId) { ])); parentId = _parentId; - _.each(pattern.elements, function (elem, i) { - if (!elem) return; + for (var i in pattern.elements) { + var elem = pattern.elements[i]; + if (!elem) continue; + + i = +i; var newPatternId; if (t.isSpreadElement(elem)) { newPatternId = opts.file.toArray(parentId); - if (+i > 0) { + if (i > 0) { newPatternId = t.callExpression(t.memberExpression(newPatternId, t.identifier("slice")), [t.literal(i)]); } @@ -83,7 +88,7 @@ var pushArrayPattern = function (opts, nodes, pattern, parentId) { } push(opts, nodes, elem, newPatternId); - }); + } }; var pushPattern = function (opts) { @@ -217,15 +222,18 @@ exports.VariableDeclaration = function (node, parent, file, scope) { var nodes = []; var hasPattern = false; - _.each(node.declarations, function (declar) { + for (var i in node.declarations) { + var declar = node.declarations[i]; if (t.isPattern(declar.id)) { hasPattern = true; - return false; + break; } - }); + } if (!hasPattern) return; - _.each(node.declarations, function (declar) { + for (var i in node.declarations) { + var declar = node.declarations[i]; + var patternId = declar.init; var pattern = declar.id; var opts = { @@ -241,12 +249,13 @@ exports.VariableDeclaration = function (node, parent, file, scope) { } else { nodes.push(buildVariableAssign(opts, declar.id, declar.init)); } - }); + } if (!t.isProgram(parent) && !t.isBlockStatement(parent)) { var declar; - _.each(nodes, function (node) { + for (var i in nodes) { + var node = nodes[i]; declar = declar || t.variableDeclaration(node.kind, []); if (!t.isVariableDeclaration(node) && declar.kind !== node.kind) { @@ -254,7 +263,7 @@ exports.VariableDeclaration = function (node, parent, file, scope) { } declar.declarations = declar.declarations.concat(node.declarations); - }); + } return declar; } diff --git a/lib/6to5/transformation/transformers/es6-generators/index.js b/lib/6to5/transformation/transformers/es6-generators/index.js index 563781f8b7..5d2aa5acba 100644 --- a/lib/6to5/transformation/transformers/es6-generators/index.js +++ b/lib/6to5/transformation/transformers/es6-generators/index.js @@ -1 +1,3 @@ -module.exports = require("./visit").transform; +var t = require("../../../types"); + +exports.ast = require("./visit").transform; diff --git a/lib/6to5/transformation/transformers/es6-let-scoping.js b/lib/6to5/transformation/transformers/es6-let-scoping.js index 194be693be..a173eb9aa2 100644 --- a/lib/6to5/transformation/transformers/es6-let-scoping.js +++ b/lib/6to5/transformation/transformers/es6-let-scoping.js @@ -18,9 +18,9 @@ var isVar = function (node) { }; var standardiseLets = function (declars) { - _.each(declars, function (declar) { - delete declar._let; - }); + for (var i in declars) { + delete declars[i]._let; + } }; exports.VariableDeclaration = function (node) { @@ -160,8 +160,9 @@ LetScoping.prototype.noClosure = function () { LetScoping.prototype.remap = function () { var replacements = this.info.duplicates; var block = this.block; + var file = this.file; - if (_.isEmpty(replacements)) return; + if (!this.info.hasDuplicates) return; var replace = function (node, parent, scope) { if (!t.isIdentifier(node)) return; @@ -209,6 +210,8 @@ LetScoping.prototype.getInfo = function () { // all references with it duplicates: {}, + hasDuplicates: false, + // array of `Identifier` names of let variables that are accessible within // the current block keys: [] @@ -221,28 +224,31 @@ LetScoping.prototype.getInfo = function () { // there's a variable with this exact name in an upper scope so we need // to generate a new name opts.duplicates[key] = id.name = file.generateUid(key, scope); + opts.hasDuplicates = true; } }; - _.each(opts.declarators, function (declar) { + for (var i in opts.declarators) { + var declar = opts.declarators[i]; opts.declarators.push(declar); var keys = t.getIds(declar, true); _.each(keys, duplicates); - keys = _.keys(keys); + keys = Object.keys(keys); opts.outsideKeys = opts.outsideKeys.concat(keys); opts.keys = opts.keys.concat(keys); - }); + } - _.each(block.body, function (declar) { - if (!isLet(declar)) return; + for (var i in block.body) { + var declar = block.body[i]; + if (!isLet(declar)) continue; _.each(t.getIds(declar, true), function (id, key) { duplicates(id, key); opts.keys.push(key); }); - }); + } return opts; }; @@ -417,12 +423,13 @@ LetScoping.prototype.pushDeclar = function (node) { var replace = []; - _.each(node.declarations, function (declar) { - if (!declar.init) return; + for (var i in node.declarations) { + var declar = node.declarations[i]; + if (!declar.init) continue; var expr = t.assignmentExpression("=", declar.id, declar.init); replace.push(t.inherits(expr, declar)); - }); + } return replace; }; diff --git a/lib/6to5/transformation/transformers/es6-modules.js b/lib/6to5/transformation/transformers/es6-modules.js index 97abf7fe16..47ffaba321 100644 --- a/lib/6to5/transformation/transformers/es6-modules.js +++ b/lib/6to5/transformation/transformers/es6-modules.js @@ -1,5 +1,4 @@ var t = require("../../types"); -var _ = require("lodash"); var inheritsComments = function (node, nodes) { if (nodes.length) { @@ -11,9 +10,9 @@ exports.ImportDeclaration = function (node, parent, file) { var nodes = []; if (node.specifiers.length) { - _.each(node.specifiers, function (specifier) { - file.moduleFormatter.importSpecifier(specifier, node, nodes, parent); - }); + for (var i in node.specifiers) { + file.moduleFormatter.importSpecifier(node.specifiers[i], node, nodes, parent); + } } else { file.moduleFormatter.import(node, nodes, parent); } @@ -36,9 +35,9 @@ exports.ExportDeclaration = function (node, parent, file) { file.moduleFormatter.export(node, nodes, parent); } else { - _.each(node.specifiers, function (specifier) { - file.moduleFormatter.exportSpecifier(specifier, node, nodes, parent); - }); + for (var i in node.specifiers) { + file.moduleFormatter.exportSpecifier(node.specifiers[i], node, nodes, parent); + } } inheritsComments(node, nodes); diff --git a/lib/6to5/transformation/transformers/es6-spread.js b/lib/6to5/transformation/transformers/es6-spread.js index 5e64db73eb..7c8062bcdf 100644 --- a/lib/6to5/transformation/transformers/es6-spread.js +++ b/lib/6to5/transformation/transformers/es6-spread.js @@ -1,19 +1,16 @@ var t = require("../../types"); -var _ = require("lodash"); var getSpreadLiteral = function (spread, file) { return file.toArray(spread.argument); }; var hasSpread = function (nodes) { - var has = false; - _.each(nodes, function (node) { - if (t.isSpreadElement(node)) { - has = true; - return false; + for (var i in nodes) { + if (t.isSpreadElement(nodes[i])) { + return true; } - }); - return has; + } + return false; }; var build = function (props, file) { @@ -27,14 +24,15 @@ var build = function (props, file) { _props = []; }; - _.each(props, function (prop) { + for (var i in props) { + var prop = props[i]; if (t.isSpreadElement(prop)) { push(); nodes.push(getSpreadLiteral(prop, file)); } else { _props.push(prop); } - }); + } push(); diff --git a/lib/6to5/transformation/transformers/es6-template-literals.js b/lib/6to5/transformation/transformers/es6-template-literals.js index 116a583609..9ef874a0be 100644 --- a/lib/6to5/transformation/transformers/es6-template-literals.js +++ b/lib/6to5/transformation/transformers/es6-template-literals.js @@ -1,5 +1,4 @@ var t = require("../../types"); -var _ = require("lodash"); var buildBinaryExpression = function (left, right) { return t.binaryExpression("+", left, right); @@ -12,10 +11,11 @@ exports.TaggedTemplateExpression = function (node, parent, file) { var strings = []; var raw = []; - _.each(quasi.quasis, function (elem) { + for (var i in quasi.quasis) { + var elem = quasi.quasis[i]; strings.push(t.literal(elem.value.cooked)); raw.push(t.literal(elem.value.raw)); - }); + } args.push(t.callExpression(file.addDeclaration("tagged-template-literal"), [ t.arrayExpression(strings), @@ -30,7 +30,9 @@ exports.TaggedTemplateExpression = function (node, parent, file) { exports.TemplateLiteral = function (node) { var nodes = []; - _.each(node.quasis, function (elem) { + for (var i in node.quasis) { + var elem = node.quasis[i]; + nodes.push(t.literal(elem.value.cooked)); var expr = node.expressions.shift(); @@ -38,18 +40,18 @@ exports.TemplateLiteral = function (node) { if (t.isBinary(expr)) expr = t.parenthesizedExpression(expr); nodes.push(expr); } - }); + } if (nodes.length > 1) { // remove redundant '' at the end of the expression - var last = _.last(nodes); + var last = nodes[nodes.length - 1]; if (t.isLiteral(last, { value: "" })) nodes.pop(); var root = buildBinaryExpression(nodes.shift(), nodes.shift()); - _.each(nodes, function (node) { - root = buildBinaryExpression(root, node); - }); + for (var i in nodes) { + root = buildBinaryExpression(root, nodes[i]); + } return root; } else { diff --git a/lib/6to5/transformation/transformers/es6-unicode-regex.js b/lib/6to5/transformation/transformers/es6-unicode-regex.js index 14c9c2143c..d85bdf4e3b 100644 --- a/lib/6to5/transformation/transformers/es6-unicode-regex.js +++ b/lib/6to5/transformation/transformers/es6-unicode-regex.js @@ -6,7 +6,7 @@ exports.Literal = function (node) { if (!regex) return; var flags = regex.flags.split(""); - if (!_.contains(regex.flags, "u")) return; + if (regex.flags.indexOf("u") < 0) return; _.pull(flags, "u"); regex.pattern = rewritePattern(regex.pattern, regex.flags); diff --git a/lib/6to5/transformation/transformers/es7-array-comprehension.js b/lib/6to5/transformation/transformers/es7-array-comprehension.js index 1cd029ac4c..daf7a37720 100644 --- a/lib/6to5/transformation/transformers/es7-array-comprehension.js +++ b/lib/6to5/transformation/transformers/es7-array-comprehension.js @@ -1,6 +1,5 @@ var util = require("../../util"); var t = require("../../types"); -var _ = require("lodash"); var single = function (node, file) { var block = node.blocks[0]; @@ -15,11 +14,13 @@ var single = function (node, file) { KEY: block.left }); - _.each([result.callee.object, result], function (call) { + var aliasPossibles = [result.callee.object, result]; + for (var i in aliasPossibles) { + var call = aliasPossibles[i]; if (t.isCallExpression(call)) { call.arguments[0]._aliasFunction = true; } - }); + } return result; }; diff --git a/lib/6to5/transformation/transformers/es7-object-spread.js b/lib/6to5/transformation/transformers/es7-object-spread.js index 73aecb4283..32cd606ef2 100644 --- a/lib/6to5/transformation/transformers/es7-object-spread.js +++ b/lib/6to5/transformation/transformers/es7-object-spread.js @@ -1,16 +1,16 @@ // https://github.com/sebmarkbage/ecmascript-rest-spread var t = require("../../types"); -var _ = require("lodash"); exports.ObjectExpression = function (node) { var hasSpread = false; - _.each(node.properties, function (prop) { + for (var i in node.properties) { + var prop = node.properties[i]; if (t.isSpreadProperty(prop)) { hasSpread = true; - return false; + break; } - }); + } if (!hasSpread) return; var args = []; @@ -22,14 +22,15 @@ exports.ObjectExpression = function (node) { props = []; }; - _.each(node.properties, function (prop) { + for (var i in node.properties) { + var prop = node.properties[i]; if (t.isSpreadProperty(prop)) { push(); args.push(prop.argument); } else { props.push(prop); } - }); + } push(); diff --git a/lib/6to5/transformation/transformers/react.js b/lib/6to5/transformation/transformers/react.js index 645e19a744..51fb6f9b8e 100644 --- a/lib/6to5/transformation/transformers/react.js +++ b/lib/6to5/transformation/transformers/react.js @@ -5,7 +5,6 @@ var esutils = require("esutils"); var t = require("../../types"); -var _ = require("lodash"); exports.XJSIdentifier = function (node) { if (esutils.keyword.isIdentifierName(node.name)) { @@ -49,7 +48,7 @@ exports.XJSOpeningElement = { tagName = tagExpr.value; } - if (tagName && (/[a-z]/.exec(tagName[0]) || _.contains(tagName, "-"))) { + if (tagName && (/[a-z]/.exec(tagName[0]) || tagName.indexOf("-") >= 0)) { args.push(t.literal(tagName)); } else { args.push(tagExpr); @@ -106,13 +105,17 @@ exports.XJSElement = { exit: function (node) { var callExpr = node.openingElement; - _.each(node.children, function (child) { + for (var i in node.children) { + var child = node.children[i]; + if (t.isLiteral(child)) { var lines = child.value.split(/\r\n|\n|\r/); - _.each(lines, function (line, i) { - var isFirstLine = i === 0; - var isLastLine = i === lines.length - 1; + for (var i in lines) { + var line = lines[i]; + + var isFirstLine = i == 0; + var isLastLine = i == lines.length - 1; // replace rendered whitespace tabs with spaces var trimmedLine = line.replace(/\t/g, ' '); @@ -130,15 +133,15 @@ exports.XJSElement = { if (trimmedLine) { callExpr.arguments.push(t.literal(trimmedLine)); } - }); + } - return; + continue; } else if (t.isXJSEmptyExpression(child)) { - return; + continue; } callExpr.arguments.push(child); - }); + } return t.inherits(callExpr, node); } @@ -171,11 +174,13 @@ var addDisplayName = function (id, call) { var props = first.properties; var safe = true; - _.each(props, function (prop) { + for (var i in props) { + var prop = props[i]; if (t.isIdentifier(prop.key, { name: "displayName" })) { - return safe = false; + safe = false; + break; } - }); + } if (safe) { props.unshift(t.property("init", t.identifier("displayName"), t.literal(id))); diff --git a/lib/6to5/transformation/transformers/spec-no-duplicate-properties.js b/lib/6to5/transformation/transformers/spec-no-duplicate-properties.js index 6bbfb3b2f9..6c7e93e761 100644 --- a/lib/6to5/transformation/transformers/spec-no-duplicate-properties.js +++ b/lib/6to5/transformation/transformers/spec-no-duplicate-properties.js @@ -1,11 +1,11 @@ var t = require("../../types"); -var _ = require("lodash"); exports.ObjectExpression = function (node, parent, file) { var keys = []; - _.each(node.properties, function (prop) { - if (prop.computed || prop.kind !== "init") return; + for (var i in node.properties) { + var prop = node.properties[i]; + if (prop.computed || prop.kind !== "init") continue; var key = prop.key; if (t.isIdentifier(key)) { @@ -13,13 +13,13 @@ exports.ObjectExpression = function (node, parent, file) { } else if (t.isLiteral(key)) { key = key.value; } else { - return; + continue; } - if (_.contains(keys, key)) { + if (keys.indexOf(key) >= 0) { throw file.errorWithNode(prop.key, "Duplicate property key"); } else { keys.push(key); } - }); + } }; diff --git a/lib/6to5/types/builder-keys.json b/lib/6to5/types/builder-keys.json index 1d7484b568..997476ba00 100644 --- a/lib/6to5/types/builder-keys.json +++ b/lib/6to5/types/builder-keys.json @@ -1,5 +1,6 @@ { "ArrayExpression": ["elements"], + "ArrowFunctionExpression": ["params", "body"], "AssignmentExpression": ["operator", "left", "right"], "BinaryExpression": ["operator", "left", "right"], "BlockStatement": ["body"], diff --git a/lib/6to5/types/index.js b/lib/6to5/types/index.js index 96cceddb6b..323e985ac8 100644 --- a/lib/6to5/types/index.js +++ b/lib/6to5/types/index.js @@ -45,20 +45,20 @@ _.each(t.BUILDER_KEYS, function (keys, type) { t.ALIAS_KEYS = require("./alias-keys"); -var _aliases = {}; +t.FLIPPED_ALIAS_KEYS = {}; _.each(t.ALIAS_KEYS, function (aliases, type) { _.each(aliases, function (alias) { - var types = _aliases[alias] = _aliases[alias] || []; + var types = t.FLIPPED_ALIAS_KEYS[alias] = t.FLIPPED_ALIAS_KEYS[alias] || []; types.push(type); }); }); -_.each(_aliases, function (types, type) { +_.each(t.FLIPPED_ALIAS_KEYS, function (types, type) { t[type.toUpperCase() + "_TYPES"] = types; var is = t["is" + type] = function (node, opts) { - return node && _.contains(types, node.type) && t.shallowEqual(node, opts); + return node && types.indexOf(node.type) >= 0 && t.shallowEqual(node, opts); }; addAssert(type, is); From fe918a3535f485981ed25d6bfee00fca0cf07d4d Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Mon, 15 Dec 2014 14:00:04 +1100 Subject: [PATCH 073/139] add async generator functions to docs --- doc/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/index.md b/doc/index.md index 7280935055..c6205dd5af 100644 --- a/doc/index.md +++ b/doc/index.md @@ -38,6 +38,7 @@ And it doesn't end here! To see all the ways you can use 6to5, check out the - [Abstract references](features.md#abstract-references) ([experimental](experimental.md)) - [Array comprehension](features.md#array-comprehension) ([experimental](experimental.md)) - [Async functions](features.md#async-functions) ([experimental](experimental.md)) + - [Async generator functions](features.md#async-generator-functions) ([experimental](experimental.md)) - [Arrow functions](features.md#arrow-functions) - [Classes](features.md#classes) - [Computed property names](features.md#computed-property-names) From 01286ebd5b029b4215e31d5ff909abbf28174971 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Mon, 15 Dec 2014 14:00:14 +1100 Subject: [PATCH 074/139] add custom regenerator runtime to build process --- Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile b/Makefile index 2c784cc090..f482af434d 100644 --- a/Makefile +++ b/Makefile @@ -52,6 +52,9 @@ build: node bin/cache-templates + node $(BROWSERIFY_CMD) -e lib/6to5/transformation/transformers/es6-generators/runtime.js >dist/regenerator-runtime.js + node $(UGLIFY_CMD) dist/regenerator-runtime.js >dist/regenerator-runtime.min.js + node $(BROWSERIFY_CMD) -e lib/6to5/polyfill.js >dist/polyfill.js node $(UGLIFY_CMD) dist/polyfill.js >dist/polyfill.min.js @@ -72,6 +75,7 @@ publish: cp dist/6to5.min.js browser.js cp dist/polyfill.min.js browser-polyfill.js cp dist/runtime.min.js runtime.js + cp dist/regenerator-runtime.min.js regenerator-runtime.js node bin/cache-templates test -f templates.json From 363b1631f5a3455df85577cb6ebb9e5aec540942 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Mon, 15 Dec 2014 14:00:41 +1100 Subject: [PATCH 075/139] switch to core-js from es6-symbol and es6-shim Conflicts: lib/6to5/polyfill.js --- doc/polyfill.md | 9 ++++----- lib/6to5/polyfill.js | 41 ++++++++++------------------------------- package.json | 3 +-- test/transformation.js | 4 ++-- 4 files changed, 17 insertions(+), 40 deletions(-) diff --git a/doc/polyfill.md b/doc/polyfill.md index 631f9adb73..47bbbcd521 100644 --- a/doc/polyfill.md +++ b/doc/polyfill.md @@ -1,12 +1,11 @@ # Polyfill -6to5 includes a polyfill that includes the -[regenerator runtime](https://github.com/facebook/regenerator/blob/master/runtime.js) and the -[es6-shim](https://github.com/paulmillr/es6-shim) and -[es6-symbol](https://github.com/medikoo/es6-symbol) polyfills. +6to5 includes a polyfill that includes a custom +[regenerator runtime](https://github.com/facebook/regenerator/blob/master/runtime.js) and +[core.js](https://github.com/zloirock/core-js). This will emulate a full ES6 environment. This polyfill is automatically loaded -when using [6to5-node](usage.md#node). +when using [6to5-node](usage.md#node) and [6to5/register](usage.md#register-hook). ## Usage diff --git a/lib/6to5/polyfill.js b/lib/6to5/polyfill.js index 9e98ba264a..74d40a296c 100644 --- a/lib/6to5/polyfill.js +++ b/lib/6to5/polyfill.js @@ -1,37 +1,16 @@ /* jshint newcap: false */ +require("core-js/shim"); +require("./transformation/transformers/es6-generators/runtime"); + var ensureSymbol = function (key) { Symbol[key] = Symbol[key] || Symbol(); }; -var ensureProto = function (Constructor, key, val) { - var proto = Constructor.prototype; - proto[key] = proto[key] || val; -}; - -// - -if (typeof Symbol === "undefined") { - require("es6-symbol/implement"); -} - -require("es6-shim"); -require("./transformation/transformers/es6-generators/runtime"); - -// Abstract references - -ensureSymbol("referenceGet"); -ensureSymbol("referenceSet"); -ensureSymbol("referenceDelete"); - -ensureProto(Function, Symbol.referenceGet, function () { return this; }); - -ensureProto(Map, Symbol.referenceGet, Map.prototype.get); -ensureProto(Map, Symbol.referenceSet, Map.prototype.set); -ensureProto(Map, Symbol.referenceDelete, Map.prototype.delete); - -if (global.WeakMap) { - ensureProto(WeakMap, Symbol.referenceGet, WeakMap.prototype.get); - ensureProto(WeakMap, Symbol.referenceSet, WeakMap.prototype.set); - ensureProto(WeakMap, Symbol.referenceDelete, WeakMap.prototype.delete); -} +ensureSymbol("species"); +ensureSymbol("hasInstance"); +ensureSymbol("isConcatSpreadable"); +ensureSymbol("isRegExp"); +ensureSymbol("toPrimitive"); +ensureSymbol("toStringTag"); +ensureSymbol("unscopables"); diff --git a/package.json b/package.json index 6b825114b2..7c00d4f611 100644 --- a/package.json +++ b/package.json @@ -39,8 +39,7 @@ "ast-types": "0.6.5", "chokidar": "0.11.1", "commander": "2.5.0", - "es6-shim": "0.21.0", - "es6-symbol": "0.1.1", + "core-js": "^0.2.2", "estraverse": "1.8.0", "esutils": "1.1.6", "fs-readdir-recursive": "0.1.0", diff --git a/test/transformation.js b/test/transformation.js index 388097e447..582ef49e4c 100644 --- a/test/transformation.js +++ b/test/transformation.js @@ -7,6 +7,8 @@ var chai = require("chai"); var util = require("../lib/6to5/util"); var _ = require("lodash"); +require("../lib/6to5/polyfill"); + var run = function (task, done) { var actual = task.actual; var expect = task.expect; @@ -27,8 +29,6 @@ var run = function (task, done) { result = transform(execCode, getOpts(exec)); execCode = result.code; - require("../lib/6to5/polyfill"); - try { var fn = new Function("assert", "done", "genHelpers", execCode); fn(assert, done, genHelpers); From 778b4e3a27c63284453e75d0711fd0fbca431a5d Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Mon, 15 Dec 2014 14:16:18 +1100 Subject: [PATCH 076/139] remove commonStrict module formatter --- doc/modules.md | 61 +++++-------------- .../transformation/modules/common-strict.js | 46 -------------- lib/6to5/transformation/modules/common.js | 47 ++++++++++---- lib/6to5/transformation/transform.js | 11 ++-- .../exports-default/actual.js | 8 --- .../exports-default/expected.js | 15 ----- .../exports-from/actual.js | 6 -- .../exports-from/expected.js | 15 ----- .../exports-named/actual.js | 5 -- .../exports-named/expected.js | 9 --- .../exports-variable/actual.js | 8 --- .../exports-variable/expected.js | 13 ---- .../hoist-function-exports/actual.js | 11 ---- .../hoist-function-exports/expected.js | 13 ---- .../imports-default/actual.js | 2 - .../imports-default/expected.js | 4 -- .../imports-glob/actual.js | 1 - .../imports-glob/expected.js | 3 - .../imports-mixing/actual.js | 1 - .../imports-mixing/expected.js | 4 -- .../imports-named/actual.js | 4 -- .../imports-named/expected.js | 8 --- .../imports/actual.js | 3 - .../imports/expected.js | 7 --- .../es6-modules-common-strict/options.json | 3 - .../overview/actual.js | 12 ---- .../overview/expected.js | 17 ------ 27 files changed, 56 insertions(+), 281 deletions(-) delete mode 100644 lib/6to5/transformation/modules/common-strict.js delete mode 100644 test/fixtures/transformation/es6-modules-common-strict/exports-default/actual.js delete mode 100644 test/fixtures/transformation/es6-modules-common-strict/exports-default/expected.js delete mode 100644 test/fixtures/transformation/es6-modules-common-strict/exports-from/actual.js delete mode 100644 test/fixtures/transformation/es6-modules-common-strict/exports-from/expected.js delete mode 100644 test/fixtures/transformation/es6-modules-common-strict/exports-named/actual.js delete mode 100644 test/fixtures/transformation/es6-modules-common-strict/exports-named/expected.js delete mode 100644 test/fixtures/transformation/es6-modules-common-strict/exports-variable/actual.js delete mode 100644 test/fixtures/transformation/es6-modules-common-strict/exports-variable/expected.js delete mode 100644 test/fixtures/transformation/es6-modules-common-strict/hoist-function-exports/actual.js delete mode 100644 test/fixtures/transformation/es6-modules-common-strict/hoist-function-exports/expected.js delete mode 100644 test/fixtures/transformation/es6-modules-common-strict/imports-default/actual.js delete mode 100644 test/fixtures/transformation/es6-modules-common-strict/imports-default/expected.js delete mode 100644 test/fixtures/transformation/es6-modules-common-strict/imports-glob/actual.js delete mode 100644 test/fixtures/transformation/es6-modules-common-strict/imports-glob/expected.js delete mode 100644 test/fixtures/transformation/es6-modules-common-strict/imports-mixing/actual.js delete mode 100644 test/fixtures/transformation/es6-modules-common-strict/imports-mixing/expected.js delete mode 100644 test/fixtures/transformation/es6-modules-common-strict/imports-named/actual.js delete mode 100644 test/fixtures/transformation/es6-modules-common-strict/imports-named/expected.js delete mode 100644 test/fixtures/transformation/es6-modules-common-strict/imports/actual.js delete mode 100644 test/fixtures/transformation/es6-modules-common-strict/imports/expected.js delete mode 100644 test/fixtures/transformation/es6-modules-common-strict/options.json delete mode 100644 test/fixtures/transformation/es6-modules-common-strict/overview/actual.js delete mode 100644 test/fixtures/transformation/es6-modules-common-strict/overview/expected.js diff --git a/doc/modules.md b/doc/modules.md index 7ce8b20d07..08dff4c8c4 100644 --- a/doc/modules.md +++ b/doc/modules.md @@ -19,7 +19,6 @@ to5.transform('import "foo";', { modules: "common" }); * [AMD](#amd) * [Common (Default)](#common-default) - * [Common Strict](#common-strict) * [Ignore](#ignore) * [System](#system) * [UMD](#umd) @@ -71,46 +70,6 @@ var bar = require("foo").bar; var bar = require("foo").foo; ``` -### Common Strict - -```sh -$ 6to5 --modules commonStrict -``` - -**In** - -```javascript -import "foo"; - -import foo from "foo"; -import * as foo from "foo"; - -import {bar} from "foo"; -import {foo as bar} from "foo"; - -export {test}; -export var test = 5; - -export default test; -``` - -**Out** - -```javascript -require("foo"); - -var foo = require("foo").default; -var foo = require("foo"); - -var bar = require("foo").bar; -var bar = require("foo").foo; - -exports.test = test; -var test = 5; exports.test = test; - -exports.default = test; -``` - ### AMD ```sh @@ -131,9 +90,14 @@ export function bar() { ```javascript define(["exports", "foo"], function (exports, _foo) { - exports.bar = bar; + "use strict"; - var foo = _foo.default; + var _interopRequire = function (obj) { + return obj && (obj["default"] || obj); + }; + + exports.bar = bar; + var foo = _interopRequire(_foo); function bar() { return foo("foobar"); @@ -172,10 +136,15 @@ export function bar() { } else if (typeof exports !== "undefined") { factory(exports, require("foo")); } -})(function (exports) { - exports.bar = bar; +})(function (exports, _foo) { + "use strict"; - var foo = _foo.default; + var _interopRequire = function (obj) { + return obj && (obj["default"] || obj); + }; + + exports.bar = bar; + var foo = _interopRequire(_foo); function bar() { return foo("foobar"); diff --git a/lib/6to5/transformation/modules/common-strict.js b/lib/6to5/transformation/modules/common-strict.js deleted file mode 100644 index eb58cb6d75..0000000000 --- a/lib/6to5/transformation/modules/common-strict.js +++ /dev/null @@ -1,46 +0,0 @@ -module.exports = CommonJSStrictFormatter; - -var DefaultFormatter = require("./_default"); -var util = require("../../util"); -var t = require("../../types"); - -function CommonJSStrictFormatter() { - DefaultFormatter.apply(this, arguments); -} - -util.inherits(CommonJSStrictFormatter, DefaultFormatter); - -CommonJSStrictFormatter.prototype.import = function (node, nodes) { - // import "foo"; - nodes.push(util.template("require", { - //inherits: node, - - MODULE_NAME: node.source.raw - }, true)); -}; - -CommonJSStrictFormatter.prototype.importSpecifier = function (specifier, node, nodes) { - var variableName = t.getSpecifierName(specifier); - - // import foo from "foo"; - if (specifier.default) { - specifier.id = t.identifier("default"); - } - - var templateName = "require-assign"; - - // import * as bar from "foo"; - if (specifier.type !== "ImportBatchSpecifier") templateName += "-key"; - - nodes.push(util.template(templateName, { - VARIABLE_NAME: variableName, - MODULE_NAME: node.source.raw, - KEY: specifier.id - })); -}; - -CommonJSStrictFormatter.prototype.exportSpecifier = function (specifier, node, nodes) { - this._exportSpecifier(function () { - return t.callExpression(t.identifier("require"), [node.source]); - }, specifier, node, nodes); -}; diff --git a/lib/6to5/transformation/modules/common.js b/lib/6to5/transformation/modules/common.js index 6676511919..4b422d0794 100644 --- a/lib/6to5/transformation/modules/common.js +++ b/lib/6to5/transformation/modules/common.js @@ -1,12 +1,12 @@ module.exports = CommonJSFormatter; -var CommonJSStrictFormatter = require("./common-strict"); -var util = require("../../util"); -var t = require("../../types"); -var _ = require("lodash"); +var DefaultFormatter = require("./_default"); +var util = require("../../util"); +var t = require("../../types"); +var _ = require("lodash"); function CommonJSFormatter(file) { - CommonJSStrictFormatter.apply(this, arguments); + DefaultFormatter.apply(this, arguments); var hasNonDefaultExports = false; _.each(file.ast.program.body, function (node) { @@ -15,13 +15,13 @@ function CommonJSFormatter(file) { this.hasNonDefaultExports = hasNonDefaultExports; } -util.inherits(CommonJSFormatter, CommonJSStrictFormatter); +util.inherits(CommonJSFormatter, DefaultFormatter); CommonJSFormatter.prototype.importSpecifier = function (specifier, node, nodes) { var variableName = t.getSpecifierName(specifier); // import foo from "foo"; - if (t.isIdentifier(specifier.id) && specifier.id.name === "default") { + if (t.isSpecifierDefault(specifier)) { nodes.push(t.variableDeclaration("var", [ t.variableDeclarator(variableName, t.callExpression(this.file.addDeclaration("interop-require"), [util.template("require", { @@ -30,10 +30,33 @@ CommonJSFormatter.prototype.importSpecifier = function (specifier, node, nodes) ) ])); } else { - CommonJSStrictFormatter.prototype.importSpecifier.apply(this, arguments); + // import foo from "foo"; + if (specifier.default) { + specifier.id = t.identifier("default"); + } + + var templateName = "require-assign"; + + // import * as bar from "foo"; + if (specifier.type !== "ImportBatchSpecifier") templateName += "-key"; + + nodes.push(util.template(templateName, { + VARIABLE_NAME: variableName, + MODULE_NAME: node.source.raw, + KEY: specifier.id + })); } }; +CommonJSFormatter.prototype.import = function (node, nodes) { + // import "foo"; + nodes.push(util.template("require", { + //inherits: node, + + MODULE_NAME: node.source.raw + }, true)); +}; + CommonJSFormatter.prototype.export = function (node, nodes) { if (node.default) { var declar = node.declaration; @@ -51,10 +74,12 @@ CommonJSFormatter.prototype.export = function (node, nodes) { // hoist to the top if this default is a function nodes.push(this._hoistExport(declar, assign)); } else { - CommonJSStrictFormatter.prototype.export.apply(this, arguments); + DefaultFormatter.prototype.export.apply(this, arguments); } }; -CommonJSFormatter.prototype.exportSpecifier = function () { - CommonJSStrictFormatter.prototype.exportSpecifier.apply(this, arguments); +CommonJSFormatter.prototype.exportSpecifier = function (specifier, node, nodes) { + this._exportSpecifier(function () { + return t.callExpression(t.identifier("require"), [node.source]); + }, specifier, node, nodes); }; diff --git a/lib/6to5/transformation/transform.js b/lib/6to5/transformation/transform.js index 87a8edfa7c..0d2440e3f6 100644 --- a/lib/6to5/transformation/transform.js +++ b/lib/6to5/transformation/transform.js @@ -30,12 +30,11 @@ transform._ensureTransformerNames = function (type, keys) { transform.transformers = {}; transform.moduleFormatters = { - commonStrict: require("./modules/common-strict"), - common: require("./modules/common"), - system: require("./modules/system"), - ignore: require("./modules/ignore"), - amd: require("./modules/amd"), - umd: require("./modules/umd") + common: require("./modules/common"), + system: require("./modules/system"), + ignore: require("./modules/ignore"), + amd: require("./modules/amd"), + umd: require("./modules/umd") }; _.each({ diff --git a/test/fixtures/transformation/es6-modules-common-strict/exports-default/actual.js b/test/fixtures/transformation/es6-modules-common-strict/exports-default/actual.js deleted file mode 100644 index 62923e5c15..0000000000 --- a/test/fixtures/transformation/es6-modules-common-strict/exports-default/actual.js +++ /dev/null @@ -1,8 +0,0 @@ -export default 42; -export default {}; -export default []; -export default foo; -export default function () {} -export default class {} -export default function foo () {} -export default class Foo {} diff --git a/test/fixtures/transformation/es6-modules-common-strict/exports-default/expected.js b/test/fixtures/transformation/es6-modules-common-strict/exports-default/expected.js deleted file mode 100644 index 8c68ab4224..0000000000 --- a/test/fixtures/transformation/es6-modules-common-strict/exports-default/expected.js +++ /dev/null @@ -1,15 +0,0 @@ -"use strict"; - -exports["default"] = 42; -exports["default"] = {}; -exports["default"] = []; -exports["default"] = foo; -exports["default"] = function () {}; - -exports["default"] = function () {}; - -function foo() {} -exports["default"] = foo; -var Foo = function Foo() {}; - -exports["default"] = Foo; diff --git a/test/fixtures/transformation/es6-modules-common-strict/exports-from/actual.js b/test/fixtures/transformation/es6-modules-common-strict/exports-from/actual.js deleted file mode 100644 index 60857f6542..0000000000 --- a/test/fixtures/transformation/es6-modules-common-strict/exports-from/actual.js +++ /dev/null @@ -1,6 +0,0 @@ -export * from "foo"; -export {foo} from "foo"; -export {foo, bar} from "foo"; -export {foo as bar} from "foo"; -export {foo as default} from "foo"; -export {foo as default, bar} from "foo"; diff --git a/test/fixtures/transformation/es6-modules-common-strict/exports-from/expected.js b/test/fixtures/transformation/es6-modules-common-strict/exports-from/expected.js deleted file mode 100644 index feaeac94ee..0000000000 --- a/test/fixtures/transformation/es6-modules-common-strict/exports-from/expected.js +++ /dev/null @@ -1,15 +0,0 @@ -"use strict"; - -(function (obj) { - for (var i in obj) { - exports[i] = obj[i]; - } -})(require("foo")); - -exports.foo = require("foo").foo; -exports.foo = require("foo").foo; -exports.bar = require("foo").bar; -exports.bar = require("foo").foo; -exports["default"] = require("foo").foo; -exports["default"] = require("foo").foo; -exports.bar = require("foo").bar; diff --git a/test/fixtures/transformation/es6-modules-common-strict/exports-named/actual.js b/test/fixtures/transformation/es6-modules-common-strict/exports-named/actual.js deleted file mode 100644 index 8515ace759..0000000000 --- a/test/fixtures/transformation/es6-modules-common-strict/exports-named/actual.js +++ /dev/null @@ -1,5 +0,0 @@ -export {foo}; -export {foo, bar}; -export {foo as bar}; -export {foo as default}; -export {foo as default, bar}; diff --git a/test/fixtures/transformation/es6-modules-common-strict/exports-named/expected.js b/test/fixtures/transformation/es6-modules-common-strict/exports-named/expected.js deleted file mode 100644 index ce378a6fb0..0000000000 --- a/test/fixtures/transformation/es6-modules-common-strict/exports-named/expected.js +++ /dev/null @@ -1,9 +0,0 @@ -"use strict"; - -exports.foo = foo; -exports.foo = foo; -exports.bar = bar; -exports.bar = foo; -exports["default"] = foo; -exports["default"] = foo; -exports.bar = bar; diff --git a/test/fixtures/transformation/es6-modules-common-strict/exports-variable/actual.js b/test/fixtures/transformation/es6-modules-common-strict/exports-variable/actual.js deleted file mode 100644 index b4629cc731..0000000000 --- a/test/fixtures/transformation/es6-modules-common-strict/exports-variable/actual.js +++ /dev/null @@ -1,8 +0,0 @@ -export var foo = 1; -export var foo2 = function () {}; -export var foo3; -export let foo4 = 2; -export let foo5; -export const foo6 = 3; -export function foo7 () {} -export class foo8 {} diff --git a/test/fixtures/transformation/es6-modules-common-strict/exports-variable/expected.js b/test/fixtures/transformation/es6-modules-common-strict/exports-variable/expected.js deleted file mode 100644 index 42e6fdf913..0000000000 --- a/test/fixtures/transformation/es6-modules-common-strict/exports-variable/expected.js +++ /dev/null @@ -1,13 +0,0 @@ -"use strict"; - -exports.foo7 = foo7; -var foo = exports.foo = 1; -var foo2 = exports.foo2 = function () {}; -var foo3 = exports.foo3 = undefined; -var foo4 = exports.foo4 = 2; -var foo5 = exports.foo5 = undefined; -var foo6 = exports.foo6 = 3; -function foo7() {} -var foo8 = function foo8() {}; - -exports.foo8 = foo8; diff --git a/test/fixtures/transformation/es6-modules-common-strict/hoist-function-exports/actual.js b/test/fixtures/transformation/es6-modules-common-strict/hoist-function-exports/actual.js deleted file mode 100644 index 3c40b7d1c1..0000000000 --- a/test/fixtures/transformation/es6-modules-common-strict/hoist-function-exports/actual.js +++ /dev/null @@ -1,11 +0,0 @@ -import { isEven } from "./evens"; - -export function nextOdd(n) { - return isEven(n) ? n + 1 : n + 2; -} - -export var isOdd = (function (isEven) { - return function (n) { - return !isEven(n); - }; -})(isEven); diff --git a/test/fixtures/transformation/es6-modules-common-strict/hoist-function-exports/expected.js b/test/fixtures/transformation/es6-modules-common-strict/hoist-function-exports/expected.js deleted file mode 100644 index 5a074e1496..0000000000 --- a/test/fixtures/transformation/es6-modules-common-strict/hoist-function-exports/expected.js +++ /dev/null @@ -1,13 +0,0 @@ -"use strict"; - -exports.nextOdd = nextOdd; -var isEven = require("./evens").isEven; -function nextOdd(n) { - return isEven(n) ? n + 1 : n + 2; -} - -var isOdd = exports.isOdd = (function (isEven) { - return function (n) { - return !isEven(n); - }; -})(isEven); diff --git a/test/fixtures/transformation/es6-modules-common-strict/imports-default/actual.js b/test/fixtures/transformation/es6-modules-common-strict/imports-default/actual.js deleted file mode 100644 index e67418654c..0000000000 --- a/test/fixtures/transformation/es6-modules-common-strict/imports-default/actual.js +++ /dev/null @@ -1,2 +0,0 @@ -import foo from "foo"; -import {default as foo} from "foo"; diff --git a/test/fixtures/transformation/es6-modules-common-strict/imports-default/expected.js b/test/fixtures/transformation/es6-modules-common-strict/imports-default/expected.js deleted file mode 100644 index 32db9b239c..0000000000 --- a/test/fixtures/transformation/es6-modules-common-strict/imports-default/expected.js +++ /dev/null @@ -1,4 +0,0 @@ -"use strict"; - -var foo = require("foo")["default"]; -var foo = require("foo")["default"]; diff --git a/test/fixtures/transformation/es6-modules-common-strict/imports-glob/actual.js b/test/fixtures/transformation/es6-modules-common-strict/imports-glob/actual.js deleted file mode 100644 index e55c077500..0000000000 --- a/test/fixtures/transformation/es6-modules-common-strict/imports-glob/actual.js +++ /dev/null @@ -1 +0,0 @@ -import * as foo from "foo"; diff --git a/test/fixtures/transformation/es6-modules-common-strict/imports-glob/expected.js b/test/fixtures/transformation/es6-modules-common-strict/imports-glob/expected.js deleted file mode 100644 index 3293bd0ebd..0000000000 --- a/test/fixtures/transformation/es6-modules-common-strict/imports-glob/expected.js +++ /dev/null @@ -1,3 +0,0 @@ -"use strict"; - -var foo = require("foo"); diff --git a/test/fixtures/transformation/es6-modules-common-strict/imports-mixing/actual.js b/test/fixtures/transformation/es6-modules-common-strict/imports-mixing/actual.js deleted file mode 100644 index ef78c95b1c..0000000000 --- a/test/fixtures/transformation/es6-modules-common-strict/imports-mixing/actual.js +++ /dev/null @@ -1 +0,0 @@ -import foo, {baz as xyz} from "foo"; diff --git a/test/fixtures/transformation/es6-modules-common-strict/imports-mixing/expected.js b/test/fixtures/transformation/es6-modules-common-strict/imports-mixing/expected.js deleted file mode 100644 index 57bcfd38fc..0000000000 --- a/test/fixtures/transformation/es6-modules-common-strict/imports-mixing/expected.js +++ /dev/null @@ -1,4 +0,0 @@ -"use strict"; - -var foo = require("foo")["default"]; -var xyz = require("foo").baz; diff --git a/test/fixtures/transformation/es6-modules-common-strict/imports-named/actual.js b/test/fixtures/transformation/es6-modules-common-strict/imports-named/actual.js deleted file mode 100644 index 83a766c62d..0000000000 --- a/test/fixtures/transformation/es6-modules-common-strict/imports-named/actual.js +++ /dev/null @@ -1,4 +0,0 @@ -import {bar} from "foo"; -import {bar, baz} from "foo"; -import {bar as baz} from "foo"; -import {bar as baz, xyz} from "foo"; diff --git a/test/fixtures/transformation/es6-modules-common-strict/imports-named/expected.js b/test/fixtures/transformation/es6-modules-common-strict/imports-named/expected.js deleted file mode 100644 index 9a51dccc06..0000000000 --- a/test/fixtures/transformation/es6-modules-common-strict/imports-named/expected.js +++ /dev/null @@ -1,8 +0,0 @@ -"use strict"; - -var bar = require("foo").bar; -var bar = require("foo").bar; -var baz = require("foo").baz; -var baz = require("foo").bar; -var baz = require("foo").bar; -var xyz = require("foo").xyz; diff --git a/test/fixtures/transformation/es6-modules-common-strict/imports/actual.js b/test/fixtures/transformation/es6-modules-common-strict/imports/actual.js deleted file mode 100644 index 222b6885ac..0000000000 --- a/test/fixtures/transformation/es6-modules-common-strict/imports/actual.js +++ /dev/null @@ -1,3 +0,0 @@ -import "foo"; -import "foo-bar"; -import "./directory/foo-bar"; diff --git a/test/fixtures/transformation/es6-modules-common-strict/imports/expected.js b/test/fixtures/transformation/es6-modules-common-strict/imports/expected.js deleted file mode 100644 index f1a139f51a..0000000000 --- a/test/fixtures/transformation/es6-modules-common-strict/imports/expected.js +++ /dev/null @@ -1,7 +0,0 @@ -"use strict"; - -require("foo"); - -require("foo-bar"); - -require("./directory/foo-bar"); diff --git a/test/fixtures/transformation/es6-modules-common-strict/options.json b/test/fixtures/transformation/es6-modules-common-strict/options.json deleted file mode 100644 index 42fca89301..0000000000 --- a/test/fixtures/transformation/es6-modules-common-strict/options.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "modules": "commonStrict" -} diff --git a/test/fixtures/transformation/es6-modules-common-strict/overview/actual.js b/test/fixtures/transformation/es6-modules-common-strict/overview/actual.js deleted file mode 100644 index a77d4d5dfa..0000000000 --- a/test/fixtures/transformation/es6-modules-common-strict/overview/actual.js +++ /dev/null @@ -1,12 +0,0 @@ -import "foo"; -import "foo-bar"; -import "./directory/foo-bar"; -import foo from "foo"; -import * as foo from "foo"; -import {bar} from "foo"; -import {foo as bar} from "foo"; - -export {test}; -export var test = 5; - -export default test; diff --git a/test/fixtures/transformation/es6-modules-common-strict/overview/expected.js b/test/fixtures/transformation/es6-modules-common-strict/overview/expected.js deleted file mode 100644 index 614b23e905..0000000000 --- a/test/fixtures/transformation/es6-modules-common-strict/overview/expected.js +++ /dev/null @@ -1,17 +0,0 @@ -"use strict"; - -require("foo"); - -require("foo-bar"); - -require("./directory/foo-bar"); - -var foo = require("foo")["default"]; -var foo = require("foo"); - -var bar = require("foo").bar; -var bar = require("foo").foo; -exports.test = test; -var test = exports.test = 5; - -exports["default"] = test; From e31e68cae3aee7460243727fdf3b23c3f72c1835 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Mon, 15 Dec 2014 14:16:34 +1100 Subject: [PATCH 077/139] use types.isSpecifierDefault in amd modules formatter --- lib/6to5/transformation/modules/amd.js | 2 +- lib/6to5/types/index.js | 4 ++++ .../es6-modules-amd/imports-default/expected.js | 2 +- .../es6-modules-umd/imports-default/expected.js | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/6to5/transformation/modules/amd.js b/lib/6to5/transformation/modules/amd.js index 9a26d52b8f..60a18b4166 100644 --- a/lib/6to5/transformation/modules/amd.js +++ b/lib/6to5/transformation/modules/amd.js @@ -78,7 +78,7 @@ AMDFormatter.prototype.importSpecifier = function (specifier, node, nodes) { if (t.isImportBatchSpecifier(specifier)) { // import * as bar from "foo"; - } else if (specifier.default) { + } else if (t.isSpecifierDefault(specifier)) { // import foo from "foo"; ref = t.callExpression(this.file.addDeclaration("interop-require"), [ref]); } else { diff --git a/lib/6to5/types/index.js b/lib/6to5/types/index.js index 323e985ac8..65fb12bedc 100644 --- a/lib/6to5/types/index.js +++ b/lib/6to5/types/index.js @@ -307,3 +307,7 @@ t.inherits = function (child, parent) { t.getSpecifierName = function (specifier) { return specifier.name || specifier.id; }; + +t.isSpecifierDefault = function (specifier) { + return t.isIdentifier(specifier.id) && specifier.id.name === "default"; +}; diff --git a/test/fixtures/transformation/es6-modules-amd/imports-default/expected.js b/test/fixtures/transformation/es6-modules-amd/imports-default/expected.js index 43e1ab9d53..b19c21fa34 100644 --- a/test/fixtures/transformation/es6-modules-amd/imports-default/expected.js +++ b/test/fixtures/transformation/es6-modules-amd/imports-default/expected.js @@ -7,5 +7,5 @@ define(["exports", "foo"], function (exports, _foo) { var foo = _interopRequire(_foo); - var foo = _foo["default"]; + var foo = _interopRequire(_foo); }); diff --git a/test/fixtures/transformation/es6-modules-umd/imports-default/expected.js b/test/fixtures/transformation/es6-modules-umd/imports-default/expected.js index b68de76392..83402d6e59 100644 --- a/test/fixtures/transformation/es6-modules-umd/imports-default/expected.js +++ b/test/fixtures/transformation/es6-modules-umd/imports-default/expected.js @@ -13,5 +13,5 @@ var foo = _interopRequire(_foo); - var foo = _foo["default"]; + var foo = _interopRequire(_foo); }); From e01e01057799512c93cc474db7123112babb78f8 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Mon, 15 Dec 2014 18:53:50 +1100 Subject: [PATCH 078/139] add 2.0.0 changelog --- CHANGELOG.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d3736834d9..6b6068e158 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,37 @@ Gaps between patch versions are faulty/broken releases. +## 2.0.0 + + * Make string literal generation only escapes unicode that it has to. + * Internal code generation format options have been exposed. + * Change playground method binding operator from `:` to `#` removing ambiguous syntax with terns. + * Fix rest parameters in async and generator functions. + * Export/import declarations replace by the modules transformer now inherit comments. + * Added playground flag to `6to5-node`. + * `6to5-node` now behaves the same as `node`. + * `6to5-node` now uses `kexec` to become the forked process to correctly propagate signals on unix. + * Constants are now block scoped. + * Exposed ast transformer. + * Merged `commonInterop` and `common` module formatters. + * Fix generator comprehensions not inheriting `arguments`, `this` etc. + * Object and class mutator shorthand are now enumerable. + * Remove regenerator `Generator has already finished` error which isn't spec-compliant. + * Expose internal `spec` transformers that nicen up code output. + * Add export variable declaration default initializers. + * Propagate export declaration reassignments. + * Add initializer default to block scoped variable declarations within a loop. + * Flow type support. + * Make async/await contextual keywords. + * Allow `yield`ing of non-objects. + * Class declarations now lack an IIFE. + * Support falsy and `null` super classes. + * Add support for experimental abstract references `private` declarations. + * Leave out IIFE for class declarations. + * Switched to [core-js](https://github.com/zloirock/core-js) over [es6-symbol](https://github.com/medikoo/es6-symbol) and [es6-shim](https://github.com/paulmillr/es6-shim/). + * `amd` and `umd` module formatters now behave the same as `common` with `interopRequire`. + * Micro-optimizations to boost performance by 200%. + ## 1.15.0 * Don't alias `GeneratorFunction` and check the name which causes minifiers to remove the name and throw an error later on when we check if it's set. From a03d491ac60d561d7539bbbb83e6daca818f56c8 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Mon, 15 Dec 2014 22:34:49 +1100 Subject: [PATCH 079/139] microoptimize module formatters, change method names to a new API, and add support for exporting multiple variable declarators - fixes #299 --- doc/modules.md | 4 +-- lib/6to5/transformation/modules/_default.js | 25 +++++++++++-------- lib/6to5/transformation/modules/amd.js | 6 ++--- lib/6to5/transformation/modules/common.js | 10 ++++---- lib/6to5/transformation/modules/ignore.js | 12 +++------ lib/6to5/transformation/modules/umd.js | 4 +-- .../exports-variable/actual.js | 1 + .../exports-variable/expected.js | 2 ++ .../exports-variable/actual.js | 1 + .../exports-variable/expected.js | 2 ++ .../exports-variable/actual.js | 1 + .../exports-variable/expected.js | 1 + .../exports-variable/actual.js | 1 + .../exports-variable/expected.js | 2 ++ 14 files changed, 40 insertions(+), 32 deletions(-) diff --git a/doc/modules.md b/doc/modules.md index 08dff4c8c4..f58c68416f 100644 --- a/doc/modules.md +++ b/doc/modules.md @@ -237,7 +237,7 @@ ModuleFormatter.prototype.transform = function (ast) { // feel free to modify this however }; -ModuleFormatter.prototype.import = function (node, nodes) { +ModuleFormatter.prototype.importDeclaration = function (node, nodes) { // node is an ImportDeclaration }; @@ -246,7 +246,7 @@ ModuleFormatter.prototype.importSpecifier = function (specifier, node, nodes) { // node is an ImportDeclaration }; -ModuleFormatter.prototype.export = function (node, nodes) { +ModuleFormatter.prototype.exportDeclaration = function (node, nodes) { // node is an ExportDeclaration }; diff --git a/lib/6to5/transformation/modules/_default.js b/lib/6to5/transformation/modules/_default.js index 7d3f06c345..2a2d3bbe02 100644 --- a/lib/6to5/transformation/modules/_default.js +++ b/lib/6to5/transformation/modules/_default.js @@ -3,15 +3,14 @@ module.exports = DefaultFormatter; var traverse = require("../../traverse"); var util = require("../../util"); var t = require("../../types"); -var _ = require("lodash"); function DefaultFormatter(file) { this.exports = []; this.file = file; var localExports = []; - _.each(file.ast.program.body, function (node) { - var declar = node.declaration; + traverse(file.ast, function (node) { + var declar = node && node.declaration; if (t.isExportDeclaration(node) && declar && t.isStatement(declar)) { localExports = localExports.concat(t.getIds(declar)); } @@ -29,7 +28,7 @@ DefaultFormatter.prototype.remapAssignments = function () { if (t.isAssignmentExpression(node)) { var left = node.left; - if (t.isIdentifier(left) && _.contains(localExports, left.name)) { + if (t.isIdentifier(left) && localExports.indexOf(left.name) >= 0) { return t.assignmentExpression( "=", left, @@ -119,7 +118,7 @@ DefaultFormatter.prototype._exportSpecifier = function (getRef, specifier, node, } }; -DefaultFormatter.prototype.export = function (node, nodes) { +DefaultFormatter.prototype.exportDeclaration = function (node, nodes) { var declar = node.declaration; if (node.default) { @@ -130,14 +129,18 @@ DefaultFormatter.prototype.export = function (node, nodes) { var assign; if (t.isVariableDeclaration(declar)) { - var decl = declar.declarations[0]; + for (var i in declar.declarations) { + var decl = declar.declarations[i]; - decl.init = util.template("exports-assign", { - VALUE: decl.init, - KEY: decl.id - }); + decl.init = util.template("exports-assign", { + VALUE: decl.init, + KEY: decl.id + }); - nodes.push(declar); + var newDeclar = t.variableDeclaration(declar.kind, [decl]); + if (i == 0) t.inherits(newDeclar, declar); + nodes.push(newDeclar); + } } else { assign = util.template("exports-assign", { VALUE: declar.id, diff --git a/lib/6to5/transformation/modules/amd.js b/lib/6to5/transformation/modules/amd.js index 60a18b4166..2aad3b9a12 100644 --- a/lib/6to5/transformation/modules/amd.js +++ b/lib/6to5/transformation/modules/amd.js @@ -23,9 +23,9 @@ AMDFormatter.prototype.transform = function (ast) { // build an array of module names var names = [t.literal("exports")]; - _.each(this.ids, function (id, name) { + for (var name in this.ids) { names.push(t.literal(name)); - }); + } names = t.arrayExpression(names); // build up define container @@ -68,7 +68,7 @@ AMDFormatter.prototype._push = function (node) { } }; -AMDFormatter.prototype.import = function (node) { +AMDFormatter.prototype.importDeclaration = function (node) { this._push(node); }; diff --git a/lib/6to5/transformation/modules/common.js b/lib/6to5/transformation/modules/common.js index 4b422d0794..2490c7df13 100644 --- a/lib/6to5/transformation/modules/common.js +++ b/lib/6to5/transformation/modules/common.js @@ -1,15 +1,15 @@ module.exports = CommonJSFormatter; var DefaultFormatter = require("./_default"); +var traverse = require("../../traverse"); var util = require("../../util"); var t = require("../../types"); -var _ = require("lodash"); function CommonJSFormatter(file) { DefaultFormatter.apply(this, arguments); var hasNonDefaultExports = false; - _.each(file.ast.program.body, function (node) { + traverse(file.ast, function (node) { if (t.isExportDeclaration(node) && !node.default) hasNonDefaultExports = true; }); this.hasNonDefaultExports = hasNonDefaultExports; @@ -48,7 +48,7 @@ CommonJSFormatter.prototype.importSpecifier = function (specifier, node, nodes) } }; -CommonJSFormatter.prototype.import = function (node, nodes) { +CommonJSFormatter.prototype.importDeclaration = function (node, nodes) { // import "foo"; nodes.push(util.template("require", { //inherits: node, @@ -57,7 +57,7 @@ CommonJSFormatter.prototype.import = function (node, nodes) { }, true)); }; -CommonJSFormatter.prototype.export = function (node, nodes) { +CommonJSFormatter.prototype.exportDeclaration = function (node, nodes) { if (node.default) { var declar = node.declaration; @@ -74,7 +74,7 @@ CommonJSFormatter.prototype.export = function (node, nodes) { // hoist to the top if this default is a function nodes.push(this._hoistExport(declar, assign)); } else { - DefaultFormatter.prototype.export.apply(this, arguments); + DefaultFormatter.prototype.exportDeclaration.apply(this, arguments); } }; diff --git a/lib/6to5/transformation/modules/ignore.js b/lib/6to5/transformation/modules/ignore.js index 28fbb4e026..3753440eed 100644 --- a/lib/6to5/transformation/modules/ignore.js +++ b/lib/6to5/transformation/modules/ignore.js @@ -6,19 +6,13 @@ function IgnoreFormatter() { } -IgnoreFormatter.prototype.import = function () { - -}; - -IgnoreFormatter.prototype.importSpecifier = function () { - -}; - -IgnoreFormatter.prototype.export = function (node, nodes) { +IgnoreFormatter.prototype.exportDeclaration = function (node, nodes) { var declar = t.toStatement(node.declaration, true); if (declar) nodes.push(t.inherits(declar, node)); }; +IgnoreFormatter.prototype.importDeclaration = +IgnoreFormatter.prototype.importSpecifier = IgnoreFormatter.prototype.exportSpecifier = function () { }; diff --git a/lib/6to5/transformation/modules/umd.js b/lib/6to5/transformation/modules/umd.js index 199de38024..e23c7c6fc2 100644 --- a/lib/6to5/transformation/modules/umd.js +++ b/lib/6to5/transformation/modules/umd.js @@ -18,9 +18,9 @@ UMDFormatter.prototype.transform = function (ast) { // build an array of module names var names = []; - _.each(this.ids, function (id, name) { + for (var name in this.ids) { names.push(t.literal(name)); - }); + } // factory diff --git a/test/fixtures/transformation/es6-modules-amd/exports-variable/actual.js b/test/fixtures/transformation/es6-modules-amd/exports-variable/actual.js index b4629cc731..c9cd5af09c 100644 --- a/test/fixtures/transformation/es6-modules-amd/exports-variable/actual.js +++ b/test/fixtures/transformation/es6-modules-amd/exports-variable/actual.js @@ -1,4 +1,5 @@ export var foo = 1; +export var foo = 1, bar = 2; export var foo2 = function () {}; export var foo3; export let foo4 = 2; diff --git a/test/fixtures/transformation/es6-modules-amd/exports-variable/expected.js b/test/fixtures/transformation/es6-modules-amd/exports-variable/expected.js index b959a86bd0..d01bae5920 100644 --- a/test/fixtures/transformation/es6-modules-amd/exports-variable/expected.js +++ b/test/fixtures/transformation/es6-modules-amd/exports-variable/expected.js @@ -3,6 +3,8 @@ define(["exports"], function (exports) { exports.foo7 = foo7; var foo = exports.foo = 1; + var foo = exports.foo = 1; + var bar = exports.bar = 2; var foo2 = exports.foo2 = function () {}; var foo3 = exports.foo3 = undefined; var foo4 = exports.foo4 = 2; diff --git a/test/fixtures/transformation/es6-modules-common/exports-variable/actual.js b/test/fixtures/transformation/es6-modules-common/exports-variable/actual.js index b4629cc731..c9cd5af09c 100644 --- a/test/fixtures/transformation/es6-modules-common/exports-variable/actual.js +++ b/test/fixtures/transformation/es6-modules-common/exports-variable/actual.js @@ -1,4 +1,5 @@ export var foo = 1; +export var foo = 1, bar = 2; export var foo2 = function () {}; export var foo3; export let foo4 = 2; diff --git a/test/fixtures/transformation/es6-modules-common/exports-variable/expected.js b/test/fixtures/transformation/es6-modules-common/exports-variable/expected.js index 42e6fdf913..2c13db0878 100644 --- a/test/fixtures/transformation/es6-modules-common/exports-variable/expected.js +++ b/test/fixtures/transformation/es6-modules-common/exports-variable/expected.js @@ -2,6 +2,8 @@ exports.foo7 = foo7; var foo = exports.foo = 1; +var foo = exports.foo = 1; +var bar = exports.bar = 2; var foo2 = exports.foo2 = function () {}; var foo3 = exports.foo3 = undefined; var foo4 = exports.foo4 = 2; diff --git a/test/fixtures/transformation/es6-modules-ignore/exports-variable/actual.js b/test/fixtures/transformation/es6-modules-ignore/exports-variable/actual.js index b4629cc731..c9cd5af09c 100644 --- a/test/fixtures/transformation/es6-modules-ignore/exports-variable/actual.js +++ b/test/fixtures/transformation/es6-modules-ignore/exports-variable/actual.js @@ -1,4 +1,5 @@ export var foo = 1; +export var foo = 1, bar = 2; export var foo2 = function () {}; export var foo3; export let foo4 = 2; diff --git a/test/fixtures/transformation/es6-modules-ignore/exports-variable/expected.js b/test/fixtures/transformation/es6-modules-ignore/exports-variable/expected.js index ecf4bd267a..854aad79f8 100644 --- a/test/fixtures/transformation/es6-modules-ignore/exports-variable/expected.js +++ b/test/fixtures/transformation/es6-modules-ignore/exports-variable/expected.js @@ -1,6 +1,7 @@ "use strict"; var foo = 1; +var foo = 1, bar = 2; var foo2 = function () {}; var foo3 = undefined; var foo4 = 2; diff --git a/test/fixtures/transformation/es6-modules-umd/exports-variable/actual.js b/test/fixtures/transformation/es6-modules-umd/exports-variable/actual.js index b4629cc731..c9cd5af09c 100644 --- a/test/fixtures/transformation/es6-modules-umd/exports-variable/actual.js +++ b/test/fixtures/transformation/es6-modules-umd/exports-variable/actual.js @@ -1,4 +1,5 @@ export var foo = 1; +export var foo = 1, bar = 2; export var foo2 = function () {}; export var foo3; export let foo4 = 2; diff --git a/test/fixtures/transformation/es6-modules-umd/exports-variable/expected.js b/test/fixtures/transformation/es6-modules-umd/exports-variable/expected.js index 989b8d476b..7cabcda1e3 100644 --- a/test/fixtures/transformation/es6-modules-umd/exports-variable/expected.js +++ b/test/fixtures/transformation/es6-modules-umd/exports-variable/expected.js @@ -9,6 +9,8 @@ exports.foo7 = foo7; var foo = exports.foo = 1; + var foo = exports.foo = 1; + var bar = exports.bar = 2; var foo2 = exports.foo2 = function () {}; var foo3 = exports.foo3 = undefined; var foo4 = exports.foo4 = 2; From 1a4110e0a1b39269e7472b28709eebfcd90e4bbf Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Mon, 15 Dec 2014 22:35:25 +1100 Subject: [PATCH 080/139] categorise differences and elaborate on why they're significant --- doc/differences.md | 78 ++++++++++++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 30 deletions(-) diff --git a/doc/differences.md b/doc/differences.md index 3694acfdff..0102fdeacf 100644 --- a/doc/differences.md +++ b/doc/differences.md @@ -1,6 +1,8 @@ # Differences -## Philosophy +There are three main points that separate 6to5 from all other transpilers. + +### Readable code The fundamental concept behind 6to5 is that the generated code must be close as possible to the original, retaining all the same formatting and readability. @@ -57,6 +59,22 @@ are bother you then you can use the [optional runtime](optional-runtime.md). We promise that these inline functions will never be significant and will always be used as little as possible. +### Static analysis + +6to5 uses a lot of static analysis to simplify code as much as possible. +Not many other transpilers do this, and those that do don't do it nearly +as much as 6to5. This process is pretty intensive but it leads to higher +quality code. + +### Spec compliancy + +6to5 prides itself on +[spec compliancy](https://kangax.github.io/compat-table/es6/). We have +excellent support for edgecases, something that many other transpilers +suffer from, including Traceur. When you use 6to5 you can be confident +that when you turn it off and use your code in a full ES6 environment +**it'll just work**. + ## Comparison to other transpilers ### Features @@ -66,38 +84,38 @@ always be used as little as possible. | Source maps | ✓ | ✓ | ✓ | ✓ | | ✓ | | No compiler global pollution | ✓ | | ✓ | ✓ | | ✓ | | Optional runtime | ✓ | | ✓ | | | ✓ | -| Browser support | ✓ | ✓ | | ✓ | | | +| Browser compiler | ✓ | ✓ | | ✓ | | | ### Language Support -| | 6to5 | Traceur | es6-transpiler | esnext | es6now | jstransform | -| ---------------------------- | ----- | ------- | -------------- | ------ | ------ | ----------- | -| Abstract references | ✓ | | | | | | -| Array comprehension | ✓ | ✓ | ✓ | | | | -| Arrow functions | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Async functions | ✓ | ✓ | | ✓ | | | -| Async generator functions | ✓ | ✓ | | | | | -| Classes | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Computed property names | ✓ | ✓ | ✓ | ✓ | ✓ | | -| Constants | ✓ | ✓ | ✓ | | | | -| Default parameters | ✓ | ✓ | ✓ | ✓ | ✓ | | -| Destructuring | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Exponentiation operator | ✓ | ✓ | | | | | -| Flow types | ✓ | | | | | | -| For-of | ✓ | ✓ | ✓ | ✓ | ✓ | | -| Generators | ✓ | ✓ | | ✓ | | | -| Generator comprehension | ✓ | ✓ | | | | | -| JSX | ✓ | | | | | | -| Let scoping | ✓ | ✓ | ✓ | | | | -| Modules | ✓ | ✓ | | | ✓ | | -| Object rest/spread | ✓ | | | | | ✓ | -| Property method assignment | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Property name shorthand | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Rest parameters | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| React | ✓ | | | | | | -| Spread | ✓ | ✓ | ✓ | ✓ | ✓ | | -| Template literals | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Unicode regex | ✓ | ✓ | ✓ | | | | +| | 6to5 | Traceur | es6-transpiler | esnext | es6now | jstransform | +| ---------------------------- | ---- | ------- | -------------- | ------ | ------ | ----------- | +| Abstract references | ✓ | | | | | | +| Array comprehension | ✓ | ✓ | ✓ | | | | +| Arrow functions | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| Async functions | ✓ | ✓ | | ✓ | | | +| Async generator functions | ✓ | ✓ | | | | | +| Classes | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| Computed property names | ✓ | ✓ | ✓ | ✓ | ✓ | | +| Constants | ✓ | ✓ | ✓ | | | | +| Default parameters | ✓ | ✓ | ✓ | ✓ | ✓ | | +| Destructuring | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| Exponentiation operator | ✓ | ✓ | | | | | +| Flow types | ✓ | | | | | ✓ | +| For-of | ✓ | ✓ | ✓ | ✓ | ✓ | | +| Generators | ✓ | ✓ | | ✓ | | | +| Generator comprehension | ✓ | ✓ | | | | | +| JSX | ✓ | | | | | | +| Let scoping | ✓ | ✓ | ✓ | | | | +| Modules | ✓ | ✓ | | | ✓ | | +| Object rest/spread | ✓ | | | | | ✓ | +| Property method assignment | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| Property name shorthand | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| Rest parameters | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| React | ✓ | | | | | | +| Spread | ✓ | ✓ | ✓ | ✓ | ✓ | | +| Template literals | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| Unicode regex | ✓ | ✓ | ✓ | | | | ### [Traceur](https://github.com/google/traceur-compiler) From 3d975da5307b01feca1fa5fb43e65612c1d3aaa9 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Mon, 15 Dec 2014 22:35:41 +1100 Subject: [PATCH 081/139] remove reference to regenerator runtime and say that the explicit polyfill is required --- doc/caveats.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/doc/caveats.md b/doc/caveats.md index d7431ca9ea..c102733e43 100644 --- a/doc/caveats.md +++ b/doc/caveats.md @@ -4,15 +4,15 @@ In order for certain features to work they require certain polyfills. You can satisfy **all** 6to5 feature requirements by using the included [polyfill](polyfill.md). You may alternatively selectively include what you need: -| Feature | Requirements | -| --------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | -| Abstract References | [experimental](experimental.md), `Symbol` | -| Array destructuring | `Array.isArray`, `Array.from` | -| Async functions, Generators | [experimental](experimental.md), [regenerator runtime](https://github.com/facebook/regenerator/blob/master/runtime.js) | -| Comprehensions | [experimental](experimental.md), `Array.isArray`, `Array.from` | -| For Of | `Symbol`, `prototype[Symbol.iterator]` | -| Object spread/rest | [experimental](experimental.md), `Object.assign` | -| Spread | `Array.isArray`, `Array.from` | +| Feature | Requirements | +| --------------------------- | -------------------------------------------------------------- | +| Abstract References | [experimental](experimental.md), `Symbol` | +| Array destructuring | `Array.isArray`, `Array.from` | +| Async functions, Generators | [experimental](experimental.md), [polyfill](polyfill.md) | +| Comprehensions | [experimental](experimental.md), `Array.isArray`, `Array.from` | +| For Of | `Symbol`, `prototype[Symbol.iterator]` | +| Object spread/rest | [experimental](experimental.md), `Object.assign` | +| Spread | `Array.isArray`, `Array.from` | ## Classes From 473b6d6a91b10821bcb9443a6cdbb2bd0c9f633b Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Mon, 15 Dec 2014 22:35:58 +1100 Subject: [PATCH 082/139] more microoptimizations --- lib/6to5/transformation/transform.js | 5 +++-- .../transformation/transformers/es6-default-parameters.js | 4 ++-- lib/6to5/transformation/transformers/es6-let-scoping.js | 5 +++-- lib/6to5/transformation/transformers/es6-modules.js | 8 ++++++-- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/lib/6to5/transformation/transform.js b/lib/6to5/transformation/transform.js index 0d2440e3f6..34583744c8 100644 --- a/lib/6to5/transformation/transform.js +++ b/lib/6to5/transformation/transform.js @@ -20,11 +20,12 @@ transform.fromAst = function (ast, code, opts) { }; transform._ensureTransformerNames = function (type, keys) { - _.each(keys, function (key) { + for (var i in keys) { + var key = keys[i]; if (!_.has(transform.transformers, key)) { throw new ReferenceError("unknown transformer " + key + " specified in " + type); } - }); + } }; transform.transformers = {}; diff --git a/lib/6to5/transformation/transformers/es6-default-parameters.js b/lib/6to5/transformation/transformers/es6-default-parameters.js index 304061943e..69fa62755d 100644 --- a/lib/6to5/transformation/transformers/es6-default-parameters.js +++ b/lib/6to5/transformation/transformers/es6-default-parameters.js @@ -26,7 +26,7 @@ exports.Function = function (node, parent, file, scope) { var check = function (node, parent) { if (!t.isIdentifier(node) || !t.isReferenced(node, parent)) return; - if (_.contains(ids, node.name)) { + if (ids.indexOf(node.name) >= 0) { throw file.errorWithNode(node, "Temporal dead zone - accessing a variable before it's initialized"); } @@ -41,7 +41,7 @@ exports.Function = function (node, parent, file, scope) { // we're accessing a variable that's already defined within this function var has = scope.get(param.name); - if (has && !_.contains(node.params, has)) { + if (has && node.params.indexOf(has) < 0) { iife = true; } } diff --git a/lib/6to5/transformation/transformers/es6-let-scoping.js b/lib/6to5/transformation/transformers/es6-let-scoping.js index a173eb9aa2..4e209b37d6 100644 --- a/lib/6to5/transformation/transformers/es6-let-scoping.js +++ b/lib/6to5/transformation/transformers/es6-let-scoping.js @@ -270,9 +270,10 @@ LetScoping.prototype.initialiseLoopLets = function () { } if (isLet(node)) { - _.each(node.declarations, function (declar) { + for (var i in node.declarations) { + var declar = node.declarations[i]; declar.init = declar.init || t.identifier("undefined"); - }); + } } }); }; diff --git a/lib/6to5/transformation/transformers/es6-modules.js b/lib/6to5/transformation/transformers/es6-modules.js index 47ffaba321..039d716aa2 100644 --- a/lib/6to5/transformation/transformers/es6-modules.js +++ b/lib/6to5/transformation/transformers/es6-modules.js @@ -10,11 +10,13 @@ exports.ImportDeclaration = function (node, parent, file) { var nodes = []; if (node.specifiers.length) { + if (!file.moduleFormatter.importSpecifier) return; for (var i in node.specifiers) { file.moduleFormatter.importSpecifier(node.specifiers[i], node, nodes, parent); } } else { - file.moduleFormatter.import(node, nodes, parent); + if (!file.moduleFormatter.importDeclaration) return; + file.moduleFormatter.importDeclaration(node, nodes, parent); } inheritsComments(node, nodes); @@ -33,8 +35,10 @@ exports.ExportDeclaration = function (node, parent, file) { declar.init = declar.init || t.identifier("undefined"); } - file.moduleFormatter.export(node, nodes, parent); + if (!file.moduleFormatter.exportDeclaration) return; + file.moduleFormatter.exportDeclaration(node, nodes, parent); } else { + if (!file.moduleFormatter.exportSpecifier) return; for (var i in node.specifiers) { file.moduleFormatter.exportSpecifier(node.specifiers[i], node, nodes, parent); } From d8e4a4a776d75e94cacd876da4fe31ca1d56c117 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Mon, 15 Dec 2014 22:36:10 +1100 Subject: [PATCH 083/139] add module changes to 2.0.0 changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b6068e158..c960261ee3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,8 @@ Gaps between patch versions are faulty/broken releases. * Switched to [core-js](https://github.com/zloirock/core-js) over [es6-symbol](https://github.com/medikoo/es6-symbol) and [es6-shim](https://github.com/paulmillr/es6-shim/). * `amd` and `umd` module formatters now behave the same as `common` with `interopRequire`. * Micro-optimizations to boost performance by 200%. + * Rename module formatter methods `import` to `importDeclaration` and `export` to `exportDeclaration`. + * Support multiple declarators in export variable declarations. ## 1.15.0 From 1f990f40303814a56f8db4d83881d4b8a7e9b60f Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 16 Dec 2014 08:06:25 +1100 Subject: [PATCH 084/139] fFix module formatter parsing bug where literals were being converted to identifiers --- lib/6to5/transformation/modules/_default.js | 2 +- lib/6to5/transformation/modules/common.js | 8 +++----- lib/6to5/util.js | 7 +------ 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/lib/6to5/transformation/modules/_default.js b/lib/6to5/transformation/modules/_default.js index 2a2d3bbe02..924ab1cb15 100644 --- a/lib/6to5/transformation/modules/_default.js +++ b/lib/6to5/transformation/modules/_default.js @@ -104,7 +104,7 @@ DefaultFormatter.prototype._exportSpecifier = function (getRef, specifier, node, } else { // export { foo } from "test"; nodes.push(util.template("exports-assign-key", { - VARIABLE_NAME: variableName.name, + VARIABLE_NAME: variableName, OBJECT: getRef(), KEY: specifier.id }, true)); diff --git a/lib/6to5/transformation/modules/common.js b/lib/6to5/transformation/modules/common.js index 2490c7df13..fa2c7263fb 100644 --- a/lib/6to5/transformation/modules/common.js +++ b/lib/6to5/transformation/modules/common.js @@ -25,7 +25,7 @@ CommonJSFormatter.prototype.importSpecifier = function (specifier, node, nodes) nodes.push(t.variableDeclaration("var", [ t.variableDeclarator(variableName, t.callExpression(this.file.addDeclaration("interop-require"), [util.template("require", { - MODULE_NAME: node.source.raw + MODULE_NAME: node.source })]) ) ])); @@ -42,7 +42,7 @@ CommonJSFormatter.prototype.importSpecifier = function (specifier, node, nodes) nodes.push(util.template(templateName, { VARIABLE_NAME: variableName, - MODULE_NAME: node.source.raw, + MODULE_NAME: node.source, KEY: specifier.id })); } @@ -51,9 +51,7 @@ CommonJSFormatter.prototype.importSpecifier = function (specifier, node, nodes) CommonJSFormatter.prototype.importDeclaration = function (node, nodes) { // import "foo"; nodes.push(util.template("require", { - //inherits: node, - - MODULE_NAME: node.source.raw + MODULE_NAME: node.source }, true)); }; diff --git a/lib/6to5/util.js b/lib/6to5/util.js index ab43d7a30e..f6fa5fe0f2 100644 --- a/lib/6to5/util.js +++ b/lib/6to5/util.js @@ -152,12 +152,7 @@ exports.template = function (name, nodes, keepExpression) { if (!_.isEmpty(nodes)) { traverse(template, function (node) { if (t.isIdentifier(node) && _.has(nodes, node.name)) { - var newNode = nodes[node.name]; - if (_.isString(newNode)) { - node.name = newNode; - } else { - return newNode; - } + return nodes[node.name]; } }); } From bd78e3ed4dc93eef941c74653adc68a17ba0cd51 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 16 Dec 2014 08:06:38 +1100 Subject: [PATCH 085/139] add end/start user transformers --- lib/6to5/file.js | 18 +++++++++++++++--- lib/6to5/transformation/transformer.js | 3 ++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/lib/6to5/file.js b/lib/6to5/file.js index c5763f991f..b4a926745d 100644 --- a/lib/6to5/file.js +++ b/lib/6to5/file.js @@ -192,13 +192,25 @@ File.prototype.transform = function (ast) { var self = this; - _.each(this.opts.transformers, function (transformer) { - transformer.transform(self); - }); + var runUserTransformers = function (end) { + _.each(self.opts.transformers, function (transformer) { + if (transformer.opts.end) { + if (!end) return; + } else if (end) { + return; + } + + transformer.transform(self); + }); + }; + + runUserTransformers(); _.each(transform.transformers, function (transformer) { transformer.transform(self); }); + + runUserTransformers(true); }; File.prototype.generate = function () { diff --git a/lib/6to5/transformation/transformer.js b/lib/6to5/transformation/transformer.js index fdac3442e9..43f5a1b7c7 100644 --- a/lib/6to5/transformation/transformer.js +++ b/lib/6to5/transformation/transformer.js @@ -4,8 +4,9 @@ var traverse = require("../traverse"); var t = require("../types"); var _ = require("lodash"); -function Transformer(key, transformer) { +function Transformer(key, transformer, opts) { this.transformer = Transformer.normalise(transformer); + this.opts = opts || {}; this.key = key; } From fc7fc384c9d878c1f5b558a7116d0899c8538518 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 16 Dec 2014 08:06:56 +1100 Subject: [PATCH 086/139] add declaration/reference support to scope --- lib/6to5/traverse/index.js | 2 +- lib/6to5/traverse/scope.js | 49 +++++++++++++++++++++++--------------- 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/lib/6to5/traverse/index.js b/lib/6to5/traverse/index.js index 32bad31add..add0a38df1 100644 --- a/lib/6to5/traverse/index.js +++ b/lib/6to5/traverse/index.js @@ -93,9 +93,9 @@ function traverse(parent, callbacks, opts) { traverse.removeProperties = function (tree) { var clear = function (node) { - delete node._scopeReferences; delete node._declarations; delete node.extendedRange; + delete node._scopeInfo; delete node._parent; delete node._scope; delete node.tokens; diff --git a/lib/6to5/traverse/scope.js b/lib/6to5/traverse/scope.js index b2faeab838..603a33a823 100644 --- a/lib/6to5/traverse/scope.js +++ b/lib/6to5/traverse/scope.js @@ -18,9 +18,14 @@ function Scope(block, parent) { this.parent = parent; this.block = block; - this.references = this.getReferences(); + var info = this.getInfo(); + this.references = info.references; + this.declarations = info.declarations; } +var vars = require("jshint/src/vars"); +Scope.defaultDeclarations = _.flatten([vars.newEcmaIdentifiers, vars.node, vars.ecmaIdentifiers, vars.reservedVars].map(_.keys)); + Scope.add = function (node, references) { if (!node) return; _.defaults(references, t.getIds(node, true)); @@ -35,14 +40,17 @@ Scope.prototype.generateTemp = function (file, name) { return id; }; -Scope.prototype.getReferences = function () { +Scope.prototype.getInfo = function () { var block = this.block; - if (block._scopeReferences) return block._scopeReferences; + if (block._scopeInfo) return block._scopeInfo; - var references = block._scopeReferences = {}; + var info = block._scopeInfo = {}; + var references = info.references = {}; + var declarations = info.declarations = {}; - var add = function (node) { + var add = function (node, reference) { Scope.add(node, references); + if (!reference) Scope.add(node, declarations); }; // ForStatement - left, init @@ -90,7 +98,7 @@ Scope.prototype.getReferences = function () { if (block.id && node === block.id) return; if (t.isIdentifier(node) && t.isReferenced(node, parent) && !scope.has(node.name)) { - add(node); + add(node, true); } // we've ran into a declaration! @@ -110,7 +118,7 @@ Scope.prototype.getReferences = function () { }); } - return references; + return info; }; Scope.prototype.push = function (opts) { @@ -137,26 +145,29 @@ Scope.prototype.add = function (node) { Scope.add(node, this.references); }; -Scope.prototype.get = function (id) { - return id && (this.getOwn(id) || this.parentGet(id)); +Scope.prototype.get = function (id, decl) { + return id && (this.getOwn(id, decl) || this.parentGet(id, decl)); }; -Scope.prototype.getOwn = function (id) { - return _.has(this.references, id) && this.references[id]; +Scope.prototype.getOwn = function (id, decl) { + var refs = this.references; + if (decl) refs = this.declarations; + return _.has(refs, id) && refs[id]; }; -Scope.prototype.parentGet = function (id) { - return this.parent && this.parent.get(id); +Scope.prototype.parentGet = function (id, decl) { + return this.parent && this.parent.get(id, decl); }; -Scope.prototype.has = function (id) { - return id && (this.hasOwn(id) || this.parentHas(id)); +Scope.prototype.has = function (id, decl) { + return (id && (this.hasOwn(id, decl) || this.parentHas(id, decl))) || + _.contains(Scope.defaultDeclarations, id); }; -Scope.prototype.hasOwn = function (id) { - return !!this.getOwn(id); +Scope.prototype.hasOwn = function (id, decl) { + return !!this.getOwn(id, decl); }; -Scope.prototype.parentHas = function (id) { - return this.parent && this.parent.has(id); +Scope.prototype.parentHas = function (id, decl) { + return this.parent && this.parent.has(id, decl); }; From 01bdb7efdcb1a8f676dc33e1e2fdafb24b40b479 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 16 Dec 2014 08:07:18 +1100 Subject: [PATCH 087/139] fix export and import specifier getIds and add support for computed properties to isReferenced --- lib/6to5/types/index.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/6to5/types/index.js b/lib/6to5/types/index.js index 65fb12bedc..d4b95ee677 100644 --- a/lib/6to5/types/index.js +++ b/lib/6to5/types/index.js @@ -128,8 +128,8 @@ t.isDynamic = function (node) { }; t.isReferenced = function (node, parent) { - // we're a property key so we aren't referenced - if (t.isProperty(parent) && parent.key === node) return false; + // we're a property key and we aren't computed so we aren't referenced + if (t.isProperty(parent) && parent.key === node && !parent.computed) return false; // we're a variable declarator id so we aren't referenced if (t.isVariableDeclarator(parent) && parent.id === node) return false; @@ -256,8 +256,8 @@ t.getIds = function (node, map, ignoreTypes) { t.getIds.nodes = { AssignmentExpression: "left", - ImportSpecifier: "id", - ExportSpecifier: "id", + ImportSpecifier: "name", + ExportSpecifier: "name", VariableDeclarator: "id", FunctionDeclaration: "id", ClassDeclaration: "id", From 49578fe2237f87470c7e64451ce0b602c830d83b Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 16 Dec 2014 08:07:46 +1100 Subject: [PATCH 088/139] fix let variable declaration hoisting bug. All let variable declarators now have a default initializer of `undefined` unless they're the left of a `ForIn` or `ForOf` --- .../transformers/es6-let-scoping.js | 57 ++++++------------- 1 file changed, 18 insertions(+), 39 deletions(-) diff --git a/lib/6to5/transformation/transformers/es6-let-scoping.js b/lib/6to5/transformation/transformers/es6-let-scoping.js index 4e209b37d6..bfcd1e6e78 100644 --- a/lib/6to5/transformation/transformers/es6-let-scoping.js +++ b/lib/6to5/transformation/transformers/es6-let-scoping.js @@ -3,18 +3,25 @@ var util = require("../../util"); var t = require("../../types"); var _ = require("lodash"); -var isLet = function (node) { +var isLet = function (node, parent) { if (!t.isVariableDeclaration(node)) return false; if (node._let) return true; if (node.kind !== "let") return false; + // https://github.com/6to5/6to5/issues/255 + if (!t.isFor(parent) || t.isFor(parent) && parent.left !== node) { + _.each(node.declarations, function (declar) { + declar.init = declar.init || t.identifier("undefined"); + }); + } + node._let = true; node.kind = "var"; return true; }; -var isVar = function (node) { - return t.isVariableDeclaration(node, { kind: "var" }) && !isLet(node); +var isVar = function (node, parent) { + return t.isVariableDeclaration(node, { kind: "var" }) && !isLet(node, parent); }; var standardiseLets = function (declars) { @@ -23,13 +30,13 @@ var standardiseLets = function (declars) { } }; -exports.VariableDeclaration = function (node) { - isLet(node); +exports.VariableDeclaration = function (node, parent) { + isLet(node, parent); }; exports.Loop = function (node, parent, file, scope) { var init = node.left || node.init; - if (isLet(init)) { + if (isLet(init, node)) { t.ensureBlock(node); node.body._letDeclars = [init]; } @@ -91,9 +98,6 @@ LetScoping.prototype.run = function () { // remap all let references that exist in upper scopes to their uid this.remap(); - // add default initializer to let variables in loop bodys - this.initialiseLoopLets(); - // this is a block within a `Function` so we can safely leave it be if (t.isFunction(this.parent)) return this.noClosure(); @@ -242,7 +246,7 @@ LetScoping.prototype.getInfo = function () { for (var i in block.body) { var declar = block.body[i]; - if (!isLet(declar)) continue; + if (!isLet(declar, block)) continue; _.each(t.getIds(declar, true), function (id, key) { duplicates(id, key); @@ -253,31 +257,6 @@ LetScoping.prototype.getInfo = function () { return opts; }; -/** - * Any let variable declared within a loop body need to have an initializer or - * else they'll be hoisted and subsequent iterations of the loop will have a - * previous state. This function adds a default initializer of `undefined` to - * those variables. - */ - -LetScoping.prototype.initialiseLoopLets = function () { - var loopParent = this.loopParent; - if (!loopParent) return; - - traverse(this.block, function (node) { - if (t.isFunction(node) || t.isLoop(node)) { - return false; - } - - if (isLet(node)) { - for (var i in node.declarations) { - var declar = node.declarations[i]; - declar.init = declar.init || t.identifier("undefined"); - } - } - }); -}; - /** * If we're inside of a loop then traverse it and check if it has one of * the following node types `ReturnStatement`, `BreakStatement`, @@ -333,16 +312,16 @@ LetScoping.prototype.checkLoop = function () { LetScoping.prototype.hoistVarDeclarations = function () { var self = this; - traverse(this.block, function (node) { + traverse(this.block, function (node, parent) { if (t.isForStatement(node)) { - if (isVar(node.init)) { + if (isVar(node.init, node)) { node.init = t.sequenceExpression(self.pushDeclar(node.init)); } } else if (t.isFor(node)) { - if (isVar(node.left)) { + if (isVar(node.left, node)) { node.left = node.left.declarations[0].id; } - } else if (isVar(node)) { + } else if (isVar(node, parent)) { return self.pushDeclar(node).map(t.expressionStatement); } else if (t.isFunction(node)) { return false; From 882ed48438e9754d6390d3ddfdd73ff76eb5e6f5 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 16 Dec 2014 08:08:06 +1100 Subject: [PATCH 089/139] fix a catch param property identifier incorrectly being replaced when exploding statements in generators - fixes #301 --- .../transformers/es6-generators/emit/explode-statements.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/6to5/transformation/transformers/es6-generators/emit/explode-statements.js b/lib/6to5/transformation/transformers/es6-generators/emit/explode-statements.js index 9f73681883..896d461561 100644 --- a/lib/6to5/transformation/transformers/es6-generators/emit/explode-statements.js +++ b/lib/6to5/transformation/transformers/es6-generators/emit/explode-statements.js @@ -297,7 +297,8 @@ exports.TryStatement = function (path, stmt) { types.visit(bodyPath, { visitIdentifier: function (path) { - if (path.value.name === catchParamName && + if (t.isReferenced(path.value, path.parentPath.node) && + path.value.name === catchParamName && path.scope.lookup(catchParamName) === catchScope) { return safeParam; } From 2fc801003499fe79428d09ac646e4c3f0d567473 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 16 Dec 2014 08:08:14 +1100 Subject: [PATCH 090/139] move jshint to normal dependencies --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e934fd78a1..ddd914f7ba 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "estraverse": "1.8.0", "esutils": "1.1.6", "fs-readdir-recursive": "0.1.0", + "jshint": "^2.5.10", "lodash": "2.4.1", "mkdirp": "0.5.0", "private": "0.1.6", @@ -55,7 +56,6 @@ "browserify": "6.3.2", "chai": "^1.9.2", "istanbul": "0.3.2", - "jshint": "2.5.10", "jshint-stylish": "^1.0.0", "matcha": "0.6.0", "mocha": "1.21.4", From f14dc60934a10bfdb59ae1fdd2044197f02d4b08 Mon Sep 17 00:00:00 2001 From: Raine Virta Date: Tue, 16 Dec 2014 00:36:18 +0200 Subject: [PATCH 091/139] Update differences.md fix typo --- doc/differences.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/differences.md b/doc/differences.md index 0102fdeacf..f4ef9475ee 100644 --- a/doc/differences.md +++ b/doc/differences.md @@ -121,7 +121,7 @@ that when you turn it off and use your code in a full ES6 environment Traceur requires quite a bulky runtime (~75KB) and produces quite verbose code. While this can be trimmed down by selectively building the runtime, it's an -unneccesary step when a large runtime can be eliminated entirely. +unnecessary step when a large runtime can be eliminated entirely. ### [es6now](https://github.com/zenparsing/es6now) From 104b1f4c9b49482c99c9d0733abddd4b9ac58955 Mon Sep 17 00:00:00 2001 From: Douglas Duteil Date: Wed, 10 Dec 2014 02:39:33 +0100 Subject: [PATCH 092/139] feat(system-module): rewrite --- lib/6to5/transformation/modules/system.js | 488 ++++++++++++------ .../exports-named/expected.js | 26 - .../exports-default/actual.js | 0 .../exports-default/expected.js | 2 - .../exports-from/actual.js | 0 .../exports-from/expected.js | 22 +- .../exports-named/actual.js | 0 .../exports-named/expected.js | 24 + .../exports-variable/actual.js | 0 .../exports-variable/expected.js | 1 - .../hoist-function-exports/actual.js | 0 .../hoist-function-exports/expected.js | 0 .../imports-default/actual.js | 0 .../imports-default/expected.js | 0 .../imports-glob/actual.js | 0 .../imports-glob/expected.js | 0 .../imports-mixing/actual.js | 0 .../imports-mixing/expected.js | 0 .../imports-named/actual.js | 0 .../imports-named/expected.js | 0 .../imports/actual.js | 0 .../imports/expected.js | 0 .../options.json | 0 .../overview/actual.js | 0 .../overview/expected.js | 0 25 files changed, 368 insertions(+), 195 deletions(-) delete mode 100644 test/fixtures/transformation/.es6-modules-system/exports-named/expected.js rename test/fixtures/transformation/{.es6-modules-system => es6-modules-system}/exports-default/actual.js (100%) rename test/fixtures/transformation/{.es6-modules-system => es6-modules-system}/exports-default/expected.js (99%) rename test/fixtures/transformation/{.es6-modules-system => es6-modules-system}/exports-from/actual.js (100%) rename test/fixtures/transformation/{.es6-modules-system => es6-modules-system}/exports-from/expected.js (59%) rename test/fixtures/transformation/{.es6-modules-system => es6-modules-system}/exports-named/actual.js (100%) create mode 100644 test/fixtures/transformation/es6-modules-system/exports-named/expected.js rename test/fixtures/transformation/{.es6-modules-system => es6-modules-system}/exports-variable/actual.js (100%) rename test/fixtures/transformation/{.es6-modules-system => es6-modules-system}/exports-variable/expected.js (99%) rename test/fixtures/transformation/{.es6-modules-system => es6-modules-system}/hoist-function-exports/actual.js (100%) rename test/fixtures/transformation/{.es6-modules-system => es6-modules-system}/hoist-function-exports/expected.js (100%) rename test/fixtures/transformation/{.es6-modules-system => es6-modules-system}/imports-default/actual.js (100%) rename test/fixtures/transformation/{.es6-modules-system => es6-modules-system}/imports-default/expected.js (100%) rename test/fixtures/transformation/{.es6-modules-system => es6-modules-system}/imports-glob/actual.js (100%) rename test/fixtures/transformation/{.es6-modules-system => es6-modules-system}/imports-glob/expected.js (100%) rename test/fixtures/transformation/{.es6-modules-system => es6-modules-system}/imports-mixing/actual.js (100%) rename test/fixtures/transformation/{.es6-modules-system => es6-modules-system}/imports-mixing/expected.js (100%) rename test/fixtures/transformation/{.es6-modules-system => es6-modules-system}/imports-named/actual.js (100%) rename test/fixtures/transformation/{.es6-modules-system => es6-modules-system}/imports-named/expected.js (100%) rename test/fixtures/transformation/{.es6-modules-system => es6-modules-system}/imports/actual.js (100%) rename test/fixtures/transformation/{.es6-modules-system => es6-modules-system}/imports/expected.js (100%) rename test/fixtures/transformation/{.es6-modules-system => es6-modules-system}/options.json (100%) rename test/fixtures/transformation/{.es6-modules-system => es6-modules-system}/overview/actual.js (100%) rename test/fixtures/transformation/{.es6-modules-system => es6-modules-system}/overview/expected.js (100%) diff --git a/lib/6to5/transformation/modules/system.js b/lib/6to5/transformation/modules/system.js index 73ddc6f107..a06706f8b1 100644 --- a/lib/6to5/transformation/modules/system.js +++ b/lib/6to5/transformation/modules/system.js @@ -1,58 +1,349 @@ module.exports = SystemFormatter; -var util = require("../../util"); -var t = require("../../types"); -var _ = require("lodash"); +var util = require("../../util"); +var t = require("../../types"); +var traverse = require("../../traverse"); +var _ = require("lodash"); -var SETTER_MODULE_NAMESPACE = t.identifier("m"); -var DEFAULT_IDENTIFIER = t.identifier("default"); -var NULL_SETTER = t.literal(null); +var SETTER_MODULE_NAMESPACE = t.identifier("m"); +var PRIVATE_MODULE_NAME_IDENTIFIER = t.identifier("__moduleName"); +var DEFAULT_IDENTIFIER = t.identifier("default"); +var NULL_SETTER = t.literal(null); function SystemFormatter(file) { + this.moduleNameLiteral = null; this.exportedStatements = []; - this.importedModule = {}; + this.moduleDependencies = {}; + this.importedVariables = {}; this.exportIdentifier = file.generateUidIdentifier("export"); this.file = file; + + /** + * @type Function + * @param {Array} args - The arguments of the "_export(...args)" function + * @return {Object} The expression statement with the call expression. + */ + this._makeExportStatements = _.compose( + t.expressionStatement, + // will generate the call expression : _export(...args) + _.partial(t.callExpression, this.exportIdentifier) + ); } +SystemFormatter.prototype.import = + SystemFormatter.prototype.export = function (node, nodes) { + nodes.push(node); + }; + +SystemFormatter.prototype.importSpecifier = + SystemFormatter.prototype.exportSpecifier = function (specifier, node, nodes) { + if (!nodes.length) nodes.push(node); + }; + SystemFormatter.prototype.transform = function (ast) { - var program = ast.program; - var body = program.body; + + var systemTransform = this; // extract the module name - var moduleName = this.file.opts.filename - .replace(/^.*\//, "").replace(/\..*$/, ""); + this.moduleNameLiteral = t.literal( + this.file.opts.filename.replace(/^.*\//, "").replace(/\..*$/, "") + ); - // build an array of module names - var dependencies = Object.keys(this.importedModule).map(t.literal); + // Post extraction of the import/export declaration + traverse(ast, function (node) { + var replacementNode = null; + /** + * Process the current node with an extractor. + * @param {Function} extractor Extract the node data + * @returns {*} Can be a `node` (for replacement), void 0 (for removing) + * or false. + */ + function processTheNode(extractor) { + var result = extractor.call(systemTransform, node); + result = (result === void 0) ? [] : result; + replacementNode = result || replacementNode; + return !!replacementNode; + } + + _.some([ + // Import + SystemFormatter.prototype._extractImportSpecifiers, + SystemFormatter.prototype._extractImport, + + // Export + SystemFormatter.prototype._extractExportDefault, + SystemFormatter.prototype._extractExportVariableDeclaration, + SystemFormatter.prototype._extractExportFunctionDeclaration, + SystemFormatter.prototype._extractExportSpecifiers + ], + processTheNode + ); + + return replacementNode; + }); + + // Other + this._prependImportVariables(ast); + this._prependPrivateModuleName(ast); + this._appendModuleReturnStatement(ast); + this._wrapInSystemRegisterCallExpression(ast); +}; + +// +// Import extraction +// + +SystemFormatter.prototype._extractImportSpecifiers = function (node) { + + var systemTransform = this; + + if (!(t.isImportDeclaration(node) && node.specifiers && node.specifiers.length )) { + return false; + } + + _.each(node.specifiers, function (specifier) { + + var variableName = t.getSpecifierName(specifier); + + if (specifier.default) { + specifier.id = DEFAULT_IDENTIFIER; + } + + var right = SETTER_MODULE_NAMESPACE; + if (!t.isImportBatchSpecifier(specifier)) { + right = t.memberExpression(right, specifier.id); + } + systemTransform.importedVariables[variableName.name] = true; + systemTransform._addImportStatement(node.source.value, t.expressionStatement( + t.assignmentExpression("=", variableName, right) + )); + + }); +}; + +SystemFormatter.prototype._extractImport = function (node) { + if (!(t.isImportDeclaration(node))) { + return false; + } + + this._addImportStatement(node.source.value); +}; + +// +// Export extraction +// + +SystemFormatter.prototype._extractExportDefault = function (node) { + if (!(t.isExportDeclaration(node) && node.default)) { + return false; + } + + var declar = node.declaration; + var variableName = DEFAULT_IDENTIFIER.name; + var returnNode; + + if (t.isFunction(declar)) { + if (!declar.id) { + declar.id = this.file.generateUidIdentifier("anonymous"); + } + returnNode = t.toStatement(declar); + declar = declar.id; + } + + this._addToExportStatements(variableName, declar); + + return returnNode; +}; + +SystemFormatter.prototype._extractExportVariableDeclaration = function (node) { + var systemTransform = this; + var declar = node.declaration; + + if (!(t.isExportDeclaration(node) && t.isVariableDeclaration(declar))) { + return false; + } + + function separateDeclarationAndInit(memo, varDeclar) { + memo.varDeclaration.push(_.omit(varDeclar, "init")); + systemTransform._addToExportStatements(varDeclar.id.name, varDeclar); + return memo; + } + + var declarationSeparation = _.reduce( + declar.declarations, + separateDeclarationAndInit, + { varDeclaration: [], varInitialization: [] } + ); + + return _.assign(declar, { declarations: declarationSeparation.varDeclaration }); +}; + +SystemFormatter.prototype._extractExportFunctionDeclaration = function (node) { + var declar = node.declaration; + + if (!(t.isExportDeclaration(node) && t.isFunctionDeclaration(declar))) { + return false; + } + this._addToExportStatements(declar.id.name, declar.id); + return declar; + +}; + +SystemFormatter.prototype._extractExportSpecifiers = function (node) { + var systemTransform = this; + + if (!( t.isExportDeclaration(node) && node.specifiers )) { + return false; + } + + _.each(node.specifiers, function (specifier) { + + // Run each, break when one is true. + _.some([ + SystemFormatter.prototype._extractExportBatch, + SystemFormatter.prototype._extractExportFrom, + SystemFormatter.prototype._extractExportNamed + ], function (extractor) { + var result = extractor.call(systemTransform, specifier, node); + return result === void 0 || result; + }); + + }); + + // Note: here we don't care about the node replacement. + // The current node will always be removed. + // So no return. +}; + +SystemFormatter.prototype._extractExportBatch = function (specifier, node) { + + if (!(node.source && t.isExportBatchSpecifier(specifier))) { + return false; + } + + var exportBatch = this._makeExportWildcard(SETTER_MODULE_NAMESPACE); + this._addImportStatement(node.source.value, exportBatch); +}; + +SystemFormatter.prototype._extractExportFrom = function (specifier, node) { + + // Weak test here... + if (!(node.source)) { + return false; + } + + var variableName = t.getSpecifierName(specifier); + + var target = t.memberExpression( + SETTER_MODULE_NAMESPACE, + specifier.id + ); + + var exportSelection = this._makeExportStatements([ + t.literal(variableName.name), target + ]); + + this._addImportStatement(node.source.value, exportSelection); +}; + +SystemFormatter.prototype._extractExportNamed = function (specifier) { + + // Last case... + // Dunno what to test here... + + var variableName = t.getSpecifierName(specifier); + this._addToExportStatements(variableName.name, specifier.id); +}; + +// +// Utils collection handler +// + +SystemFormatter.prototype._addToExportStatements = function (name, identifier) { + this.exportedStatements.push( + this._makeExportStatements([t.literal(name), identifier]) + ); +}; + +/** + * Generate a export wildcard expression + * /!\ this is a hack over the existing "exports-wildcard" template + * @param objectIdentifier + * @returns the export wildcard expression + * @private + */ +SystemFormatter.prototype._makeExportWildcard = function (objectIdentifier) { + + var exportStatement = util.template("exports-wildcard", { + OBJECT: objectIdentifier + }, true); + + delete exportStatement.expression.callee.expression._scopeReferences; + + var forStatement = exportStatement.expression.callee.expression.body.body[0]; + var iteratorIdentifier = forStatement.left.declarations[0].id; + var target = t.memberExpression( + forStatement.right, + iteratorIdentifier, + true + ); + + forStatement.body.body = [ + this._makeExportStatements([iteratorIdentifier, target]) + ]; + + return exportStatement; +}; + +SystemFormatter.prototype._addImportStatement = function (name, importStatement) { + this.moduleDependencies[name] = this.moduleDependencies[name] || []; + importStatement && this.moduleDependencies[name].push(importStatement); +}; + +// +// Additional body content +// + +SystemFormatter.prototype._prependImportVariables = function (ast) { + + var declaredSetters = _(this.importedVariables).keys().map(function (name) { + return _.compose(t.variableDeclarator, t.identifier)(name); + } + ).value(); + + if (declaredSetters.length) { + ast.program.body.splice(1, 0, t.variableDeclaration("var", declaredSetters)); + } +}; + +SystemFormatter.prototype._prependPrivateModuleName = function (ast) { // generate the __moduleName variable var moduleNameVariableNode = t.variableDeclaration("var", [ t.variableDeclarator( - t.identifier("__moduleName"), - t.literal(moduleName) + PRIVATE_MODULE_NAME_IDENTIFIER, + this.moduleNameLiteral ) ]); - body.splice(1, 0, moduleNameVariableNode); - // generate an array of import variables + ast.program.body.splice(1, 0, moduleNameVariableNode); +}; - var declaredSetters = _(this.importedModule) - .map() - .flatten() - .pluck("variableName") - .pluck("name") - .uniq() - .map(t.identifier) - .map(function (name) { - return t.variableDeclarator(name); - }) - .value(); +SystemFormatter.prototype._buildSetters = function () { + // generate setters array expression elements + return _.map(this.moduleDependencies, function (specs) { + if (!specs.length) { + return NULL_SETTER; + } - if (declaredSetters.length) { - body.splice(2, 0, t.variableDeclaration("var", declaredSetters)); - } + return t.functionExpression( + null, [SETTER_MODULE_NAMESPACE], t.blockStatement(specs) + ); + }); +}; + +SystemFormatter.prototype._appendModuleReturnStatement = function (ast) { // generate the execute function expression var executeFunctionExpression = t.functionExpression( @@ -67,12 +358,21 @@ SystemFormatter.prototype.transform = function (ast) { t.property("init", t.identifier("setters"), settersArrayExpression), t.property("init", t.identifier("execute"), executeFunctionExpression) ])); - body.push(moduleReturnStatement); - // runner + ast.program.body.push(moduleReturnStatement); +}; + +SystemFormatter.prototype._wrapInSystemRegisterCallExpression = function (ast) { + var program = ast.program; + var body = program.body; + + var moduleDependencyNames = Object + .keys(this.moduleDependencies) + .map(t.literal); + var runner = util.template("register", { - MODULE_NAME: t.literal(moduleName), - MODULE_DEPENDENCIES: t.arrayExpression(dependencies), + MODULE_NAME: this.moduleNameLiteral, + MODULE_DEPENDENCIES: t.arrayExpression(moduleDependencyNames), MODULE_BODY: t.functionExpression( null, [this.exportIdentifier], @@ -82,121 +382,3 @@ SystemFormatter.prototype.transform = function (ast) { program.body = [t.expressionStatement(runner)]; }; - -SystemFormatter.prototype._buildSetters = function () { - // generate setters array expression elements - return _.map(this.importedModule, function (specs) { - if (!specs.length) { - return NULL_SETTER; - } - - var expressionStatements = _.map(specs, function (spec) { - var right = SETTER_MODULE_NAMESPACE; - if (!spec.isBatch) { - right = t.memberExpression(right, spec.key); - } - - return t.expressionStatement( - t.assignmentExpression("=", spec.variableName, right - ) - ); - }); - - return t.functionExpression( - null, [SETTER_MODULE_NAMESPACE], t.blockStatement(expressionStatements) - ); - }); -}; - -SystemFormatter.prototype.import = function (node) { - var MODULE_NAME = node.source.value; - this.importedModule[MODULE_NAME] = this.importedModule[MODULE_NAME] || []; -}; - -SystemFormatter.prototype.importSpecifier = function (specifier, node) { - var variableName = t.getSpecifierName(specifier); - - // import foo from "foo"; - if (specifier.default) { - specifier.id = DEFAULT_IDENTIFIER; - } - - var MODULE_NAME = node.source.value; - - this.importedModule[MODULE_NAME] = this.importedModule[MODULE_NAME] || []; - - this.importedModule[MODULE_NAME].push({ - variableName: variableName, - isBatch: specifier.type === "ImportBatchSpecifier", - key: specifier.id - }); -}; - -SystemFormatter.prototype._export = function (name, identifier) { - this.exportedStatements.push(t.expressionStatement( - t.callExpression(this.exportIdentifier, [t.literal(name), identifier]) - )); -}; - -SystemFormatter.prototype.export = function (node, nodes) { - var declar = node.declaration; - var variableName, identifier; - - if (node.default) { - // export default foo - variableName = DEFAULT_IDENTIFIER.name; - if (t.isClass(declar) || t.isFunction(declar)) { - if (!declar.id) { - declar.id = this.file.generateUidIdentifier("anonymous"); - } - - nodes.push(t.toStatement(declar)); - declar = declar.id; - } - - identifier = declar; - } else if (t.isVariableDeclaration(declar)) { - // export var foo - variableName = declar.declarations[0].id.name; - identifier = declar.declarations[0].id; - - nodes.push(declar); - } else { - // export function foo () {} - variableName = declar.id.name; - identifier = declar.id; - - nodes.push(declar); - } - - this._export(variableName, identifier); -}; - -SystemFormatter.prototype.exportSpecifier = function (specifier, node) { - var variableName = t.getSpecifierName(specifier); - - if (node.source) { - if (t.isExportBatchSpecifier(specifier)) { - // export * from "foo"; - var exportIdentifier = t.identifier("exports"); - this.exportedStatements.push( - t.variableDeclaration("var", [ - t.variableDeclarator(exportIdentifier, this.exportIdentifier) - ]) - ); - - this.exportedStatements.push(util.template("exports-wildcard", { - OBJECT: t.identifier(node.source.value) - }, true)); - } else { - // export { foo } from "test"; - this._export(variableName.name, t.memberExpression( - t.identifier(node.source.value), - specifier.id - )); - } - } else { - // export { foo }; - this._export(variableName.name, specifier.id); - } -}; diff --git a/test/fixtures/transformation/.es6-modules-system/exports-named/expected.js b/test/fixtures/transformation/.es6-modules-system/exports-named/expected.js deleted file mode 100644 index e0f17a11f9..0000000000 --- a/test/fixtures/transformation/.es6-modules-system/exports-named/expected.js +++ /dev/null @@ -1,26 +0,0 @@ -System.register("actual", [], function (_export) { - "use strict"; - - var __moduleName = "actual"; - - return { - setters: [ - function(m) { - _export("foo", m.foo); - - _export("foo", m.foo); - - _export("bar", m.bar); - - _export("bar", m.foo); - - _export("default", m.foo); - - _export("default", m.foo); - - _export("bar", m.bar); - }], - execute: function () { - } - }; -}); diff --git a/test/fixtures/transformation/.es6-modules-system/exports-default/actual.js b/test/fixtures/transformation/es6-modules-system/exports-default/actual.js similarity index 100% rename from test/fixtures/transformation/.es6-modules-system/exports-default/actual.js rename to test/fixtures/transformation/es6-modules-system/exports-default/actual.js diff --git a/test/fixtures/transformation/.es6-modules-system/exports-default/expected.js b/test/fixtures/transformation/es6-modules-system/exports-default/expected.js similarity index 99% rename from test/fixtures/transformation/.es6-modules-system/exports-default/expected.js rename to test/fixtures/transformation/es6-modules-system/exports-default/expected.js index 7e90c983cb..934c42e2f3 100644 --- a/test/fixtures/transformation/.es6-modules-system/exports-default/expected.js +++ b/test/fixtures/transformation/es6-modules-system/exports-default/expected.js @@ -5,10 +5,8 @@ System.register("actual", [], function (_export) { function _anonymous() {} var _anonymous2; - function foo() {} var Foo; - return { setters: [], execute: function () { diff --git a/test/fixtures/transformation/.es6-modules-system/exports-from/actual.js b/test/fixtures/transformation/es6-modules-system/exports-from/actual.js similarity index 100% rename from test/fixtures/transformation/.es6-modules-system/exports-from/actual.js rename to test/fixtures/transformation/es6-modules-system/exports-from/actual.js diff --git a/test/fixtures/transformation/.es6-modules-system/exports-from/expected.js b/test/fixtures/transformation/es6-modules-system/exports-from/expected.js similarity index 59% rename from test/fixtures/transformation/.es6-modules-system/exports-from/expected.js rename to test/fixtures/transformation/es6-modules-system/exports-from/expected.js index 680bae3c9f..b1ff79e7e4 100644 --- a/test/fixtures/transformation/.es6-modules-system/exports-from/expected.js +++ b/test/fixtures/transformation/es6-modules-system/exports-from/expected.js @@ -3,11 +3,14 @@ System.register("actual", ["foo"], function (_export) { var __moduleName = "actual"; - var _localExports = ['foo', 'bar', 'default']; - return { - setters: [ - function(m) { + setters: [function (m) { + (function (obj) { + for (var i in obj) { + _export(i, obj[i]); + } + })(m); + _export("foo", m.foo); _export("foo", m.foo); @@ -21,14 +24,7 @@ System.register("actual", ["foo"], function (_export) { _export("default", m.foo); _export("bar", m.bar); - - for (var p in m) { - if (_localExports.indexOf(i) == -1) - _export(p, m[p]); - } - } - ], - execute: function () { - } + }], + execute: function () {} }; }); diff --git a/test/fixtures/transformation/.es6-modules-system/exports-named/actual.js b/test/fixtures/transformation/es6-modules-system/exports-named/actual.js similarity index 100% rename from test/fixtures/transformation/.es6-modules-system/exports-named/actual.js rename to test/fixtures/transformation/es6-modules-system/exports-named/actual.js diff --git a/test/fixtures/transformation/es6-modules-system/exports-named/expected.js b/test/fixtures/transformation/es6-modules-system/exports-named/expected.js new file mode 100644 index 0000000000..716fd14641 --- /dev/null +++ b/test/fixtures/transformation/es6-modules-system/exports-named/expected.js @@ -0,0 +1,24 @@ +System.register("actual", [], function (_export) { + "use strict"; + + var __moduleName = "actual"; + + return { + setters: [], + execute: function () { + _export("foo", foo); + + _export("foo", foo); + + _export("bar", bar); + + _export("bar", foo); + + _export("default", foo); + + _export("default", foo); + + _export("bar", bar); + } + }; +}); diff --git a/test/fixtures/transformation/.es6-modules-system/exports-variable/actual.js b/test/fixtures/transformation/es6-modules-system/exports-variable/actual.js similarity index 100% rename from test/fixtures/transformation/.es6-modules-system/exports-variable/actual.js rename to test/fixtures/transformation/es6-modules-system/exports-variable/actual.js diff --git a/test/fixtures/transformation/.es6-modules-system/exports-variable/expected.js b/test/fixtures/transformation/es6-modules-system/exports-variable/expected.js similarity index 99% rename from test/fixtures/transformation/.es6-modules-system/exports-variable/expected.js rename to test/fixtures/transformation/es6-modules-system/exports-variable/expected.js index fd8e2dba9e..39fe8267e1 100644 --- a/test/fixtures/transformation/.es6-modules-system/exports-variable/expected.js +++ b/test/fixtures/transformation/es6-modules-system/exports-variable/expected.js @@ -13,7 +13,6 @@ System.register("actual", [], function (_export) { _export("foo7", foo7); var foo8; - return { setters: [], execute: function () { diff --git a/test/fixtures/transformation/.es6-modules-system/hoist-function-exports/actual.js b/test/fixtures/transformation/es6-modules-system/hoist-function-exports/actual.js similarity index 100% rename from test/fixtures/transformation/.es6-modules-system/hoist-function-exports/actual.js rename to test/fixtures/transformation/es6-modules-system/hoist-function-exports/actual.js diff --git a/test/fixtures/transformation/.es6-modules-system/hoist-function-exports/expected.js b/test/fixtures/transformation/es6-modules-system/hoist-function-exports/expected.js similarity index 100% rename from test/fixtures/transformation/.es6-modules-system/hoist-function-exports/expected.js rename to test/fixtures/transformation/es6-modules-system/hoist-function-exports/expected.js diff --git a/test/fixtures/transformation/.es6-modules-system/imports-default/actual.js b/test/fixtures/transformation/es6-modules-system/imports-default/actual.js similarity index 100% rename from test/fixtures/transformation/.es6-modules-system/imports-default/actual.js rename to test/fixtures/transformation/es6-modules-system/imports-default/actual.js diff --git a/test/fixtures/transformation/.es6-modules-system/imports-default/expected.js b/test/fixtures/transformation/es6-modules-system/imports-default/expected.js similarity index 100% rename from test/fixtures/transformation/.es6-modules-system/imports-default/expected.js rename to test/fixtures/transformation/es6-modules-system/imports-default/expected.js diff --git a/test/fixtures/transformation/.es6-modules-system/imports-glob/actual.js b/test/fixtures/transformation/es6-modules-system/imports-glob/actual.js similarity index 100% rename from test/fixtures/transformation/.es6-modules-system/imports-glob/actual.js rename to test/fixtures/transformation/es6-modules-system/imports-glob/actual.js diff --git a/test/fixtures/transformation/.es6-modules-system/imports-glob/expected.js b/test/fixtures/transformation/es6-modules-system/imports-glob/expected.js similarity index 100% rename from test/fixtures/transformation/.es6-modules-system/imports-glob/expected.js rename to test/fixtures/transformation/es6-modules-system/imports-glob/expected.js diff --git a/test/fixtures/transformation/.es6-modules-system/imports-mixing/actual.js b/test/fixtures/transformation/es6-modules-system/imports-mixing/actual.js similarity index 100% rename from test/fixtures/transformation/.es6-modules-system/imports-mixing/actual.js rename to test/fixtures/transformation/es6-modules-system/imports-mixing/actual.js diff --git a/test/fixtures/transformation/.es6-modules-system/imports-mixing/expected.js b/test/fixtures/transformation/es6-modules-system/imports-mixing/expected.js similarity index 100% rename from test/fixtures/transformation/.es6-modules-system/imports-mixing/expected.js rename to test/fixtures/transformation/es6-modules-system/imports-mixing/expected.js diff --git a/test/fixtures/transformation/.es6-modules-system/imports-named/actual.js b/test/fixtures/transformation/es6-modules-system/imports-named/actual.js similarity index 100% rename from test/fixtures/transformation/.es6-modules-system/imports-named/actual.js rename to test/fixtures/transformation/es6-modules-system/imports-named/actual.js diff --git a/test/fixtures/transformation/.es6-modules-system/imports-named/expected.js b/test/fixtures/transformation/es6-modules-system/imports-named/expected.js similarity index 100% rename from test/fixtures/transformation/.es6-modules-system/imports-named/expected.js rename to test/fixtures/transformation/es6-modules-system/imports-named/expected.js diff --git a/test/fixtures/transformation/.es6-modules-system/imports/actual.js b/test/fixtures/transformation/es6-modules-system/imports/actual.js similarity index 100% rename from test/fixtures/transformation/.es6-modules-system/imports/actual.js rename to test/fixtures/transformation/es6-modules-system/imports/actual.js diff --git a/test/fixtures/transformation/.es6-modules-system/imports/expected.js b/test/fixtures/transformation/es6-modules-system/imports/expected.js similarity index 100% rename from test/fixtures/transformation/.es6-modules-system/imports/expected.js rename to test/fixtures/transformation/es6-modules-system/imports/expected.js diff --git a/test/fixtures/transformation/.es6-modules-system/options.json b/test/fixtures/transformation/es6-modules-system/options.json similarity index 100% rename from test/fixtures/transformation/.es6-modules-system/options.json rename to test/fixtures/transformation/es6-modules-system/options.json diff --git a/test/fixtures/transformation/.es6-modules-system/overview/actual.js b/test/fixtures/transformation/es6-modules-system/overview/actual.js similarity index 100% rename from test/fixtures/transformation/.es6-modules-system/overview/actual.js rename to test/fixtures/transformation/es6-modules-system/overview/actual.js diff --git a/test/fixtures/transformation/.es6-modules-system/overview/expected.js b/test/fixtures/transformation/es6-modules-system/overview/expected.js similarity index 100% rename from test/fixtures/transformation/.es6-modules-system/overview/expected.js rename to test/fixtures/transformation/es6-modules-system/overview/expected.js From a3eb8900a98d5417eabcc54447f067c5f7b65985 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Thu, 18 Dec 2014 01:09:24 +1100 Subject: [PATCH 093/139] add if super check to constructor default --- .../super-class-id-member-expression/expected.js | 8 ++++++-- .../super-class-id-non-identifiers/expected.js | 4 +++- .../transformation/es6-classes/super-class/expected.js | 4 +++- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/test/fixtures/transformation/es6-classes/super-class-id-member-expression/expected.js b/test/fixtures/transformation/es6-classes/super-class-id-member-expression/expected.js index 27635243a2..8349f0dbe3 100644 --- a/test/fixtures/transformation/es6-classes/super-class-id-member-expression/expected.js +++ b/test/fixtures/transformation/es6-classes/super-class-id-member-expression/expected.js @@ -13,13 +13,17 @@ var _extends = function (child, parent) { }; var BaseController = function BaseController() { - Chaplin.Controller.apply(this, arguments); + if (Chaplin.Controller) { + Chaplin.Controller.apply(this, arguments); + } }; _extends(BaseController, Chaplin.Controller); var BaseController2 = function BaseController2() { - Chaplin.Controller.Another.apply(this, arguments); + if (Chaplin.Controller.Another) { + Chaplin.Controller.Another.apply(this, arguments); + } }; _extends(BaseController2, Chaplin.Controller.Another); diff --git a/test/fixtures/transformation/es6-classes/super-class-id-non-identifiers/expected.js b/test/fixtures/transformation/es6-classes/super-class-id-non-identifiers/expected.js index 83a25652fb..e3085e2526 100644 --- a/test/fixtures/transformation/es6-classes/super-class-id-non-identifiers/expected.js +++ b/test/fixtures/transformation/es6-classes/super-class-id-non-identifiers/expected.js @@ -15,7 +15,9 @@ var _extends = function (child, parent) { var _QSuper = function () {}; var Q = function Q() { - _QSuper.apply(this, arguments); + if (_QSuper) { + _QSuper.apply(this, arguments); + } }; _extends(Q, _QSuper); diff --git a/test/fixtures/transformation/es6-classes/super-class/expected.js b/test/fixtures/transformation/es6-classes/super-class/expected.js index a4e3858bd8..d7d6bcbb27 100644 --- a/test/fixtures/transformation/es6-classes/super-class/expected.js +++ b/test/fixtures/transformation/es6-classes/super-class/expected.js @@ -13,7 +13,9 @@ var _extends = function (child, parent) { }; var Test = function Test() { - Foo.apply(this, arguments); + if (Foo) { + Foo.apply(this, arguments); + } }; _extends(Test, Foo); From 22eb8edf41ceadcc4167f9d576e8612ce0c8deea Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Thu, 18 Dec 2014 01:09:51 +1100 Subject: [PATCH 094/139] support other operators in abstract reference assignment expression - fixes #311 --- .../transformers/es7-abstract-references.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lib/6to5/transformation/transformers/es7-abstract-references.js b/lib/6to5/transformation/transformers/es7-abstract-references.js index 73d86adb7f..2bdf11365c 100644 --- a/lib/6to5/transformation/transformers/es7-abstract-references.js +++ b/lib/6to5/transformation/transformers/es7-abstract-references.js @@ -34,6 +34,17 @@ exports.AssignmentExpression = function (node, parent, file, scope) { } } + if (node.operator !== "=") { + value = t.binaryExpression( + node.operator[0], + util.template("abstract-expression-get", { + PROPERTY: node.property, + OBJECT: node.object + }), + value + ); + } + var call = util.template("abstract-expression-set", { PROPERTY: left.property, OBJECT: left.object, From c290a008b2b10b1b646730fbc417743761347fb3 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Thu, 18 Dec 2014 16:27:30 +1100 Subject: [PATCH 095/139] add `--cache` option to `6to5-node` --- bin/_6to5-node | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/bin/_6to5-node b/bin/_6to5-node index d31d93a46e..842ebd666b 100644 --- a/bin/_6to5-node +++ b/bin/_6to5-node @@ -1,13 +1,14 @@ #!/usr/bin/env node -var commander = require("commander"); -var Module = require("module"); -var path = require("path"); -var repl = require("repl"); -var to5 = require("../lib/6to5"); -var util = require("../lib/6to5/util"); -var vm = require("vm"); -var _ = require("lodash"); +var roadrunner = require("roadrunner"); +var commander = require("commander"); +var Module = require("module"); +var path = require("path"); +var repl = require("repl"); +var to5 = require("../lib/6to5"); +var util = require("../lib/6to5/util"); +var vm = require("vm"); +var _ = require("lodash"); commander.option("-e, --eval [script]", "Evaluate script"); commander.option("-p, --print", "Evaluate script and print result"); @@ -15,19 +16,23 @@ commander.option("-i, --ignore [regex]", "Ignore all files that match this regex commander.option("-x, --extensions [extensions]", "List of extensions to hook into [.es6,.js]"); commander.option("-r, --experimental", "Enable experimental support for proposed ES7 features"); commander.option("-g, --playground", "Enable playground support"); +commander.option("-c, --cache", "Cache compiled files and require paths"); var pkg = require("../package.json"); commander.version(pkg.version); commander.usage("[options] [ -e script | script.js ] [arguments]"); commander.parse(process.argv); +if (commander.cache) roadrunner.load(); + // to5.register({ experimental: commander.experimental, extensions: commander.extensions, playground: commander.playground, - ignore: commander.ignore + ignore: commander.ignore, + cache: commander.cache && roadrunner.get("6to5") }); // @@ -72,6 +77,8 @@ if (commander.eval) { } } +if (commander.cache) roadrunner.save(); + function replStart() { repl.start({ prompt: "> ", From cd6b678b5181388641609424f7c91c323f872801 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Thu, 18 Dec 2014 16:27:50 +1100 Subject: [PATCH 096/139] add support for exportdeclarations to constants --- lib/6to5/transformation/transformers/es6-constants.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/6to5/transformation/transformers/es6-constants.js b/lib/6to5/transformation/transformers/es6-constants.js index d20812a51c..4266ceca44 100644 --- a/lib/6to5/transformation/transformers/es6-constants.js +++ b/lib/6to5/transformation/transformers/es6-constants.js @@ -39,7 +39,11 @@ exports.ForStatement = function (node, parent, file) { */ _.each(node.body, function (child, parent) { - if (child && t.isVariableDeclaration(child, { kind: "const" })) { + if (t.isExportDeclaration(child)) { + child = child.declaration; + } + + if (t.isVariableDeclaration(child, { kind: "const" })) { for (var i in child.declarations) { var declar = child.declarations[i]; From 2a742b5face3f22622bec76aa5c6c8d360b2be5b Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Thu, 18 Dec 2014 16:28:00 +1100 Subject: [PATCH 097/139] add in todo for a better t.isReferenced --- lib/6to5/types/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/6to5/types/index.js b/lib/6to5/types/index.js index d4b95ee677..39c85d52bc 100644 --- a/lib/6to5/types/index.js +++ b/lib/6to5/types/index.js @@ -127,6 +127,7 @@ t.isDynamic = function (node) { } }; +// todo: https://github.com/eventualbuddha/ast-util/blob/9bf91c5ce8/lib/index.js#L454-L507 t.isReferenced = function (node, parent) { // we're a property key and we aren't computed so we aren't referenced if (t.isProperty(parent) && parent.key === node && !parent.computed) return false; From 5ab891b39d3e3c00a1fe23805597bab03e068fe1 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Thu, 18 Dec 2014 16:28:13 +1100 Subject: [PATCH 098/139] make first node in a class body inherit class comments --- lib/6to5/transformation/transformers/es6-classes.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/6to5/transformation/transformers/es6-classes.js b/lib/6to5/transformation/transformers/es6-classes.js index 6363138079..f43f522f60 100644 --- a/lib/6to5/transformation/transformers/es6-classes.js +++ b/lib/6to5/transformation/transformers/es6-classes.js @@ -82,6 +82,8 @@ Class.prototype.run = function () { this.buildBody(); + t.inheritsComments(body[0], this.node); + if (this.closure) { if (body.length === 1) { // only a constructor so no need for a closure container From a94892897398cb3c99833c8a4696ba025cb33ca4 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Thu, 18 Dec 2014 16:29:20 +1100 Subject: [PATCH 099/139] add roadrunner dependency --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index ddd914f7ba..ef9868cc5e 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,7 @@ "mkdirp": "0.5.0", "private": "0.1.6", "regexpu": "0.3.0", + "roadrunner": "^1.0.4", "source-map": "0.1.40", "source-map-support": "0.2.8" }, From 64216ec384e03a0b96754da388691a3555a8281f Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Thu, 18 Dec 2014 16:30:14 +1100 Subject: [PATCH 100/139] change generators/async functions to reference regenerator runtime rather than the polyfill --- doc/caveats.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/doc/caveats.md b/doc/caveats.md index c102733e43..ddb54fd507 100644 --- a/doc/caveats.md +++ b/doc/caveats.md @@ -4,15 +4,15 @@ In order for certain features to work they require certain polyfills. You can satisfy **all** 6to5 feature requirements by using the included [polyfill](polyfill.md). You may alternatively selectively include what you need: -| Feature | Requirements | -| --------------------------- | -------------------------------------------------------------- | -| Abstract References | [experimental](experimental.md), `Symbol` | -| Array destructuring | `Array.isArray`, `Array.from` | -| Async functions, Generators | [experimental](experimental.md), [polyfill](polyfill.md) | -| Comprehensions | [experimental](experimental.md), `Array.isArray`, `Array.from` | -| For Of | `Symbol`, `prototype[Symbol.iterator]` | -| Object spread/rest | [experimental](experimental.md), `Object.assign` | -| Spread | `Array.isArray`, `Array.from` | +| Feature | Requirements | +| --------------------------- | ---------------------------------------------------------------------------------------------------------------------- | +| Abstract References | [experimental](experimental.md), `Symbol` | +| Array destructuring | `Array.isArray`, `Array.from` | +| Async functions, Generators | [experimental](experimental.md), [regenerator runtime](https://github.com/facebook/regenerator/blob/master/runtime.js) | +| Comprehensions | [experimental](experimental.md), `Array.isArray`, `Array.from` | +| For Of | `Symbol`, `prototype[Symbol.iterator]` | +| Object spread/rest | [experimental](experimental.md), `Object.assign` | +| Spread | `Array.isArray`, `Array.from` | ## Classes From f84e0ba640d9c1f46006f78a9eb5de8702e9c136 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Thu, 18 Dec 2014 16:30:23 +1100 Subject: [PATCH 101/139] add if statement to class super constructor call --- lib/6to5/templates/class-super-constructor-call.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/6to5/templates/class-super-constructor-call.js b/lib/6to5/templates/class-super-constructor-call.js index 3c5be02aab..c50d3a50cc 100644 --- a/lib/6to5/templates/class-super-constructor-call.js +++ b/lib/6to5/templates/class-super-constructor-call.js @@ -1,2 +1,3 @@ -SUPER_NAME.apply(this, arguments); - +if (SUPER_NAME) { + SUPER_NAME.apply(this, arguments); +} From 122705bdafd72e54a8d3db342a2bbf3891a653f5 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Thu, 18 Dec 2014 16:30:33 +1100 Subject: [PATCH 102/139] remove custom regenerator runtime from dist --- Makefile | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Makefile b/Makefile index f482af434d..2c784cc090 100644 --- a/Makefile +++ b/Makefile @@ -52,9 +52,6 @@ build: node bin/cache-templates - node $(BROWSERIFY_CMD) -e lib/6to5/transformation/transformers/es6-generators/runtime.js >dist/regenerator-runtime.js - node $(UGLIFY_CMD) dist/regenerator-runtime.js >dist/regenerator-runtime.min.js - node $(BROWSERIFY_CMD) -e lib/6to5/polyfill.js >dist/polyfill.js node $(UGLIFY_CMD) dist/polyfill.js >dist/polyfill.min.js @@ -75,7 +72,6 @@ publish: cp dist/6to5.min.js browser.js cp dist/polyfill.min.js browser-polyfill.js cp dist/runtime.min.js runtime.js - cp dist/regenerator-runtime.min.js regenerator-runtime.js node bin/cache-templates test -f templates.json From 2a4c8e84239719a974f970dc0f612f77b3b58fba Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Thu, 18 Dec 2014 16:30:49 +1100 Subject: [PATCH 103/139] add note about sourcemaps and 6to5/register --- doc/usage.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/usage.md b/doc/usage.md index 08c19eef05..8c30b1ad8d 100644 --- a/doc/usage.md +++ b/doc/usage.md @@ -212,6 +212,9 @@ All subsequent files required by node with the extensions `.es6` and `.js` will be transformed by 6to5. The polyfill specified in [Polyfill](polyfill.md) is also required. +Source maps are automatically configured so if any errors a thrown then line +number info is mapped and you'll get the correct source location. + ```javascript require("6to5/register"); ``` From 41f072d112de84342360c2bdab8f603cbc4deba3 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Fri, 19 Dec 2014 01:11:48 +1100 Subject: [PATCH 104/139] clarify es5 and add getters/setters in IE 8<= to caveats fixes #314 --- doc/caveats.md | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/doc/caveats.md b/doc/caveats.md index ddb54fd507..67fd0d0a7b 100644 --- a/doc/caveats.md +++ b/doc/caveats.md @@ -2,7 +2,9 @@ In order for certain features to work they require certain polyfills. You can satisfy **all** 6to5 feature requirements by using the included -[polyfill](polyfill.md). You may alternatively selectively include what you need: +[polyfill](polyfill.md). + +You may alternatively selectively include what you need: | Feature | Requirements | | --------------------------- | ---------------------------------------------------------------------------------------------------------------------- | @@ -14,10 +16,17 @@ satisfy **all** 6to5 feature requirements by using the included | Object spread/rest | [experimental](experimental.md), `Object.assign` | | Spread | `Array.isArray`, `Array.from` | -## Classes +## ES5 -Built-in classes such as `Date`, `Array` and `DOM` cannot be subclassed due to -limitations in ES5 implementations. +Since 6to5 assumes that your code will be ran in an ES5 environment it uses ES5 +functions. So if you're using an environment that has limited or no support for +ES5 such as lower versions of IE then using the +[es5-shim](https://github.com/es-shims/es5-shim) along with the +[6to5 polyfill](polyfill.md) will add support for these methods. + +## Internet Explorer + +### Classes (9 and below) If you're inheriting from a class then static properties are inherited from it via [\_\_proto\_\_](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto), @@ -40,9 +49,11 @@ class Bar extends Foo { } ``` -## 6to5-node +## Getters/setters (8 and below) -It is necessary to manually install `kexec` package on Unix-like OSes for -`6to5-node` to correctly handle signals. +In IE8 `Object.defineProperty` can only be used on DOM objects. This is +unfortunate as it's required to set getters and setters. Due to this if +you plan on supporting IE8 or below then the user of getters and setters +isn't recommended. -**It is not recommended to use `6to5-node` with a process manager (`supervisord`, `upstart`, `systemd`, ...) without first installing `kexec`!** +Reference: [MDN](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty#Internet_Explorer_8_specific_notes). From bd255257f166048c26732305d02fed883bf2364d Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Mon, 22 Dec 2014 21:34:09 +1100 Subject: [PATCH 105/139] switch to vanilla regenerator --- .../transformers/es6-generators.js | 1 + .../emit/explode-expressions.js | 204 ------ .../es6-generators/emit/explode-statements.js | 335 ---------- .../transformers/es6-generators/emit/index.js | 611 ------------------ .../transformers/es6-generators/hoist.js | 151 ----- .../transformers/es6-generators/index.js | 3 - .../transformers/es6-generators/leap.js | 163 ----- .../transformers/es6-generators/meta.js | 98 --- .../transformers/es6-generators/runtime.js | 447 ------------- .../transformers/es6-generators/util.js | 28 - .../transformers/es6-generators/visit.js | 221 ------- package.json | 3 +- 12 files changed, 3 insertions(+), 2262 deletions(-) create mode 100644 lib/6to5/transformation/transformers/es6-generators.js delete mode 100644 lib/6to5/transformation/transformers/es6-generators/emit/explode-expressions.js delete mode 100644 lib/6to5/transformation/transformers/es6-generators/emit/explode-statements.js delete mode 100644 lib/6to5/transformation/transformers/es6-generators/emit/index.js delete mode 100644 lib/6to5/transformation/transformers/es6-generators/hoist.js delete mode 100644 lib/6to5/transformation/transformers/es6-generators/index.js delete mode 100644 lib/6to5/transformation/transformers/es6-generators/leap.js delete mode 100644 lib/6to5/transformation/transformers/es6-generators/meta.js delete mode 100644 lib/6to5/transformation/transformers/es6-generators/runtime.js delete mode 100644 lib/6to5/transformation/transformers/es6-generators/util.js delete mode 100644 lib/6to5/transformation/transformers/es6-generators/visit.js diff --git a/lib/6to5/transformation/transformers/es6-generators.js b/lib/6to5/transformation/transformers/es6-generators.js new file mode 100644 index 0000000000..7b7c0a3f0e --- /dev/null +++ b/lib/6to5/transformation/transformers/es6-generators.js @@ -0,0 +1 @@ +module.exports = require("regenerator").transform; diff --git a/lib/6to5/transformation/transformers/es6-generators/emit/explode-expressions.js b/lib/6to5/transformation/transformers/es6-generators/emit/explode-expressions.js deleted file mode 100644 index fe28897340..0000000000 --- a/lib/6to5/transformation/transformers/es6-generators/emit/explode-expressions.js +++ /dev/null @@ -1,204 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * https://raw.github.com/facebook/regenerator/master/LICENSE file. An - * additional grant of patent rights can be found in the PATENTS file in - * the same directory. - */ - -var assert = require("assert"); -var loc = require("../util").loc; -var t = require("../../../../types"); - -exports.ParenthesizedExpression = function (expr, path, explodeViaTempVar, finish) { - return finish(this.explodeExpression(path.get("expression"))); -}; - -exports.MemberExpression = function (expr, path, explodeViaTempVar, finish) { - return finish(t.memberExpression( - this.explodeExpression(path.get("object")), - expr.computed ? explodeViaTempVar(null, path.get("property")) : expr.property, - expr.computed - )); -}; - -exports.CallExpression = function (expr, path, explodeViaTempVar, finish) { - var oldCalleePath = path.get("callee"); - var newCallee = this.explodeExpression(oldCalleePath); - - // If the callee was not previously a MemberExpression, then the - // CallExpression was "unqualified," meaning its `this` object should - // be the global object. If the exploded expression has become a - // MemberExpression, then we need to force it to be unqualified by - // using the (0, object.property)(...) trick; otherwise, it will - // receive the object of the MemberExpression as its `this` object. - if (!t.isMemberExpression(oldCalleePath.node) && t.isMemberExpression(newCallee)) { - newCallee = t.sequenceExpression([ - t.literal(0), - newCallee - ]); - } - - return finish(t.callExpression( - newCallee, - path.get("arguments").map(function (argPath) { - return explodeViaTempVar(null, argPath); - }) - )); -}; - -exports.NewExpression = function (expr, path, explodeViaTempVar, finish) { - return finish(t.newExpression( - explodeViaTempVar(null, path.get("callee")), - path.get("arguments").map(function (argPath) { - return explodeViaTempVar(null, argPath); - }) - )); -}; - -exports.ObjectExpression = function (expr, path, explodeViaTempVar, finish) { - return finish(t.objectExpression( - path.get("properties").map(function (propPath) { - return t.property( - propPath.value.kind, - propPath.value.key, - explodeViaTempVar(null, propPath.get("value")) - ); - }) - )); -}; - -exports.ArrayExpression = function (expr, path, explodeViaTempVar, finish) { - return finish(t.arrayExpression( - path.get("elements").map(function (elemPath) { - return explodeViaTempVar(null, elemPath); - }) - )); -}; - -exports.SequenceExpression = function (expr, path, explodeViaTempVar, finish, ignoreResult) { - var lastIndex = expr.expressions.length - 1; - var self = this; - var result; - - path.get("expressions").each(function (exprPath) { - if (exprPath.name === lastIndex) { - result = self.explodeExpression(exprPath, ignoreResult); - } else { - self.explodeExpression(exprPath, true); - } - }); - - return result; -}; - -exports.LogicalExpression = function (expr, path, explodeViaTempVar, finish, ignoreResult) { - var after = loc(); - var result; - - if (!ignoreResult) { - result = this.makeTempVar(); - } - - var left = explodeViaTempVar(result, path.get("left")); - - if (expr.operator === "&&") { - this.jumpIfNot(left, after); - } else { - assert.strictEqual(expr.operator, "||"); - this.jumpIf(left, after); - } - - explodeViaTempVar(result, path.get("right"), ignoreResult); - - this.mark(after); - - return result; -}; - -exports.ConditionalExpression = function (expr, path, explodeViaTempVar, finish, ignoreResult) { - var elseLoc = loc(); - var after = loc(); - var test = this.explodeExpression(path.get("test")); - var result; - - this.jumpIfNot(test, elseLoc); - - if (!ignoreResult) { - result = this.makeTempVar(); - } - - explodeViaTempVar(result, path.get("consequent"), ignoreResult); - this.jump(after); - - this.mark(elseLoc); - explodeViaTempVar(result, path.get("alternate"), ignoreResult); - - this.mark(after); - - return result; -}; - -exports.UnaryExpression = function (expr, path, explodeViaTempVar, finish) { - return finish(t.unaryExpression( - expr.operator, - // Can't (and don't need to) break up the syntax of the argument. - // Think about delete a[b]. - this.explodeExpression(path.get("argument")), - !!expr.prefix - )); -}; - -exports.BinaryExpression = function (expr, path, explodeViaTempVar, finish) { - return finish(t.binaryExpression( - expr.operator, - explodeViaTempVar(null, path.get("left")), - explodeViaTempVar(null, path.get("right")) - )); -}; - -exports.AssignmentExpression = function (expr, path, explodeViaTempVar, finish) { - return finish(t.assignmentExpression( - expr.operator, - this.explodeExpression(path.get("left")), - this.explodeExpression(path.get("right")) - )); -}; - -exports.UpdateExpression = function (expr, path, explodeViaTempVar, finish) { - return finish(t.updateExpression( - expr.operator, - this.explodeExpression(path.get("argument")), - expr.prefix - )); -}; - -exports.YieldExpression = function (expr, path) { - var after = loc(); - var arg = expr.argument && this.explodeExpression(path.get("argument")); - var result; - - if (arg && expr.delegate) { - result = this.makeTempVar(); - - this.emit(t.returnStatement(t.callExpression( - this.contextProperty("delegateYield"), [ - arg, - t.literal(result.property.name), - after - ] - ))); - - this.mark(after); - - return result; - } - - this.emitAssign(this.contextProperty("next"), after); - this.emit(t.returnStatement(arg || null)); - this.mark(after); - - return this.contextProperty("sent"); -}; diff --git a/lib/6to5/transformation/transformers/es6-generators/emit/explode-statements.js b/lib/6to5/transformation/transformers/es6-generators/emit/explode-statements.js deleted file mode 100644 index 896d461561..0000000000 --- a/lib/6to5/transformation/transformers/es6-generators/emit/explode-statements.js +++ /dev/null @@ -1,335 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * https://raw.github.com/facebook/regenerator/master/LICENSE file. An - * additional grant of patent rights can be found in the PATENTS file in - * the same directory. - */ - -var assert = require("assert"); -var types = require("ast-types"); -var leap = require("../leap"); -var util = require("../util"); -var t = require("../../../../types"); - -var runtimeKeysMethod = util.runtimeProperty("keys"); -var loc = util.loc; - -exports.ExpressionStatement = function (path) { - this.explodeExpression(path.get("expression"), true); -}; - -exports.LabeledStatement = function (path, stmt) { - this.explodeStatement(path.get("body"), stmt.label); -}; - -exports.WhileStatement = function (path, stmt, labelId) { - var before = loc(); - var after = loc(); - - this.mark(before); - this.jumpIfNot(this.explodeExpression(path.get("test")), after); - this.leapManager.withEntry( - new leap.LoopEntry(after, before, labelId), - function () { this.explodeStatement(path.get("body")); } - ); - this.jump(before); - this.mark(after); -}; - -exports.DoWhileStatement = function (path, stmt, labelId) { - var first = loc(); - var test = loc(); - var after = loc(); - - this.mark(first); - this.leapManager.withEntry( - new leap.LoopEntry(after, test, labelId), - function () { this.explode(path.get("body")); } - ); - this.mark(test); - this.jumpIf(this.explodeExpression(path.get("test")), first); - this.mark(after); -}; - -exports.ForStatement = function (path, stmt, labelId) { - var head = loc(); - var update = loc(); - var after = loc(); - - if (stmt.init) { - // We pass true here to indicate that if stmt.init is an expression - // then we do not care about its result. - this.explode(path.get("init"), true); - } - - this.mark(head); - - if (stmt.test) { - this.jumpIfNot(this.explodeExpression(path.get("test")), after); - } else { - // No test means continue unconditionally. - } - - this.leapManager.withEntry( - new leap.LoopEntry(after, update, labelId), - function () { this.explodeStatement(path.get("body")); } - ); - - this.mark(update); - - if (stmt.update) { - // We pass true here to indicate that if stmt.update is an - // expression then we do not care about its result. - this.explode(path.get("update"), true); - } - - this.jump(head); - - this.mark(after); -}; - -exports.ForInStatement = function (path, stmt, labelId) { - t.assertIdentifier(stmt.left); - - var head = loc(); - var after = loc(); - - var keyIterNextFn = this.makeTempVar(); - this.emitAssign( - keyIterNextFn, - t.callExpression( - runtimeKeysMethod, - [this.explodeExpression(path.get("right"))] - ) - ); - - this.mark(head); - - var keyInfoTmpVar = this.makeTempVar(); - this.jumpIf( - t.memberExpression( - t.assignmentExpression( - "=", - keyInfoTmpVar, - t.callExpression(keyIterNextFn, []) - ), - t.identifier("done"), - false - ), - after - ); - - this.emitAssign( - stmt.left, - t.memberExpression( - keyInfoTmpVar, - t.identifier("value"), - false - ) - ); - - this.leapManager.withEntry( - new leap.LoopEntry(after, head, labelId), - function () { this.explodeStatement(path.get("body")); } - ); - - this.jump(head); - - this.mark(after); -}; - -exports.BreakStatement = function (path, stmt) { - this.emitAbruptCompletion({ - type: "break", - target: this.leapManager.getBreakLoc(stmt.label) - }); -}; - -exports.ContinueStatement = function (path, stmt) { - this.emitAbruptCompletion({ - type: "continue", - target: this.leapManager.getContinueLoc(stmt.label) - }); -}; - -exports.SwitchStatement = function (path, stmt) { - // Always save the discriminant into a temporary variable in case the - // test expressions overwrite values like context.sent. - var disc = this.emitAssign( - this.makeTempVar(), - this.explodeExpression(path.get("discriminant")) - ); - - var after = loc(); - var defaultLoc = loc(); - var condition = defaultLoc; - var caseLocs = []; - var self = this; - - // If there are no cases, .cases might be undefined. - var cases = stmt.cases || []; - - for (var i = cases.length - 1; i >= 0; --i) { - var c = cases[i]; - t.assertSwitchCase(c); - - if (c.test) { - condition = t.conditionalExpression( - t.binaryExpression("===", disc, c.test), - caseLocs[i] = loc(), - condition - ); - } else { - caseLocs[i] = defaultLoc; - } - } - - this.jump(this.explodeExpression( - new types.NodePath(condition, path, "discriminant") - )); - - this.leapManager.withEntry( - new leap.SwitchEntry(after), - function () { - path.get("cases").each(function (casePath) { - var i = casePath.name; - - self.mark(caseLocs[i]); - - casePath.get("consequent").each( - self.explodeStatement, - self - ); - }); - } - ); - - this.mark(after); - if (defaultLoc.value === -1) { - this.mark(defaultLoc); - assert.strictEqual(after.value, defaultLoc.value); - } -}; - -exports.IfStatement = function (path, stmt) { - var elseLoc = stmt.alternate && loc(); - var after = loc(); - - this.jumpIfNot( - this.explodeExpression(path.get("test")), - elseLoc || after - ); - - this.explodeStatement(path.get("consequent")); - - if (elseLoc) { - this.jump(after); - this.mark(elseLoc); - this.explodeStatement(path.get("alternate")); - } - - this.mark(after); -}; - -exports.ReturnStatement = function (path) { - this.emitAbruptCompletion({ - type: "return", - value: this.explodeExpression(path.get("argument")) - }); -}; - -exports.TryStatement = function (path, stmt) { - var after = loc(); - var self = this; - - var handler = stmt.handler; - if (!handler && stmt.handlers) { - handler = stmt.handlers[0] || null; - } - - var catchLoc = handler && loc(); - var catchEntry = catchLoc && new leap.CatchEntry( - catchLoc, - handler.param - ); - - var finallyLoc = stmt.finalizer && loc(); - var finallyEntry = finallyLoc && new leap.FinallyEntry(finallyLoc); - - var tryEntry = new leap.TryEntry( - this.getUnmarkedCurrentLoc(), - catchEntry, - finallyEntry - ); - - this.tryEntries.push(tryEntry); - this.updateContextPrevLoc(tryEntry.firstLoc); - - this.leapManager.withEntry(tryEntry, function () { - this.explodeStatement(path.get("block")); - - if (catchLoc) { - if (finallyLoc) { - // If we have both a catch block and a finally block, then - // because we emit the catch block first, we need to jump over - // it to the finally block. - this.jump(finallyLoc); - - } else { - // If there is no finally block, then we need to jump over the - // catch block to the fall-through location. - this.jump(after); - } - - this.updateContextPrevLoc(self.mark(catchLoc)); - - var bodyPath = path.get("handler", "body"); - var safeParam = this.makeTempVar(); - this.clearPendingException(tryEntry.firstLoc, safeParam); - - var catchScope = bodyPath.scope; - var catchParamName = handler.param.name; - t.assertCatchClause(catchScope.node); - assert.strictEqual(catchScope.lookup(catchParamName), catchScope); - - types.visit(bodyPath, { - visitIdentifier: function (path) { - if (t.isReferenced(path.value, path.parentPath.node) && - path.value.name === catchParamName && - path.scope.lookup(catchParamName) === catchScope) { - return safeParam; - } - this.traverse(path); - } - }); - - this.leapManager.withEntry(catchEntry, function () { - this.explodeStatement(bodyPath); - }); - } - - if (finallyLoc) { - this.updateContextPrevLoc(this.mark(finallyLoc)); - - this.leapManager.withEntry(finallyEntry, function () { - this.explodeStatement(path.get("finalizer")); - }); - - this.emit(t.callExpression( - this.contextProperty("finish"), - [finallyEntry.firstLoc] - )); - } - }); - - this.mark(after); -}; - -exports.ThrowStatement = function (path) { - this.emit(t.throwStatement( - this.explodeExpression(path.get("argument")) - )); -}; diff --git a/lib/6to5/transformation/transformers/es6-generators/emit/index.js b/lib/6to5/transformation/transformers/es6-generators/emit/index.js deleted file mode 100644 index 8df1576721..0000000000 --- a/lib/6to5/transformation/transformers/es6-generators/emit/index.js +++ /dev/null @@ -1,611 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * https://raw.github.com/facebook/regenerator/master/LICENSE file. An - * additional grant of patent rights can be found in the PATENTS file in - * the same directory. - */ - -exports.Emitter = Emitter; - -var explodeExpressions = require("./explode-expressions"); -var explodeStatements = require("./explode-statements"); -var assert = require("assert"); -var types = require("ast-types"); -var leap = require("../leap"); -var meta = require("../meta"); -var util = require("../util"); -var t = require("../../../../types"); -var _ = require("lodash"); - -var loc = util.loc; -var n = types.namedTypes; - -function Emitter(contextId) { - assert.ok(this instanceof Emitter); - t.assertIdentifier(contextId); - - // In order to make sure the context object does not collide with - // anything in the local scope, we might have to rename it, so we - // refer to it symbolically instead of just assuming that it will be - // called "context". - this.contextId = contextId; - - // An append-only list of Statements that grows each time this.emit is - // called. - this.listing = []; - - // A sparse array whose keys correspond to locations in this.listing - // that have been marked as branch/jump targets. - this.marked = [true]; - - // The last location will be marked when this.getDispatchLoop is - // called. - this.finalLoc = loc(); - - // A list of all leap.TryEntry statements emitted. - this.tryEntries = []; - - // Each time we evaluate the body of a loop, we tell this.leapManager - // to enter a nested loop context that determines the meaning of break - // and continue statements therein. - this.leapManager = new leap.LeapManager(this); -} - -// Sets the exact value of the given location to the offset of the next -// Statement emitted. -Emitter.prototype.mark = function (loc) { - t.assertLiteral(loc); - var index = this.listing.length; - if (loc.value === -1) { - loc.value = index; - } else { - // Locations can be marked redundantly, but their values cannot change - // once set the first time. - assert.strictEqual(loc.value, index); - } - this.marked[index] = true; - return loc; -}; - -Emitter.prototype.emit = function (node) { - if (t.isExpression(node)) node = t.expressionStatement(node); - t.assertStatement(node); - this.listing.push(node); -}; - -// Shorthand for emitting assignment statements. This will come in handy -// for assignments to temporary variables. -Emitter.prototype.emitAssign = function (lhs, rhs) { - this.emit(this.assign(lhs, rhs)); - return lhs; -}; - -// Shorthand for an assignment statement. -Emitter.prototype.assign = function (lhs, rhs) { - return t.expressionStatement( - t.assignmentExpression("=", lhs, rhs)); -}; - -// Convenience function for generating expressions like context.next, -// context.sent, and context.rval. -Emitter.prototype.contextProperty = function (name, computed) { - return t.memberExpression( - this.contextId, - computed ? t.literal(name) : t.identifier(name), - !!computed - ); -}; - -var volatileContextPropertyNames = { - prev: true, - next: true, - sent: true, - rval: true -}; - -// A "volatile" context property is a MemberExpression like context.sent -// that should probably be stored in a temporary variable when there's a -// possibility the property will get overwritten. -Emitter.prototype.isVolatileContextProperty = function (expr) { - if (t.isMemberExpression(expr)) { - if (expr.computed) { - // If it's a computed property such as context[couldBeAnything], - // assume the worst in terms of volatility. - return true; - } - - if (t.isIdentifier(expr.object) && - t.isIdentifier(expr.property) && - expr.object.name === this.contextId.name && - _.has(volatileContextPropertyNames, expr.property.name)) { - return true; - } - } - - return false; -}; - -// Shorthand for setting context.rval and jumping to `context.stop()`. -Emitter.prototype.stop = function (rval) { - if (rval) { - this.setReturnValue(rval); - } - - this.jump(this.finalLoc); -}; - -Emitter.prototype.setReturnValue = function (valuePath) { - t.assertExpression(valuePath.value); - - this.emitAssign( - this.contextProperty("rval"), - this.explodeExpression(valuePath) - ); -}; - -Emitter.prototype.clearPendingException = function (tryLoc, assignee) { - t.assertLiteral(tryLoc); - - var catchCall = t.callExpression( - this.contextProperty("catch", true), - [tryLoc] - ); - - if (assignee) { - this.emitAssign(assignee, catchCall); - } else { - this.emit(catchCall); - } -}; - -// Emits code for an unconditional jump to the given location, even if the -// exact value of the location is not yet known. -Emitter.prototype.jump = function (toLoc) { - this.emitAssign(this.contextProperty("next"), toLoc); - this.emit(t.breakStatement()); -}; - -// Conditional jump. -Emitter.prototype.jumpIf = function (test, toLoc) { - t.assertExpression(test); - t.assertLiteral(toLoc); - - this.emit(t.ifStatement( - test, - t.blockStatement([ - this.assign(this.contextProperty("next"), toLoc), - t.breakStatement() - ]) - )); -}; - -// Conditional jump, with the condition negated. -Emitter.prototype.jumpIfNot = function (test, toLoc) { - t.assertExpression(test); - t.assertLiteral(toLoc); - - var negatedTest; - if (t.isUnaryExpression(test) && test.operator === "!") { - // Avoid double negation. - negatedTest = test.argument; - } else { - negatedTest = t.unaryExpression("!", test); - } - - this.emit(t.ifStatement( - negatedTest, - t.blockStatement([ - this.assign(this.contextProperty("next"), toLoc), - t.breakStatement() - ]) - )); -}; - -// Returns a unique MemberExpression that can be used to store and -// retrieve temporary values. Since the object of the member expression is -// the context object, which is presumed to coexist peacefully with all -// other local variables, and since we just increment `nextTempId` -// monotonically, uniqueness is assured. -var nextTempId = 0; -Emitter.prototype.makeTempVar = function () { - return this.contextProperty("t" + nextTempId++); -}; - -Emitter.prototype.getContextFunction = function (id) { - var node = t.functionExpression( - id || null, - [this.contextId], - t.blockStatement([this.getDispatchLoop()]), - false, // Not a generator anymore! - false // Nor an expression. - ); - node._aliasFunction = true; - return node; -}; - -// Turns this.listing into a loop of the form -// -// while (1) switch (context.next) { -// case 0: -// ... -// case n: -// return context.stop(); -// } -// -// Each marked location in this.listing will correspond to one generated -// case statement. -Emitter.prototype.getDispatchLoop = function () { - var self = this; - var cases = []; - var current; - - // If we encounter a break, continue, or return statement in a switch - // case, we can skip the rest of the statements until the next case. - var alreadyEnded = false; - - self.listing.forEach(function (stmt, i) { - if (self.marked.hasOwnProperty(i)) { - cases.push(t.switchCase(t.literal(i), current = [])); - alreadyEnded = false; - } - - if (!alreadyEnded) { - current.push(stmt); - if (isSwitchCaseEnder(stmt)) - alreadyEnded = true; - } - }); - - // Now that we know how many statements there will be in this.listing, - // we can finally resolve this.finalLoc.value. - this.finalLoc.value = this.listing.length; - - cases.push( - t.switchCase(this.finalLoc, [ - // Intentionally fall through to the "end" case... - ]), - - // So that the runtime can jump to the final location without having - // to know its offset, we provide the "end" case as a synonym. - t.switchCase(t.literal("end"), [ - // This will check/clear both context.thrown and context.rval. - t.returnStatement( - t.callExpression(this.contextProperty("stop"), []) - ) - ]) - ); - - return t.whileStatement( - t.literal(true), - t.switchStatement( - t.assignmentExpression( - "=", - this.contextProperty("prev"), - this.contextProperty("next") - ), - cases - ) - ); -}; - -// See comment above re: alreadyEnded. -function isSwitchCaseEnder(stmt) { - return t.isBreakStatement(stmt) || - t.isContinueStatement(stmt) || - t.isReturnStatement(stmt) || - t.isThrowStatement(stmt); -} - -Emitter.prototype.getTryEntryList = function () { - if (this.tryEntries.length === 0) { - // To avoid adding a needless [] to the majority of runtime.wrap - // argument lists, force the caller to handle this case specially. - return null; - } - - var lastLocValue = 0; - - return t.arrayExpression( - this.tryEntries.map(function (tryEntry) { - var thisLocValue = tryEntry.firstLoc.value; - assert.ok(thisLocValue >= lastLocValue, "try entries out of order"); - lastLocValue = thisLocValue; - - var ce = tryEntry.catchEntry; - var fe = tryEntry.finallyEntry; - - var triple = [ - tryEntry.firstLoc, - // The null here makes a hole in the array. - ce ? ce.firstLoc : null - ]; - - if (fe) { - triple[2] = fe.firstLoc; - } - - return t.arrayExpression(triple); - }) - ); -}; - -// All side effects must be realized in order. - -// If any subexpression harbors a leap, all subexpressions must be -// neutered of side effects. - -// No destructive modification of AST nodes. - -Emitter.prototype.explode = function (path, ignoreResult) { - assert.ok(path instanceof types.NodePath); - - var node = path.value; - var self = this; - - n.Node.check(node); - - if (t.isStatement(node)) - return self.explodeStatement(path); - - if (t.isExpression(node)) - return self.explodeExpression(path, ignoreResult); - - if (t.isDeclaration(node)) - throw getDeclError(node); - - switch (node.type) { - case "Program": - return path.get("body").map(self.explodeStatement, self); - - case "VariableDeclarator": - throw getDeclError(node); - - // These node types should be handled by their parent nodes - // (ObjectExpression, SwitchStatement, and TryStatement, respectively). - case "Property": - case "SwitchCase": - case "CatchClause": - throw new Error(node.type + " nodes should be handled by their parents"); - - default: - throw new Error("unknown Node of type " + JSON.stringify(node.type)); - } -}; - -function getDeclError(node) { - return new Error( - "all declarations should have been transformed into " + - "assignments before the Exploder began its work: " + - JSON.stringify(node)); -} - -Emitter.prototype.explodeStatement = function (path, labelId) { - assert.ok(path instanceof types.NodePath); - - var stmt = path.value; - var self = this; - - t.assertStatement(stmt); - - if (labelId) { - t.assertIdentifier(labelId); - } else { - labelId = null; - } - - // Explode BlockStatement nodes even if they do not contain a yield, - // because we don't want or need the curly braces. - if (t.isBlockStatement(stmt)) { - return path.get("body").each( - self.explodeStatement, - self - ); - } - - if (!meta.containsLeap(stmt)) { - // Technically we should be able to avoid emitting the statement - // altogether if !meta.hasSideEffects(stmt), but that leads to - // confusing generated code (for instance, `while (true) {}` just - // disappears) and is probably a more appropriate job for a dedicated - // dead code elimination pass. - self.emit(stmt); - return; - } - - var fn = explodeStatements[stmt.type]; - if (fn) { - fn.call(this, path, stmt, labelId); - } else { - throw new Error("unknown Statement of type " + JSON.stringify(stmt.type)); - } -}; - -Emitter.prototype.emitAbruptCompletion = function (record) { - if (!isValidCompletion(record)) { - assert.ok( - false, - "invalid completion record: " + JSON.stringify(record) - ); - } - - assert.notStrictEqual( - record.type, "normal", - "normal completions are not abrupt" - ); - - var abruptArgs = [t.literal(record.type)]; - - if (record.type === "break" || record.type === "continue") { - t.assertLiteral(record.target); - abruptArgs[1] = record.target; - } else if (record.type === "return" || record.type === "throw") { - if (record.value) { - t.assertExpression(record.value); - abruptArgs[1] = record.value; - } - } - - this.emit( - t.returnStatement( - t.callExpression( - this.contextProperty("abrupt"), - abruptArgs - ) - ) - ); -}; - -function isValidCompletion(record) { - var type = record.type; - - if (type === "normal") { - return !_.has(record, "target"); - } - - if (type === "break" || type === "continue") { - return !_.has(record, "value") && t.isLiteral(record.target); - } - - if (type === "return" || type === "throw") { - return _.has(record, "value") && !_.has(record, "target"); - } - - return false; -} - -// Not all offsets into emitter.listing are potential jump targets. For -// example, execution typically falls into the beginning of a try block -// without jumping directly there. This method returns the current offset -// without marking it, so that a switch case will not necessarily be -// generated for this offset (I say "not necessarily" because the same -// location might end up being marked in the process of emitting other -// statements). There's no logical harm in marking such locations as jump -// targets, but minimizing the number of switch cases keeps the generated -// code shorter. -Emitter.prototype.getUnmarkedCurrentLoc = function () { - return t.literal(this.listing.length); -}; - -// The context.prev property takes the value of context.next whenever we -// evaluate the switch statement discriminant, which is generally good -// enough for tracking the last location we jumped to, but sometimes -// context.prev needs to be more precise, such as when we fall -// successfully out of a try block and into a finally block without -// jumping. This method exists to update context.prev to the freshest -// available location. If we were implementing a full interpreter, we -// would know the location of the current instruction with complete -// precision at all times, but we don't have that luxury here, as it would -// be costly and verbose to set context.prev before every statement. -Emitter.prototype.updateContextPrevLoc = function (loc) { - if (loc) { - t.assertLiteral(loc); - - if (loc.value === -1) { - // If an uninitialized location literal was passed in, set its value - // to the current this.listing.length. - loc.value = this.listing.length; - } else { - // Otherwise assert that the location matches the current offset. - assert.strictEqual(loc.value, this.listing.length); - } - - } else { - loc = this.getUnmarkedCurrentLoc(); - } - - // Make sure context.prev is up to date in case we fell into this try - // statement without jumping to it. TODO Consider avoiding this - // assignment when we know control must have jumped here. - this.emitAssign(this.contextProperty("prev"), loc); -}; - -Emitter.prototype.explodeExpression = function (path, ignoreResult) { - assert.ok(path instanceof types.NodePath); - - var expr = path.value; - if (expr) { - t.assertExpression(expr); - } else { - return expr; - } - - var self = this; - - function finish(expr) { - t.assertExpression(expr); - if (ignoreResult) { - self.emit(expr); - } else { - return expr; - } - } - - // If the expression does not contain a leap, then we either emit the - // expression as a standalone statement or return it whole. - if (!meta.containsLeap(expr)) { - return finish(expr); - } - - // If any child contains a leap (such as a yield or labeled continue or - // break statement), then any sibling subexpressions will almost - // certainly have to be exploded in order to maintain the order of their - // side effects relative to the leaping child(ren). - var hasLeapingChildren = meta.containsLeap.onlyChildren(expr); - - // In order to save the rest of explodeExpression from a combinatorial - // trainwreck of special cases, explodeViaTempVar is responsible for - // deciding when a subexpression needs to be "exploded," which is my - // very technical term for emitting the subexpression as an assignment - // to a temporary variable and the substituting the temporary variable - // for the original subexpression. Think of exploded view diagrams, not - // Michael Bay movies. The point of exploding subexpressions is to - // control the precise order in which the generated code realizes the - // side effects of those subexpressions. - function explodeViaTempVar(tempVar, childPath, ignoreChildResult) { - assert.ok(childPath instanceof types.NodePath); - - assert.ok( - !ignoreChildResult || !tempVar, - "Ignoring the result of a child expression but forcing it to " + - "be assigned to a temporary variable?" - ); - - var result = self.explodeExpression(childPath, ignoreChildResult); - - if (ignoreChildResult) { - // Side effects already emitted above. - - } else if (tempVar || (hasLeapingChildren && - (self.isVolatileContextProperty(result) || - meta.hasSideEffects(result)))) { - // If tempVar was provided, then the result will always be assigned - // to it, even if the result does not otherwise need to be assigned - // to a temporary variable. When no tempVar is provided, we have - // the flexibility to decide whether a temporary variable is really - // necessary. In general, temporary assignment is required only - // when some other child contains a leap and the child in question - // is a context property like $ctx.sent that might get overwritten - // or an expression with side effects that need to occur in proper - // sequence relative to the leap. - result = self.emitAssign( - tempVar || self.makeTempVar(), - result - ); - } - return result; - } - - // If ignoreResult is true, then we must take full responsibility for - // emitting the expression with all its side effects, and we should not - // return a result. - - var fn = explodeExpressions[expr.type]; - if (fn) { - return fn.call(this, expr, path, explodeViaTempVar, finish, ignoreResult); - } else { - throw new Error("unknown Expression of type " + JSON.stringify(expr.type)); - } -}; diff --git a/lib/6to5/transformation/transformers/es6-generators/hoist.js b/lib/6to5/transformation/transformers/es6-generators/hoist.js deleted file mode 100644 index b9772466ba..0000000000 --- a/lib/6to5/transformation/transformers/es6-generators/hoist.js +++ /dev/null @@ -1,151 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * https://raw.githut.com/facebook/regenerator/master/LICENSE file. An - * additional grant of patent rights can be found in the PATENTS file in - * the same directory. - */ - -var assert = require("assert"); -var types = require("ast-types"); -var t = require("../../../types"); -var _ = require("lodash"); - -// The hoist function takes a FunctionExpression or FunctionDeclaration -// and replaces any Declaration nodes in its body with assignments, then -// returns a VariableDeclaration containing just the names of the removed -// declarations. -exports.hoist = function (funPath) { - assert.ok(funPath instanceof types.NodePath); - t.assertFunction(funPath.value); - - var vars = {}; - - function varDeclToExpr(vdec, includeIdentifiers) { - t.assertVariableDeclaration(vdec); - var exprs = []; - - vdec.declarations.forEach(function (dec) { - vars[dec.id.name] = dec.id; - - if (dec.init) { - exprs.push(t.assignmentExpression( - "=", dec.id, dec.init - )); - } else if (includeIdentifiers) { - exprs.push(dec.id); - } - }); - - if (exprs.length === 0) - return null; - - if (exprs.length === 1) - return exprs[0]; - - return t.sequenceExpression(exprs); - } - - types.visit(funPath.get("body"), { - visitVariableDeclaration: function (path) { - var expr = varDeclToExpr(path.value, false); - if (expr === null) { - path.replace(); - } else { - // We don't need to traverse this expression any further because - // there can't be any new declarations inside an expression. - return t.expressionStatement(expr); - } - - // Since the original node has been either removed or replaced, - // avoid traversing it any further. - return false; - }, - - visitForStatement: function (path) { - var init = path.value.init; - if (t.isVariableDeclaration(init)) { - path.get("init").replace(varDeclToExpr(init, false)); - } - this.traverse(path); - }, - - visitForInStatement: function (path) { - var left = path.value.left; - if (t.isVariableDeclaration(left)) { - path.get("left").replace(varDeclToExpr(left, true)); - } - this.traverse(path); - }, - - visitFunctionDeclaration: function (path) { - var node = path.value; - vars[node.id.name] = node.id; - - var assignment = t.expressionStatement( - t.assignmentExpression( - "=", - node.id, - t.functionExpression( - node.id, - node.params, - node.body, - node.generator, - node.expression - ) - ) - ); - - if (t.isBlockStatement(path.parent.node)) { - // Insert the assignment form before the first statement in the - // enclosing block. - path.parent.get("body").unshift(assignment); - - // Remove the function declaration now that we've inserted the - // equivalent assignment form at the beginning of the block. - path.replace(); - - } else { - // If the parent node is not a block statement, then we can just - // replace the declaration with the equivalent assignment form - // without worrying about hoisting it. - path.replace(assignment); - } - - // Don't hoist variables out of inner functions. - return false; - }, - - visitFunctionExpression: function () { - // Don't descend into nested function expressions. - return false; - } - }); - - var paramNames = {}; - funPath.get("params").each(function (paramPath) { - var param = paramPath.value; - if (t.isIdentifier(param)) { - paramNames[param.name] = param; - } else { - // Variables declared by destructuring parameter patterns will be - // harmlessly re-declared. - } - }); - - var declarations = []; - - Object.keys(vars).forEach(function (name) { - if (!_.has(paramNames, name)) { - declarations.push(t.variableDeclarator(vars[name], null)); - } - }); - - if (declarations.length === 0) { - return null; // Be sure to handle this case! - } - - return t.variableDeclaration("var", declarations); -}; diff --git a/lib/6to5/transformation/transformers/es6-generators/index.js b/lib/6to5/transformation/transformers/es6-generators/index.js deleted file mode 100644 index 5d2aa5acba..0000000000 --- a/lib/6to5/transformation/transformers/es6-generators/index.js +++ /dev/null @@ -1,3 +0,0 @@ -var t = require("../../../types"); - -exports.ast = require("./visit").transform; diff --git a/lib/6to5/transformation/transformers/es6-generators/leap.js b/lib/6to5/transformation/transformers/es6-generators/leap.js deleted file mode 100644 index 5cd289b501..0000000000 --- a/lib/6to5/transformation/transformers/es6-generators/leap.js +++ /dev/null @@ -1,163 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * https://raw.github.com/facebook/regenerator/master/LICENSE file. An - * additional grant of patent rights can be found in the PATENTS file in - * the same directory. - */ - -exports.FunctionEntry = FunctionEntry; -exports.FinallyEntry = FinallyEntry; -exports.SwitchEntry = SwitchEntry; -exports.LeapManager = LeapManager; -exports.CatchEntry = CatchEntry; -exports.LoopEntry = LoopEntry; -exports.TryEntry = TryEntry; - -var assert = require("assert"); -var util = require("util"); -var t = require("../../../types"); - -var inherits = util.inherits; - -function Entry() { - assert.ok(this instanceof Entry); -} - -function FunctionEntry(returnLoc) { - Entry.call(this); - - t.assertLiteral(returnLoc); - - this.returnLoc = returnLoc; -} - -inherits(FunctionEntry, Entry); - -function LoopEntry(breakLoc, continueLoc, label) { - Entry.call(this); - - t.assertLiteral(breakLoc); - t.assertLiteral(continueLoc); - - if (label) { - t.assertIdentifier(label); - } else { - label = null; - } - - this.breakLoc = breakLoc; - this.continueLoc = continueLoc; - this.label = label; -} - -inherits(LoopEntry, Entry); - -function SwitchEntry(breakLoc) { - Entry.call(this); - - t.assertLiteral(breakLoc); - - this.breakLoc = breakLoc; -} - -inherits(SwitchEntry, Entry); - -function TryEntry(firstLoc, catchEntry, finallyEntry) { - Entry.call(this); - - t.assertLiteral(firstLoc); - - if (catchEntry) { - assert.ok(catchEntry instanceof CatchEntry); - } else { - catchEntry = null; - } - - if (finallyEntry) { - assert.ok(finallyEntry instanceof FinallyEntry); - } else { - finallyEntry = null; - } - - // Have to have one or the other (or both). - assert.ok(catchEntry || finallyEntry); - - this.firstLoc = firstLoc; - this.catchEntry = catchEntry; - this.finallyEntry = finallyEntry; -} - -inherits(TryEntry, Entry); - -function CatchEntry(firstLoc, paramId) { - Entry.call(this); - - t.assertLiteral(firstLoc); - t.assertIdentifier(paramId); - - this.firstLoc = firstLoc; - this.paramId = paramId; -} - -inherits(CatchEntry, Entry); - -function FinallyEntry(firstLoc) { - Entry.call(this); - - t.assertLiteral(firstLoc); - - this.firstLoc = firstLoc; -} - -inherits(FinallyEntry, Entry); - -function LeapManager(emitter) { - assert.ok(this instanceof LeapManager); - - var Emitter = require("./emit").Emitter; - assert.ok(emitter instanceof Emitter); - - this.emitter = emitter; - this.entryStack = [new FunctionEntry(emitter.finalLoc)]; -} - -LeapManager.prototype.withEntry = function (entry, callback) { - assert.ok(entry instanceof Entry); - this.entryStack.push(entry); - try { - callback.call(this.emitter); - } finally { - var popped = this.entryStack.pop(); - assert.strictEqual(popped, entry); - } -}; - -LeapManager.prototype._findLeapLocation = function (property, label) { - for (var i = this.entryStack.length - 1; i >= 0; --i) { - var entry = this.entryStack[i]; - var loc = entry[property]; - if (loc) { - if (label) { - if (entry.label && - entry.label.name === label.name) { - return loc; - } - } else { - return loc; - } - } - } - - return null; -}; - -LeapManager.prototype.getBreakLoc = function (label) { - return this._findLeapLocation("breakLoc", label); -}; - -LeapManager.prototype.getContinueLoc = function (label) { - return this._findLeapLocation("continueLoc", label); -}; diff --git a/lib/6to5/transformation/transformers/es6-generators/meta.js b/lib/6to5/transformation/transformers/es6-generators/meta.js deleted file mode 100644 index f7bb1248e6..0000000000 --- a/lib/6to5/transformation/transformers/es6-generators/meta.js +++ /dev/null @@ -1,98 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * https://raw.github.com/facebook/regenerator/master/LICENSE file. An - * additional grant of patent rights can be found in the PATENTS file in - * the same directory. - */ - -var assert = require("assert"); -var types = require("ast-types"); -var m = require("private").makeAccessor(); -var _ = require("lodash"); - -var isArray = types.builtInTypes.array; -var n = types.namedTypes; - -function makePredicate(propertyName, knownTypes) { - function onlyChildren(node) { - n.Node.check(node); - - // Assume no side effects until we find out otherwise. - var result = false; - - function check(child) { - if (result) { - // Do nothing. - } else if (isArray.check(child)) { - child.some(check); - } else if (n.Node.check(child)) { - assert.strictEqual(result, false); - result = predicate(child); - } - return result; - } - - types.eachField(node, function (name, child) { - check(child); - }); - - return result; - } - - function predicate(node) { - n.Node.check(node); - - var meta = m(node); - if (_.has(meta, propertyName)) return meta[propertyName]; - - // Certain types are "opaque," which means they have no side - // effects or leaps and we don't care about their subexpressions. - if (_.has(opaqueTypes, node.type)) return meta[propertyName] = false; - - if (_.has(knownTypes, node.type)) return meta[propertyName] = true; - - return meta[propertyName] = onlyChildren(node); - } - - predicate.onlyChildren = onlyChildren; - - return predicate; -} - -var opaqueTypes = { - FunctionExpression: true -}; - -// These types potentially have side effects regardless of what side -// effects their subexpressions have. -var sideEffectTypes = { - CallExpression: true, // Anything could happen! - ForInStatement: true, // Modifies the key variable. - UnaryExpression: true, // Think delete. - BinaryExpression: true, // Might invoke .toString() or .valueOf(). - AssignmentExpression: true, // Side-effecting by definition. - UpdateExpression: true, // Updates are essentially assignments. - NewExpression: true // Similar to CallExpression. -}; - -// These types are the direct cause of all leaps in control flow. -var leapTypes = { - YieldExpression: true, - BreakStatement: true, - ContinueStatement: true, - ReturnStatement: true, - ThrowStatement: true -}; - -// All leap types are also side effect types. -for (var type in leapTypes) { - if (_.has(leapTypes, type)) { - sideEffectTypes[type] = leapTypes[type]; - } -} - -exports.hasSideEffects = makePredicate("hasSideEffects", sideEffectTypes); -exports.containsLeap = makePredicate("containsLeap", leapTypes); diff --git a/lib/6to5/transformation/transformers/es6-generators/runtime.js b/lib/6to5/transformation/transformers/es6-generators/runtime.js deleted file mode 100644 index 9fe09b03cb..0000000000 --- a/lib/6to5/transformation/transformers/es6-generators/runtime.js +++ /dev/null @@ -1,447 +0,0 @@ -/** -* Copyright (c) 2014, Facebook, Inc. -* All rights reserved. -* -* This source code is licensed under the BSD-style license found in the -* https://raw.github.com/facebook/regenerator/master/LICENSE file. An -* additional grant of patent rights can be found in the PATENTS file in -* the same directory. -*/ - -var iteratorSymbol = typeof Symbol === "function" && Symbol.iterator || "@@iterator"; -var runtime = global.regeneratorRuntime = exports; -var hasOwn = Object.prototype.hasOwnProperty; - -var wrap = runtime.wrap = function wrap(innerFn, outerFn, self, tryList) { - return new Generator(innerFn, outerFn, self || null, tryList || []); -}; - -var GenStateSuspendedStart = "suspendedStart"; -var GenStateSuspendedYield = "suspendedYield"; -var GenStateExecuting = "executing"; -var GenStateCompleted = "completed"; - -// Returning this object from the innerFn has the same effect as -// breaking out of the dispatch switch statement. -var ContinueSentinel = {}; - -// Dummy constructor that we use as the .constructor property for -// functions that return Generator objects. -function GeneratorFunction() {} -var GFp = function GeneratorFunctionPrototype() {}; -var Gp = GFp.prototype = Generator.prototype; -(GFp.constructor = GeneratorFunction).prototype = Gp.constructor = GFp; - -runtime.isGeneratorFunction = function (genFun) { - var ctor = genFun && genFun.constructor; - return ctor ? GeneratorFunction.name === ctor.name : false; -}; - -runtime.mark = function (genFun) { - genFun.__proto__ = GFp; - 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) { - var info; - var value; - - try { - info = this(arg); - 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"); - } - - var alreadyFinished = state === GenStateCompleted; - - while (true) { - var delegate = context.delegate; - var info; - - if (delegate) { - try { - info = delegate.iterator[method](arg); - - // Delegate generator ran and handled its own exceptions so - // regardless of what the method was, we continue as if it is - // "next" with an undefined arg. - method = "next"; - arg = undefined; - - } catch (uncaught) { - context.delegate = null; - - // Like returning generator.throw(uncaught), but without the - // overhead of an extra function call. - 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") { - // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume - 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)) { - // If the dispatched exception was caught by a catch block, - // then let that catch block handle the exception normally. - method = "next"; - arg = undefined; - } - - } else if (method === "return") { - context.abrupt("return", arg); - } - - state = GenStateExecuting; - - try { - var value; - if (!alreadyFinished) value = innerFn.call(self, context); - - // If an exception is thrown from innerFn, we leave state === - // GenStateExecuting and loop back for another invocation. - state = context.done ? GenStateCompleted : GenStateSuspendedYield; - - info = { - value: value, - done: context.done - }; - - if (value === ContinueSentinel) { - if (context.delegate && method === "next") { - // Deliberately forget the last sent value so that we don't - // accidentally pass it on to the delegate. - 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) { - // The root entry object (effectively a try statement without a catch - // or a finally block) gives us a place to store values thrown from - // locations where there is no enclosing try statement. - 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(); - - // Rather than returning an object with a next method, we keep - // things simple and return the next function itself. - return function next() { - while (keys.length) { - var key = keys.pop(); - if (key in object) { - next.value = key; - next.done = false; - return next; - } - } - - // To avoid creating an additional object, we just hang the .value - // and .done properties off the next function object itself. This - // also ensures that the minifier will not anonymize the function. - next.done = true; - return next; - }; -}; - -function values(iterable) { - var iterator = iterable; - if (iterable[iteratorSymbol]) { - iterator = iterable[iteratorSymbol](); - } else if (!isNaN(iterable.length)) { - var i = -1; - iterator = function next() { - while (++i < iterable.length) { - if (i in iterable) { - next.value = iterable[i]; - next.done = false; - return next; - } - } - next.done = true; - return next; - }; - iterator.next = iterator; - } - return iterator; -} -runtime.values = values; - -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); - - // Pre-initialize at least 20 temporary variables to enable hidden - // class optimizations for simple generators. - 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") { - // Exception thrown outside of any try block that could handle - // it, so set the completion value of the entire function to - // throw the exception. - 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; - var thrown; - if (record.type === "throw") { - thrown = record.arg; - resetTryEntry(entry, i); - } - return thrown; - } - } - - // The context.catch method must only be called with a location - // argument that corresponds to a known catch block. - throw new Error("illegal catch attempt"); - }, - - delegateYield: function (iterable, resultName, nextLoc) { - this.delegate = { - iterator: values(iterable), - resultName: resultName, - nextLoc: nextLoc - }; - - return ContinueSentinel; - } -}; diff --git a/lib/6to5/transformation/transformers/es6-generators/util.js b/lib/6to5/transformation/transformers/es6-generators/util.js deleted file mode 100644 index 99e7072a19..0000000000 --- a/lib/6to5/transformation/transformers/es6-generators/util.js +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * https://raw.github.com/facebook/regenerator/master/LICENSE file. An - * additional grant of patent rights can be found in the PATENTS file in - * the same directory. - */ - -var t = require("../../../types"); - -exports.runtimeProperty = function (name) { - return t.memberExpression( - t.identifier("regeneratorRuntime"), - t.identifier(name) - ); -}; - -// Offsets into this.listing that could be used as targets for branches or -// jumps are represented as numeric Literal nodes. This representation has -// the amazingly convenient benefit of allowing the exact value of the -// location to be determined at any time, even after generating code that -// refers to the location. - -exports.loc = function () { - return t.literal(-1); -}; diff --git a/lib/6to5/transformation/transformers/es6-generators/visit.js b/lib/6to5/transformation/transformers/es6-generators/visit.js deleted file mode 100644 index eaa504fbab..0000000000 --- a/lib/6to5/transformation/transformers/es6-generators/visit.js +++ /dev/null @@ -1,221 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * https://raw.githut.com/facebook/regenerator/master/LICENSE file. An - * additional grant of patent rights can be found in the PATENTS file in - * the same directory. - */ - -var runtimeProperty = require("./util").runtimeProperty; -var Emitter = require("./emit").Emitter; -var hoist = require("./hoist").hoist; -var types = require("ast-types"); -var t = require("../../../types"); - -var runtimeAsyncMethod = runtimeProperty("async"); -var runtimeWrapMethod = runtimeProperty("wrap"); -var runtimeMarkMethod = runtimeProperty("mark"); - -exports.transform = function transform(node, file) { - return types.visit(node, { - visitFunction: function (path) { - return visitor.call(this, path, file); - } - }); -}; - -var visitor = function (path, file) { - // Calling this.traverse(path) first makes for a post-order traversal. - this.traverse(path); - - var node = path.value; - var scope; // we need to actually get the current scope - - if (!node.generator && !node.async) { - return; - } - - node.generator = false; - - if (node.expression) { - // Transform expression lambdas into normal functions. - node.expression = false; - node.body = t.blockStatement([ - t.returnStatement(node.body) - ]); - } - - if (node.async) { - awaitVisitor.visit(path.get("body")); - } - - var outerFnId = node.id || ( - node.id = file.generateUidIdentifier("callee", scope) - ); - - var innerFnId = t.identifier(node.id.name + "$"); - var contextId = file.generateUidIdentifier("context", scope); - var vars = hoist(path); - - var emitter = new Emitter(contextId); - emitter.explode(path.get("body")); - - var outerBody = []; - - if (vars && vars.declarations.length > 0) { - outerBody.push(vars); - } - - var wrapArgs = [ - emitter.getContextFunction(innerFnId), - // Async functions don't care about the outer function because they - // don't need it to be marked and don't inherit from its .prototype. - node.async ? t.literal(null) : outerFnId, - t.thisExpression() - ]; - - var tryEntryList = emitter.getTryEntryList(); - if (tryEntryList) { - wrapArgs.push(tryEntryList); - } - - var wrapCall = t.callExpression( - node.async ? runtimeAsyncMethod : runtimeWrapMethod, - wrapArgs - ); - - outerBody.push(t.returnStatement(wrapCall)); - node.body = t.blockStatement(outerBody); - - if (node.async) { - node.async = false; - return; - } - - if (t.isFunctionDeclaration(node)) { - var pp = path.parent; - - while (pp && !(t.isBlockStatement(pp.value) || t.isProgram(pp.value))) { - pp = pp.parent; - } - - if (!pp) { - return; - } - - // Here we turn the FunctionDeclaration into a named - // FunctionExpression that will be assigned to a variable of the - // same name at the top of the enclosing block. This is important - // for a very subtle reason: named function expressions can refer to - // themselves by name without fear that the binding may change due - // to code executing outside the function, whereas function - // declarations are vulnerable to the following rebinding: - // - // function f() { return f } - // var g = f; - // f = "asdf"; - // g(); // "asdf" - // - // One way to prevent the problem illustrated above is to transform - // the function declaration thus: - // - // var f = function f() { return f }; - // var g = f; - // f = "asdf"; - // g(); // f - // g()()()()(); // f - // - // In the code below, we transform generator function declarations - // in the following way: - // - // gen().next(); // { value: gen, done: true } - // function *gen() { - // return gen; - // } - // - // becomes something like - // - // var gen = runtime.mark(function *gen() { - // return gen; - // }); - // gen().next(); // { value: gen, done: true } - // - // which ensures that the generator body can always reliably refer - // to gen by name. - - // Remove the FunctionDeclaration so that we can add it back as a - // FunctionExpression passed to runtime.mark. - path.replace(); - - // Change the type of the function to be an expression instead of a - // declaration. Note that all the other fields are the same. - node.type = "FunctionExpression"; - - var varDecl = t.variableDeclaration("var", [ - t.variableDeclarator( - node.id, - t.callExpression(runtimeMarkMethod, [node]) - ) - ]); - - // Copy any comments preceding the function declaration to the - // variable declaration, to avoid weird formatting consequences. - t.inheritsComments(varDecl, node); - t.removeComments(node); - - varDecl._blockHoist = true; - - var bodyPath = pp.get("body"); - var bodyLen = bodyPath.value.length; - - for (var i = 0; i < bodyLen; ++i) { - var firstStmtPath = bodyPath.get(i); - if (!shouldNotHoistAbove(firstStmtPath)) { - firstStmtPath.insertBefore(varDecl); - return; - } - } - - bodyPath.push(varDecl); - } else { - t.assertFunctionExpression(node); - return t.callExpression(runtimeMarkMethod, [node]); - } -}; - -function shouldNotHoistAbove(stmtPath) { - var value = stmtPath.value; - t.assertStatement(value); - - // If the first statement is a "use strict" declaration, make sure to - // insert hoisted declarations afterwards. - if (t.isExpressionStatement(value) && - t.isLiteral(value.expression) && - value.expression.value === "use strict") { - return true; - } - - if (t.isVariableDeclaration(value)) { - for (var i = 0; i < value.declarations.length; ++i) { - var decl = value.declarations[i]; - if (t.isCallExpression(decl.init) && types.astNodesAreEquivalent(decl.init.callee, runtimeMarkMethod)) { - return true; - } - } - } - - return false; -} - -var awaitVisitor = types.PathVisitor.fromMethodsObject({ - visitFunction: function () { - return false; // Don't descend into nested function scopes. - }, - - visitAwaitExpression: function (path) { - // Convert await expressions to yield expressions. - return t.yieldExpression(path.value.argument, false); - } -}); diff --git a/package.json b/package.json index ef9868cc5e..77dcca580e 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ }, "dependencies": { "acorn-6to5": "0.9.1-14", - "ast-types": "0.6.5", + "ast-types": "~0.6.1", "chokidar": "0.11.1", "commander": "2.5.0", "es6-shim": "0.21.0", @@ -48,6 +48,7 @@ "lodash": "2.4.1", "mkdirp": "0.5.0", "private": "0.1.6", + "regenerator": "^0.8.2", "regexpu": "0.3.0", "roadrunner": "^1.0.4", "source-map": "0.1.40", From 4ea425ac7b0852a7a70da229f3d20cea958f5a80 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Mon, 22 Dec 2014 21:36:33 +1100 Subject: [PATCH 106/139] remove ParenthesizedExpression --- lib/6to5/generation/generator.js | 2 +- lib/6to5/generation/generators/expressions.js | 13 +++++-------- lib/6to5/generation/node/parentheses.js | 7 ------- .../transformers/es6-computed-property-names.js | 2 +- .../transformers/es6-template-literals.js | 5 +---- .../transformers/es7-array-comprehension.js | 2 +- lib/6to5/traverse/index.js | 1 - lib/6to5/types/builder-keys.json | 1 - lib/6to5/types/index.js | 3 +-- lib/6to5/types/visitor-keys.json | 1 - lib/6to5/util.js | 11 +---------- .../comments/return-no-argument/expected.js | 2 +- .../edgecase/bitwise-precedence/expected.js | 2 +- .../generation/edgecase/floating-point/expected.js | 2 +- .../generation/edgecase/for-in-no-in/expected.js | 6 +++--- .../generation/edgecase/new-precedence/actual.js | 8 ++++---- .../generation/edgecase/new-precedence/expected.js | 10 +++++----- .../edgecase/variable-declaration/expected.js | 4 ++-- .../types/ParenthesizedExpression/actual.js | 2 -- .../types/ParenthesizedExpression/expected.js | 2 -- .../es7-object-spread/expression/expected.js | 2 +- 21 files changed, 29 insertions(+), 59 deletions(-) delete mode 100644 test/fixtures/generation/types/ParenthesizedExpression/actual.js delete mode 100644 test/fixtures/generation/types/ParenthesizedExpression/expected.js diff --git a/lib/6to5/generation/generator.js b/lib/6to5/generation/generator.js index 4406a84f46..b12f235b55 100644 --- a/lib/6to5/generation/generator.js +++ b/lib/6to5/generation/generator.js @@ -156,7 +156,7 @@ CodeGenerator.prototype.print = function (node, parent, opts) { // only compute if this node needs parens if our parent has been changed // since acorn would've wrapped us in a ParanthesizedExpression - var needsParens = parent !== node._parent && n.needsParens(node, parent); + var needsParens = n.needsParens(node, parent); if (needsParens) this.push("("); this[node.type](node, this.buildPrint(node), parent); diff --git a/lib/6to5/generation/generators/expressions.js b/lib/6to5/generation/generators/expressions.js index 65d0be8710..b5a583d6bb 100644 --- a/lib/6to5/generation/generators/expressions.js +++ b/lib/6to5/generation/generators/expressions.js @@ -18,12 +18,6 @@ exports.UnaryExpression = function (node, print) { print(node.argument); }; -exports.ParenthesizedExpression = function (node, print) { - this.push("("); - print(node.expression); - this.push(")"); -}; - exports.UpdateExpression = function (node, print) { if (node.prefix) { this.push(node.operator); @@ -98,8 +92,11 @@ exports.AssignmentExpression = function (node, print) { print(node.right); }; +var SCIENTIFIC_NOTATION = /e/i; + exports.MemberExpression = function (node, print) { - print(node.object); + var obj = node.object; + print(obj); if (node.computed) { this.push("["); @@ -107,7 +104,7 @@ exports.MemberExpression = function (node, print) { this.push("]"); } else { // 5..toFixed(2); - if (t.isLiteral(node.object) && util.isInteger(node.object.value)) { + if (t.isLiteral(obj) && util.isInteger(obj.value) && !SCIENTIFIC_NOTATION.test(obj.value.toString())) { this.push("."); } diff --git a/lib/6to5/generation/node/parentheses.js b/lib/6to5/generation/node/parentheses.js index 544da11d7a..bdea11d6d2 100644 --- a/lib/6to5/generation/node/parentheses.js +++ b/lib/6to5/generation/node/parentheses.js @@ -92,13 +92,6 @@ exports.YieldExpression = function (node, parent) { t.isYieldExpression(parent); }; -exports.Literal = function (node, parent) { - // (1).valueOf() - if (_.isNumber(node.value) && t.isMemberExpression(parent) && parent.object === node) { - return true; - } -}; - exports.ClassExpression = function (node, parent) { return t.isExpressionStatement(parent); }; diff --git a/lib/6to5/transformation/transformers/es6-computed-property-names.js b/lib/6to5/transformation/transformers/es6-computed-property-names.js index 91242d4947..3b434abb14 100644 --- a/lib/6to5/transformation/transformers/es6-computed-property-names.js +++ b/lib/6to5/transformation/transformers/es6-computed-property-names.js @@ -25,7 +25,7 @@ exports.ObjectExpression = function (node, parent, file) { OBJECT: node }); - var containerCallee = container.callee.expression; + var containerCallee = container.callee; var containerBody = containerCallee.body.body; containerCallee._aliasFunction = true; diff --git a/lib/6to5/transformation/transformers/es6-template-literals.js b/lib/6to5/transformation/transformers/es6-template-literals.js index 9ef874a0be..dd29d7a0f5 100644 --- a/lib/6to5/transformation/transformers/es6-template-literals.js +++ b/lib/6to5/transformation/transformers/es6-template-literals.js @@ -36,10 +36,7 @@ exports.TemplateLiteral = function (node) { nodes.push(t.literal(elem.value.cooked)); var expr = node.expressions.shift(); - if (expr) { - if (t.isBinary(expr)) expr = t.parenthesizedExpression(expr); - nodes.push(expr); - } + if (expr) nodes.push(expr); } if (nodes.length > 1) { diff --git a/lib/6to5/transformation/transformers/es7-array-comprehension.js b/lib/6to5/transformation/transformers/es7-array-comprehension.js index daf7a37720..ded4f5a28f 100644 --- a/lib/6to5/transformation/transformers/es7-array-comprehension.js +++ b/lib/6to5/transformation/transformers/es7-array-comprehension.js @@ -33,7 +33,7 @@ var multiple = function (node, file) { }); container.callee.expression._aliasFunction = true; - var block = container.callee.expression.body; + var block = container.callee.body; var body = block.body; var returnStatement = body.pop(); diff --git a/lib/6to5/traverse/index.js b/lib/6to5/traverse/index.js index add0a38df1..aea63764e0 100644 --- a/lib/6to5/traverse/index.js +++ b/lib/6to5/traverse/index.js @@ -96,7 +96,6 @@ traverse.removeProperties = function (tree) { delete node._declarations; delete node.extendedRange; delete node._scopeInfo; - delete node._parent; delete node._scope; delete node.tokens; delete node.range; diff --git a/lib/6to5/types/builder-keys.json b/lib/6to5/types/builder-keys.json index 997476ba00..beca94c0e4 100644 --- a/lib/6to5/types/builder-keys.json +++ b/lib/6to5/types/builder-keys.json @@ -16,7 +16,6 @@ "MemberExpression": ["object", "property", "computed"], "NewExpression": ["callee", "arguments"], "ObjectExpression": ["properties"], - "ParenthesizedExpression": ["expression"], "Program": ["body"], "Property": ["kind", "key", "value", "computed"], "ReturnStatement": ["argument"], diff --git a/lib/6to5/types/index.js b/lib/6to5/types/index.js index 39c85d52bc..97be33b034 100644 --- a/lib/6to5/types/index.js +++ b/lib/6to5/types/index.js @@ -116,7 +116,7 @@ t.shallowEqual = function (actual, expected) { // t.isDynamic = function (node) { - if (t.isParenthesizedExpression(node) || t.isExpressionStatement(node)) { + if (t.isExpressionStatement(node)) { return t.isDynamic(node.expression); } else if (t.isIdentifier(node) || t.isLiteral(node) || t.isThisExpression(node)) { return false; @@ -262,7 +262,6 @@ t.getIds.nodes = { VariableDeclarator: "id", FunctionDeclaration: "id", ClassDeclaration: "id", - ParenthesizedExpression: "expression", MemeberExpression: "object", SpreadElement: "argument", Property: "value" diff --git a/lib/6to5/types/visitor-keys.json b/lib/6to5/types/visitor-keys.json index b90e63942f..32292aa669 100644 --- a/lib/6to5/types/visitor-keys.json +++ b/lib/6to5/types/visitor-keys.json @@ -45,7 +45,6 @@ "NewExpression": ["callee", "arguments"], "ObjectExpression": ["properties"], "ObjectPattern": ["properties"], - "ParenthesizedExpression": ["expression"], "PrivateDeclaration": ["declarations"], "Program": ["body"], "Property": ["key", "value"], diff --git a/lib/6to5/util.js b/lib/6to5/util.js index f6fa5fe0f2..1478340ae8 100644 --- a/lib/6to5/util.js +++ b/lib/6to5/util.js @@ -161,8 +161,6 @@ exports.template = function (name, nodes, keepExpression) { if (!keepExpression && t.isExpressionStatement(node)) { node = node.expression; - - if (t.isParenthesizedExpression(node)) node = node.expression; } return node; @@ -209,13 +207,7 @@ exports.repeat = function (width, cha) { exports.normaliseAst = function (ast, comments, tokens) { if (ast && ast.type === "Program") { - ast = t.file(ast, comments || [], tokens || []); - - traverse(ast, function (node, parent) { - node._parent = parent; - }); - - return ast; + return t.file(ast, comments || [], tokens || []); } else { throw new Error("Not a valid ast?"); } @@ -228,7 +220,6 @@ exports.parse = function (opts, code, callback) { var ast = acorn.parse(code, { allowReturnOutsideFunction: true, - preserveParens: true, ecmaVersion: opts.experimental ? 7 : 6, playground: opts.playground, strictMode: true, diff --git a/test/fixtures/generation/comments/return-no-argument/expected.js b/test/fixtures/generation/comments/return-no-argument/expected.js index c8f39a07a5..0dc96b3a8c 100644 --- a/test/fixtures/generation/comments/return-no-argument/expected.js +++ b/test/fixtures/generation/comments/return-no-argument/expected.js @@ -1,3 +1,3 @@ (function () { return; // comment -}()); +})(); diff --git a/test/fixtures/generation/edgecase/bitwise-precedence/expected.js b/test/fixtures/generation/edgecase/bitwise-precedence/expected.js index 7c6969bfc8..ffcf91adde 100644 --- a/test/fixtures/generation/edgecase/bitwise-precedence/expected.js +++ b/test/fixtures/generation/edgecase/bitwise-precedence/expected.js @@ -1,3 +1,3 @@ x | y ^ z; -x | (y ^ z); +x | y ^ z; (x | y) ^ z; diff --git a/test/fixtures/generation/edgecase/floating-point/expected.js b/test/fixtures/generation/edgecase/floating-point/expected.js index b38eebf513..f0c3126dbe 100644 --- a/test/fixtures/generation/edgecase/floating-point/expected.js +++ b/test/fixtures/generation/edgecase/floating-point/expected.js @@ -1,2 +1,2 @@ 1.1.valueOf(); -(1e+300).valueOf(); +1e+300.valueOf(); diff --git a/test/fixtures/generation/edgecase/for-in-no-in/expected.js b/test/fixtures/generation/edgecase/for-in-no-in/expected.js index f84b95ae6b..029b11e515 100644 --- a/test/fixtures/generation/edgecase/for-in-no-in/expected.js +++ b/test/fixtures/generation/edgecase/for-in-no-in/expected.js @@ -1,12 +1,12 @@ for (var i = (1 in []) in []); -for (var i = 1 in [] in []); +for (var i = 1 in ([] in [])); for (var i = (10 * 10 in []) in []); for (var i = (10 + 10 in []) in []); for (var i = 10 + (10 in []) in []); -for (var i = 10 + 10 in [] in []); +for (var i = 10 + 10 in ([] in [])); for (var i = (1 in []);;); for ((1 in []);;); for (1 * (1 in []);;); for (1 * (1 + 1 in []);;); -for (1 * ((1 + 1) in []);;); +for (1 * (1 + 1 in []);;); for (1 * (1 + (1 in []));;); diff --git a/test/fixtures/generation/edgecase/new-precedence/actual.js b/test/fixtures/generation/edgecase/new-precedence/actual.js index 56044a7b99..7100c69c3d 100644 --- a/test/fixtures/generation/edgecase/new-precedence/actual.js +++ b/test/fixtures/generation/edgecase/new-precedence/actual.js @@ -1,9 +1,9 @@ new (a().b)(); new a().b(); new (a()).b(); -new (a()); -new new a(a); -new (new a)(a); +new (a())(); +new new a(a)(); +new (new a())(a); (new a()).test; (new a().test); -(new (a().test)); +(new (a().test)()); diff --git a/test/fixtures/generation/edgecase/new-precedence/expected.js b/test/fixtures/generation/edgecase/new-precedence/expected.js index 7100c69c3d..646afe94da 100644 --- a/test/fixtures/generation/edgecase/new-precedence/expected.js +++ b/test/fixtures/generation/edgecase/new-precedence/expected.js @@ -1,9 +1,9 @@ new (a().b)(); new a().b(); -new (a()).b(); +new (a().b)(); new (a())(); new new a(a)(); -new (new a())(a); -(new a()).test; -(new a().test); -(new (a().test)()); +new new a()(a); +new a().test; +new a().test; +new (a().test)(); diff --git a/test/fixtures/generation/edgecase/variable-declaration/expected.js b/test/fixtures/generation/edgecase/variable-declaration/expected.js index 12407627ec..0af0dd6ac0 100644 --- a/test/fixtures/generation/edgecase/variable-declaration/expected.js +++ b/test/fixtures/generation/edgecase/variable-declaration/expected.js @@ -1,4 +1,4 @@ -var fact5 = function fact(n) { +var fact5 = (function fact(n) { if (n <= 1) return 1; return n * fact(n - 1); -}(5); +})(5); diff --git a/test/fixtures/generation/types/ParenthesizedExpression/actual.js b/test/fixtures/generation/types/ParenthesizedExpression/actual.js deleted file mode 100644 index 5d7b0fd7c0..0000000000 --- a/test/fixtures/generation/types/ParenthesizedExpression/actual.js +++ /dev/null @@ -1,2 +0,0 @@ -(foo()); -(5 * 6); diff --git a/test/fixtures/generation/types/ParenthesizedExpression/expected.js b/test/fixtures/generation/types/ParenthesizedExpression/expected.js deleted file mode 100644 index 5d7b0fd7c0..0000000000 --- a/test/fixtures/generation/types/ParenthesizedExpression/expected.js +++ /dev/null @@ -1,2 +0,0 @@ -(foo()); -(5 * 6); diff --git a/test/fixtures/transformation/es7-object-spread/expression/expected.js b/test/fixtures/transformation/es7-object-spread/expression/expected.js index ae48d06c13..856b5c1f8c 100644 --- a/test/fixtures/transformation/es7-object-spread/expression/expected.js +++ b/test/fixtures/transformation/es7-object-spread/expression/expected.js @@ -1,3 +1,3 @@ "use strict"; -(Object.assign({ x: x }, y, { a: a }, b, { c: c })); +Object.assign({ x: x }, y, { a: a }, b, { c: c }); From bc914e6f23dfaec1dfd6c7c3b96b298b1c2084a1 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Mon, 22 Dec 2014 21:36:59 +1100 Subject: [PATCH 107/139] freeze tagged template literal object - fixes #328 --- lib/6to5/templates/tagged-template-literal.js | 2 +- .../transformation/es6-template-literals/tag/expected.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/6to5/templates/tagged-template-literal.js b/lib/6to5/templates/tagged-template-literal.js index 9d3b26a3b7..a1735f0fc7 100644 --- a/lib/6to5/templates/tagged-template-literal.js +++ b/lib/6to5/templates/tagged-template-literal.js @@ -1,4 +1,4 @@ (function (strings, raw) { - return Object.defineProperties(strings, { raw: { value: raw } }); + return Object.freeze(Object.defineProperties(strings, { raw: { value: raw } })); }); diff --git a/test/fixtures/transformation/es6-template-literals/tag/expected.js b/test/fixtures/transformation/es6-template-literals/tag/expected.js index 9992ad8f15..6d6de74206 100644 --- a/test/fixtures/transformation/es6-template-literals/tag/expected.js +++ b/test/fixtures/transformation/es6-template-literals/tag/expected.js @@ -1,11 +1,11 @@ "use strict"; var _taggedTemplateLiteral = function (strings, raw) { - return Object.defineProperties(strings, { + return Object.freeze(Object.defineProperties(strings, { raw: { value: raw } - }); + })); }; var foo = bar(_taggedTemplateLiteral(["wow\na", "b ", ""], ["wow\\na", "b ", ""]), 42, _.foobar()); From 275c4cc34e6e203e54e831ff192d6a7971165d5f Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Mon, 22 Dec 2014 21:37:32 +1100 Subject: [PATCH 108/139] add note about node/browserify polyfill usage --- doc/polyfill.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/polyfill.md b/doc/polyfill.md index 4249e038dc..569d70bcd9 100644 --- a/doc/polyfill.md +++ b/doc/polyfill.md @@ -10,7 +10,7 @@ when using [6to5-node](usage.md#node). ## Usage -### Node +### Node/Browserify You need to include the polyfill require at the top the **entry point** to your application. @@ -31,3 +31,5 @@ Available from the `browser-polyfill.js` file within the 6to5 directory of an npm release. This needs to be included **before** all your compiled 6to5 code. You can either prepend it to your compiled code or include it in a `