diff --git a/FEATURES.md b/FEATURES.md index fd28c17940c0..d012284d203e 100644 --- a/FEATURES.md +++ b/FEATURES.md @@ -10,21 +10,13 @@ arr.map(x => x * x); ```javascript class Foo extends Bar { - constructor() { + constructor() { } - } - - foo() { - - } + foo() { } - get bar() { - - } - - set bar() { + get bar() { } - } + set bar() { } } ``` @@ -99,6 +91,18 @@ console.log(`${x} + ${y} = ${x + y}`); // "5 + 10 = 15" ```javascript ``` +## Binary and Octal Literals + +```javascript +0b111110111 === 503; // true +0o767 === 503; // true +``` + +## Iterators + +```javascript +``` + ## Constants ```javascript diff --git a/README.md b/README.md index 21e9943d386e..be2504c82f16 100644 --- a/README.md +++ b/README.md @@ -24,29 +24,31 @@ - **Fast** - [10x faster than Traceur](#performance). - **Extensive** - with Browserify support, Node API, Connect Middleware and a CLI. - - **Lossless** - source map support so you can debug your compiled code with ease. + - **Lossless** - **source map support** so you can debug your compiled code with ease. - **Compact** - maps directly to the equivalent ES5 with **no runtime required**. - **Concise** - does not pollute scope with unneccesary variables. -## Features - -| Name | Implemented | -| -------------------------------------------------------------------- | ----------- | -| [Arrow functions](FEATURES.md#arrow-functions) | ✓ | -| [Classes](FEATURES.md#classes) | ✓ | -| [Default parameters](FEATURES.md#default-parameters) | ✓ | -| [Spread](FEATURES.md#spread) | ✓ | -| [Block binding](FEATURES.md#block-binding) | ✓ | -| [Property method assignment](FEATURES.md#property-method-assignment) | ✓ | -| [Rest parameters](FEATURES.md#rest-parameters) | ✓ | -| [Template literals](FEATURES.md#template-literals) | ✓ | -| [Modules](FEATURES.md#modules) | ✓ | -| [Property name shorthand](FEATURES.md#property-name-shorthand) | ✓ | -| [Computed property names](FEATURES.md#computed-property-names) | ✓ | -| [Constants](FEATURES.md#constants) | ✓ | -| [Destructuring assignment](FEATURES.md#destructuring-assignment) | | -| [Array comprehension](FEATURES.md#array-comprehension) | | -| [Generators](FEATURES.md#generators) | | +## [Features](FEATURES.md) + +| Name | Implemented | [Polyfill](#polyfill) | +| -------------------------------------------------------------------- | ----------- | --------------------- | +| [Arrow functions](FEATURES.md#arrow-functions) | ✓ | | +| [Classes](FEATURES.md#classes) | ✓ | | +| [Default parameters](FEATURES.md#default-parameters) | ✓ | | +| [Spread](FEATURES.md#spread) | ✓ | | +| [Block binding](FEATURES.md#block-binding) | ✓ | | +| [Property method assignment](FEATURES.md#property-method-assignment) | ✓ | | +| [Rest parameters](FEATURES.md#rest-parameters) | ✓ | | +| [Template literals](FEATURES.md#template-literals) | ✓ | | +| [Modules](FEATURES.md#modules) | ✓ | | +| [Property name shorthand](FEATURES.md#property-name-shorthand) | ✓ | | +| [Computed property names](FEATURES.md#computed-property-names) | ✓ | | +| [Constants](FEATURES.md#constants) | ✓ | | +| [Binary and Octal Literals](FEATURES.md#binary-and-octal-literals) | ✓ | | +| [Iterators](FEATURES.md#iterators) | | ✓ | +| [Destructuring assignment](FEATURES.md#destructuring-assignment) | | | +| [Array comprehension](FEATURES.md#array-comprehension) | | | +| [Generators](FEATURES.md#generators) | | | ## Installation @@ -147,6 +149,14 @@ browserify() .pipe(fs.createWriteStream("bundle.js")); ``` +## Caveats + +### Polyfill + +### Classes + +Cannot subclass built-ins such as `Date`, `Array`, `DOM` etc. + ## Comparison to Traceur ### Performance diff --git a/lib/6to5/templates/for-of.js b/lib/6to5/templates/for-of.js new file mode 100644 index 000000000000..916c6c8eb610 --- /dev/null +++ b/lib/6to5/templates/for-of.js @@ -0,0 +1,3 @@ +for (var ITERATOR_KEY = OBJECT[Symbol.iterator](), STEP_KEY; !(STEP_KEY = ITERATOR_KEY.next()).done; ) { + var KEY = STEP_KEY.value; +} diff --git a/lib/6to5/transform.js b/lib/6to5/transform.js index 5cbdc71b5144..517ef046c788 100644 --- a/lib/6to5/transform.js +++ b/lib/6to5/transform.js @@ -30,6 +30,8 @@ var transform = module.exports = function (code, opts) { } }); + var generateUid = util.buildUidGenerator(); + _.each(transform.transformers, function (transformer, name) { var blacklist = opts.blacklist; if (blacklist.length && _.contains(blacklist, name)) return; @@ -37,7 +39,7 @@ var transform = module.exports = function (code, opts) { var whitelist = opts.whitelist; if (whitelist.length && !_.contains(whitelist, name)) return; - transform._runTransformer(transformer, tree, opts); + transform._runTransformer(transformer, tree, opts, generateUid); }); var genOpts = { @@ -64,14 +66,14 @@ var transform = module.exports = function (code, opts) { } }; -transform._runTransformer = function (transformer, tree, opts) { +transform._runTransformer = function (transformer, tree, opts, generateUid) { if (transformer.Program) transformer.Program(tree, opts); traverse.replace(tree, function (node, parent) { var fn = transformer[node.type] || transformer.all; if (!fn) return; - return fn(node, parent, opts); + return fn(node, parent, opts, generateUid); }); }; @@ -109,5 +111,6 @@ transform.transformers = { generators: require("./transformers/generators"), blockBinding: require("./transformers/block-binding"), modules: require("./transformers/modules"), - restParameters: require("./transformers/rest-parameters") + restParameters: require("./transformers/rest-parameters"), + iterators: require("./transformers/iterators") }; diff --git a/lib/6to5/transformers/arrow-functions.js b/lib/6to5/transformers/arrow-functions.js index 6fbe9893718b..558cd8388d60 100644 --- a/lib/6to5/transformers/arrow-functions.js +++ b/lib/6to5/transformers/arrow-functions.js @@ -3,6 +3,8 @@ var util = require("../util"); exports.ArrowFunctionExpression = function (node) { var body = node.body; + + // expression body if (body.type !== "BlockStatement") { body = { type: "BlockStatement", diff --git a/lib/6to5/transformers/block-binding.js b/lib/6to5/transformers/block-binding.js index a6a4b50758a9..ee53ae3a3818 100644 --- a/lib/6to5/transformers/block-binding.js +++ b/lib/6to5/transformers/block-binding.js @@ -35,6 +35,7 @@ exports.BlockStatement = function (node, parent) { node.body = buildNode(node.body); }; +exports.ForOfStatement = exports.ForInStatement = function (node) { if (isLet(node.left)) return buildNode(node); }; diff --git a/lib/6to5/transformers/constants.js b/lib/6to5/transformers/constants.js index 485285d04749..65d579444b87 100644 --- a/lib/6to5/transformers/constants.js +++ b/lib/6to5/transformers/constants.js @@ -5,6 +5,7 @@ var _ = require("lodash"); exports.Program = exports.BlockStatement = exports.ForInStatement = +exports.ForOfStatement = exports.ForStatement = function (node) { var constants = []; diff --git a/lib/6to5/transformers/iterators.js b/lib/6to5/transformers/iterators.js new file mode 100644 index 000000000000..b1ac7426ea23 --- /dev/null +++ b/lib/6to5/transformers/iterators.js @@ -0,0 +1,20 @@ +var util = require("../util"); + +exports.ForOfStatement = function (node, parent, opts, generateUid) { + var node2 = util.template("for-of", { + ITERATOR_KEY: generateUid("iterator"), + STEP_KEY: generateUid("step"), + + KEY: node.left.declarations[0].id, + OBJECT: node.right + }); + + var block = node2.body; + + var declar = block.body[0]; + declar.kind = node.left.kind; + + block.body = block.body.concat(node.body.body); + + return node2; +}; diff --git a/lib/6to5/util.js b/lib/6to5/util.js index 18d0d92019fe..9eadafcf1ba4 100644 --- a/lib/6to5/util.js +++ b/lib/6to5/util.js @@ -47,6 +47,19 @@ exports.canCompile = function (filename) { return path.extname(filename) === ".js"; }; +exports.buildUidGenerator = function () { + var ids = {}; + + return function (name) { + var i = ids[name] || 0; + + var id = "_" + name; + if (i > 0) id += i; + ids[name] = i + 1; + return id; + }; +}; + exports.sourceMapToComment = function (map) { var json = JSON.stringify(map); var base64 = new Buffer(json).toString("base64"); diff --git a/test/fixtures/arrow-functions/expression/actual.js b/test/fixtures/arrow-functions/expression/actual.js new file mode 100644 index 000000000000..adc984840775 --- /dev/null +++ b/test/fixtures/arrow-functions/expression/actual.js @@ -0,0 +1 @@ +arr.map(x => x * x); diff --git a/test/fixtures/arrow-functions/expression/expected.js b/test/fixtures/arrow-functions/expression/expected.js new file mode 100644 index 000000000000..e2bcfeb4cdbd --- /dev/null +++ b/test/fixtures/arrow-functions/expression/expected.js @@ -0,0 +1,3 @@ +arr.map(function (x) { + return x * x; +}); diff --git a/test/fixtures/arrow-functions/statement/actual.js b/test/fixtures/arrow-functions/statement/actual.js new file mode 100644 index 000000000000..668b7483d24d --- /dev/null +++ b/test/fixtures/arrow-functions/statement/actual.js @@ -0,0 +1,5 @@ +nums.forEach(v => { + if (v % 5 === 0) { + fives.push(v); + } +}); diff --git a/test/fixtures/arrow-functions/statement/expected.js b/test/fixtures/arrow-functions/statement/expected.js new file mode 100644 index 000000000000..40ecaad5725c --- /dev/null +++ b/test/fixtures/arrow-functions/statement/expected.js @@ -0,0 +1,5 @@ +nums.forEach(function (v) { + if (v % 5 === 0) { + fives.push(v); + } +}); diff --git a/test/fixtures/iterators/for-of-let/actual.js b/test/fixtures/iterators/for-of-let/actual.js new file mode 100644 index 000000000000..f1e32392def1 --- /dev/null +++ b/test/fixtures/iterators/for-of-let/actual.js @@ -0,0 +1,3 @@ +for (let i of arr) { + +} diff --git a/test/fixtures/iterators/for-of-let/expected.js b/test/fixtures/iterators/for-of-let/expected.js new file mode 100644 index 000000000000..ee144f69328f --- /dev/null +++ b/test/fixtures/iterators/for-of-let/expected.js @@ -0,0 +1,5 @@ +(function () { + for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { + var i = _step.value; + } +}()); diff --git a/test/fixtures/iterators/for-of/actual.js b/test/fixtures/iterators/for-of/actual.js new file mode 100644 index 000000000000..48e5f59b2c6b --- /dev/null +++ b/test/fixtures/iterators/for-of/actual.js @@ -0,0 +1,3 @@ +for (var i of arr) { + +} diff --git a/test/fixtures/iterators/for-of/expected.js b/test/fixtures/iterators/for-of/expected.js new file mode 100644 index 000000000000..7bfbba16366b --- /dev/null +++ b/test/fixtures/iterators/for-of/expected.js @@ -0,0 +1,3 @@ +for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done; ) { + var i = _step.value; +}