Compare commits

...

47 Commits

Author SHA1 Message Date
Sebastian McKenzie
4c41c904f5 v1.12.8 2014-11-13 13:42:54 +11:00
Sebastian McKenzie
0917a6a5b1 better destructuring AssignmentExpression error message 2014-11-13 13:42:18 +11:00
Sebastian McKenzie
349eba33ce add async functions to traceur differences 2014-11-13 13:40:54 +11:00
Sebastian McKenzie
8ff21b407d temporarily forbid AssignmentExpression destructuring outside of ExpressionStatement 2014-11-13 13:40:41 +11:00
Sebastian McKenzie
751ea7a12c v1.12.7 2014-11-13 13:19:45 +11:00
Sebastian McKenzie
b30cd227cc update acorn-6to5 - fixes #153 2014-11-13 13:18:59 +11:00
Sebastian McKenzie
18dc7b8143 v1.12.6 2014-11-13 12:55:39 +11:00
Sebastian McKenzie
1c628bbec1 disable generation/comments/comment-only test 2014-11-13 12:53:38 +11:00
Sebastian McKenzie
d4c3dde02a update to latest acorn-6to5 2014-11-13 12:49:29 +11:00
Sebastian McKenzie
a587106a6b v1.12.5 2014-11-13 12:26:16 +11:00
Sebastian McKenzie
9c1b60e451 fix excessive whitespace trimming resulting in innaccurate sourcemap line - fixes #151 2014-11-13 12:25:11 +11:00
Sebastian McKenzie
0c7e0b65b9 add browser support, array comprehension, async functions and generator comprehension to differences table 2014-11-13 03:24:45 +11:00
Sebastian McKenzie
5c17091db4 replace documentation link 2014-11-13 01:17:14 +11:00
Sebastian McKenzie
7fa5ba88df v1.12.4 2014-11-13 01:16:45 +11:00
Sebastian McKenzie
2fae245cd5 add 1.12.4 changelog 2014-11-13 01:15:41 +11:00
Sebastian McKenzie
297f103ddb move docs to folder 2014-11-13 01:13:48 +11:00
Sebastian McKenzie
fd63650d6a add .hound.yml 2014-11-12 19:25:35 +11:00
Sebastian McKenzie
e13ed39567 v1.12.3 2014-11-12 18:43:39 +11:00
Sebastian McKenzie
bb00f641b7 remove unused variables in spread transformer 2014-11-12 18:42:24 +11:00
Sebastian McKenzie
25b466a627 remove unused variables 2014-11-12 18:39:50 +11:00
Sebastian McKenzie
ac231f2987 add 1.12.3 changelog 2014-11-12 18:38:39 +11:00
Sebastian McKenzie
458e3d48f6 use Array.from instead of Array.prototype.slice in spread transformer and support NewExpression spreads - fixes #148 2014-11-12 18:38:30 +11:00
Sebastian McKenzie
c235780611 move down 6to5-node util declaration 2014-11-12 18:37:32 +11:00
Sebastian McKenzie
56b858ccb1 add generator comprehension transformer 2014-11-12 18:29:41 +11:00
Sebastian McKenzie
d42351bb02 add default parameters existence change to well... the defaultParameters transformer 2014-11-12 18:29:27 +11:00
Sebastian McKenzie
ed7378cc2d add apply-constructor declaration and add support for not returning generated code in opts.code 2014-11-12 18:29:03 +11:00
Sebastian McKenzie
a47a7dc347 rename util.parseNoProperties to util.parseTemplate 2014-11-12 18:28:11 +11:00
Sebastian McKenzie
2c82b5a4b0 add generator option to FunctionExpression builder keys 2014-11-12 18:27:56 +11:00
Sebastian McKenzie
3578135b90 add spread caveat and add generator comprehension and react/jsx to features 2014-11-12 18:27:05 +11:00
Sebastian McKenzie
5f3408b2a2 upgrade regenerator-6to5 2014-11-12 18:26:29 +11:00
Sebastian McKenzie
9e3f9fda6b add support for generator comprehensions - fixes #149 2014-11-12 18:26:22 +11:00
Sebastian McKenzie
7f425d2c6e v1.12.2 2014-11-12 12:22:03 +11:00
Sebastian McKenzie
311a8e042b add missing semicolon 2014-11-12 12:19:25 +11:00
Sebastian McKenzie
27d30329fd add more react spread tests 2014-11-12 12:18:16 +11:00
Sebastian McKenzie
12c5a3e73b add 1.12.2 changelog 2014-11-12 12:17:59 +11:00
Sebastian McKenzie
2a166a6ed1 support jsx spread attributes that aren't the first - fixes #146 2014-11-12 12:17:45 +11:00
Sebastian McKenzie
896929378e add util.trimRight method - fixes #147 2014-11-12 12:17:26 +11:00
Sebastian McKenzie
ae439d27b9 update mocha and browserify 2014-11-12 12:08:33 +11:00
Sebastian McKenzie
e22798261a change useless self references to this 2014-11-12 02:03:46 +11:00
Sebastian McKenzie
d0af8b8d0a remove numeric literals transformer 2014-11-12 02:03:25 +11:00
Sebastian McKenzie
beaa2fa540 add async functions to features 2014-11-12 02:03:11 +11:00
Sebastian McKenzie
b8cac9787e produce new MemberExpression in a CallExpression super identifier instead of mutating the property 2014-11-12 01:51:57 +11:00
Sebastian McKenzie
64f6e4a0c5 clean up classes transformer and add comments 2014-11-12 01:48:55 +11:00
Sebastian McKenzie
c4a7ac5a8b turn classes transformer into a class like let scoping 2014-11-12 01:39:35 +11:00
Sebastian McKenzie
1ed682fa76 fix up jsdoc in let-scoping transformer 2014-11-12 01:39:02 +11:00
Sebastian McKenzie
9987e7fe0e add 1.12.1 changelog 2014-11-12 01:38:50 +11:00
Sebastian McKenzie
e74c7cb0b7 turn the let scoping transformer into a class because it's quite complicated and the logic needs to be WAY more organised 2014-11-12 01:20:51 +11:00
94 changed files with 1136 additions and 862 deletions

3
.hound.yml Normal file
View File

@@ -0,0 +1,3 @@
java_script:
enabled: true
config_file: .jshintrc

View File

@@ -8,4 +8,4 @@ Makefile
.*
dist
tests.json
!README.md
CHANGELOG.md

View File

@@ -1,3 +1,39 @@
# 1.12.8
* Temporarily forbid `AssignmentExpression` destructuring outside of `ExpressionStatement`.
# 1.12.7
* Update to latest `acorn-6to5`.
# 1.12.6
* Update to latest `acorn-6to5`.
# 1.12.5
* Fix excessive whitespace trimming resulting in innaccurate sourcemap line.
# 1.12.4
* Add `doc` folder for documentation.
# 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
* 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
* Fix `this` and `arguments` mapping in the `_aliasFunctions` transformer.
# 1.12.0
* Combine `jsx` and `react` transformers to `react`.

487
README.md
View File

@@ -26,489 +26,4 @@
**6to5** turns ES6 code into vanilla ES5, so you can use ES6 features **today.**
- **Readable** - formatting is retained if possible so your generated code is as similar as possible.
- **Extensible** - with a large range of [plugins](#plugins) and **browser support**.
- **Lossless** - **source map support** so you can debug your compiled code with ease.
- **Compact** - maps directly to the equivalent ES5 with **no runtime**[\*](#generators).
## Installation
It's as easy as:
$ npm install -g 6to5
## Table of Contents
- [Features](#features)
- [Usage](#usage)
- [Plugins](#plugins)
- [CLI](#cli)
- [Node](#node-1)
- [Browser](#browser)
- [Modules](#modules)
- [Caveats](#caveats)
- [Polyfill](#polyfill)
- [Optional runtime](#optional-runtime)
- [React/JSX](#reactjsx)
- [Differences](#differences)
## [Features](FEATURES.md)
- [Array comprehension](FEATURES.md#array-comprehension)
- [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)
- [For-of](FEATURES.md#for-of)
- [Generators](FEATURES.md#generators) via [regenerator](https://github.com/facebook/regenerator)
- [Let scoping](FEATURES.md#let-scoping)
- [Modules](FEATURES.md#modules)
- [Numeric literals](FEATURES.md#numeric-literals)
- [Property method assignment](FEATURES.md#property-method-assignment)
- [Property name shorthand](FEATURES.md#property-name-shorthand)
- [Rest parameters](FEATURES.md#rest-parameters)
- [Spread](FEATURES.md#spread)
- [Template literals](FEATURES.md#template-literals)
- [Unicode regex](FEATURES.md#unicode-regex)
## Usage
### Plugins
- [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)
- [Gulp](https://github.com/sindresorhus/gulp-6to5)
- [Grunt](https://github.com/sindresorhus/grunt-6to5)
- [Jade](https://github.com/Apoxx/jade-6to5)
- [Jest](https://github.com/6to5/6to5-jest)
- [Karma](https://github.com/shuhei/karma-6to5-preprocessor)
- [Mocha](https://github.com/6to5/6to5-mocha)
- [Rails](https://github.com/6to5/6to5-rails)
- [webpack](https://github.com/Couto/6to5-loader)
### CLI
Compile the file `script.js` and output it to stdout.
$ 6to5 script.js
Compile the file `script.js` and output it to `script-compiled.js`.
$ 6to5 script.js --out-file script-compiled.js
Compile the file `script.js` and output it to `script-compiled.js` and save a
source map to `script-compiled.js.map`.
$ 6to5 script.js --source-maps --out-file script-compiled.js
Compile the file `script.js` and output it to `script-compiled.js` with a source
map embedded in a comment at the bottom.
$ 6to5 script.js --source-maps-inline --out-file script-compiled.js
Compile the entire `src` directory and output it to the `lib` directory.
$ 6to5 src --out-dir lib
Compile the entire `src` directory and output it to the one concatenated file.
$ 6to5 src --out-file script-compiled.js
Pipe a file in via stdin and output it to `script-compiled.js`
$ 6to5 --out-file script-compiled.js < script.js
#### Node
Launch a repl.
$ 6to5-node
Evaluate code.
$ 6to5-node -e "class Test { }"
Compile and run `test.js`.
$ 6to5-node test
### Node
```javascript
var to5 = require("6to5");
var result = to5.transform("code();", options);
result.code;
result.map;
result.ast;
to5.transformFileSync("filename.js", options).code;
to5.transformFile("filename.js", options, function (err, result) {
});
```
##### Options
```javascript
{
// Filename for use in errors etc.
// Default: "unknown"
filename: "filename",
// List of transformers to EXCLUDE.
// Run `6to5 --help` to see a full list of transformers.
blacklist: [],
// List of transformers to ONLY use.
// Run `6to5 --help` to see a full list of transformers.
whitelist: [],
// Module formatter to use
// Run `6to5 --help` to see a full list of module formatters.
// Default: "common"
modules: "common",
// If truthy, adds a `map` property to returned output.
// If set to "inline", a comment with a sourceMappingURL directive is added to
// the bottom of the returned code.
// Default: false
sourceMap: true,
// Set `file` on returned source map.
// Default: `filename` option.
sourceMapName: "filename",
// Set `sources[0]` on returned source map.
// Default: `filename` option.
sourceFileName: "filename",
// Optionally replace all 6to5 helper declarations with a referenece to this
// variable. If set to `true` then the default namespace is used "to5Runtime".
// Default: false
runtime: true
}
```
#### Require hook
All subsequent files required by node with the extensions `.es6` and `.js` will
be transformed by 6to5. The polyfill specified in [Polyfill](#polyfill) is also
required.
```javascript
require("6to5/register");
```
**NOTE:** By default all requires to `node_modules` will be ignored. You can
override this by passing an ignore regex via:
```javascript
require("6to5/register")({
// This will override `node_modules` ignoring - you can alternatively pass
// a regex
ignore: false
});
```
##### Options
```javascript
require("6to5/register")({
// Optional ignore regex - if any filenames **do** match this regex then they
// aren't compiled
ignore: /regex/,
// Optional only regex - if any filenames **don't** match this regex then they
// aren't compiled
only: /my_es6_folder/,
// See options above for usage
whitelist: [],
blacklist: [],
// This will remove the currently hooked extensions of .es6 and .js so you'll
// have to add them back if you want them to be used again.
extensions: [".js", ".es6"]
});
```
### Browser
A browser version of 6to5 is available from `browser.js` inside the 6to5
directory in an npm release.
#### Scripts
While it's not recommended for serious use, when the browser version is included
all scripts with the type `text/ecmascript-6` and `text/6to5` are automatically
compiled and ran.
For example:
```html
<script src="node_modules/6to5/browser.js"></script>
<script type="text/6to5">
class Test {
test() {
return "test";
}
}
var test = new Test;
test.test();
</script>
```
#### Build
You can build a browser version of the compiler by running the following in the
6to5 directory:
$ make build
This will output the files `dist/6to5.js` and `dist/6to5.min.js`.
#### API
```javascript
to5.transform("class Test {}").code;
```
#### Test
To test 6to5 in your browser run:
$ make test-browser
And open `test/browser.html` in your browser if it doesn't open automatically.
## [Modules](MODULES.md)
See [Modules - Common](MODULES.md#common-default) for documentation on the
default module formatting.
Alternatively see [Modules](MODULES.md) for all other supported module formatting types.
## Caveats
### For-of
A polyfill is required for for-of functionality that implements `Symbol` and
adds `prototype[Symbol.iterator]` behaviour to built-ins. Using the polyfills
specified in [polyfill](#polyfill) suffices.
### Classes
Built-in classes such as `Date`, `Array` and `DOM` cannot be subclassed due to
limitations in ES5 implementations.
If you're inheriting from a class then static properties are inherited from it
via [\_\_proto\_\_](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto),
this is widely supported but you may run into problems with much older browsers.
**NOTE:** `__proto__` is not supported on IE <= 9 so static properties
**will not** be inherited. A possible workaround is to use `super();`:
```javascript
class Foo {
static foo() {
}
}
class Bar extends Foo {
static foo() {
super();
}
}
```
### Generators
The [regenerator runtime](https://github.com/facebook/regenerator/blob/master/runtime.js)
and an [ES6 polyfill](#polyfill) are required in order for generators to work.
## 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.
### Node
```javascript
require("6to5/polyfill");
```
### Browser
Available from the `browser-polyfill.js` file within the 6to5 directory of an
npm release.
## Optional runtime
6to5 has a few helper functions that'll be placed at the top of the generated
code if needed so it's not inlined multiple times throughout that file. This may
become an issue if you have multiple files, especially when you're sending them
to the browser. gzip alleviates most of this concern but it's still not ideal.
You can tell 6to5 to not place any declarations at the top of your files and
instead just point them to a reference contained within the runtime.
Simply use the following option if you're using the [Node API](#node-1):
```javascript
{
runtime: true
}
```
or the following flag if you're using the [CLI](#cli):
$ 6to5 --runtime
Then just include the runtime before your generated code.
### Getting the runtime
You can get the runtime via either:
$ 6to5-runtime
or
```javascript
require("6to5").runtime();
```
or from an npm release in `runtime.js` from the 6to5 directory.
### Customising namespace
You can also customise the runtime namespace by passing an optional namespace
argument:
```javascript
require("6to5").runtime("myCustomNamespace");
```
$ 6to5-runtime myCustomNamespace
See [Options - runtime](#options) for documentation on changing the reference in
generated code.
## React/JSX
6to5 has built-in support for React v0.12. Tags are automatically transformed to
their equivalent `React.createElement(...)` and `displayName` is automatically
inferred and added to all `React.createClass` calls.
To disable this behaviour add `react` to your blacklist.
## Differences
### Philosophy
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.
Many other transpilers are just concerned with making the code work while 6to5
is concerned with making sure it works **and** is readable at the same time.
For example, given the following array comprehension:
```javascript
var seattlers = [for (c of customers) if (c.city == "Seattle") { name: c.name, age: c.age }];
```
is generated to the following with 6to5:
```javascript
var seattlers = customers.filter(function (c) {
return c.city == "Seattle";
}).map(function (c) {
return {
name: c.name,
age: c.age
};
});
```
The following is what Traceur generates:
```javascript
var seattlers = (function() {
var c;
var $__20 = 0,
$__21 = [];
for (var $__22 = customers[$traceurRuntime.toProperty(Symbol.iterator)](),
$__23; !($__23 = $__22.next()).done; ) {
c = $__23.value;
if (c.city == "Seattle")
$traceurRuntime.setProperty($__21, $__20++, {
name: c.name,
age: c.age
});
}
return $__21;
}());
```
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.
I'm not saying 6to5 is for everyone or even suited for everything. Traceur is
better suited if you'd like a full ES6 environment with polyfills and all.
### Comparison to other transpilers
| | 6to5 | Traceur | esnext | es6now | es6-transpiler | jstransform |
| ---------------------------- | ---- | ------- | ------ | ------ | -------------- | ----------- |
| No runtime | ✓ | | | | ✓ | ✓ |
| Source maps | ✓ | ✓ | ✓ | | ✓ | ✓ |
| No compiler global pollution | ✓ | | ✓ | | ✓ | ✓ |
| Arrow functions | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Classes | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Computed property names | ✓ | ✓ | ✓ | ✓ | ✓ | |
| Constants | ✓ | ✓ | | | ✓ | |
| Default parameters | ✓ | ✓ | ✓ | ✓ | ✓ | |
| Destructuring | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| For-of | ✓ | ✓ | ✓ | ✓ | ✓ | |
| Generators | ✓ | ✓ | ✓ | | | |
| Let scoping | ✓ | ✓ | | | ✓ | |
| Modules | ✓ | ✓ | | ✓ | | |
| Property method assignment | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Property name shorthand | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Rest parameters | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Spread | ✓ | ✓ | ✓ | ✓ | ✓ | |
| Template literals | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Unicode regex | ✓ | ✓ | | | ✓ | |
#### [Traceur](https://github.com/google/traceur-compiler)
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 runtime can be eliminated entirely.
#### [es6now](https://github.com/zenparsing/es6now)
es6now doesn't output sourcemaps. This is cited as a positive as line-to-line
mapping is the goal. This however obviously doesn't retain column mapping
resulting in the output code not being very pleasant.
#### [es6-transpiler](https://github.com/termi/es6-transpiler)
The es6-transpiler compiler requires shims to operate which pollutes the global
scope resulting in possible collisions.
es6-transpiler maps line-by-line, just like es6now, this results in the same
issues such as lack of column information and unpleasant code output.
For more information view the [documentation](https://6to5.github.io).

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env node
var commander = require("commander");
var util = require("../lib/6to5/util");
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");

49
doc/browser.md Normal file
View File

@@ -0,0 +1,49 @@
# Browser
A browser version of 6to5 is available from `browser.js` inside the 6to5
directory in an npm release.
## API
```javascript
to5.transform("class Test {}").code;
```
## Scripts
While it's not recommended for serious use, when the browser version is included
all scripts with the type `text/ecmascript-6` and `text/6to5` are automatically
compiled and ran.
For example:
```html
<script src="node_modules/6to5/browser.js"></script>
<script type="text/6to5">
class Test {
test() {
return "test";
}
}
var test = new Test;
test.test();
</script>
```
## Build
You can build a browser version of the compiler by running the following in the
6to5 directory:
$ make build
This will output the files `dist/6to5.js` and `dist/6to5.min.js`.
## Test
To test 6to5 in your browser run:
$ make test-browser
And open `test/browser.html` in your browser if it doesn't open automatically.

43
doc/caveats.md Normal file
View File

@@ -0,0 +1,43 @@
# Caveats
## Classes
Built-in classes such as `Date`, `Array` and `DOM` cannot be subclassed due to
limitations in ES5 implementations.
If you're inheriting from a class then static properties are inherited from it
via [\_\_proto\_\_](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto),
this is widely supported but you may run into problems with much older browsers.
**NOTE:** `__proto__` is not supported on IE <= 9 so static properties
**will not** be inherited. A possible workaround is to use `super();`:
```javascript
class Foo {
static foo() {
}
}
class Bar extends Foo {
static foo() {
super();
}
}
```
## For-of
A polyfill is required for for-of functionality that implements `Symbol` and
adds `prototype[Symbol.iterator]` behaviour to built-ins. Using the polyfills
specified in [polyfill](polyfill.md) suffices.
## Generators
The [regenerator runtime](https://github.com/facebook/regenerator/blob/master/runtime.js)
and an [ES6 polyfill](polyfill.md) are required in order for generators to work.
## Spread
An [ES6 polyfill](polyfill.md) is required in order for spread to work. More
specifically a polyfill for `Array.from`.

103
doc/differences.md Normal file
View File

@@ -0,0 +1,103 @@
# Differences
## Philosophy
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.
Many other transpilers are just concerned with making the code work while 6to5
is concerned with making sure it works **and** is readable at the same time.
For example, given the following array comprehension:
```javascript
var seattlers = [for (c of customers) if (c.city == "Seattle") { name: c.name, age: c.age }];
```
is generated to the following with 6to5:
```javascript
var seattlers = customers.filter(function (c) {
return c.city == "Seattle";
}).map(function (c) {
return {
name: c.name,
age: c.age
};
});
```
The following is what Traceur generates:
```javascript
var seattlers = (function() {
var c;
var $__20 = 0,
$__21 = [];
for (var $__22 = customers[$traceurRuntime.toProperty(Symbol.iterator)](),
$__23; !($__23 = $__22.next()).done; ) {
c = $__23.value;
if (c.city == "Seattle")
$traceurRuntime.setProperty($__21, $__20++, {
name: c.name,
age: c.age
});
}
return $__21;
}());
```
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.
I'm not saying 6to5 is for everyone or even suited for everything. Traceur is
better suited if you'd like a full ES6 environment with polyfills and all.
## Comparison to other transpilers
| | 6to5 | Traceur | esnext | es6now | es6-transpiler | jstransform |
| ---------------------------- | ---- | ------- | ------ | ------ | -------------- | ----------- |
| No runtime | ✓ | | | | ✓ | ✓ |
| Source maps | ✓ | ✓ | ✓ | | ✓ | ✓ |
| No compiler global pollution | ✓ | | ✓ | | ✓ | ✓ |
| Browser support | ✓ | ✓ | ✓ | | | |
| Array comprehension | ✓ | ✓ | | | ✓ | |
| Arrow functions | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Async functions | ✓ | ✓ | ✓ | | | |
| Classes | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Computed property names | ✓ | ✓ | ✓ | ✓ | ✓ | |
| Constants | ✓ | ✓ | | | ✓ | |
| Default parameters | ✓ | ✓ | ✓ | ✓ | ✓ | |
| Destructuring | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| For-of | ✓ | ✓ | ✓ | ✓ | ✓ | |
| Generators | ✓ | ✓ | ✓ | | | |
| Generator comprehension | ✓ | ✓ | | | | |
| Let scoping | ✓ | ✓ | | | ✓ | |
| Modules | ✓ | ✓ | | ✓ | | |
| Property method assignment | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Property name shorthand | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Rest parameters | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Spread | ✓ | ✓ | ✓ | ✓ | ✓ | |
| Template literals | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Unicode regex | ✓ | ✓ | | | ✓ | |
### [Traceur](https://github.com/google/traceur-compiler)
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 runtime can be eliminated entirely.
### [es6now](https://github.com/zenparsing/es6now)
es6now doesn't output sourcemaps. This is cited as a positive as line-to-line
mapping is the goal. This however obviously doesn't retain column mapping
resulting in the output code not being very pleasant.
### [es6-transpiler](https://github.com/termi/es6-transpiler)
The es6-transpiler compiler requires shims to operate which pollutes the global
scope resulting in possible collisions.
es6-transpiler maps line-by-line, just like es6now, this results in the same
issues such as lack of column information and unpleasant code output.

View File

@@ -6,6 +6,16 @@
[for (i of [1, 2, 3]) i * i]; // [1, 4, 9]
```
## Async functions
```javascript
async function chainAnimationsAsync(elem, animations) {
for (var anim of animations) {
await anim(elem);
}
}
```
## Arrow functions
```javascript
@@ -85,6 +95,11 @@ for (var i of [1, 2, 3]) {
```javascript
```
## Generator comprehension
```javascript
```
## Modules
```javascript

36
doc/index.md Normal file
View File

@@ -0,0 +1,36 @@
**6to5** turns ES6 code into vanilla ES5, so you can use ES6 features **today.**
- **Readable** - formatting is retained if possible so your generated code is as similar as possible.
- **Extensible** - with a large range of [plugins](plugins.md) and **browser support**.
- **Lossless** - **source map support** so you can debug your compiled code with ease.
- **Compact** - maps directly to the equivalent ES5 with **no runtime**[\*](caveats.md#generators).
## Installation
It's as easy as:
$ npm install -g 6to5
## [Features](features.md)
- [Array comprehension](features.md#array-comprehension)
- [Async functions](features.md#async-functions) via [regenerator](https://github.com/facebook/regenerator)
- [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)
- [For-of](features.md#for-of)
- [Generators](features.md#generators) via [regenerator](https://github.com/facebook/regenerator)
- [Generator comprehension](features.md#generator-comprehension)
- [Let scoping](features.md#let-scoping)
- [Modules](features.md#modules)
- [Numeric literals](features.md#numeric-literals)
- [Property method assignment](features.md#property-method-assignment)
- [Property name shorthand](features.md#property-name-shorthand)
- [React/JSX](react.md)
- [Rest parameters](features.md#rest-parameters)
- [Spread](features.md#spread)
- [Template literals](features.md#template-literals)
- [Unicode regex](features.md#unicode-regex)

51
doc/optional-runtime.md Normal file
View File

@@ -0,0 +1,51 @@
# Optional runtime
6to5 has a few helper functions that'll be placed at the top of the generated
code if needed so it's not inlined multiple times throughout that file. This may
become an issue if you have multiple files, especially when you're sending them
to the browser. gzip alleviates most of this concern but it's still not ideal.
You can tell 6to5 to not place any declarations at the top of your files and
instead just point them to a reference contained within the runtime.
Simply use the following option if you're using the [Node API](usage.md#node):
```javascript
{
runtime: true
}
```
or the following flag if you're using the [CLI](usage.md#cli):
$ 6to5 --runtime
Then just include the runtime before your generated code.
## Getting the runtime
You can get the runtime via either:
$ 6to5-runtime
or
```javascript
require("6to5").runtime();
```
or from an npm release in `runtime.js` from the 6to5 directory.
## Customising namespace
You can also customise the runtime namespace by passing an optional namespace
argument:
```javascript
require("6to5").runtime("myCustomNamespace");
```
$ 6to5-runtime myCustomNamespace
See [Options - runtime](usage.md#options) for documentation on changing the
reference in generated code.

15
doc/plugins.md Normal file
View File

@@ -0,0 +1,15 @@
# Plugins
- [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)
- [Gulp](https://github.com/sindresorhus/gulp-6to5)
- [Grunt](https://github.com/sindresorhus/grunt-6to5)
- [Jade](https://github.com/Apoxx/jade-6to5)
- [Jest](https://github.com/6to5/6to5-jest)
- [Karma](https://github.com/shuhei/karma-6to5-preprocessor)
- [Mocha](https://github.com/6to5/6to5-mocha)
- [Rails](https://github.com/6to5/6to5-rails)
- [webpack](https://github.com/Couto/6to5-loader)

17
doc/polyfill.md Normal file
View File

@@ -0,0 +1,17 @@
# 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.
## Node
```javascript
require("6to5/polyfill");
```
## Browser
Available from the `browser-polyfill.js` file within the 6to5 directory of an
npm release.

16
doc/react.md Normal file
View File

@@ -0,0 +1,16 @@
# React/JSX
6to5 has built-in support for React v0.12. Tags are automatically transformed to
their equivalent `React.createElement(...)` and `displayName` is automatically
inferred and added to all `React.createClass` calls.
## Blacklist
To disable this behaviour add `react` to your blacklist:
```javascript
to5.transform("code", { blacklist: ["react"] });
```
$ 6to5 --blacklist react

149
doc/usage.md Normal file
View File

@@ -0,0 +1,149 @@
# Usage
## CLI
Compile the file `script.js` and output it to stdout.
$ 6to5 script.js
Compile the file `script.js` and output it to `script-compiled.js`.
$ 6to5 script.js --out-file script-compiled.js
Compile the file `script.js` and output it to `script-compiled.js` and save a
source map to `script-compiled.js.map`.
$ 6to5 script.js --source-maps --out-file script-compiled.js
Compile the file `script.js` and output it to `script-compiled.js` with a source
map embedded in a comment at the bottom.
$ 6to5 script.js --source-maps-inline --out-file script-compiled.js
Compile the entire `src` directory and output it to the `lib` directory.
$ 6to5 src --out-dir lib
Compile the entire `src` directory and output it to the one concatenated file.
$ 6to5 src --out-file script-compiled.js
Pipe a file in via stdin and output it to `script-compiled.js`
$ 6to5 --out-file script-compiled.js < script.js
### Node
Launch a repl.
$ 6to5-node
Evaluate code.
$ 6to5-node -e "class Test { }"
Compile and run `test.js`.
$ 6to5-node test
## Node
```javascript
var to5 = require("6to5");
var result = to5.transform("code();", options);
result.code;
result.map;
result.ast;
to5.transformFileSync("filename.js", options).code;
to5.transformFile("filename.js", options, function (err, result) {
});
```
#### Options
```javascript
{
// Filename for use in errors etc.
// Default: "unknown"
filename: "filename",
// List of transformers to EXCLUDE.
// Run `6to5 --help` to see a full list of transformers.
blacklist: [],
// List of transformers to ONLY use.
// Run `6to5 --help` to see a full list of transformers.
whitelist: [],
// Module formatter to use
// Run `6to5 --help` to see a full list of module formatters.
// Default: "common"
modules: "common",
// If truthy, adds a `map` property to returned output.
// If set to "inline", a comment with a sourceMappingURL directive is added to
// the bottom of the returned code.
// Default: false
sourceMap: true,
// Set `file` on returned source map.
// Default: `filename` option.
sourceMapName: "filename",
// Set `sources[0]` on returned source map.
// Default: `filename` option.
sourceFileName: "filename",
// Optionally replace all 6to5 helper declarations with a referenece to this
// variable. If set to `true` then the default namespace is used "to5Runtime".
// Default: false
runtime: true
}
```
### Require hook
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.
```javascript
require("6to5/register");
```
**NOTE:** By default all requires to `node_modules` will be ignored. You can
override this by passing an ignore regex via:
```javascript
require("6to5/register")({
// This will override `node_modules` ignoring - you can alternatively pass
// a regex
ignore: false
});
```
#### Options
```javascript
require("6to5/register")({
// Optional ignore regex - if any filenames **do** match this regex then they
// aren't compiled
ignore: /regex/,
// Optional only regex - if any filenames **don't** match this regex then they
// aren't compiled
only: /my_es6_folder/,
// See options above for usage
whitelist: [],
blacklist: [],
// This will remove the currently hooked extensions of .es6 and .js so you'll
// have to add them back if you want them to be used again.
extensions: [".js", ".es6"]
});
```

View File

@@ -18,7 +18,7 @@ function File(opts) {
this.ast = {};
}
File.declarations = ["extends", "class-props", "slice"];
File.declarations = ["extends", "class-props", "slice", "apply-constructor"];
File.normaliseOptions = function (opts) {
opts = _.cloneDeep(opts || {});
@@ -30,7 +30,8 @@ File.normaliseOptions = function (opts) {
sourceMap: false,
filename: "unknown",
modules: "common",
runtime: false
runtime: false,
code: true
});
// normalise windows path separators to unix
@@ -142,6 +143,14 @@ File.prototype.generate = function () {
var opts = this.opts;
var ast = this.ast;
if (!opts.code) {
return {
code: "",
map: null,
ast: ast
};
}
var result = generate(ast, opts, this.code);
if (this.shebang) {
@@ -153,6 +162,8 @@ File.prototype.generate = function () {
result.code += "\n" + util.sourceMapToComment(result.map);
}
result.ast = result;
return result;
};

View File

@@ -11,7 +11,7 @@ function Buffer(position, format) {
}
Buffer.prototype.get = function () {
return this.buf.trimRight();
return util.trimRight(this.buf);
};
Buffer.prototype.getIndent = function () {
@@ -76,6 +76,8 @@ Buffer.prototype.newline = function (i, removeLast) {
}
if (_.isNumber(i)) {
if (this.endsWith(util.repeat(i, "\n"))) return;
var self = this;
_.times(i, function () {
self.newline(null, removeLast);
@@ -86,7 +88,7 @@ Buffer.prototype.newline = function (i, removeLast) {
if (removeLast && this.isLast("\n")) this.removeLast("\n");
this.removeLast(" ");
this.buf = this.buf.replace(/\n(\s+)$/, "\n");
this.buf = this.buf.replace(/\n +$/, "\n");
this._push("\n");
};
@@ -116,7 +118,7 @@ Buffer.prototype.endsWith = function (str) {
Buffer.prototype.isLast = function (cha, trimRight) {
var buf = this.buf;
if (trimRight) buf = buf.trimRight();
if (trimRight) buf = util.trimRight(buf);
var chars = [].concat(cha);
return _.contains(chars, _.last(buf));

View File

@@ -53,16 +53,16 @@ CodeGenerator.normaliseOptions = function (opts) {
};
CodeGenerator.generators = {
arrayComprehensions: require("./generators/array-comprehensions"),
templateLiterals: require("./generators/template-literals"),
expressions: require("./generators/expressions"),
statements: require("./generators/statements"),
classes: require("./generators/classes"),
methods: require("./generators/methods"),
modules: require("./generators/modules"),
types: require("./generators/types"),
base: require("./generators/base"),
jsx: require("./generators/jsx")
templateLiterals: require("./generators/template-literals"),
comprehensions: require("./generators/comprehensions"),
expressions: require("./generators/expressions"),
statements: require("./generators/statements"),
classes: require("./generators/classes"),
methods: require("./generators/methods"),
modules: require("./generators/modules"),
types: require("./generators/types"),
base: require("./generators/base"),
jsx: require("./generators/jsx")
};
_.each(CodeGenerator.generators, function (generator) {
@@ -76,7 +76,6 @@ CodeGenerator.prototype.generate = function () {
return {
map: this.map.get(),
ast: ast,
code: this.buffer.get()
};
};
@@ -116,8 +115,6 @@ CodeGenerator.prototype.print = function (node, parent, opts) {
opts = opts || {};
var newline = function (leading) {
var ignoreDuplicates = false;
if (!opts.statement && !n.isUserWhitespacable(node, parent)) {
return;
}
@@ -140,7 +137,7 @@ CodeGenerator.prototype.print = function (node, parent, opts) {
lines += needs(node, parent);
}
self.newline(lines, ignoreDuplicates);
self.newline(lines);
};
if (this[node.type]) {

View File

@@ -8,7 +8,8 @@ exports.ComprehensionBlock = function (node, print) {
};
exports.ComprehensionExpression = function (node, print) {
this.push("[");
this.push(node.generator ? "(" : "[");
print.join(node.blocks, { separator: " " });
this.space();
@@ -21,5 +22,6 @@ exports.ComprehensionExpression = function (node, print) {
}
print(node.body);
this.push("]");
this.push(node.generator ? ")" : "]");
};

View File

@@ -36,6 +36,7 @@ var blacklistTest = function (transformer, code) {
};
blacklistTest("arrayComprehension", "var foo = [for (foo of bar) foo * foo];");
//blacklistTest("generatorComprehension", "");
blacklistTest("arrowFunctions", "var foo = x => x * x;");
blacklistTest("classes", "class Foo {}");
blacklistTest("computedPropertyNames", "var foo = { [foo]: bar };");

View File

@@ -0,0 +1,5 @@
(function (Constructor, args) {
var bindArgs = [null].concat(args);
var Factory = Constructor.bind.apply(Constructor, bindArgs);
return new Factory;
});

View File

@@ -31,6 +31,7 @@ _.each({
propertyNameShorthand: require("./transformers/property-name-shorthand"),
constants: require("./transformers/constants"),
arrayComprehension: require("./transformers/array-comprehension"),
generatorComprehension: require("./transformers/generator-comprehension"),
arrowFunctions: require("./transformers/arrow-functions"),
classes: require("./transformers/classes"),
@@ -46,7 +47,6 @@ _.each({
letScoping: require("./transformers/let-scoping"),
forOf: require("./transformers/for-of"),
unicodeRegex: require("./transformers/unicode-regex"),
numericLiterals: require("./transformers/numeric-literals"),
react: require("./transformers/react"),

View File

@@ -15,6 +15,7 @@ Transformer.normalise = function (transformer) {
}
_.each(transformer, function (fns, type) {
if (type[0] === "_") return;
if (_.isFunction(fns)) fns = { enter: fns };
transformer[type] = fns;
});

View File

@@ -37,39 +37,42 @@ var multiple = function (node, file) {
var returnStatement = body.pop();
var build = function () {
var self = node.blocks.shift();
if (!self) return;
var child = build();
if (!child) {
// last item
child = util.template("array-push", {
STATEMENT: node.body,
KEY: uid
}, true);
// add a filter as this is our final stop
if (node.filter) {
child = t.ifStatement(node.filter, t.blockStatement([child]));
}
}
return t.forOfStatement(
t.variableDeclaration("var", [t.variableDeclarator(self.left)]),
self.right,
t.blockStatement([child])
);
};
body.push(build());
body.push(exports._build(node, function () {
return util.template("array-push", {
STATEMENT: node.body,
KEY: uid
}, true);
}));
body.push(returnStatement);
return container;
};
exports._build = function (node, buildBody) {
var self = node.blocks.shift();
if (!self) return;
var child = exports._build(node, buildBody);
if (!child) {
// last item
child = buildBody();
// add a filter as this is our final stop
if (node.filter) {
child = t.ifStatement(node.filter, t.blockStatement([child]));
}
}
return t.forOfStatement(
t.variableDeclaration("var", [t.variableDeclarator(self.left)]),
self.right,
t.blockStatement([child])
);
};
exports.ComprehensionExpression = function (node, parent, file) {
if (node.generator) return;
if (node.blocks.length === 1 && t.isArrayExpression(node.blocks[0].right)) {
return singleArrayExpression(node);
} else {

View File

@@ -5,12 +5,12 @@ var _ = require("lodash");
exports.ClassDeclaration = function (node, parent, file, scope) {
return t.variableDeclaration("var", [
t.variableDeclarator(node.id, buildClass(node, file, scope))
t.variableDeclarator(node.id, new Class(node, file, scope).run())
]);
};
exports.ClassExpression = function (node, parent, file, scope) {
return buildClass(node, file, scope);
return new Class(node, file, scope).run();
};
var getMemberExpressionObject = function (node) {
@@ -20,31 +20,59 @@ var getMemberExpressionObject = function (node) {
return node;
};
var buildClass = function (node, file, scope) {
var superName = node.superClass;
var className = node.id || t.identifier(file.generateUid("class", scope));
/**
* Description
*
* @param {Node} node
* @param {File} file
* @param {Scope} scope
*/
var superClassArgument = node.superClass;
var superClassCallee = node.superClass;
function Class(node, file, scope) {
this.scope = scope;
this.node = node;
this.file = file;
this.instanceMutatorMap = {};
this.staticMutatorMap = {};
this.hasConstructor = false;
this.className = node.id || t.identifier(file.generateUid("class", scope));
this.superName = node.superClass;
}
/**
* Description
*
* @returns {Array}
*/
Class.prototype.run = function () {
var superClassArgument = this.superName;
var superClassCallee = this.superName;
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 = t.identifier(file.generateUid("ref", scope));
superClassCallee = superName = t.identifier(file.generateUid("ref", this.scope));
}
}
this.superName = superName;
var container = util.template("class", {
CLASS_NAME: className
});
var block = container.callee.expression.body;
var body = block.body;
var constructor = body[0].declarations[0].init;
var body = this.body = block.body;
var constructor = this.constructor = body[0].declarations[0].init;
if (node.id) constructor.id = className;
if (this.node.id) constructor.id = className;
var returnStatement = body.pop();
@@ -55,14 +83,7 @@ var buildClass = function (node, file, scope) {
container.callee.expression.params.push(superClassCallee);
}
buildClassBody({
file: file,
body: body,
node: node,
className: className,
superName: superName,
constructor: constructor,
});
this.buildBody();
if (body.length === 1) {
// only a constructor so no need for a closure container
@@ -73,49 +94,29 @@ var buildClass = function (node, file, scope) {
}
};
var buildClassBody = function (opts) {
var file = opts.file;
var body = opts.body;
var node = opts.node;
var constructor = opts.constructor;
var className = opts.className;
var superName = opts.superName;
/**
* Description
*/
var instanceMutatorMap = {};
var staticMutatorMap = {};
var hasConstructor = false;
var classBody = node.body.body;
Class.prototype.buildBody = function () {
var constructor = this.constructor;
var className = this.className;
var superName = this.superName;
var classBody = this.node.body.body;
var body = this.body;
var self = this;
_.each(classBody, function (node) {
var methodName = node.key;
var method = node.value;
replaceInstanceSuperReferences(superName, node);
self.replaceInstanceSuperReferences(node);
if (node.key.name === "constructor") {
if (node.kind === "") {
hasConstructor = true;
addConstructor(constructor, method);
} else {
throw file.errorWithNode(node, "illegal kind for constructor method");
}
self.pushConstructor(node);
} else {
var mutatorMap = instanceMutatorMap;
if (node.static) mutatorMap = staticMutatorMap;
var kind = node.kind;
if (kind === "") {
kind = "value";
util.pushMutatorMap(mutatorMap, methodName, "writable", t.identifier("true"));
}
util.pushMutatorMap(mutatorMap, methodName, kind, node);
self.pushMethod(node);
}
});
if (!hasConstructor && superName) {
if (!this.hasConstructor && superName) {
constructor.body.body.push(util.template("class-super-constructor-call", {
SUPER_NAME: superName
}, true));
@@ -124,16 +125,16 @@ var buildClassBody = function (opts) {
var instanceProps;
var staticProps;
if (!_.isEmpty(instanceMutatorMap)) {
if (!_.isEmpty(this.instanceMutatorMap)) {
var protoId = util.template("prototype-identifier", {
CLASS_NAME: className
});
instanceProps = util.buildDefineProperties(instanceMutatorMap, protoId);
instanceProps = util.buildDefineProperties(this.instanceMutatorMap, protoId);
}
if (!_.isEmpty(staticMutatorMap)) {
staticProps = util.buildDefineProperties(staticMutatorMap, className);
if (!_.isEmpty(this.staticMutatorMap)) {
staticProps = util.buildDefineProperties(this.staticMutatorMap, className);
}
if (instanceProps || staticProps) {
@@ -143,17 +144,50 @@ var buildClassBody = function (opts) {
if (instanceProps) args.push(instanceProps);
body.push(t.expressionStatement(
t.callExpression(file.addDeclaration("class-props"), args)
t.callExpression(this.file.addDeclaration("class-props"), args)
));
}
};
var superIdentifier = function (superName, methodNode, node, parent) {
var methodName = methodNode.key;
/**
* Push a method to it's respective mutatorMap.
*
* @param {Node} node MethodDefinition
*/
if (parent.property === node) {
Class.prototype.pushMethod = function (node) {
var methodName = node.key;
var mutatorMap = this.instanceMutatorMap;
if (node.static) mutatorMap = this.staticMutatorMap;
var kind = node.kind;
if (kind === "") {
kind = "value";
util.pushMutatorMap(mutatorMap, methodName, "writable", t.identifier("true"));
}
util.pushMutatorMap(mutatorMap, methodName, kind, node);
};
/**
* Given a `methodNode`, produce a `MemberExpression` super class reference.
*
* @param {Node} methodNode MethodDefinition
* @param {Node} node Identifier
* @param {Node} parent
*
* @returns {Node}
*/
Class.prototype.superIdentifier = function (methodNode, id, parent) {
var methodName = methodNode.key;
var superName = this.superName || t.identifier("Function");
if (parent.property === id) {
return;
} else if (t.isCallExpression(parent, { callee: node })) {
} else if (t.isCallExpression(parent, { callee: id })) {
// super(); -> ClassName.prototype.MethodName.call(this);
parent.arguments.unshift(t.thisExpression());
@@ -161,15 +195,15 @@ var superIdentifier = function (superName, methodNode, node, parent) {
// constructor() { super(); }
return t.memberExpression(superName, t.identifier("call"));
} else {
node = superName;
id = superName;
// foo() { super(); }
if (!methodNode.static) {
node = t.memberExpression(node, t.identifier("prototype"));
id = t.memberExpression(id, t.identifier("prototype"));
}
node = t.memberExpression(node, methodName, methodNode.computed);
return t.memberExpression(node, t.identifier("call"));
id = t.memberExpression(id, methodName, methodNode.computed);
return t.memberExpression(id, t.identifier("call"));
}
} else if (t.isMemberExpression(parent) && !methodNode.static) {
// super.test -> ClassName.prototype.test
@@ -179,31 +213,50 @@ var superIdentifier = function (superName, methodNode, node, parent) {
}
};
var replaceInstanceSuperReferences = function (superName, methodNode) {
var method = methodNode.value;
/**
* Replace all `super` references with a reference to our `superClass`.
*
* @param {Node} methodNode MethodDefinition
*/
superName = superName || t.identifier("Function");
Class.prototype.replaceInstanceSuperReferences = function (methodNode) {
var method = methodNode.value;
var self = this;
traverse(method, function (node, parent) {
if (t.isIdentifier(node, { name: "super" })) {
return superIdentifier(superName, methodNode, node, parent);
return self.superIdentifier(methodNode, node, parent);
} else if (t.isCallExpression(node)) {
var callee = node.callee;
if (!t.isMemberExpression(callee)) return;
if (callee.object.name !== "super") return;
// super.test(); -> ClassName.prototype.MethodName.call(this);
callee.property.name = callee.property.name + ".call";
// super.test(); -> ClassName.prototype.MethodName.call(this);
callee.property = t.memberExpression(callee.property, t.identifier("call"));
node.arguments.unshift(t.thisExpression());
}
});
};
var addConstructor = function (construct, method) {
construct.defaults = method.defaults;
construct.params = method.params;
construct.body = method.body;
construct.rest = method.rest;
/**
* Replace the constructor body of our class.
*
* @param {Node} method MethodDefinition
*/
t.inherits(construct, method);
Class.prototype.pushConstructor = function (method) {
if (method.kind !== "") {
throw this.file.errorWithNode(method, "illegal kind for constructor method");
}
var construct = this.constructor;
var fn = method.value;
this.hasConstructor = true;
t.inherits(construct, fn);
construct.defaults = fn.defaults;
construct.params = fn.params;
construct.body = fn.body;
construct.rest = fn.rest;
};

View File

@@ -3,7 +3,7 @@ var t = require("../../types");
var _ = require("lodash");
exports.Function = function (node) {
if (!node.defaults.length) return;
if (!node.defaults || !node.defaults.length) return;
t.ensureBlock(node);
_.each(node.defaults, function (def, i) {

View File

@@ -146,6 +146,12 @@ exports.ExpressionStatement = function (node, parent, file, scope) {
return nodes;
};
exports.AssignmentExpression = function (node, parent, file) {
if (parent.type === "ExpressionStatement") return;
if (!t.isPattern(node.left)) return;
throw file.errorWithNode(node, "AssignmentExpression destructuring outside of a ExpressionStatement is forbidden due to current 6to5 limitations");
};
exports.VariableDeclaration = function (node, parent, file, scope) {
if (t.isForInStatement(parent) || t.isForOfStatement(parent)) return;

View File

@@ -0,0 +1,15 @@
var arrayComprehension = require("./array-comprehension");
var t = require("../../types");
exports.ComprehensionExpression = function (node) {
if (!node.generator) return;
var body = [];
var container = t.functionExpression(null, [], t.blockStatement(body), true);
body.push(arrayComprehension._build(node, function () {
return t.expressionStatement(t.yieldExpression(node.body));
}));
return t.callExpression(container, []);
};

View File

@@ -17,6 +17,12 @@ var isVar = function (node) {
return t.isVariableDeclaration(node, { kind: "var" }) && !isLet(node);
};
var standardiseLets = function (declars) {
_.each(declars, function (declar) {
delete declar._let;
});
};
exports.VariableDeclaration = function (node) {
isLet(node);
};
@@ -33,7 +39,8 @@ exports.For = function (node, parent, file, scope) {
node.label = parent.label;
}
run(node, node.body, parent, file, scope);
var letScoping = new LetScoping(node, node.body, parent, file, scope);
letScoping.run();
if (node.label && !t.isLabeledStatement(parent)) {
// we've been given a label so let's wrap ourselves
@@ -43,12 +50,98 @@ exports.For = function (node, parent, file, scope) {
exports.BlockStatement = function (block, parent, file, scope) {
if (!t.isFor(parent)) {
run(false, block, parent, file, scope);
var letScoping = new LetScoping(false, block, parent, file, scope);
letScoping.run();
}
};
var noClosure = function (letDeclars, block, replacements) {
standardiseLets(letDeclars);
/**
* Description
*
* @param {Boolean|Node} forParent
* @param {Node} block
* @param {Node} parent
* @param {File} file
* @param {Scope} scope
*/
function LetScoping(forParent, block, parent, file, scope) {
this.forParent = forParent;
this.parent = parent;
this.scope = scope;
this.block = block;
this.file = file;
this.letReferences = {};
this.body = [];
this.info = this.getInfo();
}
/**
* Start the ball rolling.
*/
LetScoping.prototype.run = function () {
var block = this.block;
if (block._letDone) return;
block._letDone = true;
// this is a block within a `Function` so we can safely leave it be
if (t.isFunction(this.parent)) return;
// this block has no let references so let's clean up
if (!this.info.keys.length) return this.noClosure();
// returns whether or not there are any outside let references within any
// functions
var referencesInClosure = this.getLetReferences();
// no need for a closure so let's clean up
if (!referencesInClosure) return this.noClosure();
// if we're inside of a for loop then we search to see if there are any
// `break`s, `continue`s, `return`s etc
this.has = this.checkFor();
// hoist var references to retain scope
this.hoistVarDeclarations();
// set let references to plain var references
standardiseLets(this.info.declarators);
// turn letReferences into an array
var letReferences = _.values(this.letReferences);
// build the closure that we're going to wrap the block with
var fn = t.functionExpression(null, letReferences, t.blockStatement(block.body));
fn._aliasFunction = true;
// replace the current block body with the one we're going to build
block.body = this.body;
// change upper scope references with their uid if they have one
var params = this.getParams(letReferences);
// build a call and a unique id that we can assign the return value to
var call = t.callExpression(fn, params);
var ret = t.identifier(this.file.generateUid("ret", this.scope));
this.build(ret, call);
};
/**
* There are no let references accessed within a closure so we can just traverse
* through this block and replace all references that exist in a high scope to
* their uids.
*/
LetScoping.prototype.noClosure = function () {
var replacements = this.info.duplicates;
var declarators = this.info.declarators;
var block = this.block;
standardiseLets(declarators);
if (_.isEmpty(replacements)) return;
@@ -59,13 +152,17 @@ var noClosure = function (letDeclars, block, replacements) {
});
};
var standardiseLets = function (declars) {
_.each(declars, function (declar) {
delete declar._let;
});
};
/**
* Description
*
* @returns {Object}
*/
LetScoping.prototype.getInfo = function () {
var block = this.block;
var scope = this.scope;
var file = this.file;
var getInfo = function (block, file, scope) {
var opts = {
// array of `Identifier` names of let variables that appear lexically out of
// this scope but should be accessible - eg. `ForOfStatement`.left
@@ -111,15 +208,23 @@ var getInfo = function (block, file, scope) {
return opts;
};
var checkFor = function (forParent, block) {
/**
* If we're inside of a `For*Statement` then traverse it and check if it has one
* of the following node types `ReturnStatement`, `BreakStatement`,
* `ContinueStatement` and replace it with a return value we can track later on.
*
* @returns {Object}
*/
LetScoping.prototype.checkFor = function () {
var has = {
hasContinue: false,
hasReturn: false,
hasBreak: false,
};
if (forParent) {
traverse(block, function (node) {
if (this.forParent) {
traverse(this.block, function (node) {
var replace;
if (t.isFunction(node) || t.isFor(node)) {
@@ -144,38 +249,59 @@ var checkFor = function (forParent, block) {
return has;
};
var hoistVarDeclarations = function (block, pushDeclar) {
traverse(block, function (node) {
/**
* Hoist all var declarations in this block to before it so they retain scope
* once we wrap everything is in a closure.
*/
LetScoping.prototype.hoistVarDeclarations = function () {
var self = this;
traverse(this.block, function (node) {
if (t.isForStatement(node)) {
if (isVar(node.init)) {
node.init = t.sequenceExpression(pushDeclar(node.init));
node.init = t.sequenceExpression(self.pushDeclar(node.init));
}
} else if (t.isFor(node)) {
if (isVar(node.left)) {
node.left = node.left.declarations[0].id;
}
} else if (isVar(node)) {
return pushDeclar(node).map(t.expressionStatement);
return self.pushDeclar(node).map(t.expressionStatement);
} else if (t.isFunction(node)) {
return false;
}
});
};
var getParams = function (info, letReferences) {
var params = _.cloneDeep(letReferences);
/**
* Build up a parameter list that we'll call our closure wrapper with, replacing
* all duplicate ids with their uid.
*
* @param {Array} params
* @returns {Array}
*/
LetScoping.prototype.getParams = function (params) {
var info = this.info;
params = _.cloneDeep(params);
_.each(params, function (param) {
param.name = info.duplicates[param.name] || param.name;
});
return params;
};
var getLetReferences = function (block, info, letReferences) {
/**
* Get all let references within this block. Stopping whenever we reach another
* block.
*/
LetScoping.prototype.getLetReferences = function () {
var closurify = false;
var self = this;
// traverse through this block, stopping on functions and checking if they
// contain any outside let references
traverse(block, function (node, parent, scope) {
traverse(this.block, function (node, parent, scope) {
if (t.isFunction(node)) {
traverse(node, function (node, parent) {
// not an identifier so we have no use
@@ -191,10 +317,10 @@ var getLetReferences = function (block, info, letReferences) {
closurify = true;
// this key doesn't appear just outside our scope
if (!_.contains(info.outsideKeys, node.name)) return;
if (!_.contains(self.info.outsideKeys, node.name)) return;
// push this badboy
letReferences[node.name] = node;
self.letReferences[node.name] = node;
});
return false;
@@ -206,125 +332,100 @@ var getLetReferences = function (block, info, letReferences) {
return closurify;
};
var buildPushDeclar = function (body) {
return function (node) {
body.push(t.variableDeclaration(node.kind, node.declarations.map(function (declar) {
return t.variableDeclarator(declar.id);
})));
/**
* Turn a `VariableDeclaration` into an array of `AssignmentExpressions` with
* their declarations hoisted to before the closure wrapper.
*
* @param {Node} node VariableDeclaration
* @returns {Array}
*/
var replace = [];
LetScoping.prototype.buildPushDeclar = function (node) {
this.body.push(t.variableDeclaration(node.kind, node.declarations.map(function (declar) {
return t.variableDeclarator(declar.id);
})));
_.each(node.declarations, function (declar) {
if (!declar.init) return;
var replace = [];
var expr = t.assignmentExpression("=", declar.id, declar.init);
replace.push(t.inherits(expr, declar));
});
_.each(node.declarations, function (declar) {
if (!declar.init) return;
return replace;
};
var expr = t.assignmentExpression("=", declar.id, declar.init);
replace.push(t.inherits(expr, declar));
});
return replace;
};
var run = function (forParent, block, parent, file, scope) {
if (block._letDone) return;
block._letDone = true;
var info = getInfo(block, file, scope);
var declarators = info.declarators;
var letKeys = info.keys;
// this is a block within a `Function` so we can safely leave it be
if (t.isFunction(parent)) return;
// this block has no let references so let's clean up
if (!letKeys.length) return noClosure(declarators, block, info.duplicates);
// outside let references that we need to wrap
var letReferences = {};
// returns whether or not there are any outside let references within any
// functions
var closurify = getLetReferences(block, info, letReferences);
letReferences = _.values(letReferences);
// no need for a closure so let's clean up
if (!closurify) return noClosure(declarators, block, info.duplicates);
// if we're inside of a for loop then we search to see if there are any
// `break`s, `continue`s, `return`s etc
var has = checkFor(forParent, block);
var body = [];
// hoist a `VariableDeclaration` and add `AssignmentExpression`s in it's place
var pushDeclar = buildPushDeclar(body);
// hoist var references to retain scope
hoistVarDeclarations(block, pushDeclar);
// set let references to plain var references
standardiseLets(declarators);
// build the closure that we're going to wrap the block with
var fn = t.functionExpression(null, letReferences, t.blockStatement(block.body));
fn._aliasFunction = true;
// replace the current block body with the one we've built
block.body = body;
// change duplicate let references to their uid if they have one
var params = getParams(info, letReferences);
var call = t.callExpression(fn, params);
var ret = t.identifier(file.generateUid("ret", scope));
/**
* Push the closure to the body.
*
* @param {Node} ret Identifier
* @param {Node} call CallExpression
*/
LetScoping.prototype.build = function (ret, call) {
var has = this.has;
if (has.hasReturn || has.hasBreak || has.hasContinue) {
body.push(t.variableDeclaration("var", [
t.variableDeclarator(ret, call)
]));
var retCheck;
var cases = [];
if (has.hasReturn) {
// typeof ret === "object"
retCheck = util.template("let-scoping-return", {
RETURN: ret,
});
}
if (has.hasBreak || has.hasContinue) {
// ensure that the parent has a label as we're building a switch and we
// need to be able to access it
var label = forParent.label = forParent.label || t.identifier(file.generateUid("loop", scope));
if (has.hasBreak) {
cases.push(t.switchCase(t.literal("break"), [t.breakStatement(label)]));
}
if (has.hasContinue) {
cases.push(t.switchCase(t.literal("continue"), [t.continueStatement(label)]));
}
if (has.hasReturn) {
cases.push(t.switchCase(null, [retCheck]));
}
if (cases.length === 1) {
var single = cases[0];
body.push(t.ifStatement(
t.binaryExpression("===", ret, single.test),
single.consequent[0]
));
} else {
body.push(t.switchStatement(ret, cases));
}
} else {
if (has.hasReturn) body.push(retCheck);
}
this.buildHas(ret, call);
} else {
body.push(t.expressionStatement(call));
this.body.push(t.expressionStatement(call));
}
};
/**
* Description
*
* @param {Node} ret Identifier
* @param {Node} call CallExpression
*/
LetScoping.prototype.buildHas = function (ret, call) {
var body = this.body;
body.push(t.variableDeclaration("var", [
t.variableDeclarator(ret, call)
]));
var forParent = this.forParent;
var retCheck;
var has = this.has;
var cases = [];
if (has.hasReturn) {
// typeof ret === "object"
retCheck = util.template("let-scoping-return", {
RETURN: ret
});
}
if (has.hasBreak || has.hasContinue) {
// ensure that the parent has a label as we're building a switch and we
// need to be able to access it
var label = forParent.label = forParent.label || t.identifier(this.file.generateUid("loop", this.scope));
if (has.hasBreak) {
cases.push(t.switchCase(t.literal("break"), [t.breakStatement(label)]));
}
if (has.hasContinue) {
cases.push(t.switchCase(t.literal("continue"), [t.continueStatement(label)]));
}
if (has.hasReturn) {
cases.push(t.switchCase(null, [retCheck]));
}
if (cases.length === 1) {
var single = cases[0];
body.push(t.ifStatement(
t.binaryExpression("===", ret, single.test),
single.consequent[0]
));
} else {
body.push(t.switchStatement(ret, cases));
}
} else {
if (has.hasReturn) body.push(retCheck);
}
};

View File

@@ -1,6 +0,0 @@
var _ = require("lodash");
exports.Literal = function (node) {
// TODO: remove this when the new code generator is released
if (_.isNumber(node.value)) delete node.raw;
};

View File

@@ -57,15 +57,39 @@ exports.XJSOpeningElement = {
var props = node.attributes;
if (props.length) {
var first = props[0];
if (t.isXJSSpreadAttribute(first)) {
props.shift();
var _props = [];
var objs = [];
var pushProps = function () {
if (!_props.length) return;
objs.push(t.objectExpression(_props));
_props = [];
};
while (props.length) {
var prop = props.shift();
if (t.isXJSSpreadAttribute(prop)) {
pushProps();
objs.push(prop.argument);
} else {
_props.push(prop);
}
}
pushProps();
if (objs.length === 1) {
props = objs[0];
} else {
if (!t.isObjectExpression(objs[0])) {
objs.unshift(t.objectExpression([]));
}
props = t.callExpression(
t.memberExpression(t.identifier("React"), t.identifier("__spread")),
[t.objectExpression([]), first.argument, t.objectExpression(props)]
objs
);
} else {
props = t.objectExpression(props);
}
} else {
props = t.literal(null);

View File

@@ -1,14 +1,13 @@
var util = require("../../util");
var t = require("../../types");
var _ = require("lodash");
var t = require("../../types");
var _ = require("lodash");
var getSpreadLiteral = function (spread, file) {
var getSpreadLiteral = function (spread) {
var literal = spread.argument;
if (!t.isArrayExpression(literal)) {
literal = util.template("call", {
OBJECT: file.addDeclaration("slice"),
CONTEXT: literal
});
literal = t.callExpression(
t.memberExpression(t.identifier("Array"), t.identifier("from")),
[literal]
);
}
return literal;
};
@@ -24,7 +23,7 @@ var hasSpread = function (nodes) {
return has;
};
var build = function (props, file) {
var build = function (props) {
var nodes = [];
var _props = [];
@@ -38,7 +37,7 @@ var build = function (props, file) {
_.each(props, function (prop) {
if (t.isSpreadElement(prop)) {
push();
nodes.push(getSpreadLiteral(prop, file));
nodes.push(getSpreadLiteral(prop));
} else {
_props.push(prop);
}
@@ -49,11 +48,11 @@ var build = function (props, file) {
return nodes;
};
exports.ArrayExpression = function (node, parent, file) {
exports.ArrayExpression = function (node) {
var elements = node.elements;
if (!hasSpread(elements)) return;
var nodes = build(elements, file);
var nodes = build(elements);
var first = nodes.shift();
if (!nodes.length) return first;
@@ -61,7 +60,7 @@ exports.ArrayExpression = function (node, parent, file) {
return t.callExpression(t.memberExpression(first, t.identifier("concat")), nodes);
};
exports.CallExpression = function (node, parent, file) {
exports.CallExpression = function (node) {
var args = node.arguments;
if (!hasSpread(args)) return;
@@ -69,7 +68,7 @@ exports.CallExpression = function (node, parent, file) {
node.arguments = [];
var nodes = build(args, file);
var nodes = build(args);
var first = nodes.shift();
if (nodes.length) {
@@ -96,3 +95,19 @@ exports.CallExpression = function (node, parent, file) {
node.arguments.unshift(contextLiteral);
};
exports.NewExpression = function (node, parent, file) {
var args = node.arguments;
if (!hasSpread(args)) return;
var nodes = build(args);
var first = nodes.shift();
if (nodes.length) {
args = t.callExpression(t.memberExpression(first, t.identifier("concat")), nodes);
} else {
args = first;
}
return t.callExpression(file.addDeclaration("apply-constructor"), [node.callee, args]);
};

View File

@@ -7,11 +7,12 @@
"ConditionalExpression": ["test", "consequent", "alternate"],
"ExpressionStatement": ["expression"],
"File": ["program", "comments", "tokens"],
"FunctionExpression": ["id", "params", "body"],
"FunctionExpression": ["id", "params", "body", "generator"],
"Identifier": ["name"],
"IfStatement": ["test", "consequent", "alternate"],
"Literal": ["value"],
"MemberExpression": ["object", "property", "computed"],
"NewExpression": ["callee", "arguments"],
"ObjectExpression": ["properties"],
"ParenthesizedExpression": ["expression"],
"Program": ["body"],

View File

@@ -25,6 +25,10 @@ exports.resolve = function (loc) {
}
};
exports.trimRight = function (str) {
return str.replace(/[\n\s]+$/g, "");
};
exports.list = function (val) {
return val ? val.split(",") : [];
};
@@ -240,7 +244,7 @@ exports.parse = function (opts, code, callback) {
}
};
exports.parseNoProperties = function (loc, code) {
exports.parseTemplate = function (loc, code) {
var ast = exports.parse({ filename: loc }, code).program;
return traverse.removeProperties(ast);
};
@@ -262,7 +266,7 @@ var loadTemplates = function () {
var loc = templatesLoc + "/" + name;
var code = fs.readFileSync(loc, "utf8");
templates[key] = exports.parseNoProperties(loc, code);
templates[key] = exports.parseTemplate(loc, code);
});
return templates;

View File

@@ -1,7 +1,7 @@
{
"name": "6to5",
"description": "Turn ES6 code into readable vanilla ES5 with source maps",
"version": "1.12.1",
"version": "1.12.8",
"author": "Sebastian McKenzie <sebmck@gmail.com>",
"homepage": "https://github.com/6to5/6to5",
"repository": {
@@ -44,19 +44,19 @@
"es6-symbol": "0.1.1",
"regexpu": "0.3.0",
"source-map": "0.1.40",
"regenerator-6to5": "https://github.com/6to5/regenerator-6to5/archive/62d1bfcb331dcf0bbcdbbee8043da0c6408f09cf.tar.gz",
"regenerator-6to5": "https://github.com/6to5/regenerator-6to5/archive/75925940a7bb67d1ee8afec36b6d6eec072fb47c.tar.gz",
"chokidar": "0.10.5",
"source-map-support": "0.2.8",
"esutils": "1.1.4",
"acorn-6to5": "https://github.com/6to5/acorn-6to5/archive/0384a0d51f630f66ed591769c1765581a17d2124.tar.gz",
"acorn-6to5": "https://github.com/6to5/acorn-6to5/archive/a6c34ba73e215bd16ee585f6794f6a6587820c58.tar.gz",
"estraverse": "^1.7.0"
},
"devDependencies": {
"istanbul": "0.3.2",
"matcha": "0.5.0",
"matcha": "0.6.0",
"mocha": "2.0.1",
"uglify-js": "2.4.15",
"browserify": "6.2.0",
"browserify": "6.3.2",
"rimraf": "2.2.8",
"jshint": "2.5.10",
"chai": "^1.9.2"

View File

@@ -20,8 +20,11 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
function test() {}
// Copyright (C) 2012 Yusuke Suzuki <utatane.tea@gmail.com>
//
// Redistribution and use in source and binary forms, with or without

View File

@@ -2,7 +2,6 @@
function add() {
var _arguments = arguments;
return [1, 2, 3].map(function (i) {
return i * _arguments[0];
});

View File

@@ -2,13 +2,10 @@
var seattlers = (function () {
var _arr = [];
for (var _iterator = countries[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) {
var customers = _step.value;
for (var _iterator2 = customers[Symbol.iterator](), _step2; !(_step2 = _iterator2.next()).done;) {
var c = _step2.value;
if (c.city == "Seattle") {
_arr.push({ name: c.name, age: c.age });
}

View File

@@ -2,10 +2,8 @@
var arr = (function () {
var _arr = [];
for (var _iterator = "abcdefgh".split("")[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) {
var x = _step.value;
for (var _iterator2 = "12345678".split("")[Symbol.iterator](), _step2; !(_step2 = _iterator2.next()).done;) {
var y = _step2.value;
_arr.push(x + y);

View File

@@ -2,7 +2,6 @@
function add() {
var _this = this;
return [1, 2, 3].map(function (i) {
return i * _this.multiplier;
});

View File

@@ -2,7 +2,6 @@
function one() {
var _arguments = arguments;
var inner = function () {
return _arguments;
};
@@ -12,14 +11,12 @@ one(1, 2);
function two() {
var _arguments2 = arguments;
var inner = function () {
return _arguments2;
};
var another = function () {
var _arguments3 = arguments;
var inner2 = function () {
return _arguments3;
};
@@ -31,7 +28,6 @@ two(1, 2);
function three() {
var _arguments4 = arguments;
var fn = function () {
return _arguments4[0] + "bar";
};
@@ -41,7 +37,6 @@ three("foo");
function four() {
var _arguments5 = arguments;
var fn = function () {
return _arguments5[0].foo + "bar";
};

View File

@@ -2,7 +2,6 @@
var some = function (count) {
if (count === undefined) count = "30";
console.log("count", count);
};

View File

@@ -3,7 +3,6 @@
module.exports = {
init: function () {
var _this = this;
return new Promise(function (resolve, reject) {
MongoClient.connect(config.mongodb, function (err, db) {
if (err) {

View File

@@ -1,9 +1,7 @@
"use strict";
var _slice = Array.prototype.slice;
var _classProps = function (child, staticProps, instanceProps) {
if (staticProps) Object.defineProperties(child, staticProps);
if (instanceProps) Object.defineProperties(child.prototype, instanceProps);
};
@@ -26,11 +24,11 @@ var Test = (function (Foo) {
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(Array.from(arguments)));
Foo.call.apply(Foo, [this, "test"].concat(Array.from(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(Array.from(arguments)));
Foo.prototype.test.call.apply(Foo.prototype, [this, "test"].concat(Array.from(arguments)));
};
_extends(Test, Foo);
@@ -40,8 +38,8 @@ var Test = (function (Foo) {
writable: true,
value: function () {
Foo.foo.call(this);
Foo.foo.call.apply(Foo.foo, [this].concat(_slice.call(arguments)));
Foo.foo.call.apply(Foo.foo, [this, "test"].concat(_slice.call(arguments)));
Foo.foo.call.apply(Foo.foo, [this].concat(Array.from(arguments)));
Foo.foo.call.apply(Foo.foo, [this, "test"].concat(Array.from(arguments)));
}
}
}, {
@@ -49,8 +47,8 @@ var Test = (function (Foo) {
writable: true,
value: 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)));
Foo.prototype.test.call.apply(Foo.prototype.test, [this].concat(Array.from(arguments)));
Foo.prototype.test.call.apply(Foo.prototype.test, [this, "test"].concat(Array.from(arguments)));
}
}
});

View File

@@ -2,7 +2,6 @@
var _classProps = function (child, staticProps, instanceProps) {
if (staticProps) Object.defineProperties(child, staticProps);
if (instanceProps) Object.defineProperties(child.prototype, instanceProps);
};

View File

@@ -2,7 +2,6 @@
var _classProps = function (child, staticProps, instanceProps) {
if (staticProps) Object.defineProperties(child, staticProps);
if (instanceProps) Object.defineProperties(child.prototype, instanceProps);
};

View File

@@ -2,7 +2,6 @@
var _classProps = function (child, staticProps, instanceProps) {
if (staticProps) Object.defineProperties(child, staticProps);
if (instanceProps) Object.defineProperties(child.prototype, instanceProps);
};

View File

@@ -2,7 +2,6 @@
var _classProps = function (child, staticProps, instanceProps) {
if (staticProps) Object.defineProperties(child, staticProps);
if (instanceProps) Object.defineProperties(child.prototype, instanceProps);
};

View File

@@ -2,7 +2,6 @@
var _classProps = function (child, staticProps, instanceProps) {
if (staticProps) Object.defineProperties(child, staticProps);
if (instanceProps) Object.defineProperties(child.prototype, instanceProps);
};

View File

@@ -2,7 +2,6 @@
var _classProps = function (child, staticProps, instanceProps) {
if (staticProps) Object.defineProperties(child, staticProps);
if (instanceProps) Object.defineProperties(child.prototype, instanceProps);
};

View File

@@ -2,7 +2,6 @@
var _classProps = function (child, staticProps, instanceProps) {
if (staticProps) Object.defineProperties(child, staticProps);
if (instanceProps) Object.defineProperties(child.prototype, instanceProps);
};

View File

@@ -2,14 +2,11 @@
var t = function (t, f) {
if (f === undefined) f = 5;
if (t === undefined) t = "foo";
return t + " bar " + f;
};
var a = function (t, f) {
if (f === undefined) f = 5;
return t + " bar " + f;
};

View File

@@ -2,6 +2,5 @@
var t = function (t) {
if (t === undefined) t = "foo";
return t + " bar";
};

View File

@@ -0,0 +1 @@
console.log([x] = [123]);

View File

@@ -0,0 +1,3 @@
{
"throws": "AssignmentExpression destructuring outside of a ExpressionStatement is forbidden due to current 6to5 limitations"
}

View File

@@ -3,6 +3,5 @@
for (var _ref in obj) {
var name = _ref[0];
var value = _ref[1];
print("Name: " + name + ", Value: " + value);
}

View File

@@ -10,7 +10,6 @@ function somethingAdvanced(_ref) {
function unpackObject(_ref2) {
var title = _ref2.title;
var author = _ref2.author;
return title + " " + author;
}
@@ -23,7 +22,6 @@ var unpackArray = function (_ref3, _ref4) {
var x = _ref4[0];
var y = _ref4[1];
var z = _ref4[2];
return a + b + c;
};

View File

@@ -0,0 +1,6 @@
var nums = [1, 2, 3, 4, 5, 6];
var multiples = (for (i of nums) if (i % 2) i * i);
assert.equal(multiples.next().value, 1);
assert.equal(multiples.next().value, 9);
assert.equal(multiples.next().value, 25);
assert.ok(multiples.next().done);

View File

@@ -1,7 +1,6 @@
var Component;
Component = React.createClass({
displayName: "Component",
render: function () {
return null;
}

View File

@@ -1,7 +1,6 @@
exports = {
Component: React.createClass({
displayName: "Component",
render: function () {
return null;
}

View File

@@ -1,6 +1,5 @@
exports.Component = React.createClass({
displayName: "Component",
render: function () {
return null;
}

View File

@@ -1,6 +1,5 @@
var Component = React.createClass({
displayName: "Component",
render: function () {
return null;
}

View File

@@ -0,0 +1 @@
<Component y={2} z { ... x } />

View File

@@ -0,0 +1,4 @@
React.createElement(Component, React.__spread({
y: 2,
z: true
}, x));

View File

@@ -0,0 +1 @@
<Component y={2} { ... x } z />

View File

@@ -0,0 +1,5 @@
React.createElement(Component, React.__spread({
y: 2
}, x, {
z: true
}));

View File

@@ -3,4 +3,4 @@
var _slice = Array.prototype.slice;
var concat = function () {
var arrs = _slice.call(arguments);
};
};

View File

@@ -7,4 +7,4 @@ var t = function (f) {
function t(f) {
var items = _slice.call(arguments, 1);
}
}

View File

@@ -7,4 +7,4 @@ var t = function () {
function t() {
var items = _slice.call(arguments);
}
}

View File

@@ -2,7 +2,6 @@
var _classProps = function (child, staticProps, instanceProps) {
if (staticProps) Object.defineProperties(child, staticProps);
if (instanceProps) Object.defineProperties(child.prototype, instanceProps);
};

View File

@@ -4,7 +4,7 @@
"column": 10
},
"generated": {
"line": 15,
"line": 14,
"column": 15
}
}]

View File

@@ -1,12 +1,11 @@
"use strict";
var _slice = Array.prototype.slice;
function foo() {
return bar.apply(null, ["test"].concat(_slice.call(arguments)));
return bar.apply(null, ["test"].concat(Array.from(arguments)));
}
function bar(one, two, three) {
return [one, two, three];
}
foo("foo", "bar");
foo("foo", "bar");

View File

@@ -1,4 +1,3 @@
"use strict";
var _slice = Array.prototype.slice;
var lyrics = _slice.call(parts).concat(["head", "and", "toes"]);
var lyrics = Array.from(parts).concat(["head", "and", "toes"]);

View File

@@ -1,4 +1,3 @@
"use strict";
var _slice = Array.prototype.slice;
var a = [b].concat(_slice.call(c), [d]);
var a = [b].concat(Array.from(c), [d]);

View File

@@ -1,4 +1,3 @@
"use strict";
var _slice = Array.prototype.slice;
var a = [b].concat(_slice.call(c), [d, e], _slice.call(f));
var a = [b].concat(Array.from(c), [d, e], Array.from(f));

View File

@@ -1,4 +1,3 @@
"use strict";
var _slice = Array.prototype.slice;
var lyrics = ["head", "and", "toes"].concat(_slice.call(parts));
var lyrics = ["head", "and", "toes"].concat(Array.from(parts));

View File

@@ -1,4 +1,3 @@
"use strict";
var _slice = Array.prototype.slice;
obj[method].apply(obj, [foo, bar].concat(_slice.call(args)));
obj[method].apply(obj, [foo, bar].concat(Array.from(args)));

View File

@@ -1,4 +1,3 @@
"use strict";
var _slice = Array.prototype.slice;
obj[method].apply(obj, _slice.call(args));
obj[method].apply(obj, Array.from(args));

View File

@@ -1,5 +1,4 @@
"use strict";
var _slice = Array.prototype.slice;
foob.add.apply(foob, [foo, bar].concat(_slice.call(numbers)));
foob.test.add.apply(foob.test, [foo, bar].concat(_slice.call(numbers)));
foob.add.apply(foob, [foo, bar].concat(Array.from(numbers)));
foob.test.add.apply(foob.test, [foo, bar].concat(Array.from(numbers)));

View File

@@ -1,5 +1,4 @@
"use strict";
var _slice = Array.prototype.slice;
foob.add.apply(foob, _slice.call(numbers));
foob.test.add.apply(foob.test, _slice.call(numbers));
foob.add.apply(foob, Array.from(numbers));
foob.test.add.apply(foob.test, Array.from(numbers));

View File

@@ -1,4 +1,3 @@
"use strict";
var _slice = Array.prototype.slice;
add.apply(null, _slice.call(numbers).concat([foo, bar]));
add.apply(null, Array.from(numbers).concat([foo, bar]));

View File

@@ -1,4 +1,3 @@
"use strict";
var _slice = Array.prototype.slice;
add.apply(null, [foo].concat(_slice.call(numbers), [bar]));
add.apply(null, [foo].concat(Array.from(numbers), [bar]));

View File

@@ -1,4 +1,3 @@
"use strict";
var _slice = Array.prototype.slice;
add.apply(null, [foo, bar].concat(_slice.call(numbers)));
add.apply(null, [foo, bar].concat(Array.from(numbers)));

View File

@@ -1,4 +1,3 @@
"use strict";
var _slice = Array.prototype.slice;
add.apply(null, [foo].concat(_slice.call(numbers), [bar, what], _slice.call(test)));
add.apply(null, [foo].concat(Array.from(numbers), [bar, what], Array.from(test)));

View File

@@ -1,4 +1,3 @@
"use strict";
var _slice = Array.prototype.slice;
add.apply(null, _slice.call(numbers));
add.apply(null, Array.from(numbers));

View File

@@ -0,0 +1,2 @@
new Numbers(...nums);
new Numbers(1, ...nums);

View File

@@ -0,0 +1,12 @@
"use strict";
var _applyConstructor = function (Constructor, args) {
var bindArgs = [null].concat(args);
var Factory = Constructor.bind.apply(Constructor, bindArgs);
return new Factory();
};
_applyConstructor(Numbers, Array.from(nums));
_applyConstructor(Numbers, [1].concat(Array.from(nums)));