Compare commits
149 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4f5669f53c | ||
|
|
262fd995da | ||
|
|
1696f77980 | ||
|
|
ca2cbb02f1 | ||
|
|
b72427cdd0 | ||
|
|
44e9812ad4 | ||
|
|
b7814e5e24 | ||
|
|
ec67a83326 | ||
|
|
6a560cea25 | ||
|
|
46f9ed7d74 | ||
|
|
92366dfc7b | ||
|
|
f520a46175 | ||
|
|
88bec1196b | ||
|
|
ff0098f3f3 | ||
|
|
d01d7722f4 | ||
|
|
2845c1a894 | ||
|
|
ed51728aba | ||
|
|
4c8f4121f0 | ||
|
|
b9e4340700 | ||
|
|
4c9e39afa1 | ||
|
|
7439247095 | ||
|
|
254424ced5 | ||
|
|
4fc6823ece | ||
|
|
d531c8aa4c | ||
|
|
fc59f1ff46 | ||
|
|
7c7cd6f9b8 | ||
|
|
e3174d5a39 | ||
|
|
2558a5e12e | ||
|
|
7526ae5486 | ||
|
|
811fcf7e1b | ||
|
|
62818d468e | ||
|
|
a88bd69e30 | ||
|
|
8164bb17ce | ||
|
|
3ec97fc86d | ||
|
|
b38a00d70e | ||
|
|
1b85607d7d | ||
|
|
fd6704ac25 | ||
|
|
9c527f9d9c | ||
|
|
6cf318d60f | ||
|
|
64f9f4dff5 | ||
|
|
145413dbfd | ||
|
|
8c58e0f14c | ||
|
|
d62914e41c | ||
|
|
85db67edf4 | ||
|
|
348ad2e25c | ||
|
|
5ce8ee6c2b | ||
|
|
98ad5d42e1 | ||
|
|
b12734abd6 | ||
|
|
f34907d518 | ||
|
|
3bd6ec20c1 | ||
|
|
b8d4479333 | ||
|
|
ed833be34a | ||
|
|
16024242b0 | ||
|
|
77add8704e | ||
|
|
9fd1ec0596 | ||
|
|
90ce4e93ed | ||
|
|
cf7b9234c1 | ||
|
|
f85eeeb93c | ||
|
|
45d0eea842 | ||
|
|
b0c9d3daa4 | ||
|
|
3f152bfc3f | ||
|
|
ffbfa5281b | ||
|
|
7f87ca0d43 | ||
|
|
a8fad4b958 | ||
|
|
945ea145e7 | ||
|
|
4f10bcedda | ||
|
|
601b3d584f | ||
|
|
42878f85fe | ||
|
|
3b4c9c415e | ||
|
|
7345899343 | ||
|
|
316102ab14 | ||
|
|
4c2b85deec | ||
|
|
108784db20 | ||
|
|
a3b30bae7a | ||
|
|
6420954c53 | ||
|
|
a6fda01fa0 | ||
|
|
655cc8fcb9 | ||
|
|
97a504bbef | ||
|
|
bf3443962b | ||
|
|
a4394494ef | ||
|
|
2b333de81f | ||
|
|
b81f824b7e | ||
|
|
9bfb8c440a | ||
|
|
9a6c13a6a4 | ||
|
|
ac8d77fb45 | ||
|
|
09c88238e1 | ||
|
|
103b619364 | ||
|
|
c8a404fb72 | ||
|
|
05669204dd | ||
|
|
38e6abec02 | ||
|
|
1abef2c1e2 | ||
|
|
cc6678361a | ||
|
|
2587694d44 | ||
|
|
f16079c83f | ||
|
|
b7132f3529 | ||
|
|
ed41f1652e | ||
|
|
c522bdb4b9 | ||
|
|
005362a615 | ||
|
|
88e542634f | ||
|
|
c8304138eb | ||
|
|
35608d497e | ||
|
|
b5a78355c4 | ||
|
|
223e28ba8f | ||
|
|
6a35bdb42b | ||
|
|
18813f26bb | ||
|
|
ccabb91f69 | ||
|
|
35fda899a8 | ||
|
|
e2f01d41a3 | ||
|
|
931a80f5b3 | ||
|
|
9a2fd22e91 | ||
|
|
cbcad22d81 | ||
|
|
4d5861cfdc | ||
|
|
c578db7ae8 | ||
|
|
dea73b7186 | ||
|
|
4506e39cf5 | ||
|
|
7ab6df093b | ||
|
|
22eeae1a93 | ||
|
|
a645ae0583 | ||
|
|
7f4efecb7d | ||
|
|
0c0f40d14a | ||
|
|
cb54c11d84 | ||
|
|
55123be7d7 | ||
|
|
324a0b408a | ||
|
|
8b2788e930 | ||
|
|
d945379b5b | ||
|
|
5a622ac9c7 | ||
|
|
0e9eac610b | ||
|
|
1de94a2705 | ||
|
|
71132c3538 | ||
|
|
d20ab0eb05 | ||
|
|
51f7e75d2e | ||
|
|
ab4b5ce994 | ||
|
|
f0d50ca9a2 | ||
|
|
5168355a64 | ||
|
|
2f209a9e4e | ||
|
|
20695eaba6 | ||
|
|
340a4dd1f2 | ||
|
|
ef1c7a5c69 | ||
|
|
5a01beaa1f | ||
|
|
5a5bf7b4ac | ||
|
|
88ee15bb4d | ||
|
|
3e51b65095 | ||
|
|
371df9ad09 | ||
|
|
d43d5ff409 | ||
|
|
c2c8e52430 | ||
|
|
57c0ebc5f4 | ||
|
|
339bf82481 | ||
|
|
f4055612e5 | ||
|
|
46911bd28c |
6
.gitmodules
vendored
Normal file
6
.gitmodules
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
[submodule "vendor/traceur"]
|
||||
path = vendor/traceur
|
||||
url = https://github.com/google/traceur-compiler
|
||||
[submodule "vendor/regenerator"]
|
||||
path = vendor/regenerator
|
||||
url = https://github.com/facebook/regenerator
|
||||
81
CHANGELOG.md
81
CHANGELOG.md
@@ -1,6 +1,85 @@
|
||||
# Changelog
|
||||
|
||||
Gaps between patch versions are faulty/broken releases.
|
||||
> **Tags:**
|
||||
> - [New Feature]
|
||||
> - [Bug Fix]
|
||||
> - [Spec Compliancy]
|
||||
> - [Breaking Change]
|
||||
> - [Documentation]
|
||||
> - [Internal]
|
||||
> - [Polish]
|
||||
|
||||
_Note: Gaps between patch versions are faulty/broken releases._
|
||||
|
||||
## 2.6.2
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix rest parameter keys when on functions with params.
|
||||
|
||||
## 2.6.1
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix rest parameter arguments key.
|
||||
|
||||
## 2.6.0
|
||||
|
||||
* **Bug Fix**
|
||||
* Better handling of number literal property keys.
|
||||
* Handle `NewExpression` paren insertion edegcases better.
|
||||
* **Internal**
|
||||
* Fix incorrect AST node `identifier("this")`.
|
||||
* Better `toIdentifier` method that handles reserved words.
|
||||
* Upgrade `acorn-6to5`.
|
||||
* Fix exponentiation operator precedence.
|
||||
* Fix line terminators after async contextual keywords.
|
||||
* Add semicolons as class elements inside of a class body.
|
||||
* Upgrade to `core-js` 4.0.0.
|
||||
* Upgrade to `regenerator` 0.8.3.
|
||||
* Fix non-loop labeled statements.
|
||||
* **New Feature**
|
||||
* Basic destructuring defaults
|
||||
* Add `.es` to list of supported extensions.
|
||||
* Add optional `typeofSymbol` transformer.
|
||||
* Use a `for` loop for rest parameters instead of `Array.prototype.slice`.
|
||||
* **Polish**
|
||||
* Move `"use strict";` to inside module bodies instead of at the top of the file.
|
||||
* Better handling of dynamic imports.
|
||||
* **Spec Compliancy**
|
||||
* Class inheritance now has a `function` or `null` type check.
|
||||
* Add `interopRequireWildcard` around wildcard imports and exports to handle non-object exports.
|
||||
|
||||
## 2.5.0
|
||||
|
||||
* Remove `noDuplicateProperties` transformer.
|
||||
* Better generated UIDs based on nodes.
|
||||
* Default parameters now use `arguments[i]`, conditionals and variable declarations instead of using long-form if statements.
|
||||
|
||||
## 2.4.10
|
||||
|
||||
* Upgrade `acorn-6to5`.
|
||||
|
||||
## 2.4.9
|
||||
|
||||
* Upgrade `acorn-6to5`.
|
||||
* Add optional `protoToAssign` transformer.
|
||||
* Fix missing properties from computed property keys.
|
||||
* Make ES7 comprehensions `let` variables.
|
||||
|
||||
## 2.4.8
|
||||
|
||||
* Make `require("6to5/register")` work with browserify - [#370](https://github.com/6to5/6to5/pull/370). Thanks [@hughsk](https://github.com/hughsk)!
|
||||
|
||||
## 2.4.7
|
||||
|
||||
* Upgrade `acorn-6to5`.
|
||||
|
||||
## 2.4.6
|
||||
|
||||
* Move `coreAliasing` and `undefinedToVoid` transformers down to catch `moduleFormatter` transforms.
|
||||
|
||||
## 2.4.5
|
||||
|
||||
* Avoid printing comments if they've already been output.
|
||||
|
||||
## 2.4.4
|
||||
|
||||
|
||||
13
CODE_OF_CONDUCT.md
Normal file
13
CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# Contributor Code of Conduct
|
||||
|
||||
As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
|
||||
|
||||
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, age, or religion.
|
||||
|
||||
Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
|
||||
@@ -1,5 +1,7 @@
|
||||
# Contributing
|
||||
|
||||
Before contributing, please read the [code of conduct](https://github.com/6to5/6to5/blob/master/CODE_OF_CONDUCT.md).
|
||||
|
||||
* **General**
|
||||
* No ES6 syntax features or methods, exclusively ES5.
|
||||
* Max of five arguments for functions
|
||||
|
||||
39
Makefile
39
Makefile
@@ -6,7 +6,23 @@ MOCHA_CMD = node_modules/mocha/bin/_mocha
|
||||
|
||||
export NODE_ENV = test
|
||||
|
||||
.PHONY: clean test test-cov test-clean lint test-travis test-spec test-browser publish bench build
|
||||
.PHONY: clean test test-cov test-clean lint test-travis test-spec test-browser publish bench build bootstrap
|
||||
|
||||
build:
|
||||
mkdir -p dist
|
||||
|
||||
node bin/cache-templates
|
||||
|
||||
node $(BROWSERIFY_CMD) -e lib/6to5/polyfill.js >dist/polyfill.js
|
||||
node $(UGLIFY_CMD) dist/polyfill.js >dist/polyfill.min.js
|
||||
|
||||
node $(BROWSERIFY_CMD) lib/6to5/browser.js -s to5 >dist/6to5.js
|
||||
node $(UGLIFY_CMD) dist/6to5.js >dist/6to5.min.js
|
||||
|
||||
node bin/6to5-runtime >dist/runtime.js
|
||||
node $(UGLIFY_CMD) dist/runtime.js >dist/runtime.min.js
|
||||
|
||||
rm -rf templates.json
|
||||
|
||||
clean:
|
||||
rm -rf coverage templates.json test/tmp dist
|
||||
@@ -45,22 +61,6 @@ test-browser:
|
||||
|
||||
test -n "`which open`" && open test/browser.html
|
||||
|
||||
build:
|
||||
mkdir -p dist
|
||||
|
||||
node bin/cache-templates
|
||||
|
||||
node $(BROWSERIFY_CMD) -e lib/6to5/polyfill.js >dist/polyfill.js
|
||||
node $(UGLIFY_CMD) dist/polyfill.js >dist/polyfill.min.js
|
||||
|
||||
node $(BROWSERIFY_CMD) lib/6to5/browser.js -s to5 >dist/6to5.js
|
||||
node $(UGLIFY_CMD) dist/6to5.js >dist/6to5.min.js
|
||||
|
||||
node bin/6to5-runtime >dist/runtime.js
|
||||
node $(UGLIFY_CMD) dist/runtime.js >dist/runtime.min.js
|
||||
|
||||
rm -rf templates.json
|
||||
|
||||
publish:
|
||||
git pull --rebase
|
||||
|
||||
@@ -81,3 +81,8 @@ publish:
|
||||
git push --follow-tags
|
||||
|
||||
rm -rf templates.json browser.js runtime.js browser-polyfill.js
|
||||
|
||||
bootstrap:
|
||||
npm install
|
||||
git submodule update --init
|
||||
cd vendor/regenerator; npm install
|
||||
|
||||
8
NOTES.md
Normal file
8
NOTES.md
Normal file
@@ -0,0 +1,8 @@
|
||||
# Notes
|
||||
|
||||
* Wildcard exports/imports wont normalise if `export default` is a non-object.
|
||||
|
||||
## 3.0.0 breaking changes
|
||||
|
||||
* Remove `allowImportExportEverywhere` option from acorn.
|
||||
* Remove this shorthand from playground.
|
||||
@@ -1,65 +0,0 @@
|
||||
# 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:
|
||||
|
||||
```sh
|
||||
$ make build
|
||||
```
|
||||
|
||||
This will output the files `dist/6to5.js` and `dist/6to5.min.js`.
|
||||
|
||||
## Test
|
||||
|
||||
To test 6to5 in your browser run:
|
||||
|
||||
```sh
|
||||
$ make test-browser
|
||||
```
|
||||
|
||||
And open `test/browser.html` in your browser if it doesn't open automatically.
|
||||
|
||||
## API
|
||||
|
||||
### to5.transform(code, [opts])
|
||||
|
||||
See [options](usage.md#options) for additional documentation.
|
||||
|
||||
```javascript
|
||||
to5.transform("class Test {}").code;
|
||||
```
|
||||
|
||||
### to5.run(code, [opts])
|
||||
|
||||
See [options](usage.md#options) for additional documentation.
|
||||
|
||||
```javascript
|
||||
to5.run("class Test {}");
|
||||
```
|
||||
@@ -1,4 +1,12 @@
|
||||
# Caveats
|
||||
---
|
||||
layout: docs
|
||||
title: Caveats
|
||||
description: Just some things to keep in mind when using 6to5.
|
||||
permalink: /docs/caveats/
|
||||
redirect_from: /caveats.html
|
||||
---
|
||||
|
||||
## Polyfills
|
||||
|
||||
In order for certain features to work they require certain polyfills. You can
|
||||
satisfy **all** 6to5 feature requirements by using the included
|
||||
@@ -13,9 +21,12 @@ You may alternatively selectively include what you need:
|
||||
| Async functions, Generators | [experimental](experimental.md), [regenerator runtime](https://github.com/facebook/regenerator/blob/master/runtime.js) |
|
||||
| Comprehensions | [experimental](experimental.md), `Array.from` |
|
||||
| For Of | `Symbol`, `prototype[Symbol.iterator]` |
|
||||
| Modules | `Object.assign`* |
|
||||
| Object spread/rest | [experimental](experimental.md), `Object.assign` |
|
||||
| Spread | `Array.from` |
|
||||
|
||||
*Only required for exporting a non-function `default` with additional `export`s.
|
||||
|
||||
## ES5
|
||||
|
||||
Since 6to5 assumes that your code will be ran in an ES5 environment it uses ES5
|
||||
@@ -32,24 +43,43 @@ 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 in IE <= 10 so static properties
|
||||
**will not** be inherited. A possible workaround is to use `super();`:
|
||||
**NOTE:** `__proto__` is not supported on IE <= 10 so static properties
|
||||
**will not** be inherited.
|
||||
|
||||
You can use the `protoToAssign` optional transformer that will transform all
|
||||
`__proto__` assignments to a method that will shallowly copy it over all
|
||||
properties.
|
||||
|
||||
```javascript
|
||||
class Foo {
|
||||
static foo() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class Bar extends Foo {
|
||||
static foo() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
require("6to5").transform("code", { optional: ["protoToAssign"] });
|
||||
```
|
||||
|
||||
## Getters/setters (8 and below)
|
||||
```sh
|
||||
$ 6to5 --optional protoToAssign script.js
|
||||
```
|
||||
|
||||
This means that the following **will** work:
|
||||
|
||||
```javascript
|
||||
var foo = { a: 1 };
|
||||
var bar = { b: 2 };
|
||||
bar.__proto__ = foo;
|
||||
bar.a; // 1
|
||||
bar.b; // 2
|
||||
```
|
||||
|
||||
however the following **will not**:
|
||||
|
||||
```javascript
|
||||
var foo = { a: 1 };
|
||||
var bar = { b: 2 };
|
||||
bar.__proto__ = foo;
|
||||
bar.a; // 1
|
||||
foo.a = 2;
|
||||
bar.a; // 1 - should be 2 but remember that nothing is bound and it's a straight copy
|
||||
```
|
||||
|
||||
### Getters/setters (8 and below)
|
||||
|
||||
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
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
# Differences
|
||||
---
|
||||
layout: docs
|
||||
title: Compare
|
||||
description: Differences between 6to5 and other ES6 transpilers.
|
||||
permalink: /docs/compare/
|
||||
redirect_from: /differences.html
|
||||
---
|
||||
|
||||
There are three main points that separate 6to5 from all other transpilers.
|
||||
## Differences
|
||||
|
||||
### Readable code
|
||||
|
||||
@@ -12,13 +18,13 @@ is concerned with making sure it works **and** is readable at the same time.
|
||||
|
||||
For example, given the following array comprehension:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
var seattlers = [for (c of customers) if (c.city == "Seattle") { name: c.name, age: c.age }];
|
||||
```
|
||||
|
||||
is generated to the following with 6to5:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
var seattlers = Array.from(customers).filter(function (c) {
|
||||
return c.city == "Seattle";
|
||||
}).map(function (c) {
|
||||
@@ -31,7 +37,7 @@ var seattlers = Array.from(customers).filter(function (c) {
|
||||
|
||||
The following is what Traceur generates:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
var seattlers = (function() {
|
||||
var c;
|
||||
var $__20 = 0,
|
||||
@@ -49,13 +55,12 @@ var seattlers = (function() {
|
||||
}());
|
||||
```
|
||||
|
||||
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.
|
||||
As you can tell, it's not very pretty. Instead of mapping directly to a runtime,
|
||||
like other transpilers, 6to5 maps directly to the equivalent ES5.
|
||||
|
||||
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).
|
||||
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.
|
||||
|
||||
@@ -79,43 +84,43 @@ that when you turn it off and use your code in a full ES6 environment
|
||||
|
||||
### Features
|
||||
|
||||
| | 6to5 | Traceur | es6-transpiler | esnext | es6now | jstransform |
|
||||
| ---------------------------- | ---- | ------- | -------------- | ------ | ------ | ----------- |
|
||||
| Source maps | ✓ | ✓ | ✓ | ✓ | | ✓ |
|
||||
| No compiler global pollution | ✓ | | ✓ | ✓ | | ✓ |
|
||||
| Optional runtime | ✓ | | ✓ | | | ✓ |
|
||||
| Browser compiler | ✓ | ✓ | | ✓ | | |
|
||||
| | 6to5 | Traceur | es6-transpiler | es6now | jstransform |
|
||||
| ---------------------------- | ---- | ------- | -------------- | ------ | ----------- |
|
||||
| Source maps | ✓ | ✓ | ✓ | | ✓ |
|
||||
| No compiler global pollution | ✓ | | ✓ | | ✓ |
|
||||
| Optional runtime | ✓ | | ✓ | | ✓ |
|
||||
| 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 | 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)
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
## 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**.
|
||||
283
doc/features.md
283
doc/features.md
@@ -1,283 +0,0 @@
|
||||
# Features
|
||||
|
||||
## Abstract references ([experimental](experimental.md)) ([spec](https://github.com/zenparsing/es-abstract-refs))
|
||||
|
||||
```javascript
|
||||
foo::bar;
|
||||
foo::bar = baz;
|
||||
delete foo::bar;
|
||||
```
|
||||
|
||||
## Array comprehensions ([experimental](experimental.md))
|
||||
|
||||
```javascript
|
||||
var results = [for (c of customers) if (c.city == "Seattle") { name: c.name, age: c.age }]
|
||||
```
|
||||
|
||||
## Arrow functions
|
||||
|
||||
```javascript
|
||||
// Expression bodies
|
||||
var odds = evens.map(v => v + 1);
|
||||
var nums = evens.map((v, i) => v + i);
|
||||
|
||||
// Statement bodies
|
||||
nums.forEach(v => {
|
||||
if (v % 5 === 0)
|
||||
fives.push(v);
|
||||
});
|
||||
|
||||
// Lexical this
|
||||
var bob = {
|
||||
_name: "Bob",
|
||||
_friends: [],
|
||||
printFriends() {
|
||||
this._friends.forEach(f => {
|
||||
console.log(this._name + " knows " + f);
|
||||
});
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## Async functions ([experimental](experimental.md)) ([spec](https://github.com/lukehoban/ecmascript-asyncawait))
|
||||
|
||||
```javascript
|
||||
async function chainAnimationsAsync(elem, animations) {
|
||||
for (var anim of animations) {
|
||||
await anim(elem);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Async generator functions ([experimental](experimental.md)) ([spec](https://github.com/jhusain/asyncgenerator))
|
||||
|
||||
```javascript
|
||||
|
||||
```
|
||||
|
||||
## Classes
|
||||
|
||||
```javascript
|
||||
class SkinnedMesh extends THREE.Mesh {
|
||||
constructor(geometry, materials) {
|
||||
super(geometry, materials);
|
||||
|
||||
this.idMatrix = SkinnedMesh.defaultMatrix();
|
||||
this.bones = [];
|
||||
this.boneMatrices = [];
|
||||
//...
|
||||
}
|
||||
|
||||
update(camera) {
|
||||
//...
|
||||
super.update();
|
||||
}
|
||||
|
||||
static defaultMatrix() {
|
||||
return new THREE.Matrix4();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Computed property names
|
||||
|
||||
```javascript
|
||||
var foo = "foo";
|
||||
var bar = "bar";
|
||||
var obj = {
|
||||
["foo" + bar]: "heh",
|
||||
["bar" + foo]: "noo",
|
||||
foo: "foo",
|
||||
bar: "bar"
|
||||
};
|
||||
```
|
||||
|
||||
## Constants
|
||||
|
||||
```javascript
|
||||
const MULTIPLIER = 5;
|
||||
console.log(2 * MULTIPLIER);
|
||||
|
||||
MULTIPLIER = 6; // error
|
||||
var MULTIPLIER; // error
|
||||
```
|
||||
|
||||
## Default parameters
|
||||
|
||||
```javascript
|
||||
function f(x, y = 12) {
|
||||
// y is 12 if not passed (or passed as undefined)
|
||||
return x + y;
|
||||
}
|
||||
f(3) == 15
|
||||
```
|
||||
|
||||
## Destructuring
|
||||
|
||||
```javascript
|
||||
// list matching
|
||||
var [a, , b] = [1,2,3];
|
||||
|
||||
// object matching
|
||||
var { op: a, lhs: { op: b }, rhs: c } = getASTNode();
|
||||
|
||||
// object matching shorthand
|
||||
// binds `op`, `lhs` and `rhs` in scope
|
||||
var { op, lhs, rhs } = getASTNode();
|
||||
|
||||
// Can be used in parameter position
|
||||
function g({ name: x }) {
|
||||
console.log(x);
|
||||
}
|
||||
g({ name: 5 });
|
||||
|
||||
// Fail-soft destructuring
|
||||
var [a] = [];
|
||||
a === undefined;
|
||||
```
|
||||
|
||||
## Exponentiation operator ([experimental](experimental.md)) ([spec](https://github.com/rwaldron/exponentiation-operator))
|
||||
|
||||
```javascript
|
||||
var a = 2;
|
||||
a **= 2;
|
||||
|
||||
var squared = 2 ** 2;
|
||||
```
|
||||
|
||||
## For-of
|
||||
|
||||
```javascript
|
||||
for (var i of [1, 2, 3]) {
|
||||
console.log(i * i);
|
||||
}
|
||||
```
|
||||
|
||||
## Generators
|
||||
|
||||
```javascript
|
||||
function* fibonacci() {
|
||||
var pre = 0, cur = 1;
|
||||
for (;;) {
|
||||
var temp = pre;
|
||||
pre = cur;
|
||||
cur += temp;
|
||||
yield cur;
|
||||
}
|
||||
}
|
||||
|
||||
for (var n of fibonacci()) {
|
||||
// truncate the sequence at 1000
|
||||
if (n > 1000) break;
|
||||
console.log(n);
|
||||
}
|
||||
```
|
||||
|
||||
## Generator comprehensions ([experimental](experimental.md))
|
||||
|
||||
```javascript
|
||||
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);
|
||||
```
|
||||
|
||||
## Let scoping
|
||||
|
||||
```javascript
|
||||
for (let i in arr) {
|
||||
let v = arr[i];
|
||||
}
|
||||
```
|
||||
|
||||
## Modules
|
||||
|
||||
```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 function test() {}
|
||||
|
||||
export default test;
|
||||
```
|
||||
|
||||
## Numeric literals
|
||||
|
||||
```javascript
|
||||
0b111110111 === 503; // true
|
||||
0o767 === 503; // true
|
||||
```
|
||||
|
||||
## Object spread/rest ([experimental](experimental.md)) ([spec](https://github.com/sebmarkbage/ecmascript-rest-spread))
|
||||
|
||||
```javascript
|
||||
var n = { x, y, ...z };
|
||||
var { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
|
||||
```
|
||||
|
||||
## Property method assignment
|
||||
|
||||
```javascript
|
||||
var obj = {
|
||||
foo() {
|
||||
return "foobar";
|
||||
},
|
||||
|
||||
get bar() {
|
||||
return this._bar;
|
||||
},
|
||||
|
||||
set bar(val) {
|
||||
this._bar = val;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## Property name shorthand
|
||||
|
||||
```javascript
|
||||
function f(x, y) {
|
||||
return { x, y };
|
||||
}
|
||||
```
|
||||
|
||||
## Rest parameters
|
||||
|
||||
```javascript
|
||||
function f(x, ...y) {
|
||||
// y is an Array
|
||||
return x * y.length;
|
||||
}
|
||||
f(3, "hello", true) == 6
|
||||
```
|
||||
|
||||
## Spread
|
||||
|
||||
```javascript
|
||||
function f(x, y, z) {
|
||||
return x + y + z;
|
||||
}
|
||||
// Pass each elem of array as argument
|
||||
f(...[1,2,3]) == 6
|
||||
```
|
||||
|
||||
## Template literals
|
||||
|
||||
```javascript
|
||||
var x = 5;
|
||||
var y = 10;
|
||||
console.log(`${x} + ${y} = ${x + y}`); // "5 + 10 = 15"
|
||||
```
|
||||
## Unicode regex
|
||||
|
||||
```javascript
|
||||
var string = 'foo💩bar';
|
||||
var match = string.match(/foo(.)bar/u);
|
||||
console.log(match[1]);
|
||||
```
|
||||
62
doc/index.md
62
doc/index.md
@@ -1,62 +0,0 @@
|
||||
**6to5** turns ES6+ code into vanilla ES5, so you can use next generation 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).
|
||||
|
||||
## Installation
|
||||
|
||||
It's as easy as:
|
||||
|
||||
$ npm install -g 6to5
|
||||
|
||||
## Usage
|
||||
|
||||
Once you've installed 6to5, there are multiple paths you can take depending on
|
||||
how you want to use it.
|
||||
|
||||
6to5 will simply compile your ES6+ script to ES5 if you pass it as an argument
|
||||
to the command-line tool `6to5`:
|
||||
|
||||
```sh
|
||||
$ 6to5 script.js
|
||||
```
|
||||
|
||||
If you have a file written using ES6+ and you just want to run it, `6to5-node`
|
||||
has you covered:
|
||||
|
||||
```sh
|
||||
$ 6to5-node script.js
|
||||
```
|
||||
|
||||
And it doesn't end here! To see all the ways you can use 6to5, check out the
|
||||
[Usage](http://6to5.github.io/usage.html) page.
|
||||
|
||||
## [Features](features.md)
|
||||
|
||||
- [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)
|
||||
- [Constants](features.md#constants)
|
||||
- [Default parameters](features.md#default-parameters)
|
||||
- [Destructuring](features.md#destructuring)
|
||||
- [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](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](experimental.md))
|
||||
- [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)
|
||||
@@ -1,140 +0,0 @@
|
||||
# Playground
|
||||
|
||||
Playground is a proving ground for **possible** ES7 proposals.
|
||||
|
||||
**NOTE: These features are in no way endorsed by Ecma International and are not a part of ES6. They might become a part of ECMAScript in the future.**
|
||||
|
||||
## Usage
|
||||
|
||||
$ 6to5 --playground
|
||||
|
||||
```javascript
|
||||
to5.transform("code", { playground: true });
|
||||
```
|
||||
|
||||
**NOTE:** Enabling `playground` also enables [experimental support](experimental.md).
|
||||
|
||||
## Features
|
||||
|
||||
* [Memoization operator](#memoization-operator)
|
||||
* [Method binding](#method-binding)
|
||||
* [Method binding function shorthand](#method-binding-function-shorthand)
|
||||
* [Object getter memoization](#object-getter-memoization)
|
||||
* [This shorthand](#this-shorthand)
|
||||
|
||||
### Memoization assignment operator
|
||||
|
||||
The memoization assignment operator allows you to lazily set an object property.
|
||||
It checks whether there's a property defined on the object and if there isn't then
|
||||
the right hand value is set.
|
||||
|
||||
This means that `obj.x` in the following `var x = { x: undefined }; obj.x ?= 2;`
|
||||
will still be `undefined` because it's already been defined on the object.
|
||||
|
||||
```javascript
|
||||
var obj = {};
|
||||
obj.x ?= 2;
|
||||
obj.x; // 2
|
||||
|
||||
obj = { x: 1 };
|
||||
obj.x ?= 2;
|
||||
obj.x; // 1
|
||||
|
||||
obj = { x: undefined }
|
||||
obj.x ?= 2;
|
||||
obj.x; // undefined
|
||||
```
|
||||
|
||||
```javascript
|
||||
var obj = {};
|
||||
obj.x ?= 2;
|
||||
```
|
||||
|
||||
equivalent to
|
||||
|
||||
```javascript
|
||||
var obj = {};
|
||||
if (!Object.prototype.hasOwnProperty.call(obj, "x")) obj.x = 2;
|
||||
```
|
||||
|
||||
### Method binding
|
||||
|
||||
```javascript
|
||||
var fn = obj#method;
|
||||
var fn = obj#method("foob");
|
||||
```
|
||||
|
||||
equivalent to
|
||||
|
||||
```javascript
|
||||
var fn = obj.method.bind(obj);
|
||||
var fn = obj.method.bind(obj, "foob");
|
||||
```
|
||||
|
||||
### Method binding function shorthand
|
||||
|
||||
```javascript
|
||||
["foo", "bar"].map(#toUpperCase); // ["FOO", "BAR"]
|
||||
[1.1234, 23.53245, 3].map(#toFixed(2)); // ["1.12", "23.53", "3.00"]
|
||||
```
|
||||
|
||||
equivalent to
|
||||
|
||||
```javascript
|
||||
["foo", "bar"].map(function (val) { return val.toUpperCase(); });
|
||||
[1.1234, 23.53245, 3].map(function (val) { return val.toFixed(2); });
|
||||
```
|
||||
|
||||
### Object getter memoization
|
||||
|
||||
```javascript
|
||||
var foo = {
|
||||
memo bar() {
|
||||
return complex();
|
||||
}
|
||||
};
|
||||
|
||||
class Foo {
|
||||
memo bar() {
|
||||
return complex();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
equivalent to
|
||||
|
||||
```javascript
|
||||
var foo = {
|
||||
get bar() {
|
||||
return Object.defineProperty(this, "bar", {
|
||||
value: complex(),
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true
|
||||
}).bar;
|
||||
}
|
||||
};
|
||||
|
||||
class Foo {
|
||||
get bar() {
|
||||
return Object.defineProperty(this, "bar", {
|
||||
value: complex(),
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true
|
||||
}).bar;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### This shorthand
|
||||
|
||||
```javascript
|
||||
@foo
|
||||
```
|
||||
|
||||
equivalent to
|
||||
|
||||
```javascirpt
|
||||
this.foo
|
||||
```
|
||||
@@ -1,33 +0,0 @@
|
||||
# Plugins
|
||||
|
||||
## Build systems
|
||||
|
||||
- [Broccoli](https://github.com/6to5/broccoli-6to5-transpiler)
|
||||
- [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)
|
||||
- [Gulp](https://github.com/6to5/gulp-6to5)
|
||||
- [Grunt](https://github.com/6to5/grunt-6to5)
|
||||
- [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)
|
||||
|
||||
## 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)
|
||||
@@ -1,34 +0,0 @@
|
||||
# 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).
|
||||
|
||||
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).
|
||||
|
||||
## Usage
|
||||
|
||||
### Node/Browserify
|
||||
|
||||
You need to include the polyfill require at the top the **entry point** to your
|
||||
application.
|
||||
|
||||
```javascript
|
||||
require("6to5/polyfill");
|
||||
```
|
||||
|
||||
Fortunately, this is automatically loaded when using:
|
||||
|
||||
```javascript
|
||||
require("6to5/register");
|
||||
```
|
||||
|
||||
### Browser
|
||||
|
||||
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 `<script>`
|
||||
before it.
|
||||
|
||||
**NOTE:** Do not `require` this via browserify etc, use `6to5/polyfill`.
|
||||
17
doc/react.md
17
doc/react.md
@@ -1,17 +0,0 @@
|
||||
# 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"] });
|
||||
```
|
||||
|
||||
```sh
|
||||
$ 6to5 --blacklist react
|
||||
```
|
||||
708
doc/setup.md
Normal file
708
doc/setup.md
Normal file
@@ -0,0 +1,708 @@
|
||||
---
|
||||
layout: docs
|
||||
title: Setup
|
||||
description: Guides on how to setup 6to5 in whatever environment you might be working in.
|
||||
permalink: /docs/setup/
|
||||
redirect_from: /plugins.html
|
||||
---
|
||||
|
||||
<blockquote class="to5-callout to5-callout-info">
|
||||
<h4>Find your guide</h4>
|
||||
<p>
|
||||
It doesn't matter if you're using Node.js or Rails, Gulp or Grunt, there's likely a guide on
|
||||
this page to help guide you. Go ahead and <span class="label label-info">⌘ + F</span>
|
||||
whatever you're looking for. If it doesn't happen to be on this page you might want to stop by
|
||||
our <a href="https://gitter.im/6to5/6to5">support chat</a>.
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
## Node.js
|
||||
|
||||
### CLI
|
||||
|
||||
**Install**
|
||||
|
||||
```sh
|
||||
$ npm install --global 6to5
|
||||
```
|
||||
|
||||
**Usage**
|
||||
|
||||
```sh
|
||||
$ 6to5 script.js
|
||||
```
|
||||
|
||||
<blockquote class="to5-callout to5-callout-info">
|
||||
<p>
|
||||
For full documentation on the 6to5 CLI see the
|
||||
<a href="/docs/usage/cli/">usage docs</a>.
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
### Require Hook
|
||||
|
||||
**Install**
|
||||
|
||||
```sh
|
||||
$ npm install 6to5
|
||||
```
|
||||
|
||||
**Usage**
|
||||
|
||||
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');
|
||||
```
|
||||
|
||||
<blockquote class="to5-callout to5-callout-info">
|
||||
<p>
|
||||
For full documentation on the 6to5 require hook see the
|
||||
<a href="/docs/usage/require/">usage docs</a>.
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
## Rails
|
||||
|
||||
### Sprockets
|
||||
|
||||
<blockquote class="to5-callout to5-callout-info">
|
||||
<p>
|
||||
See <strong>sprockets-es6</strong>'s
|
||||
<a href="https://github.com/josh/sprockets-es6">repo</a> for more info. If
|
||||
you find any bugs please
|
||||
<a href="https://github.com/josh/sprockets-es6/issues">report them</a>.
|
||||
</p>
|
||||
<p>
|
||||
<em>Issues with the output should be reported on the 6to5
|
||||
<a href="https://github.com/6to5/6to5/issues">issue tracker</a></em>.
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
**Install**
|
||||
|
||||
```sh
|
||||
$ gem install sprockets-es6
|
||||
```
|
||||
|
||||
**Usage**
|
||||
|
||||
```rb
|
||||
# Gemfile
|
||||
gem 'sprockets'
|
||||
gem 'sprockets-es6'
|
||||
```
|
||||
|
||||
```rb
|
||||
require 'sprockets/es6'
|
||||
```
|
||||
|
||||
## Build Systems
|
||||
|
||||
### Brocolli
|
||||
|
||||
<blockquote class="to5-callout to5-callout-info">
|
||||
<p>
|
||||
See <strong>broccoli-6to5-transpiler</strong>'s
|
||||
<a href="https://github.com/6to5/broccoli-6to5-transpiler">repo</a> for more
|
||||
info. If you find any bugs please
|
||||
<a href="https://github.com/6to5/broccoli-6to5-transpiler/issues">report
|
||||
them</a>.
|
||||
</p>
|
||||
<p>
|
||||
<em>Issues with the output should be reported on the 6to5
|
||||
<a href="https://github.com/6to5/6to5/issues">issue tracker</a></em>.
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
**Install**
|
||||
|
||||
```sh
|
||||
$ npm install --save-dev broccoli-6to5-transpiler
|
||||
```
|
||||
|
||||
**Usage**
|
||||
|
||||
```js
|
||||
var to5Transpiler = require('broccoli-6to5-transpiler');
|
||||
var scriptTree = to5Transpiler(inputTree, options);
|
||||
```
|
||||
|
||||
<blockquote class="to5-callout to5-callout-warning">
|
||||
<h4>Source maps</h4>
|
||||
<p>
|
||||
Currently this plugin only support inline source maps. If you need separate
|
||||
source map feature, we welcome you to submit a pull request.
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
### Browserify
|
||||
|
||||
<blockquote class="to5-callout to5-callout-info">
|
||||
<p>
|
||||
See <strong>6to5ify</strong>'s
|
||||
<a href="https://github.com/6to5/6to5ify">repo</a> for more info. If you
|
||||
find any bugs please
|
||||
<a href="https://github.com/6to5/6to5ify/issues">report them</a>.
|
||||
</p>
|
||||
<p>
|
||||
<em>Issues with the output should be reported on the 6to5
|
||||
<a href="https://github.com/6to5/6to5/issues">issue tracker</a></em>.
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
**Install**
|
||||
|
||||
```sh
|
||||
$ npm install --save-dev 6to5ify
|
||||
```
|
||||
|
||||
**Usage via CLI**
|
||||
|
||||
```sh
|
||||
$ browserify script.js -t 6to5ify --outfile bundle.js
|
||||
```
|
||||
|
||||
**Usage via Node.js**
|
||||
|
||||
```js
|
||||
browserify({ debug: true })
|
||||
.transform(to5ify);
|
||||
```
|
||||
|
||||
Or a more complete example:
|
||||
|
||||
```js
|
||||
var fs = require('fs');
|
||||
var browserify = require('browserify');
|
||||
var to5ify = require('6to5ify');
|
||||
|
||||
browserify({ debug: true })
|
||||
.transform(to5ify)
|
||||
.require('./script.js', { entry: true })
|
||||
.bundle()
|
||||
.on('error', function (err) { console.log('Error: ' + err.message); })
|
||||
.pipe(fs.createWriteStream("bundle.js"));
|
||||
```
|
||||
**Passing Options**
|
||||
|
||||
```sh
|
||||
$ browserify -d -e script.js -t [ 6to5ify --blacklist generators ]
|
||||
```
|
||||
|
||||
```js
|
||||
browserify().transform(to5ify.configure({
|
||||
blacklist: ['generators']
|
||||
}))
|
||||
```
|
||||
|
||||
<blockquote class="to5-callout to5-callout-info">
|
||||
<h4>More info</h4>
|
||||
<p>
|
||||
For more information see the
|
||||
<a href="https://github.com/6to5/6to5ify">6to5ify README</a>
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
### Brunch
|
||||
|
||||
<blockquote class="to5-callout to5-callout-info">
|
||||
<p>
|
||||
See <strong>6to5-brunch</strong>'s
|
||||
<a href="https://github.com/6to5/6to5-brunch">repo</a> for more info. If you
|
||||
find any bugs please
|
||||
<a href="https://github.com/6to5/6to5-brunch/issues">report them</a>.
|
||||
</p>
|
||||
<p>
|
||||
<em>Issues with the output should be reported on the 6to5
|
||||
<a href="https://github.com/6to5/6to5/issues">issue tracker</a></em>.
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
**Install**
|
||||
|
||||
```sh
|
||||
$ npm install --save-dev 6to5-brunch
|
||||
```
|
||||
|
||||
**Configuring**
|
||||
|
||||
Set 6to5 options in your brunch config (such as `brunch-config.coffee`) except
|
||||
for `filename` and `sourceMap` which are handled internally.
|
||||
|
||||
```coffee
|
||||
plugins:
|
||||
ES6to5:
|
||||
whitelist: ['arrowFunctions']
|
||||
format:
|
||||
semicolons: false
|
||||
```
|
||||
|
||||
### Duo
|
||||
|
||||
<blockquote class="to5-callout to5-callout-info">
|
||||
<p>
|
||||
See <strong>duo-6to5</strong>'s
|
||||
<a href="https://github.com/6to5/duo-6to5">repo</a> for more info. If you
|
||||
find any bugs please
|
||||
<a href="https://github.com/6to5/duo-6to5/issues">report them</a>.
|
||||
</p>
|
||||
<p>
|
||||
<em>Issues with the output should be reported on the 6to5
|
||||
<a href="https://github.com/6to5/6to5/issues">issue tracker</a></em>.
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
**Install**
|
||||
|
||||
```sh
|
||||
$ npm install --save-dev duo-6to5
|
||||
```
|
||||
|
||||
**Usage via CLI**
|
||||
|
||||
```sh
|
||||
$ duo --use duo-6to5
|
||||
```
|
||||
|
||||
**Usage via Node.js**
|
||||
|
||||
```js
|
||||
Duo(root)
|
||||
.entry(entry)
|
||||
.use(to5)
|
||||
.run(fn);
|
||||
```
|
||||
|
||||
### Gobble
|
||||
|
||||
<blockquote class="to5-callout to5-callout-info">
|
||||
<p>
|
||||
See <strong>gobble-6to5</strong>'s
|
||||
<a href="https://github.com/6to5/gobble-6to5">repo</a> for more info. If you
|
||||
find any bugs please
|
||||
<a href="https://github.com/6to5/gobble-6to5/issues">report them</a>.
|
||||
</p>
|
||||
<p>
|
||||
<em>Issues with the output should be reported on the 6to5
|
||||
<a href="https://github.com/6to5/6to5/issues">issue tracker</a></em>.
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
**Install**
|
||||
|
||||
```sh
|
||||
$ npm install --save-dev gobble-6to5
|
||||
```
|
||||
|
||||
**Usage**
|
||||
|
||||
The `options` argument, if specified, is passed to 6to5.
|
||||
|
||||
```
|
||||
var gobble = require('gobble');
|
||||
module.exports = gobble('src').transform('6to5', options);
|
||||
```
|
||||
|
||||
**Source maps**
|
||||
|
||||
Sourcemaps are created by default (all the relevant information is filled in by
|
||||
Gobble, you don't need to specify `sourceMapName` options etc). If you don't
|
||||
want that, pass `sourceMap: false`.
|
||||
|
||||
### Grunt
|
||||
|
||||
<blockquote class="to5-callout to5-callout-info">
|
||||
<p>
|
||||
See <strong>grunt-6to5</strong>'s
|
||||
<a href="https://github.com/6to5/grunt-6to5">repo</a> for more info. If you
|
||||
find any bugs please
|
||||
<a href="https://github.com/6to5/grunt-6to5/issues">report them</a>.
|
||||
</p>
|
||||
<p>
|
||||
<em>Issues with the output should be reported on the 6to5
|
||||
<a href="https://github.com/6to5/6to5/issues">issue tracker</a></em>.
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
**Install**
|
||||
|
||||
```sh
|
||||
$ npm install --save-dev grunt-6to5
|
||||
```
|
||||
|
||||
**Usage**
|
||||
|
||||
```js
|
||||
require('load-grunt-tasks')(grunt); // npm install --save-dev load-grunt-tasks
|
||||
|
||||
grunt.initConfig({
|
||||
'6to5': {
|
||||
options: {
|
||||
sourceMap: true
|
||||
},
|
||||
dist: {
|
||||
files: {
|
||||
'dist/app.js': 'src/app.js'
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
grunt.registerTask('default', ['6to5']);
|
||||
```
|
||||
|
||||
### Gulp
|
||||
|
||||
<blockquote class="to5-callout to5-callout-info">
|
||||
<p>
|
||||
See <strong>gulp-6to5</strong>'s
|
||||
<a href="https://github.com/6to5/gulp-6to5">repo</a> for more info. If you
|
||||
find any bugs please
|
||||
<a href="https://github.com/6to5/gulp-6to5/issues">report them</a>.
|
||||
</p>
|
||||
<p>
|
||||
<em>Issues with the output should be reported on the 6to5
|
||||
<a href="https://github.com/6to5/6to5/issues">issue tracker</a></em>.
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
**Install**
|
||||
|
||||
```sh
|
||||
$ npm install --save-dev gulp-6to5
|
||||
```
|
||||
|
||||
**Usage**
|
||||
|
||||
```js
|
||||
var gulp = require('gulp');
|
||||
var to5 = require('gulp-6to5');
|
||||
|
||||
gulp.task('default', function () {
|
||||
return gulp.src('src/app.js')
|
||||
.pipe(to5())
|
||||
.pipe(gulp.dest('dist'));
|
||||
});
|
||||
```
|
||||
|
||||
**Source maps**
|
||||
|
||||
Use [gulp-sourcemaps](https://github.com/floridoo/gulp-sourcemaps) like this:
|
||||
|
||||
```js
|
||||
var gulp = require('gulp');
|
||||
var sourcemaps = require('gulp-sourcemaps');
|
||||
var to5 = require('gulp-6to5');
|
||||
var concat = require('gulp-concat');
|
||||
|
||||
gulp.task('default', function () {
|
||||
return gulp.src('src/**/*.js')
|
||||
.pipe(sourcemaps.init())
|
||||
.pipe(to5())
|
||||
.pipe(concat('all.js'))
|
||||
.pipe(sourcemaps.write('.'))
|
||||
.pipe(gulp.dest('dist'));
|
||||
});
|
||||
```
|
||||
|
||||
### Webpack
|
||||
|
||||
<blockquote class="to5-callout to5-callout-info">
|
||||
<p>
|
||||
See <strong>6to5-loader</strong>'s
|
||||
<a href="https://github.com/6to5/6to5-loader">repo</a> for more info. If you
|
||||
find any bugs please
|
||||
<a href="https://github.com/6to5/6to5-loader/issues">report them</a>.
|
||||
</p>
|
||||
<p>
|
||||
<em>Issues with the output should be reported on the 6to5
|
||||
<a href="https://github.com/6to5/6to5/issues">issue tracker</a></em>.
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
**Install**
|
||||
|
||||
```sh
|
||||
$ npm install --save-dev 6to5-loader
|
||||
```
|
||||
|
||||
**Usage via loader**
|
||||
|
||||
```js
|
||||
import Animal from '6to5!./Animal.js';
|
||||
|
||||
class Person extends Animal {
|
||||
constructor(arg='default') {
|
||||
this.eat = 'Happy Meal';
|
||||
}
|
||||
}
|
||||
|
||||
export default Person;
|
||||
```
|
||||
```js
|
||||
var Person = require('6to5!./Person.js').default;
|
||||
new Person();
|
||||
```
|
||||
|
||||
**Usage via config**
|
||||
|
||||
```js
|
||||
module: {
|
||||
loaders: [
|
||||
{ test: /\.js$/, exclude: /node_modules/, loader: '6to5-loader'}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
and then import normally:
|
||||
|
||||
```js
|
||||
import Person from './Person.js';
|
||||
```
|
||||
|
||||
<blockquote class="to5-callout to5-callout-warning">
|
||||
<h4>Troubleshooting</h4>
|
||||
<p>
|
||||
For additional information on how to troubleshoot **6to5-loader** please
|
||||
see the
|
||||
<a href="https://github.com/6to5/6to5-loader#troubleshooting">README</a>.
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
## Misc
|
||||
|
||||
### Connect
|
||||
|
||||
<blockquote class="to5-callout to5-callout-info">
|
||||
<p>
|
||||
See <strong>6to5-connect</strong>'s
|
||||
<a href="https://github.com/6to5/6to5-connect">repo</a> for more info. If
|
||||
you find any bugs please
|
||||
<a href="https://github.com/6to5/6to5-connect/issues">report them</a>.
|
||||
</p>
|
||||
<p>
|
||||
<em>Issues with the output should be reported on the 6to5
|
||||
<a href="https://github.com/6to5/6to5/issues">issue tracker</a></em>.
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
**Install**
|
||||
|
||||
```js
|
||||
$ npm install 6to5-connect
|
||||
```
|
||||
|
||||
**Usage**
|
||||
|
||||
```js
|
||||
var to5Middleware = require('6to5-connect');
|
||||
|
||||
app.use(to5Middleware({
|
||||
options: {
|
||||
// options to use when transforming files
|
||||
},
|
||||
src: 'assets',
|
||||
dest: 'cache'
|
||||
}));
|
||||
|
||||
app.use(connect.static('cache'));
|
||||
```
|
||||
|
||||
### Jade
|
||||
|
||||
<blockquote class="to5-callout to5-callout-info">
|
||||
<p>
|
||||
See <strong>jade-6to5</strong>'s
|
||||
<a href="https://github.com/6to5/jade-6to5">repo</a> for more info. If you
|
||||
find any bugs please
|
||||
<a href="https://github.com/6to5/jade-6to5/issues">report them</a>.
|
||||
</p>
|
||||
<p>
|
||||
<em>Issues with the output should be reported on the 6to5
|
||||
<a href="https://github.com/6to5/6to5/issues">issue tracker</a></em>.
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
**Install**
|
||||
|
||||
```js
|
||||
$ npm install jade-6to5
|
||||
```
|
||||
|
||||
**Usage**
|
||||
|
||||
```js
|
||||
var jade = require('jade');
|
||||
var to5 = require('jade-6to5');
|
||||
|
||||
jade.filters.to5 = to5({});
|
||||
```
|
||||
|
||||
OR
|
||||
|
||||
```js
|
||||
var jade = require('jade');
|
||||
var to5 = require('jade-6to5');
|
||||
|
||||
jade = to5({}, jade);
|
||||
```
|
||||
|
||||
Now you can use ES6 in your jade templates as following.
|
||||
|
||||
```jade
|
||||
script
|
||||
:to5
|
||||
console.log('Hello World !!!');
|
||||
class Person {
|
||||
constructor(name) {
|
||||
this.name = name;
|
||||
}
|
||||
sayName(){
|
||||
console.log(`Hello, my name is ${this.name}`);
|
||||
}
|
||||
}
|
||||
var person = new Person('Apoxx');
|
||||
person.sayName();
|
||||
```
|
||||
|
||||
### Jest
|
||||
|
||||
<blockquote class="to5-callout to5-callout-info">
|
||||
<p>
|
||||
See <strong>6to5-jest</strong>'s
|
||||
<a href="https://github.com/6to5/6to5-jest">repo</a> for more info. If you
|
||||
find any bugs please
|
||||
<a href="https://github.com/6to5/6to5-jest/issues">report them</a>.
|
||||
</p>
|
||||
<p>
|
||||
<em>Issues with the output should be reported on the 6to5
|
||||
<a href="https://github.com/6to5/6to5/issues">issue tracker</a></em>.
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
**Install**
|
||||
|
||||
```sh
|
||||
$ npm install --save-dev 6to5-jest
|
||||
```
|
||||
|
||||
**Usage**
|
||||
|
||||
In your `package.json` file please make the following changes:
|
||||
|
||||
```
|
||||
{
|
||||
"dependencies": {
|
||||
"6to5-jest": "*",
|
||||
"jest": "*"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "jest"
|
||||
},
|
||||
"jest": {
|
||||
"scriptPreprocessor": "<rootDir>/node_modules/6to5-jest",
|
||||
"testFileExtensions": ["es6", "js"],
|
||||
"moduleFileExtensions": ["js", "json", "es6"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Karma
|
||||
|
||||
<blockquote class="to5-callout to5-callout-info">
|
||||
<p>
|
||||
See <strong>karma-6to5-preprocessor</strong>'s
|
||||
<a href="https://github.com/6to5/karma-6to5-preprocessor">repo</a> for more
|
||||
info. If you find any bugs please
|
||||
<a href="https://github.com/6to5/karma-6to5-preprocessor/issues">report them</a>.
|
||||
</p>
|
||||
<p>
|
||||
<em>Issues with the output should be reported on the 6to5
|
||||
<a href="https://github.com/6to5/6to5/issues">issue tracker</a></em>.
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
**Install**
|
||||
|
||||
```js
|
||||
npm install --save-dev karma-6to5-preprocessor
|
||||
```
|
||||
|
||||
**Usage**
|
||||
|
||||
See 6to5 options for more details.
|
||||
|
||||
Given `options` properties are passed to 6to5 with no change except:
|
||||
|
||||
- `filename`
|
||||
- `sourceMapName`
|
||||
- `sourceFileName`
|
||||
|
||||
Because they should differ from file to file, corresponding configuration
|
||||
functions are available.
|
||||
|
||||
For example, inline sourcemap configuration would look like the following.
|
||||
|
||||
```js
|
||||
module.exports = function(config) {
|
||||
config.set({
|
||||
files: [
|
||||
'src/**/*.js',
|
||||
'test/**/*.js'
|
||||
],
|
||||
preprocessors: {
|
||||
'src/**/*.js': ['6to5'],
|
||||
'test/**/*.js': ['6to5']
|
||||
},
|
||||
'6to5Preprocessor': {
|
||||
options: {
|
||||
sourceMap: 'inline'
|
||||
},
|
||||
filename: function(file) {
|
||||
return file.originalPath.replace(/\.js$/, '.es5.js');
|
||||
},
|
||||
sourceFileName: function(file) {
|
||||
return file.originalPath;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
```
|
||||
|
||||
### Mocha
|
||||
|
||||
<blockquote class="to5-callout to5-callout-info">
|
||||
<p>
|
||||
See <strong>6to5-mocha</strong>'s
|
||||
<a href="https://github.com/6to5/6to5-mocha">repo</a> for more info. If you
|
||||
find any bugs please
|
||||
<a href="https://github.com/6to5/6to5-mocha/issues">report them</a>.
|
||||
</p>
|
||||
<p>
|
||||
<em>Issues with the output should be reported on the 6to5
|
||||
<a href="https://github.com/6to5/6to5/issues">issue tracker</a></em>.
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
**Install**
|
||||
|
||||
```sh
|
||||
$ npm install --save-dev 6to5
|
||||
```
|
||||
|
||||
**Usage**
|
||||
|
||||
```js
|
||||
{
|
||||
"scripts": {
|
||||
"test": "mocha --require 6to5/register"
|
||||
},
|
||||
"devDependencies": {
|
||||
"6to5": "*",
|
||||
"mocha": "*"
|
||||
}
|
||||
}
|
||||
```
|
||||
771
doc/tour.md
Normal file
771
doc/tour.md
Normal file
@@ -0,0 +1,771 @@
|
||||
---
|
||||
layout: docs
|
||||
title: Tour
|
||||
description: A detailed overview of ECMAScript 6 features.
|
||||
permalink: /docs/tour/
|
||||
redirect_from: /features.html
|
||||
---
|
||||
|
||||
<blockquote class="to5-callout to5-callout-info">
|
||||
<h4>es6features</h4>
|
||||
<p>
|
||||
This document is taken from Luke Hoban's excellent
|
||||
<a href="http://git.io/es6features">es6features</a> repo. Go give it a star
|
||||
on GitHub!
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
<blockquote class="to5-callout to5-callout-info">
|
||||
<h4>REPL</h4>
|
||||
<p>
|
||||
Be sure to try these features out in the online
|
||||
<a href="repl.html">REPL</a>.
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
## Introduction
|
||||
|
||||
> ECMAScript 6 is the upcoming version of the ECMAScript standard. This
|
||||
standard is targeting ratification in June 2015. ES6 is a significant update to
|
||||
the language, and the first update to the language since ES5 was standardized in
|
||||
2009. Implementation of these features in major JavaScript engines is
|
||||
[underway now](http://kangax.github.io/es5-compat-table/es6/).
|
||||
|
||||
See the [draft ES6 standard](https://people.mozilla.org/~jorendorff/es6-draft.html)
|
||||
for full specification of the ECMAScript 6 language.
|
||||
|
||||
## ECMAScript 6 Features
|
||||
|
||||
### Arrows
|
||||
|
||||
Arrows are a function shorthand using the `=>` syntax. They are syntactically
|
||||
similar to the related feature in C#, Java 8 and CoffeeScript. They support
|
||||
both expression and statement bodies. Unlike functions, arrows share the same
|
||||
lexical `this` as their surrounding code.
|
||||
|
||||
```js
|
||||
// Expression bodies
|
||||
var odds = evens.map(v => v + 1);
|
||||
var nums = evens.map((v, i) => v + i);
|
||||
|
||||
// Statement bodies
|
||||
nums.forEach(v => {
|
||||
if (v % 5 === 0)
|
||||
fives.push(v);
|
||||
});
|
||||
|
||||
// Lexical this
|
||||
var bob = {
|
||||
_name: "Bob",
|
||||
_friends: [],
|
||||
printFriends() {
|
||||
this._friends.forEach(f =>
|
||||
console.log(this._name + " knows " + f));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Classes
|
||||
|
||||
ES6 classes are a simple sugar over the prototype-based OO pattern. Having a
|
||||
single convenient declarative form makes class patterns easier to use, and
|
||||
encourages interoperability. Classes support prototype-based inheritance, super
|
||||
calls, instance and static methods and constructors.
|
||||
|
||||
```js
|
||||
class SkinnedMesh extends THREE.Mesh {
|
||||
constructor(geometry, materials) {
|
||||
super(geometry, materials);
|
||||
|
||||
this.idMatrix = SkinnedMesh.defaultMatrix();
|
||||
this.bones = [];
|
||||
this.boneMatrices = [];
|
||||
//...
|
||||
}
|
||||
update(camera) {
|
||||
//...
|
||||
super.update();
|
||||
}
|
||||
static defaultMatrix() {
|
||||
return new THREE.Matrix4();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Enhanced Object Literals
|
||||
|
||||
Object literals are extended to support setting the prototype at construction,
|
||||
shorthand for `foo: foo` assignments, defining methods and making super calls.
|
||||
Together, these also bring object literals and class declarations closer
|
||||
together, and let object-based design benefit from some of the same
|
||||
conveniences.
|
||||
|
||||
```js
|
||||
var obj = {
|
||||
// __proto__
|
||||
__proto__: theProtoObj,
|
||||
// Shorthand for ‘handler: handler’
|
||||
handler,
|
||||
// Methods
|
||||
toString() {
|
||||
// Super calls
|
||||
return "d " + super.toString();
|
||||
},
|
||||
// Computed (dynamic) property names
|
||||
[ 'prop_' + (() => 42)() ]: 42
|
||||
};
|
||||
```
|
||||
|
||||
<blockquote class="to5-callout to5-callout-warning">
|
||||
<p>
|
||||
<code>__proto__</code> support comes from the JavaScript engine running
|
||||
your program. Although most support the now standard property,
|
||||
<a href="http://kangax.github.io/compat-table/es6/#__proto___in_object_literals">some do not</a>.
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
### Template Strings
|
||||
|
||||
Template strings provide syntactic sugar for constructing strings. This is
|
||||
similar to string interpolation features in Perl, Python and more. Optionally, a
|
||||
tag can be added to allow the string construction to be customized, avoiding
|
||||
injection attacks or constructing higher level data structures from string
|
||||
contents.
|
||||
|
||||
```js
|
||||
// Basic literal string creation
|
||||
`In JavaScript '\n' is a line-feed.`
|
||||
|
||||
// Multiline strings
|
||||
`In JavaScript this is
|
||||
not legal.`
|
||||
|
||||
// Construct a DOM query
|
||||
var name = "Bob", time = "today";
|
||||
`Hello ${name}, how are you ${time}?`
|
||||
|
||||
// Construct an HTTP request prefix is used to interpret the replacements and construction
|
||||
GET`http://foo.org/bar?a=${a}&b=${b}
|
||||
Content-Type: application/json
|
||||
X-Credentials: ${credentials}
|
||||
{ "foo": ${foo},
|
||||
"bar": ${bar}}`(myOnReadyStateChangeHandler);
|
||||
```
|
||||
|
||||
### Destructuring
|
||||
|
||||
Destructuring allows binding using pattern matching, with support for matching
|
||||
arrays and objects. Destructuring is fail-soft, similar to standard object
|
||||
lookup `foo["bar"]`, producing `undefined` values when not found.
|
||||
|
||||
```js
|
||||
// list matching
|
||||
var [a, , b] = [1,2,3];
|
||||
|
||||
// object matching
|
||||
var { op: a, lhs: { op: b }, rhs: c }
|
||||
= getASTNode()
|
||||
|
||||
// object matching shorthand
|
||||
// binds `op`, `lhs` and `rhs` in scope
|
||||
var {op, lhs, rhs} = getASTNode()
|
||||
|
||||
// Can be used in parameter position
|
||||
function g({name: x}) {
|
||||
console.log(x);
|
||||
}
|
||||
g({name: 5})
|
||||
|
||||
// Fail-soft destructuring
|
||||
var [a] = [];
|
||||
a === undefined;
|
||||
|
||||
// Fail-soft destructuring with defaults
|
||||
var [a = 1] = [];
|
||||
a === 1;
|
||||
```
|
||||
|
||||
### Default + Rest + Spread
|
||||
|
||||
Callee-evaluated default parameter values. Turn an array into consecutive
|
||||
arguments in a function call. Bind trailing parameters to an array. Rest
|
||||
replaces the need for `arguments` and addresses common cases more directly.
|
||||
|
||||
```js
|
||||
function f(x, y=12) {
|
||||
// y is 12 if not passed (or passed as undefined)
|
||||
return x + y;
|
||||
}
|
||||
f(3) == 15
|
||||
```
|
||||
```js
|
||||
function f(x, ...y) {
|
||||
// y is an Array
|
||||
return x * y.length;
|
||||
}
|
||||
f(3, "hello", true) == 6
|
||||
```
|
||||
```js
|
||||
function f(x, y, z) {
|
||||
return x + y + z;
|
||||
}
|
||||
// Pass each elem of array as argument
|
||||
f(...[1,2,3]) == 6
|
||||
```
|
||||
|
||||
### Let + Const
|
||||
|
||||
Block-scoped binding constructs. `let` is the new `var`. `const` is
|
||||
single-assignment. Static restrictions prevent use before assignment.
|
||||
|
||||
|
||||
```js
|
||||
function f() {
|
||||
{
|
||||
let x;
|
||||
{
|
||||
// okay, block scoped name
|
||||
const x = "sneaky";
|
||||
// error, const
|
||||
x = "foo";
|
||||
}
|
||||
// error, already declared in block
|
||||
let x = "inner";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Iterators + For..Of
|
||||
|
||||
Iterator objects enable custom iteration like CLR IEnumerable or Java
|
||||
Iteratable. Generalize `for..in` to custom iterator-based iteration with
|
||||
`for..of`. Don’t require realizing an array, enabling lazy design patterns like
|
||||
LINQ.
|
||||
|
||||
```js
|
||||
let fibonacci = {
|
||||
[Symbol.iterator]() {
|
||||
let pre = 0, cur = 1;
|
||||
return {
|
||||
next() {
|
||||
[pre, cur] = [cur, pre + cur];
|
||||
return { done: false, value: cur }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var n of fibonacci) {
|
||||
// truncate the sequence at 1000
|
||||
if (n > 1000)
|
||||
break;
|
||||
print(n);
|
||||
}
|
||||
```
|
||||
|
||||
Iteration is based on these duck-typed interfaces (using
|
||||
[TypeScript](http://typescriptlang.org) type syntax for exposition only):
|
||||
|
||||
```ts
|
||||
interface IteratorResult {
|
||||
done: boolean;
|
||||
value: any;
|
||||
}
|
||||
interface Iterator {
|
||||
next(): IteratorResult;
|
||||
}
|
||||
interface Iterable {
|
||||
[Symbol.iterator](): Iterator
|
||||
}
|
||||
```
|
||||
|
||||
### Generators
|
||||
|
||||
Generators simplify iterator-authoring using `function*` and `yield`. A function
|
||||
declared as function* returns a Generator instance. Generators are subtypes of
|
||||
iterators which include additional `next` and `throw`. These enable values to
|
||||
flow back into the generator, so `yield` is an expression form which returns a
|
||||
value (or throws).
|
||||
|
||||
Note: Can also be used to enable ‘await’-like async programming, see also ES7
|
||||
`await` proposal.
|
||||
|
||||
```js
|
||||
var fibonacci = {
|
||||
[Symbol.iterator]: function*() {
|
||||
var pre = 0, cur = 1;
|
||||
for (;;) {
|
||||
var temp = pre;
|
||||
pre = cur;
|
||||
cur += temp;
|
||||
yield cur;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var n of fibonacci) {
|
||||
// truncate the sequence at 1000
|
||||
if (n > 1000)
|
||||
break;
|
||||
print(n);
|
||||
}
|
||||
```
|
||||
|
||||
The generator interface is (using [TypeScript](http://typescriptlang.org) type
|
||||
syntax for exposition only):
|
||||
|
||||
```ts
|
||||
interface Generator extends Iterator {
|
||||
next(value?: any): IteratorResult;
|
||||
throw(exception: any);
|
||||
}
|
||||
```
|
||||
|
||||
### Comprehensions
|
||||
|
||||
Array and generator comprehensions provide simple declarative list processing
|
||||
similar as used in many functional programming patterns.
|
||||
|
||||
```js
|
||||
// Array comprehensions
|
||||
var results = [
|
||||
for(c of customers)
|
||||
if (c.city == "Seattle")
|
||||
{ name: c.name, age: c.age }
|
||||
]
|
||||
|
||||
// Generator comprehensions
|
||||
var results = (
|
||||
for(c of customers)
|
||||
if (c.city == "Seattle")
|
||||
{ name: c.name, age: c.age }
|
||||
)
|
||||
```
|
||||
|
||||
### Unicode
|
||||
|
||||
Non-breaking additions to support full Unicode, including new unicode literal
|
||||
form in strings and new RegExp `u` mode to handle code points, as well as new
|
||||
APIs to process strings at the 21bit code points level. These additions support
|
||||
building global apps in JavaScript.
|
||||
|
||||
```js
|
||||
// same as ES5.1
|
||||
"𠮷".length == 2
|
||||
|
||||
// new RegExp behaviour, opt-in ‘u’
|
||||
"𠮷".match(/./u)[0].length == 2
|
||||
|
||||
// new form
|
||||
"\u{20BB7}"=="𠮷" == "\uD842\uDFB7"
|
||||
|
||||
// new String ops
|
||||
"𠮷".codePointAt(0) == 0x20BB7
|
||||
|
||||
// for-of iterates code points
|
||||
for(var c of "𠮷") {
|
||||
console.log(c);
|
||||
}
|
||||
```
|
||||
|
||||
### Modules
|
||||
|
||||
Language-level support for modules for component definition. Codifies patterns
|
||||
from popular JavaScript module loaders (AMD, CommonJS). Runtime behaviour
|
||||
defined by a host-defined default loader. Implicitly async model – no code
|
||||
executes until requested modules are available and processed.
|
||||
|
||||
```js
|
||||
// lib/math.js
|
||||
export function sum(x, y) {
|
||||
return x + y;
|
||||
}
|
||||
export var pi = 3.141593;
|
||||
```
|
||||
```js
|
||||
// app.js
|
||||
module math from "lib/math";
|
||||
alert("2π = " + math.sum(math.pi, math.pi));
|
||||
```
|
||||
```js
|
||||
// otherApp.js
|
||||
import {sum, pi} from "lib/math";
|
||||
alert("2π = " + sum(pi, pi));
|
||||
```
|
||||
|
||||
Some additional features include `export default` and `export *`:
|
||||
|
||||
```js
|
||||
// lib/mathplusplus.js
|
||||
export * from "lib/math";
|
||||
export var e = 2.71828182846;
|
||||
export default function(x) {
|
||||
return Math.exp(x);
|
||||
}
|
||||
```
|
||||
```js
|
||||
// app.js
|
||||
module math from "lib/mathplusplus";
|
||||
import exp from "lib/mathplusplus";
|
||||
alert("2π = " + exp(math.pi, math.e));
|
||||
```
|
||||
|
||||
<blockquote class="to5-callout to5-callout-info">
|
||||
<h4>Module Formatters</h4>
|
||||
<p>
|
||||
6to5 can transpile ES6 Modules to several different formats including
|
||||
Common.js, AMD, System, and UMD. You can even create your own. For more
|
||||
details see the <a href="modules.html">modules docs</a>.
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
### Module Loaders
|
||||
|
||||
Module loaders support:
|
||||
- Dynamic loading
|
||||
- State isolation
|
||||
- Global namespace isolation
|
||||
- Compilation hooks
|
||||
- Nested virtualization
|
||||
|
||||
The default module loader can be configured, and new loaders can be constructed
|
||||
to evaluated and load code in isolated or constrained contexts.
|
||||
|
||||
```js
|
||||
// Dynamic loading – ‘System’ is default loader
|
||||
System.import('lib/math').then(function(m) {
|
||||
alert("2π = " + m.sum(m.pi, m.pi));
|
||||
});
|
||||
|
||||
// Create execution sandboxes – new Loaders
|
||||
var loader = new Loader({
|
||||
global: fixup(window) // replace ‘console.log’
|
||||
});
|
||||
loader.eval("console.log('hello world!');");
|
||||
|
||||
// Directly manipulate module cache
|
||||
System.get('jquery');
|
||||
System.set('jquery', Module({$: $})); // WARNING: not yet finalized
|
||||
```
|
||||
|
||||
<blockquote class="to5-callout to5-callout-warning">
|
||||
<h4>Additional polyfill needed</h4>
|
||||
<p>
|
||||
Since 6to5 defaults to using common.js modules, it does not include the
|
||||
polyfill for the module loader api. Get it
|
||||
<a href="https://github.com/ModuleLoader/es6-module-loader">here</a>.
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
<blockquote class="to5-callout to5-callout-info">
|
||||
<h4>Using Module Loader</h4>
|
||||
<p>
|
||||
In order to use this, you'll need to tell 6to5 to use the
|
||||
<code>system</code> module formatter. Also be sure to check out
|
||||
<a href="https://github.com/systemjs/systemjs">System.js</a>
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
|
||||
### Map + Set + WeakMap + WeakSet
|
||||
|
||||
Efficient data structures for common algorithms. WeakMaps provides leak-free
|
||||
object-key’d side tables.
|
||||
|
||||
```js
|
||||
// Sets
|
||||
var s = new Set();
|
||||
s.add("hello").add("goodbye").add("hello");
|
||||
s.size === 2;
|
||||
s.has("hello") === true;
|
||||
|
||||
// Maps
|
||||
var m = new Map();
|
||||
m.set("hello", 42);
|
||||
m.set(s, 34);
|
||||
m.get(s) == 34;
|
||||
|
||||
// Weak Maps
|
||||
var wm = new WeakMap();
|
||||
wm.set(s, { extra: 42 });
|
||||
wm.size === undefined
|
||||
|
||||
// Weak Sets
|
||||
var ws = new WeakSet();
|
||||
ws.add({ data: 42 });
|
||||
// Because the added object has no other references, it will not be held in the set
|
||||
```
|
||||
|
||||
<blockquote class="to5-callout to5-callout-info">
|
||||
<h4>Support via polyfill</h4>
|
||||
<p>
|
||||
In order to support Promises you must include the 6to5 Polyfill.
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
### Proxies
|
||||
|
||||
Proxies enable creation of objects with the full range of behaviors available to
|
||||
host objects. Can be used for interception, object virtualization,
|
||||
logging/profiling, etc.
|
||||
|
||||
```js
|
||||
// Proxying a normal object
|
||||
var target = {};
|
||||
var handler = {
|
||||
get: function (receiver, name) {
|
||||
return `Hello, ${name}!`;
|
||||
}
|
||||
};
|
||||
|
||||
var p = new Proxy(target, handler);
|
||||
p.world === 'Hello, world!';
|
||||
```
|
||||
|
||||
```js
|
||||
// Proxying a function object
|
||||
var target = function () { return 'I am the target'; };
|
||||
var handler = {
|
||||
apply: function (receiver, ...args) {
|
||||
return 'I am the proxy';
|
||||
}
|
||||
};
|
||||
|
||||
var p = new Proxy(target, handler);
|
||||
p() === 'I am the proxy';
|
||||
```
|
||||
|
||||
There are traps available for all of the runtime-level meta-operations:
|
||||
|
||||
```js
|
||||
var handler =
|
||||
{
|
||||
get:...,
|
||||
set:...,
|
||||
has:...,
|
||||
deleteProperty:...,
|
||||
apply:...,
|
||||
construct:...,
|
||||
getOwnPropertyDescriptor:...,
|
||||
defineProperty:...,
|
||||
getPrototypeOf:...,
|
||||
setPrototypeOf:...,
|
||||
enumerate:...,
|
||||
ownKeys:...,
|
||||
preventExtensions:...,
|
||||
isExtensible:...
|
||||
}
|
||||
```
|
||||
|
||||
<blockquote class="to5-callout to5-callout-danger">
|
||||
<h4>Unsupported feature</h4>
|
||||
<p>
|
||||
Due to the limitations of ES5, Proxies cannot be transpiled or polyfilled.
|
||||
See support from various
|
||||
<a href="http://kangax.github.io/compat-table/es6/#Proxy">JavaScript
|
||||
engines</a>.
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
### Symbols
|
||||
|
||||
Symbols enable access control for object state. Symbols allow properties to be
|
||||
keyed by either `string` (as in ES5) or `symbol`. Symbols are a new primitive
|
||||
type. Optional `name` parameter used in debugging - but is not part of identity.
|
||||
Symbols are unique (like gensym), but not private since they are exposed via
|
||||
reflection features like `Object.getOwnPropertySymbols`.
|
||||
|
||||
```js
|
||||
(function() {
|
||||
|
||||
// module scoped symbol
|
||||
var key = Symbol("key");
|
||||
|
||||
function MyClass(privateData) {
|
||||
this[key] = privateData;
|
||||
}
|
||||
|
||||
MyClass.prototype = {
|
||||
doStuff: function() {
|
||||
... this[key] ...
|
||||
}
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
var c = new MyClass("hello")
|
||||
c["key"] === undefined
|
||||
```
|
||||
|
||||
<blockquote class="to5-callout to5-callout-info">
|
||||
<h4>Support via polyfill</h4>
|
||||
<p>
|
||||
In order to support Promises you must include the 6to5 Polyfill.
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
### Subclassable Built-ins
|
||||
In ES6, built-ins like `Array`, `Date` and DOM `Element`s can be subclassed.
|
||||
|
||||
Object construction for a function named `Ctor` now uses two-phases (both
|
||||
virtually dispatched):
|
||||
|
||||
- Call `Ctor[@@create]` to allocate the object, installing any special behavior
|
||||
- Invoke constructor on new instance to initialize
|
||||
|
||||
The known `@@create` symbol is available via `Symbol.create`. Built-ins now
|
||||
expose their `@@create` explicitly.
|
||||
|
||||
```js
|
||||
// Pseudo-code of Array
|
||||
class Array {
|
||||
constructor(...args) { /* ... */ }
|
||||
static [Symbol.create]() {
|
||||
// Install special [[DefineOwnProperty]]
|
||||
// to magically update 'length'
|
||||
}
|
||||
}
|
||||
|
||||
// User code of Array subclass
|
||||
class MyArray extends Array {
|
||||
constructor(...args) { super(...args); }
|
||||
}
|
||||
|
||||
// Two-phase 'new':
|
||||
// 1) Call @@create to allocate object
|
||||
// 2) Invoke constructor on new instance
|
||||
var arr = new MyArray();
|
||||
arr[1] = 12;
|
||||
arr.length == 2
|
||||
```
|
||||
|
||||
### Math + Number + String + Object APIs
|
||||
|
||||
Many new library additions, including core Math libraries, Array conversion
|
||||
helpers, and Object.assign for copying.
|
||||
|
||||
```js
|
||||
Number.EPSILON
|
||||
Number.isInteger(Infinity) // false
|
||||
Number.isNaN("NaN") // false
|
||||
|
||||
Math.acosh(3) // 1.762747174039086
|
||||
Math.hypot(3, 4) // 5
|
||||
Math.imul(Math.pow(2, 32) - 1, Math.pow(2, 32) - 2) // 2
|
||||
|
||||
"abcde".contains("cd") // true
|
||||
"abc".repeat(3) // "abcabcabc"
|
||||
|
||||
Array.from(document.querySelectorAll('*')) // Returns a real Array
|
||||
Array.of(1, 2, 3) // Similar to new Array(...), but without special one-arg behavior
|
||||
[0, 0, 0].fill(7, 1) // [0,7,7]
|
||||
[1,2,3].findIndex(x => x == 2) // 1
|
||||
["a", "b", "c"].entries() // iterator [0, "a"], [1,"b"], [2,"c"]
|
||||
["a", "b", "c"].keys() // iterator 0, 1, 2
|
||||
["a", "b", "c"].values() // iterator "a", "b", "c"
|
||||
|
||||
Object.assign(Point, { origin: new Point(0,0) })
|
||||
```
|
||||
|
||||
<blockquote class="to5-callout to5-callout-warning">
|
||||
<h4>Limited support from polyfill</h4>
|
||||
<p>
|
||||
Most of these APIs are supported by the 6to5 Polyfill. However, certain
|
||||
features are omitted for various reasons (ie.
|
||||
<code>String.prototype.normalize</code> needs a lot of additional code to
|
||||
support). You can find more polyfills
|
||||
<a href="https://github.com/addyosmani/es6-tools#polyfills">here</a>.
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
### Binary and Octal Literals
|
||||
Two new numeric literal forms are added for binary (`b`) and octal (`o`).
|
||||
|
||||
```js
|
||||
0b111110111 === 503 // true
|
||||
0o767 === 503 // true
|
||||
```
|
||||
|
||||
<blockquote class="to5-callout to5-callout-warning">
|
||||
<h4>Only supports literal form</h4>
|
||||
<p>
|
||||
6to5 is only able to transform <code>0o767</code> and not
|
||||
<code>Number('0o767')</code>.
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
|
||||
### Promises
|
||||
|
||||
Promises are a library for asynchronous programming. Promises are a first class
|
||||
representation of a value that may be made available in the future. Promises are
|
||||
used in many existing JavaScript libraries.
|
||||
|
||||
```js
|
||||
function timeout(duration = 0) {
|
||||
return new Promise((resolve, reject) => {
|
||||
setTimeout(resolve, duration);
|
||||
})
|
||||
}
|
||||
|
||||
var p = timeout(1000).then(() => {
|
||||
return timeout(2000);
|
||||
}).then(() => {
|
||||
throw new Error("hmm");
|
||||
}).catch(err => {
|
||||
return Promise.all([timeout(100), timeout(200)]);
|
||||
})
|
||||
```
|
||||
|
||||
<blockquote class="to5-callout to5-callout-info">
|
||||
<h4>Support via polyfill</h4>
|
||||
<p>
|
||||
In order to support Promises you must include the 6to5 Polyfill.
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
### Reflect API
|
||||
|
||||
Full reflection API exposing the runtime-level meta-operations on objects. This
|
||||
is effectively the inverse of the Proxy API, and allows making calls
|
||||
corresponding to the same meta-operations as the proxy traps. Especially useful
|
||||
for implementing proxies.
|
||||
|
||||
```js
|
||||
// No sample yet
|
||||
```
|
||||
|
||||
<blockquote class="to5-callout to5-callout-danger">
|
||||
<h4>Limited support from polyfill</h4>
|
||||
<p>
|
||||
Core.js only currently supports <code>Reflect.ownKeys</code>, if you would
|
||||
like a much more complete Reflect API, include another polyfill such as
|
||||
<a href="https://github.com/tvcutsem/harmony-reflect">Harmony Reflect</a>.
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
### Tail Calls
|
||||
|
||||
Calls in tail-position are guaranteed to not grow the stack unboundedly. Makes
|
||||
recursive algorithms safe in the face of unbounded inputs.
|
||||
|
||||
```js
|
||||
function factorial(n, acc = 1) {
|
||||
'use strict';
|
||||
if (n <= 1) return acc;
|
||||
return factorial(n - 1, n * acc);
|
||||
}
|
||||
|
||||
// Stack overflow in most implementations today,
|
||||
// but safe on arbitrary inputs in eS6
|
||||
factorial(100000)
|
||||
```
|
||||
|
||||
<blockquote class="to5-callout to5-callout-danger">
|
||||
<h4>Unsupported feature</h4>
|
||||
<p>
|
||||
Due to high complexity of transpiling Tail Calls, 6to5 does not currently
|
||||
have them implemented. See
|
||||
<a href="https://github.com/6to5/6to5/issues/256">#256</a>.
|
||||
</p>
|
||||
</blockquote>
|
||||
259
doc/usage.md
259
doc/usage.md
@@ -1,259 +0,0 @@
|
||||
# Usage
|
||||
|
||||
## CLI
|
||||
|
||||
Compile the file `script.js` and output it to stdout.
|
||||
|
||||
```sh
|
||||
$ 6to5 script.js
|
||||
```
|
||||
|
||||
Compile the file `script.js` and output it to `script-compiled.js`.
|
||||
|
||||
```sh
|
||||
$ 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`.
|
||||
|
||||
```sh
|
||||
$ 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.
|
||||
|
||||
```sh
|
||||
$ 6to5 script.js --source-maps-inline --out-file script-compiled.js
|
||||
```
|
||||
|
||||
Compile the entire `src` directory and output it to the `lib` directory.
|
||||
|
||||
```sh
|
||||
$ 6to5 src --out-dir lib
|
||||
```
|
||||
|
||||
Compile the entire `src` directory and output it to the one concatenated file.
|
||||
|
||||
```sh
|
||||
$ 6to5 src --out-file script-compiled.js
|
||||
```
|
||||
|
||||
Pipe a file in via stdin and output it to `script-compiled.js`
|
||||
|
||||
```sh
|
||||
$ 6to5 --out-file script-compiled.js < script.js
|
||||
```
|
||||
|
||||
### Node
|
||||
|
||||
Launch a repl.
|
||||
|
||||
```sh
|
||||
$ 6to5-node
|
||||
```
|
||||
|
||||
Evaluate code.
|
||||
|
||||
```sh
|
||||
$ 6to5-node -e "class Test { }"
|
||||
```
|
||||
|
||||
Compile and run `test.js`.
|
||||
|
||||
```sh
|
||||
$ 6to5-node test
|
||||
```
|
||||
|
||||
## Node
|
||||
|
||||
```javascript
|
||||
var to5 = require("6to5");
|
||||
```
|
||||
|
||||
### to5.transform(code, [opts]);
|
||||
|
||||
```javascript
|
||||
var result = to5.transform("code();", options);
|
||||
result.code;
|
||||
result.map;
|
||||
result.ast;
|
||||
```
|
||||
|
||||
### to5.transformFileSync(filename, [opts])
|
||||
|
||||
```javascript
|
||||
to5.transformFileSync("filename.js", options).code;
|
||||
```
|
||||
|
||||
### to5.transformFile(filename, [opts], callback)
|
||||
|
||||
```javascript
|
||||
to5.transformFile("filename.js", options, function (err, result) {
|
||||
result.code;
|
||||
});
|
||||
```
|
||||
|
||||
### to5.transform.fromAst(ast, [code], [opts])
|
||||
|
||||
```javascript
|
||||
var result = to5.transform.fromAst(ast, "var a = 2;", opts);
|
||||
result.code;
|
||||
result.map;
|
||||
result.ast;
|
||||
```
|
||||
|
||||
#### Options
|
||||
|
||||
```javascript
|
||||
{
|
||||
// Filename for use in errors etc.
|
||||
// Default: "unknown"
|
||||
filename: "filename",
|
||||
|
||||
// Filename relative to `sourceRoot`
|
||||
// Default: `filename` option.
|
||||
filenameRelative: "",
|
||||
|
||||
// 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: `filenameRelative` option.
|
||||
sourceMapName: "filename",
|
||||
|
||||
// Set `sources[0]` on returned source map.
|
||||
// Default: `filenameRelative` option.
|
||||
sourceFileName: "filename",
|
||||
|
||||
// The root from which all sources are relative
|
||||
// Default: `moduleRoot` option.
|
||||
sourceRoot: "assets/scripts",
|
||||
|
||||
// Optional prefix for the AMD module formatter that will be prepend to the
|
||||
// filename on module definitions
|
||||
// Default: `sourceRoot` option.
|
||||
moduleRoot: "my-app",
|
||||
|
||||
// If truthy, insert an explicit id for each defined AMD/System module.
|
||||
// By default, AMD/System modules are anonymous.
|
||||
// Default: false
|
||||
moduleIds: true,
|
||||
|
||||
// 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,
|
||||
|
||||
// Enable support for experimental ES7 features
|
||||
// Default: false
|
||||
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,
|
||||
|
||||
format: {
|
||||
// Output comments in generated output
|
||||
// Default: true
|
||||
comments: true,
|
||||
|
||||
// Do not include superfluous whitespace characters and line terminators
|
||||
// Default: false
|
||||
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,
|
||||
|
||||
// Indent string
|
||||
// Default: " "
|
||||
style: " ",
|
||||
|
||||
// Base indent level
|
||||
// Default: 0
|
||||
base: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 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; but this is automatically loaded when using:
|
||||
|
||||
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");
|
||||
```
|
||||
|
||||
**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
|
||||
});
|
||||
```
|
||||
|
||||
**NOTE:** Using 6to5-node or `require("6to5/register")`, 6to5 will check what features are available in the current environment and blacklists them if they're supported.
|
||||
|
||||
#### 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"],
|
||||
|
||||
// Enables `roadrunner` cache that will save to a `.roadrunner.json` file in your cwd
|
||||
// Do not check this into git as it's user-specific
|
||||
cache: true
|
||||
});
|
||||
```
|
||||
59
doc/usage/api.md
Normal file
59
doc/usage/api.md
Normal file
@@ -0,0 +1,59 @@
|
||||
---
|
||||
layout: docs
|
||||
title: API
|
||||
description: How to use the Node.js API.
|
||||
permalink: /docs/usage/api/
|
||||
---
|
||||
|
||||
|
||||
```javascript
|
||||
var to5 = require('6to5');
|
||||
```
|
||||
|
||||
## to5.transform
|
||||
|
||||
Transforms the passed in `code`.
|
||||
|
||||
```
|
||||
to5.transform(code, [options])
|
||||
```
|
||||
|
||||
**Example**
|
||||
|
||||
```js
|
||||
var result = to5.transform('code();', options);
|
||||
result.code;
|
||||
result.map;
|
||||
result.ast;
|
||||
```
|
||||
|
||||
## to5.transformFile
|
||||
|
||||
Asynchronously transforms the entire contents of a file.
|
||||
|
||||
```js
|
||||
to5.transformFile(filename, [options], callback)
|
||||
```
|
||||
|
||||
**Example**
|
||||
|
||||
```js
|
||||
to5.transformFile('filename.js', options, function (err, result) {
|
||||
result.code;
|
||||
});
|
||||
```
|
||||
|
||||
## to5.transformFileSync
|
||||
|
||||
Synchronous version of `to5.transformFile`. Returns the transformed contents of
|
||||
the `filename`.
|
||||
|
||||
```js
|
||||
to5.transformFileSync(filename, [options])
|
||||
```
|
||||
|
||||
**Example**
|
||||
|
||||
```js
|
||||
to5.transformFileSync('filename.js', options).code;
|
||||
```
|
||||
59
doc/usage/browser.md
Normal file
59
doc/usage/browser.md
Normal file
@@ -0,0 +1,59 @@
|
||||
---
|
||||
layout: docs
|
||||
title: Browser
|
||||
description: How to transpile in the browser.
|
||||
permalink: /docs/usage/browser/
|
||||
redirect_from: /browser.html
|
||||
---
|
||||
|
||||
<p class="lead">
|
||||
A browser version of 6to5 is available from `browser.js` inside the 6to5
|
||||
directory in an npm release.
|
||||
</p>
|
||||
|
||||
<blockquote class="to5-callout to5-callout-warning">
|
||||
<h4>Not intended for serious use</h4>
|
||||
<p>
|
||||
Compiling in the browser has a fairly limited use case, so if you are
|
||||
working on a production site you should be precompiling your scripts
|
||||
server-side. See <a href="../setup/#build-systems">setup build systems</a>
|
||||
for more information.
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
## Script tags
|
||||
|
||||
When the `browser.js` file is included all scripts with the type
|
||||
`text/ecmascript-6` and `text/6to5` are automatically compiled and ran.
|
||||
|
||||
```html
|
||||
<script src="node_modules/6to5/browser.js"></script>
|
||||
<script type="text/6to5">
|
||||
class Test {
|
||||
test() {
|
||||
return 'test';
|
||||
}
|
||||
}
|
||||
|
||||
var test = new Test;
|
||||
test.test(); // "test"
|
||||
</script>
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
Programmatically transpile and execute strings of ES6 code.
|
||||
|
||||
See [options](#options) for additional documentation.
|
||||
|
||||
### `to5.transform(code, [opts])`
|
||||
|
||||
```js
|
||||
to5.transform('class Test {}').code;
|
||||
```
|
||||
|
||||
### `to5.run(code, [opts])`
|
||||
|
||||
````js
|
||||
to5.run('class Test {}');
|
||||
````
|
||||
99
doc/usage/cli.md
Normal file
99
doc/usage/cli.md
Normal file
@@ -0,0 +1,99 @@
|
||||
---
|
||||
layout: docs
|
||||
title: CLI
|
||||
description: How to use the CLI tools.
|
||||
permalink: /docs/usage/cli/
|
||||
redirect_from: /usage.html
|
||||
---
|
||||
|
||||
<p class="lead">
|
||||
6to5 comes with a built-in CLI which can be used to compile files from the
|
||||
command line.
|
||||
</p>
|
||||
|
||||
## Install
|
||||
|
||||
Using [npm](https://www.npmjs.com/) you can install 6to5 globally, making it
|
||||
available from the command line.
|
||||
|
||||
```sh
|
||||
$ npm install --global 6to5
|
||||
```
|
||||
|
||||
## 6to5
|
||||
|
||||
#### Compile Files
|
||||
|
||||
Compile the file `script.js` and **output to stdout**.
|
||||
|
||||
```sh
|
||||
$ 6to5 script.js
|
||||
# output...
|
||||
```
|
||||
|
||||
If you would like to **output to a file** you may use `--out-file` or `-o`.
|
||||
|
||||
```sh
|
||||
$ 6to5 script.js --out-file script-compiled.js
|
||||
```
|
||||
|
||||
### Compile with Source Maps
|
||||
|
||||
If you would then like to add a **source map file** you can use
|
||||
`--source-maps` or `-s`. [Learn more about source maps](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/).
|
||||
|
||||
```sh
|
||||
$ 6to5 script.js --out-file script-compiled.js --source-maps
|
||||
```
|
||||
|
||||
If you would rather have **inline source maps**, you may use
|
||||
`--source-maps-inline` or `-t`.
|
||||
|
||||
```sh
|
||||
$ 6to5 script.js --out-file script-compiled.js --source-maps-inline
|
||||
```
|
||||
|
||||
### Compile Directories
|
||||
|
||||
Compile the entire `src` directory and output it to the `lib` directory.
|
||||
|
||||
```sh
|
||||
$ 6to5 src --out-dir lib
|
||||
```
|
||||
|
||||
Compile the entire `src` directory and output it to the one concatenated file.
|
||||
|
||||
```sh
|
||||
$ 6to5 src --out-file script-compiled.js
|
||||
```
|
||||
|
||||
### Piping Files
|
||||
|
||||
Pipe a file in via stdin and output it to `script-compiled.js`
|
||||
|
||||
```sh
|
||||
$ 6to5 --out-file script-compiled.js < script.js
|
||||
```
|
||||
|
||||
## 6to5-node
|
||||
|
||||
6to5 comes with a second CLI which works exactly the same as Node.js's CLI, only
|
||||
it will compile ES6 code before running it.
|
||||
|
||||
Launch a REPL (Read-Eval-Print-Loop).
|
||||
|
||||
```sh
|
||||
$ 6to5-node
|
||||
```
|
||||
|
||||
Evaluate code.
|
||||
|
||||
```sh
|
||||
$ 6to5-node -e "class Test { }"
|
||||
```
|
||||
|
||||
Compile and run `test.js`.
|
||||
|
||||
```sh
|
||||
$ 6to5-node test
|
||||
```
|
||||
28
doc/usage/experimental.md
Normal file
28
doc/usage/experimental.md
Normal file
@@ -0,0 +1,28 @@
|
||||
---
|
||||
layout: docs
|
||||
title: Experimental
|
||||
description: How to use experimental ES7 features.
|
||||
permalink: /docs/usage/experimental/
|
||||
redirect_from: /experimental.html
|
||||
---
|
||||
|
||||
> 6to5 also has experimental support for ES7 proposals.
|
||||
|
||||
<blockquote class="to5-callout to5-callout-danger">
|
||||
<h4>Subject to change</h4>
|
||||
<p>
|
||||
These proposals are subject to change so <strong><em>use with extreme
|
||||
caution</em></strong>. 6to5 may update without warning in order to track spec
|
||||
changes. Please do not use them in production applications.
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
#### Usage
|
||||
|
||||
```js
|
||||
$ 6to5 --experimental
|
||||
```
|
||||
|
||||
```js
|
||||
to5.transform('code', { experimental: true });
|
||||
```
|
||||
22
doc/usage/jsx.md
Normal file
22
doc/usage/jsx.md
Normal file
@@ -0,0 +1,22 @@
|
||||
---
|
||||
layout: docs
|
||||
title: JSX
|
||||
description: How to use JSX.
|
||||
permalink: /docs/usage/jsx/
|
||||
---
|
||||
|
||||
<p class="lead">
|
||||
6to5 has built-in support for React v0.12. Tags are automatically transformed
|
||||
to their equivalent <code>React.createElement(...)</code> and
|
||||
<code>displayName</code> is automatically inferred and added to all
|
||||
<code>React.createClass</code> calls.
|
||||
</p>
|
||||
|
||||
## Blacklist
|
||||
|
||||
To disable this behaviour add react to your blacklist:
|
||||
|
||||
````js
|
||||
to5.transform("code", { blacklist: ["react"] });
|
||||
$ 6to5 --blacklist react
|
||||
```
|
||||
@@ -1,37 +1,39 @@
|
||||
# Modules
|
||||
---
|
||||
layout: docs
|
||||
title: Modules
|
||||
description: How to use module formatters.
|
||||
permalink: /docs/usage/modules/
|
||||
redirect_from: /modules.html
|
||||
---
|
||||
|
||||
<p class="lead">
|
||||
6to5 has the ability to transpile ES6 modules to the module system of your
|
||||
choice. You can even easily create your own.
|
||||
</p>
|
||||
|
||||
## Usage
|
||||
|
||||
### CLI
|
||||
|
||||
```sh
|
||||
$ 6to5 --modules common script.js
|
||||
```
|
||||
|
||||
### Node
|
||||
|
||||
```javascript
|
||||
var to5 = require("6to5");
|
||||
```js
|
||||
to5.transform('import "foo";', { modules: "common" });
|
||||
```
|
||||
|
||||
## Formats
|
||||
|
||||
* [AMD](#amd)
|
||||
* [Common (Default)](#common-default)
|
||||
* [Ignore](#ignore)
|
||||
* [System](#system)
|
||||
* [UMD](#umd)
|
||||
### Common (Default)
|
||||
|
||||
### Common
|
||||
**Usage**
|
||||
|
||||
```sh
|
||||
$ 6to5 --modules common
|
||||
```
|
||||
|
||||
**In**
|
||||
**Example**
|
||||
|
||||
```javascript
|
||||
```js
|
||||
export default test;
|
||||
|
||||
export {test};
|
||||
@@ -46,9 +48,7 @@ import {bar} from "foo";
|
||||
import {foo as bar} from "foo";
|
||||
```
|
||||
|
||||
**Out**
|
||||
|
||||
```javascript
|
||||
```js
|
||||
"use strict";
|
||||
|
||||
var _interopRequire = function (obj) {
|
||||
@@ -72,13 +72,15 @@ var bar = require("foo").foo;
|
||||
|
||||
### AMD
|
||||
|
||||
**Usage**
|
||||
|
||||
```sh
|
||||
$ 6to5 --modules amd
|
||||
```
|
||||
|
||||
**In**
|
||||
**Example**
|
||||
|
||||
```javascript
|
||||
```js
|
||||
import foo from "foo";
|
||||
|
||||
export function bar() {
|
||||
@@ -86,9 +88,7 @@ export function bar() {
|
||||
}
|
||||
```
|
||||
|
||||
**Out**
|
||||
|
||||
```javascript
|
||||
```js
|
||||
define(["exports", "foo"], function (exports, _foo) {
|
||||
"use strict";
|
||||
|
||||
@@ -105,21 +105,24 @@ define(["exports", "foo"], function (exports, _foo) {
|
||||
});
|
||||
```
|
||||
|
||||
You can optionally specify to include the module id (using the `--amd-module-id` argument):
|
||||
You can optionally specify to include the module id (using the `--amd-module-id`
|
||||
argument):
|
||||
|
||||
```javascript
|
||||
```js
|
||||
define("filename", ["exports", "foo"], function (exports, _foo) {})
|
||||
```
|
||||
|
||||
### UMD
|
||||
### System
|
||||
|
||||
**Usage**
|
||||
|
||||
```sh
|
||||
$ 6to5 --modules umd
|
||||
$ 6to5 --modules system
|
||||
```
|
||||
|
||||
**In**
|
||||
**Example**
|
||||
|
||||
```javascript
|
||||
```js
|
||||
import foo from "foo";
|
||||
|
||||
export function bar() {
|
||||
@@ -127,9 +130,46 @@ export function bar() {
|
||||
}
|
||||
```
|
||||
|
||||
**Out**
|
||||
```js
|
||||
System.register("bar", ["foo"], function (_export) {
|
||||
"use strict";
|
||||
|
||||
```javascript
|
||||
var __moduleName = "bar";
|
||||
|
||||
var foo;
|
||||
function bar() {
|
||||
return foo("foobar");
|
||||
}
|
||||
return {
|
||||
setters: [function (m) {
|
||||
foo = m.default;
|
||||
}],
|
||||
execute: function () {
|
||||
_export("bar", bar);
|
||||
}
|
||||
};
|
||||
});
|
||||
```
|
||||
|
||||
### UMD
|
||||
|
||||
**Usage**
|
||||
|
||||
```sh
|
||||
$ 6to5 --modules umd
|
||||
```
|
||||
|
||||
**Example**
|
||||
|
||||
```js
|
||||
import foo from "foo";
|
||||
|
||||
export function bar() {
|
||||
return foo("foobar");
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
(function (factory) {
|
||||
if (typeof define === "function" && define.amd) {
|
||||
define(["exports", "foo"], factory);
|
||||
@@ -154,13 +194,15 @@ export function bar() {
|
||||
|
||||
### Ignore
|
||||
|
||||
**Usage**
|
||||
|
||||
```sh
|
||||
$ 6to5 --modules ignore
|
||||
```
|
||||
|
||||
**In**
|
||||
**Example**
|
||||
|
||||
```javascript
|
||||
```js
|
||||
import foo from "foo";
|
||||
|
||||
export function bar() {
|
||||
@@ -168,69 +210,30 @@ export function bar() {
|
||||
}
|
||||
```
|
||||
|
||||
**Out**
|
||||
|
||||
```javascript
|
||||
```js
|
||||
function bar() {
|
||||
return foo("foobar");
|
||||
}
|
||||
```
|
||||
|
||||
### System
|
||||
|
||||
```sh
|
||||
$ 6to5 --modules system
|
||||
```
|
||||
|
||||
**In**
|
||||
|
||||
```javascript
|
||||
import foo from "foo";
|
||||
|
||||
export function bar() {
|
||||
return foo("foobar");
|
||||
}
|
||||
```
|
||||
|
||||
**Out**
|
||||
|
||||
```javascript
|
||||
System.register("bar", ["foo"], function (_export) {
|
||||
"use strict";
|
||||
|
||||
var __moduleName = "bar";
|
||||
|
||||
var foo;
|
||||
function bar() {
|
||||
return foo("foobar");
|
||||
}
|
||||
return {
|
||||
setters: [function (m) {
|
||||
foo = m.default;
|
||||
}],
|
||||
execute: function () {
|
||||
_export("bar", bar);
|
||||
}
|
||||
};
|
||||
});
|
||||
```
|
||||
|
||||
## Custom
|
||||
### Custom
|
||||
|
||||
You can alternatively specify module names instead of one of the built-in types.
|
||||
|
||||
```sh
|
||||
**Usage**
|
||||
|
||||
```js
|
||||
$ 6to5 --modules custom-module-formatter
|
||||
```
|
||||
|
||||
**node_modules/custom-module-formatter/index.js**
|
||||
**Example**
|
||||
|
||||
```javascript
|
||||
**`node_modules/custom-module-formatter/index.js`**
|
||||
|
||||
```js
|
||||
module.exports = ModuleFormatter;
|
||||
|
||||
function ModuleFormatter() {
|
||||
|
||||
}
|
||||
function ModuleFormatter() {}
|
||||
|
||||
ModuleFormatter.prototype.transform = function (ast) {
|
||||
// this is ran after all transformers have had their turn at modifying the ast
|
||||
35
doc/usage/options.md
Normal file
35
doc/usage/options.md
Normal file
@@ -0,0 +1,35 @@
|
||||
---
|
||||
layout: docs
|
||||
title: Options
|
||||
description: Options for 6to5 transpiling.
|
||||
permalink: /docs/usage/options/
|
||||
---
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
to5.transform(code, options);
|
||||
```
|
||||
|
||||
```sh
|
||||
$ 6to5 --name=value
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
| Option | Default | Description |
|
||||
| ------------------ | -------------------- | ------------------------------- |
|
||||
| `filename` | `"unknown"` | Filename for use in errors etc. |
|
||||
| `fileNameRelative` | `(filename)` | Filename relative to `sourceRoot`. |
|
||||
| `blacklist` | `[]` | Array of transformers to **exclude**. Run `6to5 --help` to see a full list of transformers. |
|
||||
| `whitelist` | `[]` | Array of transformers to **only** use. Run `6to5 --help` to see a full list of transformers. |
|
||||
| `modules` | `"common"` | Which module formatter to use. Run `6to5 --help` to see a full list of module formatters. |
|
||||
| `sourceMap` | `false` | 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. |
|
||||
| `sourceMapName` | `(filenameRelative)` | Set `file` on returned source map. |
|
||||
| `sourceFileName` | `(filenameRelative)` | Set `sources[0]` on returned source map. |
|
||||
| `sourceRoot` | `(moduleRoot)` | The root from which all sources are relative. |
|
||||
| `moduleRoot` | `(sourceRoot)` | Optional prefix for the AMD module formatter that will be prepend to the filename on module definitions. |
|
||||
| `amdModuleIds` | `false` | If truthy, insert an explicit id for each defined AMD module. By default, AMD modules are anonymous. |
|
||||
| `runtime` | `false` | Optionally replace all 6to5 helper declarations with a referenece to this variable. If set to `true` then the default namespace is used `to5Runtime`. |
|
||||
| `comments` | `true` | Output comments in generated output. |
|
||||
| `experimental` | `false` | Enable support for experimental ES7 features. |
|
||||
173
doc/usage/playground.md
Normal file
173
doc/usage/playground.md
Normal file
@@ -0,0 +1,173 @@
|
||||
---
|
||||
layout: docs
|
||||
title: Playground
|
||||
description: How to use the playground.
|
||||
permalink: /docs/usage/playground/
|
||||
redirect_from: /playground.html
|
||||
---
|
||||
|
||||
> Playground is a proving ground for language ideas.
|
||||
|
||||
<blockquote class="to5-callout to5-callout-danger">
|
||||
<h4>Unofficial</h4>
|
||||
<p>
|
||||
These features are in no way endorsed by Ecma International and are not a
|
||||
part of any ECMAScript standard, nor are they necessarily on track to become
|
||||
part of any standard. <strong><em>Use with extreme caution</em></strong>.
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
<blockquote class="to5-callout to5-callout-info">
|
||||
<h4>Proposal Authors</h4>
|
||||
<p>
|
||||
If you are actively working on an
|
||||
<a href="https://github.com/tc39/ecma262">ECMAScript proposal</a>, this is a
|
||||
good place to get your ideas implemented with so that they may be tested
|
||||
with all of the latest language and API features.
|
||||
</p>
|
||||
<p>
|
||||
Please feel free to <a href="https://github.com/6to5/6to5/issues/new">open
|
||||
an issue</a> on the 6to5 repository with your WIP spec, and we can discuss
|
||||
getting it implemented. Be sure to include as much information as possible.
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
$ 6to5 --playground
|
||||
```
|
||||
|
||||
```js
|
||||
to5.transform('code', { playground: true });
|
||||
```
|
||||
|
||||
<blockquote class="to5-callout to5-callout-info">
|
||||
<h4>Enables experimental</h4>
|
||||
<p>
|
||||
Enabling playground also enables experimental support.
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
## Features
|
||||
|
||||
### Memoization assignment operator
|
||||
|
||||
The memoization assignment operator allows you to lazily set an object property.
|
||||
It checks whether there's a property defined on the object and if there isn't
|
||||
then the right hand value is set.
|
||||
|
||||
This means that `obj.x` in the following `var x = { x: undefined }; obj.x ?= 2;``
|
||||
will still be `undefined` because it's already been defined on the object.
|
||||
|
||||
**Uses**
|
||||
|
||||
```js
|
||||
var obj = {};
|
||||
obj.x ?= 2;
|
||||
obj.x; // 2
|
||||
|
||||
obj = { x: 1 };
|
||||
obj.x ?= 2;
|
||||
obj.x; // 1
|
||||
|
||||
obj = { x: undefined }
|
||||
obj.x ?= 2;
|
||||
obj.x; // undefined
|
||||
```
|
||||
|
||||
**Example**
|
||||
|
||||
```js
|
||||
var obj = {};
|
||||
obj.x ?= 2;
|
||||
```
|
||||
|
||||
is equivalent to
|
||||
|
||||
```js
|
||||
var obj = {};
|
||||
if (!Object.prototype.hasOwnProperty.call(obj, 'x')) obj.x = 2;
|
||||
```
|
||||
|
||||
### Method binding
|
||||
|
||||
```javascript
|
||||
var fn = obj#method;
|
||||
var fn = obj#method("foob");
|
||||
```
|
||||
|
||||
is equivalent to
|
||||
|
||||
```javascript
|
||||
var fn = obj.method.bind(obj);
|
||||
var fn = obj.method.bind(obj, "foob");
|
||||
```
|
||||
|
||||
### Method binding function shorthand
|
||||
|
||||
```javascript
|
||||
["foo", "bar"].map(#toUpperCase); // ["FOO", "BAR"]
|
||||
[1.1234, 23.53245, 3].map(#toFixed(2)); // ["1.12", "23.53", "3.00"]
|
||||
```
|
||||
|
||||
equivalent to
|
||||
|
||||
```javascript
|
||||
["foo", "bar"].map(function (val) { return val.toUpperCase(); });
|
||||
[1.1234, 23.53245, 3].map(function (val) { return val.toFixed(2); });
|
||||
```
|
||||
|
||||
### Object getter memoization
|
||||
|
||||
```js
|
||||
var foo = {
|
||||
memo bar() {
|
||||
return complex();
|
||||
}
|
||||
};
|
||||
|
||||
class Foo {
|
||||
memo bar() {
|
||||
return complex();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
is equivalent to
|
||||
|
||||
```js
|
||||
var foo = {
|
||||
get bar() {
|
||||
return Object.defineProperty(this, "bar", {
|
||||
value: complex(),
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true
|
||||
}).bar;
|
||||
}
|
||||
};
|
||||
|
||||
class Foo {
|
||||
get bar() {
|
||||
return Object.defineProperty(this, "bar", {
|
||||
value: complex(),
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true
|
||||
}).bar;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### This shorthand
|
||||
|
||||
```js
|
||||
@foo
|
||||
```
|
||||
|
||||
is equivalent to
|
||||
|
||||
```
|
||||
this.foo
|
||||
```
|
||||
56
doc/usage/polyfill.md
Normal file
56
doc/usage/polyfill.md
Normal file
@@ -0,0 +1,56 @@
|
||||
---
|
||||
layout: docs
|
||||
title: Polyfill
|
||||
description: How to use the Polyfill.
|
||||
permalink: /docs/usage/polyfill/
|
||||
---
|
||||
|
||||
<p class="lead">
|
||||
6to5 includes a polyfill that includes a custom
|
||||
<a href="https://github.com/facebook/regenerator/blob/master/runtime.js">regenerator runtime</a>
|
||||
and <a href="https://github.com/zloirock/core-js">core.js</a>.
|
||||
</p>
|
||||
|
||||
This will emulate a full ES6 environment. This polyfill is automatically loaded
|
||||
when using `6to5-node` and `6to5/register`.
|
||||
|
||||
## Usage in Node/Browserify
|
||||
|
||||
You need to include the polyfill require at the top the **entry point** to
|
||||
your application.
|
||||
|
||||
```js
|
||||
require('6to5/polyfill');
|
||||
```
|
||||
|
||||
Fortunately, this is automatically loaded when using:
|
||||
|
||||
```js
|
||||
require('6to5/register');
|
||||
```
|
||||
|
||||
## Usage in Browser
|
||||
|
||||
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 `<script>`
|
||||
before it.
|
||||
|
||||
**NOTE:** Do not `require` this via browserify etc, use `6to5/polyfill`.
|
||||
|
||||
<blockquote class="to5-callout to5-callout-warning">
|
||||
<h4>Polyfills are not perfect</h4>
|
||||
<p>
|
||||
Due to limitations in various ES5 environments not every polyfill will work
|
||||
in every environment.
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
<blockquote class="to5-callout to5-callout-warning">
|
||||
<h4>Certain polyfills not included</h4>
|
||||
<p>
|
||||
Certain polyfills are too large/complex for their implemented features to
|
||||
justify including them for all builds. You may have to include additional
|
||||
polyfills for a subset of ES6 features.
|
||||
</p>
|
||||
</blockquote>
|
||||
55
doc/usage/require.md
Normal file
55
doc/usage/require.md
Normal file
@@ -0,0 +1,55 @@
|
||||
---
|
||||
layout: docs
|
||||
title: Require Hook
|
||||
description: How to use the require hook.
|
||||
permalink: /docs/usage/require/
|
||||
---
|
||||
|
||||
## Install
|
||||
|
||||
```sh
|
||||
$ npm install 6to5
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
require('6to5/register');
|
||||
```
|
||||
|
||||
All subsequent files required by node with the extensions `.es6`, `.es`, and
|
||||
`.js` will be transformed by 6to5. The polyfill specified in Polyfill is also
|
||||
required.
|
||||
|
||||
**NOTE:** By default all requires to `node_modules` will be ignored. You can
|
||||
override this by passing an ignore regex via:
|
||||
|
||||
```js
|
||||
require('6to5/register')({
|
||||
// This will override `node_modules` ignoring - you can alternatively pass
|
||||
// a regex
|
||||
ignore: false
|
||||
});
|
||||
```
|
||||
|
||||
## Register 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']
|
||||
});
|
||||
```
|
||||
@@ -1,4 +1,11 @@
|
||||
# Optional runtime
|
||||
---
|
||||
layout: docs
|
||||
title: Optional Runtime
|
||||
description: How to use the optional runtime.
|
||||
permalink: /docs/usage/runtime/
|
||||
---
|
||||
|
||||
## Details
|
||||
|
||||
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
|
||||
@@ -8,25 +15,17 @@ 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):
|
||||
## Usage
|
||||
|
||||
```javascript
|
||||
{
|
||||
runtime: true
|
||||
}
|
||||
```
|
||||
|
||||
or the following flag if you're using the [CLI](usage.md#cli):
|
||||
|
||||
```ssh
|
||||
```js
|
||||
$ 6to5 --runtime
|
||||
```
|
||||
|
||||
Then just include the runtime before your generated code.
|
||||
```js
|
||||
to5.transform('code', { runtime: true });
|
||||
```
|
||||
|
||||
## Getting the runtime
|
||||
|
||||
You can get the runtime via either:
|
||||
### Getting the runtime
|
||||
|
||||
```sh
|
||||
$ 6to5-runtime
|
||||
@@ -34,24 +33,24 @@ $ 6to5-runtime
|
||||
|
||||
or
|
||||
|
||||
```javascript
|
||||
require("6to5").runtime();
|
||||
```js
|
||||
require('6to5').runtime();
|
||||
```
|
||||
|
||||
or from an npm release in `runtime.js` from the 6to5 directory.
|
||||
|
||||
## Customising namespace
|
||||
### Customising namespace
|
||||
|
||||
You can also customise the runtime namespace by passing an optional namespace
|
||||
argument:
|
||||
|
||||
```javascript
|
||||
require("6to5").runtime("myCustomNamespace");
|
||||
```
|
||||
|
||||
```sh
|
||||
$ 6to5-runtime myCustomNamespace
|
||||
```
|
||||
|
||||
See [Options - runtime](usage.md#options) for documentation on changing the
|
||||
reference in generated code.
|
||||
```js
|
||||
require("6to5").runtime('myCustomNamespace');
|
||||
```
|
||||
|
||||
See [Options - runtime](../options) for documentation on changing the reference in
|
||||
generated code.
|
||||
@@ -10,15 +10,17 @@ var t = require("./types");
|
||||
var _ = require("lodash");
|
||||
|
||||
function File(opts) {
|
||||
this.dynamicImports = [];
|
||||
this.opts = File.normaliseOptions(opts);
|
||||
this.transformers = this.getTransformers();
|
||||
this.uids = {};
|
||||
this.ast = {};
|
||||
this.dynamicImports = [];
|
||||
this.dynamicImportIds = {};
|
||||
this.opts = File.normaliseOptions(opts);
|
||||
this.transformers = this.getTransformers();
|
||||
this.uids = {};
|
||||
this.ast = {};
|
||||
}
|
||||
|
||||
File.declarations = [
|
||||
File.helpers = [
|
||||
"inherits",
|
||||
"defaults",
|
||||
"prototype-properties",
|
||||
"apply-constructor",
|
||||
"tagged-template-literal",
|
||||
@@ -28,12 +30,17 @@ File.declarations = [
|
||||
"object-without-properties",
|
||||
"has-own",
|
||||
"slice",
|
||||
"bind",
|
||||
"define-property",
|
||||
"async-to-generator"
|
||||
"async-to-generator",
|
||||
"interop-require-wildcard",
|
||||
"typeof",
|
||||
"exports-wildcard"
|
||||
];
|
||||
|
||||
File.excludeDeclarationsFromRuntime = [
|
||||
"async-to-generator"
|
||||
File.excludeHelpersFromRuntime = [
|
||||
"async-to-generator",
|
||||
"typeof"
|
||||
];
|
||||
|
||||
File.normaliseOptions = function (opts) {
|
||||
@@ -97,25 +104,30 @@ File.normaliseOptions = function (opts) {
|
||||
File.prototype.getTransformers = function () {
|
||||
var file = this;
|
||||
var transformers = [];
|
||||
var secondPassTransformers = [];
|
||||
|
||||
_.each(transform.transformers, function (transformer) {
|
||||
if (transformer.canRun(file)) {
|
||||
transformers.push(transformer);
|
||||
|
||||
if (transformer.secondPass) {
|
||||
secondPassTransformers.push(transformer);
|
||||
}
|
||||
|
||||
if (transformer.manipulateOptions) {
|
||||
transformer.manipulateOptions(file.opts, file);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return transformers;
|
||||
return transformers.concat(secondPassTransformers);
|
||||
};
|
||||
|
||||
File.prototype.toArray = function (node, i) {
|
||||
if (t.isArrayExpression(node)) {
|
||||
return node;
|
||||
} else if (t.isIdentifier(node) && node.name === "arguments") {
|
||||
return t.callExpression(t.memberExpression(this.addDeclaration("slice"), t.identifier("call")), [node]);
|
||||
return t.callExpression(t.memberExpression(this.addHelper("slice"), t.identifier("call")), [node]);
|
||||
} else {
|
||||
var declarationName = "to-array";
|
||||
var args = [node];
|
||||
@@ -123,7 +135,7 @@ File.prototype.toArray = function (node, i) {
|
||||
args.push(t.literal(i));
|
||||
declarationName = "sliced-to-array";
|
||||
}
|
||||
return t.callExpression(this.addDeclaration(declarationName), args);
|
||||
return t.callExpression(this.addHelper(declarationName), args);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -154,15 +166,24 @@ File.prototype.parseShebang = function (code) {
|
||||
return code;
|
||||
};
|
||||
|
||||
File.prototype.addImport = function (id, source) {
|
||||
var specifiers = [t.importSpecifier(t.identifier("default"), id)];
|
||||
var declar = t.importDeclaration(specifiers, t.literal(source));
|
||||
declar._blockHoist = 3;
|
||||
this.dynamicImports.push(declar);
|
||||
File.prototype.addImport = function (source, name) {
|
||||
name = name || source;
|
||||
var id = this.dynamicImportIds[name];
|
||||
|
||||
if (!id) {
|
||||
id = this.dynamicImportIds[name] = this.generateUidIdentifier(name);
|
||||
|
||||
var specifiers = [t.importSpecifier(t.identifier("default"), id)];
|
||||
var declar = t.importDeclaration(specifiers, t.literal(source));
|
||||
declar._blockHoist = 3;
|
||||
this.dynamicImports.push(declar);
|
||||
}
|
||||
|
||||
return id;
|
||||
};
|
||||
|
||||
File.prototype.addDeclaration = function (name) {
|
||||
if (!_.contains(File.declarations, name)) {
|
||||
File.prototype.addHelper = function (name) {
|
||||
if (!_.contains(File.helpers, name)) {
|
||||
throw new ReferenceError("unknown declaration " + name);
|
||||
}
|
||||
|
||||
@@ -173,7 +194,7 @@ File.prototype.addDeclaration = function (name) {
|
||||
|
||||
var ref;
|
||||
var runtimeNamespace = this.opts.runtime;
|
||||
if (runtimeNamespace && !_.contains(File.excludeDeclarationsFromRuntime, name)) {
|
||||
if (runtimeNamespace && !_.contains(File.excludeHelpersFromRuntime, name)) {
|
||||
name = t.identifier(t.toIdentifier(name));
|
||||
return t.memberExpression(t.identifier(runtimeNamespace), name);
|
||||
} else {
|
||||
@@ -267,7 +288,7 @@ File.prototype.generate = function () {
|
||||
};
|
||||
|
||||
File.prototype.generateUid = function (name, scope) {
|
||||
name = t.toIdentifier(name);
|
||||
name = t.toIdentifier(name).replace(/^_+/, "");
|
||||
|
||||
scope = scope || this.scope;
|
||||
|
||||
|
||||
@@ -148,11 +148,11 @@ CodeGenerator.prototype.print = function (node, parent, opts) {
|
||||
};
|
||||
|
||||
if (this[node.type]) {
|
||||
var needsCommentParens = t.isExpression(node) && node.leadingComments && node.leadingComments.length;
|
||||
var needsParens = needsCommentParens || n.needsParens(node, parent);
|
||||
var needsNoLineTermParens = n.needsParensNoLineTerminator(node, parent);
|
||||
var needsParens = needsNoLineTermParens || n.needsParens(node, parent);
|
||||
|
||||
if (needsParens) this.push("(");
|
||||
if (needsCommentParens) this.indent();
|
||||
if (needsNoLineTermParens) this.indent();
|
||||
|
||||
this.printLeadingComments(node, parent);
|
||||
|
||||
@@ -163,7 +163,7 @@ CodeGenerator.prototype.print = function (node, parent, opts) {
|
||||
|
||||
this[node.type](node, this.buildPrint(node), parent);
|
||||
|
||||
if (needsCommentParens) {
|
||||
if (needsNoLineTermParens) {
|
||||
this.newline();
|
||||
this.dedent();
|
||||
}
|
||||
@@ -274,14 +274,21 @@ CodeGenerator.prototype._printComments = function (comments) {
|
||||
var self = this;
|
||||
|
||||
_.each(comments, function (comment) {
|
||||
var skip = false;
|
||||
|
||||
// find the original comment in the ast and set it as displayed
|
||||
_.each(self.ast.comments, function (origComment) {
|
||||
if (origComment.start === comment.start) {
|
||||
// comment has already been output
|
||||
if (origComment._displayed) skip = true;
|
||||
|
||||
origComment._displayed = true;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
if (skip) return;
|
||||
|
||||
// whitespace before
|
||||
self.newline(self.whitespace.getNewlinesBefore(comment));
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
exports.UnaryExpression = function (node, print) {
|
||||
var hasSpace = /[a-z]$/.test(node.operator);
|
||||
@@ -86,6 +87,7 @@ exports.ExpressionStatement = function (node, print) {
|
||||
|
||||
exports.BinaryExpression =
|
||||
exports.LogicalExpression =
|
||||
exports.AssignmentPattern =
|
||||
exports.AssignmentExpression = function (node, print) {
|
||||
print(node.left);
|
||||
this.push(" " + node.operator + " ");
|
||||
@@ -102,7 +104,12 @@ exports.MemberExpression = function (node, print) {
|
||||
throw new TypeError("Got a MemberExpression for MemberExpression property");
|
||||
}
|
||||
|
||||
if (node.computed) {
|
||||
var computed = node.computed;
|
||||
if (t.isLiteral(node.property) && _.isNumber(node.property.value)) {
|
||||
computed = true;
|
||||
}
|
||||
|
||||
if (computed) {
|
||||
this.push("[");
|
||||
print(node.property);
|
||||
this.push("]");
|
||||
|
||||
@@ -61,14 +61,40 @@ Node.prototype.needsParens = function () {
|
||||
if (!parent) return false;
|
||||
|
||||
if (t.isNewExpression(parent) && parent.callee === node) {
|
||||
return t.isCallExpression(node) || _.some(node, function (val) {
|
||||
if (t.isCallExpression(node)) return true;
|
||||
|
||||
var hasCall = _.some(node, function (val) {
|
||||
return t.isCallExpression(val);
|
||||
});
|
||||
if (hasCall) return true;
|
||||
}
|
||||
|
||||
return find(parens, node, parent);
|
||||
};
|
||||
|
||||
Node.prototype.needsParensNoLineTerminator = function () {
|
||||
var parent = this.parent;
|
||||
var node = this.node;
|
||||
|
||||
if (!parent) return false;
|
||||
|
||||
// no comments
|
||||
if (!node.leadingComments || !node.leadingComments.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (t.isYieldExpression(parent) || t.isAwaitExpression(parent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (t.isContinueStatement(parent) || t.isBreakStatement(parent) ||
|
||||
t.isReturnStatement(parent) || t.isThrowStatement(parent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
_.each(Node.prototype, function (fn, key) {
|
||||
Node[key] = function (node, parent) {
|
||||
var n = new Node(node, parent);
|
||||
|
||||
@@ -13,15 +13,30 @@ _.each([
|
||||
["<", ">", "<=", ">=", "in", "instanceof"],
|
||||
[">>", "<<", ">>>"],
|
||||
["+", "-"],
|
||||
["*", "/", "%"]
|
||||
["*", "/", "%"],
|
||||
["**"]
|
||||
], function (tier, i) {
|
||||
_.each(tier, function (op) {
|
||||
PRECEDENCE[op] = i;
|
||||
});
|
||||
});
|
||||
|
||||
exports.ObjectExpression = function (node, parent) {
|
||||
if (t.isExpressionStatement(parent)) {
|
||||
// ({ foo: "bar" });
|
||||
return true;
|
||||
}
|
||||
|
||||
if (t.isMemberExpression(parent) && parent.object === node) {
|
||||
// ({ foo: "bar" }).foo
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
exports.Binary = function (node, parent) {
|
||||
if (t.isCallExpression(parent) && parent.callee === node) {
|
||||
if ((t.isCallExpression(parent) || t.isNewExpression(parent)) && parent.callee === node) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,12 @@ var types = require("ast-types");
|
||||
var def = types.Type.def;
|
||||
var or = types.Type.or;
|
||||
|
||||
def("AssignmentPattern")
|
||||
.bases("Pattern")
|
||||
.build("left", "right")
|
||||
.field("left", def("Pattern"))
|
||||
.field("right", def("Expression"));
|
||||
|
||||
// Acorn - Same as ImportNamespaceSpecifier but `id` is `name`
|
||||
def("ImportBatchSpecifier")
|
||||
.bases("Specifier")
|
||||
|
||||
4
lib/6to5/register-browser.js
Normal file
4
lib/6to5/register-browser.js
Normal file
@@ -0,0 +1,4 @@
|
||||
// Required to safely use 6to5/register within a browserify codebase.
|
||||
module.exports = function () {};
|
||||
|
||||
require("./polyfill");
|
||||
@@ -123,7 +123,7 @@ var hookExtensions = function (_exts) {
|
||||
});
|
||||
};
|
||||
|
||||
hookExtensions([".es6", ".js"]);
|
||||
hookExtensions([".es6", ".es", ".js"]);
|
||||
|
||||
module.exports = function (opts) {
|
||||
// normalise options
|
||||
|
||||
@@ -18,8 +18,8 @@ module.exports = function (namespace) {
|
||||
)
|
||||
]));
|
||||
|
||||
_.each(File.declarations, function (name) {
|
||||
if (_.contains(File.excludeDeclarationsFromRuntime, name)) {
|
||||
_.each(File.helpers, function (name) {
|
||||
if (_.contains(File.excludeHelpersFromRuntime, name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ DefaultFormatter.prototype.remapAssignments = function () {
|
||||
traverse(this.file.ast, {
|
||||
enter: function (node, parent, scope) {
|
||||
if (t.isUpdateExpression(node) && isLocalReference(node.argument, scope)) {
|
||||
this.stop();
|
||||
this.skip();
|
||||
|
||||
// expand to long file assignment expression
|
||||
var assign = t.assignmentExpression(node.operator[0] + "=", node.argument, t.literal(1));
|
||||
@@ -79,7 +79,7 @@ DefaultFormatter.prototype.remapAssignments = function () {
|
||||
}
|
||||
|
||||
if (t.isAssignmentExpression(node) && isLocalReference(node.left, scope)) {
|
||||
this.stop();
|
||||
this.skip();
|
||||
return self.remapExportAssignment(node);
|
||||
}
|
||||
}
|
||||
@@ -141,10 +141,17 @@ DefaultFormatter.prototype._exportSpecifier = function (getRef, specifier, node,
|
||||
// export * from "foo";
|
||||
nodes.push(this._exportsWildcard(getRef(), node));
|
||||
} else {
|
||||
var ref;
|
||||
if (t.isSpecifierDefault(specifier.id) || this.noInteropRequire) {
|
||||
ref = t.memberExpression(getRef(), specifier.id);
|
||||
} else {
|
||||
ref = t.callExpression(this.file.addHelper("interop-require"), [getRef()]);
|
||||
}
|
||||
|
||||
// export { foo } from "test";
|
||||
nodes.push(this._exportsAssign(
|
||||
t.getSpecifierName(specifier),
|
||||
t.memberExpression(getRef(), specifier.id),
|
||||
ref,
|
||||
node
|
||||
));
|
||||
}
|
||||
@@ -155,9 +162,9 @@ DefaultFormatter.prototype._exportSpecifier = function (getRef, specifier, node,
|
||||
};
|
||||
|
||||
DefaultFormatter.prototype._exportsWildcard = function (objectIdentifier) {
|
||||
return util.template("exports-wildcard", {
|
||||
OBJECT: objectIdentifier
|
||||
}, true);
|
||||
return t.expressionStatement(t.callExpression(this.file.addHelper("exports-wildcard"), [
|
||||
t.callExpression(this.file.addHelper("interop-require-wildcard"), [objectIdentifier])
|
||||
]));
|
||||
};
|
||||
|
||||
DefaultFormatter.prototype._exportsAssign = function (id, init) {
|
||||
|
||||
@@ -85,7 +85,7 @@ AMDFormatter.prototype.importSpecifier = function (specifier, node, nodes) {
|
||||
// import * as bar from "foo";
|
||||
} else if (t.isSpecifierDefault(specifier) && !this.noInteropRequire) {
|
||||
// import foo from "foo";
|
||||
ref = t.callExpression(this.file.addDeclaration("interop-require"), [ref]);
|
||||
ref = t.callExpression(this.file.addHelper("interop-require"), [ref]);
|
||||
} else {
|
||||
// import {foo} from "foo";
|
||||
ref = t.memberExpression(ref, specifier.id, false);
|
||||
|
||||
@@ -26,24 +26,30 @@ CommonJSFormatter.prototype.importSpecifier = function (specifier, node, nodes)
|
||||
if (t.isSpecifierDefault(specifier)) {
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(variableName,
|
||||
t.callExpression(this.file.addDeclaration("interop-require"), [util.template("require", {
|
||||
t.callExpression(this.file.addHelper("interop-require"), [util.template("require", {
|
||||
MODULE_NAME: node.source
|
||||
})])
|
||||
)
|
||||
]));
|
||||
} else {
|
||||
// import foo from "foo";
|
||||
|
||||
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,
|
||||
KEY: specifier.id
|
||||
}));
|
||||
if (specifier.type === "ImportBatchSpecifier") {
|
||||
// import * as bar from "foo";
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(
|
||||
variableName,
|
||||
t.callExpression(this.file.addHelper("interop-require-wildcard"), [
|
||||
t.callExpression(t.identifier("require"), [node.source])
|
||||
])
|
||||
)
|
||||
]));
|
||||
} else {
|
||||
// import foo from "foo";
|
||||
nodes.push(util.template("require-assign-key", {
|
||||
VARIABLE_NAME: variableName,
|
||||
MODULE_NAME: node.source,
|
||||
KEY: specifier.id
|
||||
}));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -65,7 +71,7 @@ CommonJSFormatter.prototype.exportDeclaration = function (node, nodes) {
|
||||
// exports = module.exports = VALUE;
|
||||
if (this.hasNonDefaultExports) templateName = "exports-default-module-override";
|
||||
|
||||
if (t.isFunction(declar) || !this.hasNonDefaultExports) {
|
||||
if (t.isFunctionDeclaration(declar) || !this.hasNonDefaultExports) {
|
||||
assign = util.template(templateName, {
|
||||
VALUE: this._pushStatement(declar, nodes)
|
||||
}, true);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
module.exports = SystemFormatter;
|
||||
|
||||
var AMDFormatter = require("./amd");
|
||||
var useStrict = require("../transformers/use-strict");
|
||||
var traverse = require("../../traverse");
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
@@ -31,7 +32,7 @@ SystemFormatter.prototype._exportsWildcard = function (objectIdentifier, node) {
|
||||
var right = objectIdentifier;
|
||||
|
||||
var block = t.blockStatement([
|
||||
this.buildExportCall(leftIdentifier, valIdentifier)
|
||||
t.expressionStatement(this.buildExportCall(leftIdentifier, valIdentifier))
|
||||
]);
|
||||
|
||||
return this._addImportSource(t.forInStatement(left, right, block), node);
|
||||
@@ -114,7 +115,7 @@ SystemFormatter.prototype.transform = function (ast) {
|
||||
enter: function (node, parent, scope) {
|
||||
if (t.isFunction(node)) {
|
||||
// nothing inside is accessible
|
||||
return this.stop();
|
||||
return this.skip();
|
||||
}
|
||||
|
||||
if (t.isVariableDeclaration(node)) {
|
||||
@@ -159,7 +160,7 @@ SystemFormatter.prototype.transform = function (ast) {
|
||||
// hoist up function declarations for circular references
|
||||
traverse(block, {
|
||||
enter: function (node) {
|
||||
if (t.isFunction(node)) this.stop();
|
||||
if (t.isFunction(node)) this.skip();
|
||||
|
||||
if (t.isFunctionDeclaration(node) || node._blockHoist) {
|
||||
handlerBody.push(node);
|
||||
@@ -170,5 +171,9 @@ SystemFormatter.prototype.transform = function (ast) {
|
||||
|
||||
handlerBody.push(returnStatement);
|
||||
|
||||
if (useStrict._has(block)) {
|
||||
handlerBody.unshift(block.body.shift());
|
||||
}
|
||||
|
||||
program.body = [runner];
|
||||
};
|
||||
|
||||
1
lib/6to5/transformation/templates/bind.js
Normal file
1
lib/6to5/transformation/templates/bind.js
Normal file
@@ -0,0 +1 @@
|
||||
Function.prototype.bind
|
||||
@@ -1,3 +1,3 @@
|
||||
if (SUPER_NAME) {
|
||||
if (SUPER_NAME !== null) {
|
||||
SUPER_NAME.apply(this, arguments);
|
||||
}
|
||||
|
||||
1
lib/6to5/transformation/templates/default-parameter.js
Normal file
1
lib/6to5/transformation/templates/default-parameter.js
Normal file
@@ -0,0 +1 @@
|
||||
var VARIABLE_NAME = ARGUMENTS[ARGUMENT_KEY] === undefined ? DEFAULT_VALUE : ARGUMENTS[ARGUMENT_KEY];
|
||||
8
lib/6to5/transformation/templates/defaults.js
Normal file
8
lib/6to5/transformation/templates/defaults.js
Normal file
@@ -0,0 +1,8 @@
|
||||
(function (obj, defaults) {
|
||||
for (var key in defaults) {
|
||||
if (obj[key] === undefined) {
|
||||
obj[key] = defaults[key];
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
})
|
||||
@@ -1,5 +1,7 @@
|
||||
(function (obj) {
|
||||
for (var i in obj) {
|
||||
exports[i] = obj[i];
|
||||
if (exports[i] !== undefined) {
|
||||
exports[i] = obj[i];
|
||||
}
|
||||
}
|
||||
})(OBJECT);
|
||||
})
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
if (VARIABLE === undefined) VARIABLE = DEFAULT;
|
||||
@@ -1,4 +1,7 @@
|
||||
(function (child, parent) {
|
||||
if (typeof parent !== "function" && parent !== null) {
|
||||
throw new TypeError("Super expression must either be null or a function, not " + typeof parent);
|
||||
}
|
||||
child.prototype = Object.create(parent && parent.prototype, {
|
||||
constructor: {
|
||||
value: child,
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
(function (obj) {
|
||||
return obj && obj.constructor === Object ? obj : { default: obj };
|
||||
})
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
(function (KEY) {
|
||||
CONTENT;
|
||||
return KEY;
|
||||
})(OBJECT);
|
||||
@@ -0,0 +1,11 @@
|
||||
(function (FUNCTION_KEY) {
|
||||
var WRAPPER_KEY = function FUNCTION_ID() {
|
||||
return FUNCTION_KEY.apply(this, arguments);
|
||||
};
|
||||
|
||||
WRAPPER_KEY.toString = function () {
|
||||
return FUNCTION_KEY.toString();
|
||||
};
|
||||
|
||||
return WRAPPER_KEY;
|
||||
})(FUNCTION)
|
||||
@@ -1 +0,0 @@
|
||||
var VARIABLE_NAME = require(MODULE_NAME);
|
||||
3
lib/6to5/transformation/templates/rest.js
Normal file
3
lib/6to5/transformation/templates/rest.js
Normal file
@@ -0,0 +1,3 @@
|
||||
for (var KEY = START; KEY < ARGUMENTS.length; KEY++) {
|
||||
ARRAY[ARRAY_KEY] = ARGUMENTS[KEY];
|
||||
}
|
||||
3
lib/6to5/transformation/templates/typeof.js
Normal file
3
lib/6to5/transformation/templates/typeof.js
Normal file
@@ -0,0 +1,3 @@
|
||||
(function (obj) {
|
||||
return obj && obj.constructor === Symbol ? "symbol" : typeof obj;
|
||||
});
|
||||
@@ -42,7 +42,6 @@ _.each({
|
||||
// spec
|
||||
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"),
|
||||
@@ -66,7 +65,7 @@ _.each({
|
||||
exponentiationOperator: require("./transformers/es7-exponentiation-operator"),
|
||||
spread: require("./transformers/es6-spread"),
|
||||
templateLiterals: require("./transformers/es6-template-literals"),
|
||||
propertyMethodAssignment: require("./transformers/es5-property-method-assignment"),
|
||||
propertyMethodAssignment: require("./transformers/es6-property-method-assignment"),
|
||||
destructuring: require("./transformers/es6-destructuring"),
|
||||
defaultParameters: require("./transformers/es6-default-parameters"),
|
||||
forOf: require("./transformers/es6-for-of"),
|
||||
@@ -81,15 +80,18 @@ _.each({
|
||||
generators: require("./transformers/es6-generators"),
|
||||
restParameters: require("./transformers/es6-rest-parameters"),
|
||||
|
||||
protoToAssign: require("./transformers/optional-proto-to-assign"),
|
||||
|
||||
_declarations: require("./transformers/_declarations"),
|
||||
|
||||
coreAliasing: require("./transformers/optional-core-aliasing"),
|
||||
undefinedToVoid: require("./transformers/optional-undefined-to-void"),
|
||||
|
||||
// wrap up
|
||||
useStrict: require("./transformers/use-strict"),
|
||||
_aliasFunctions: require("./transformers/_alias-functions"),
|
||||
_moduleFormatter: require("./transformers/_module-formatter"),
|
||||
useStrict: require("./transformers/use-strict"),
|
||||
|
||||
typeofSymbol: require("./transformers/optional-typeof-symbol"),
|
||||
coreAliasing: require("./transformers/optional-core-aliasing"),
|
||||
undefinedToVoid: require("./transformers/optional-undefined-to-void"),
|
||||
|
||||
// spec
|
||||
specPropertyLiterals: require("./transformers/spec-property-literals"),
|
||||
|
||||
@@ -7,20 +7,26 @@ var _ = require("lodash");
|
||||
function Transformer(key, transformer, opts) {
|
||||
this.manipulateOptions = transformer.manipulateOptions;
|
||||
this.experimental = !!transformer.experimental;
|
||||
this.transformer = Transformer.normalise(transformer);
|
||||
this.secondPass = !!transformer.secondPass;
|
||||
this.transformer = this.normalise(transformer);
|
||||
this.optional = !!transformer.optional;
|
||||
this.opts = opts || {};
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
Transformer.normalise = function (transformer) {
|
||||
Transformer.prototype.normalise = function (transformer) {
|
||||
var self = this;
|
||||
|
||||
if (_.isFunction(transformer)) {
|
||||
transformer = { ast: transformer };
|
||||
}
|
||||
|
||||
_.each(transformer, function (fns, type) {
|
||||
// hidden property
|
||||
if (type[0] === "_") return;
|
||||
if (type[0] === "_") {
|
||||
self[type] = fns;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_.isFunction(fns)) fns = { enter: fns };
|
||||
|
||||
@@ -41,16 +47,14 @@ Transformer.normalise = function (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.ast[key](file.ast, file);
|
||||
}
|
||||
};
|
||||
|
||||
Transformer.prototype.transform = function (file) {
|
||||
var transformer = this.transformer;
|
||||
var ast = file.ast;
|
||||
|
||||
var build = function (exit) {
|
||||
return function (node, parent, scope) {
|
||||
@@ -67,7 +71,7 @@ Transformer.prototype.transform = function (file) {
|
||||
|
||||
this.astRun(file, "before");
|
||||
|
||||
traverse(ast, {
|
||||
traverse(file.ast, {
|
||||
enter: build(),
|
||||
exit: build(true)
|
||||
});
|
||||
|
||||
@@ -20,7 +20,7 @@ var go = function (getBody, node, file, scope) {
|
||||
if (!node._aliasFunction) {
|
||||
if (t.isFunction(node)) {
|
||||
// stop traversal of this node as it'll be hit again by this transformer
|
||||
return this.stop();
|
||||
return this.skip();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
@@ -30,10 +30,10 @@ var go = function (getBody, node, file, scope) {
|
||||
traverse(node, {
|
||||
enter: function (node, parent) {
|
||||
if (t.isFunction(node) && !node._aliasFunction) {
|
||||
return this.stop();
|
||||
return this.skip();
|
||||
}
|
||||
|
||||
if (node._ignoreAliasFunctions) return this.stop();
|
||||
if (node._ignoreAliasFunctions) return this.skip();
|
||||
|
||||
var getId;
|
||||
|
||||
@@ -49,7 +49,7 @@ var go = function (getBody, node, file, scope) {
|
||||
}
|
||||
});
|
||||
|
||||
return this.stop();
|
||||
return this.skip();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -67,7 +67,7 @@ var go = function (getBody, node, file, scope) {
|
||||
}
|
||||
|
||||
if (thisId) {
|
||||
pushDeclaration(thisId, t.identifier("this"));
|
||||
pushDeclaration(thisId, t.thisExpression());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
var _ = require("lodash");
|
||||
var useStrict = require("./use-strict");
|
||||
var _ = require("lodash");
|
||||
|
||||
// Priority:
|
||||
//
|
||||
@@ -17,13 +18,15 @@ exports.Program = {
|
||||
}
|
||||
if (!hasChange) return;
|
||||
|
||||
var nodePriorities = _.groupBy(node.body, function (bodyNode) {
|
||||
var priority = bodyNode._blockHoist;
|
||||
if (priority == null) priority = 1;
|
||||
if (priority === true) priority = 2;
|
||||
return priority;
|
||||
});
|
||||
useStrict._wrap(node, function () {
|
||||
var nodePriorities = _.groupBy(node.body, function (bodyNode) {
|
||||
var priority = bodyNode._blockHoist;
|
||||
if (priority == null) priority = 1;
|
||||
if (priority === true) priority = 2;
|
||||
return priority;
|
||||
});
|
||||
|
||||
node.body = _.flatten(_.values(nodePriorities).reverse());
|
||||
node.body = _.flatten(_.values(nodePriorities).reverse());
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,25 +1,32 @@
|
||||
var t = require("../../types");
|
||||
var useStrict = require("./use-strict");
|
||||
var t = require("../../types");
|
||||
|
||||
exports.secondPass = true;
|
||||
|
||||
exports.BlockStatement =
|
||||
exports.Program = function (node) {
|
||||
var kinds = {};
|
||||
var kind;
|
||||
|
||||
for (var i in node._declarations) {
|
||||
var declar = node._declarations[i];
|
||||
useStrict._wrap(node, function () {
|
||||
for (var i in node._declarations) {
|
||||
var declar = node._declarations[i];
|
||||
|
||||
kind = declar.kind || "var";
|
||||
var declarNode = t.variableDeclarator(declar.id, declar.init);
|
||||
kind = declar.kind || "var";
|
||||
var declarNode = t.variableDeclarator(declar.id, declar.init);
|
||||
|
||||
if (!declar.init) {
|
||||
kinds[kind] = kinds[kind] || [];
|
||||
kinds[kind].push(declarNode);
|
||||
} else {
|
||||
node.body.unshift(t.variableDeclaration(kind, [declarNode]));
|
||||
if (!declar.init) {
|
||||
kinds[kind] = kinds[kind] || [];
|
||||
kinds[kind].push(declarNode);
|
||||
} else {
|
||||
node.body.unshift(t.variableDeclaration(kind, [declarNode]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (kind in kinds) {
|
||||
node.body.unshift(t.variableDeclaration(kind, kinds[kind]));
|
||||
}
|
||||
for (kind in kinds) {
|
||||
node.body.unshift(t.variableDeclaration(kind, kinds[kind]));
|
||||
}
|
||||
});
|
||||
|
||||
node._declarations = null;
|
||||
};
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
|
||||
exports.Property = function (node) {
|
||||
if (node.method) node.method = false;
|
||||
};
|
||||
|
||||
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 {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
if (!hasAny) return;
|
||||
|
||||
if (node.properties.length) {
|
||||
var objId = t.getUid(parent, file);
|
||||
|
||||
return util.template("object-define-properties-closure", {
|
||||
KEY: objId,
|
||||
OBJECT: node,
|
||||
CONTENT: util.template("object-define-properties", {
|
||||
OBJECT: objId,
|
||||
PROPS: util.buildDefineProperties(mutatorMap)
|
||||
})
|
||||
});
|
||||
} else {
|
||||
return util.template("object-define-properties", {
|
||||
OBJECT: node,
|
||||
PROPS: util.buildDefineProperties(mutatorMap)
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -89,14 +89,14 @@ Class.prototype.run = function () {
|
||||
this.closure = true;
|
||||
|
||||
// so we're only evaluating it once
|
||||
var superRef = t.getUid(superName, this.file);
|
||||
var superRef = this.scope.generateUidBasedOnNode(superName, this.file);
|
||||
body.unshift(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(superRef, superName)
|
||||
]));
|
||||
superName = superRef;
|
||||
|
||||
this.superName = superName;
|
||||
body.push(t.expressionStatement(t.callExpression(file.addDeclaration("inherits"), [className, superName])));
|
||||
body.push(t.expressionStatement(t.callExpression(file.addHelper("inherits"), [className, superName])));
|
||||
}
|
||||
|
||||
this.buildBody();
|
||||
@@ -175,7 +175,7 @@ Class.prototype.buildBody = function () {
|
||||
if (instanceProps) args.push(instanceProps);
|
||||
|
||||
body.push(t.expressionStatement(
|
||||
t.callExpression(this.file.addDeclaration("prototype-properties"), args)
|
||||
t.callExpression(this.file.addHelper("prototype-properties"), args)
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
var t = require("../../types");
|
||||
|
||||
exports.ObjectExpression = function (node, parent, file) {
|
||||
exports.ObjectExpression = function (node, parent, file, scope) {
|
||||
var hasComputed = false;
|
||||
var prop;
|
||||
var key;
|
||||
@@ -13,7 +13,7 @@ exports.ObjectExpression = function (node, parent, file) {
|
||||
|
||||
if (!hasComputed) return;
|
||||
|
||||
var objId = t.getUid(parent, file);
|
||||
var objId = scope.generateUidBasedOnNode(parent, file);
|
||||
|
||||
var body = [];
|
||||
var container = t.functionExpression(null, [], t.blockStatement(body));
|
||||
@@ -44,7 +44,7 @@ exports.ObjectExpression = function (node, parent, file) {
|
||||
broken = true;
|
||||
}
|
||||
|
||||
if (!broken || t.isLiteral(prop.key, { value: "__proto__" })) {
|
||||
if (!broken || t.isLiteral(t.toComputedKey(prop, prop.key), { value: "__proto__" })) {
|
||||
initProps.push(prop);
|
||||
props[i] = null;
|
||||
}
|
||||
@@ -61,13 +61,14 @@ exports.ObjectExpression = function (node, parent, file) {
|
||||
var bodyNode;
|
||||
|
||||
if (prop.computed && t.isMemberExpression(key) && t.isIdentifier(key.object, { name: "Symbol" })) {
|
||||
// { [Symbol.iterator]: "foo" }
|
||||
bodyNode = t.assignmentExpression(
|
||||
"=",
|
||||
t.memberExpression(objId, key, true),
|
||||
prop.value
|
||||
);
|
||||
} else {
|
||||
bodyNode = t.callExpression(file.addDeclaration("define-property"), [objId, key, prop.value]);
|
||||
bodyNode = t.callExpression(file.addHelper("define-property"), [objId, key, prop.value]);
|
||||
}
|
||||
|
||||
body.push(t.expressionStatement(bodyNode));
|
||||
@@ -79,7 +80,7 @@ exports.ObjectExpression = function (node, parent, file) {
|
||||
var first = body[0].expression;
|
||||
|
||||
if (t.isCallExpression(first)) {
|
||||
first.arguments[0] = t.objectExpression([]);
|
||||
first.arguments[0] = t.objectExpression(initProps);
|
||||
return first;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,16 +49,29 @@ exports.Function = function (node, parent, file, scope) {
|
||||
|
||||
var body = [];
|
||||
|
||||
var argsIdentifier = t.identifier("arguments");
|
||||
argsIdentifier._ignoreAliasFunctions = true;
|
||||
|
||||
var lastNonDefaultParam = 0;
|
||||
|
||||
for (i in node.defaults) {
|
||||
def = node.defaults[i];
|
||||
if (!def) continue;
|
||||
if (!def) {
|
||||
lastNonDefaultParam = +i + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
body.push(util.template("if-undefined-set-to", {
|
||||
VARIABLE: node.params[i],
|
||||
DEFAULT: def
|
||||
body.push(util.template("default-parameter", {
|
||||
VARIABLE_NAME: node.params[i],
|
||||
DEFAULT_VALUE: def,
|
||||
ARGUMENT_KEY: t.literal(+i),
|
||||
ARGUMENTS: argsIdentifier
|
||||
}, true));
|
||||
}
|
||||
|
||||
// we need to cut off all trailing default parameters
|
||||
node.params = node.params.slice(0, lastNonDefaultParam);
|
||||
|
||||
if (iife) {
|
||||
var container = t.functionExpression(null, [], node.body, node.generator);
|
||||
container._aliasFunction = true;
|
||||
|
||||
@@ -20,11 +20,31 @@ var push = function (opts, nodes, elem, parentId) {
|
||||
pushObjectPattern(opts, nodes, elem, parentId);
|
||||
} else if (t.isArrayPattern(elem)) {
|
||||
pushArrayPattern(opts, nodes, elem, parentId);
|
||||
} else if (t.isAssignmentPattern(elem)) {
|
||||
pushAssignmentPattern(opts, nodes, elem, parentId);
|
||||
} else {
|
||||
nodes.push(buildVariableAssign(opts, elem, parentId));
|
||||
}
|
||||
};
|
||||
|
||||
var pushAssignmentPattern = function (opts, nodes, pattern, parentId) {
|
||||
var tempParentId = opts.scope.generateUidBasedOnNode(parentId, opts.file);
|
||||
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(tempParentId, parentId)
|
||||
]));
|
||||
|
||||
nodes.push(buildVariableAssign(
|
||||
opts,
|
||||
pattern.left,
|
||||
t.conditionalExpression(
|
||||
t.binaryExpression("===", tempParentId, t.identifier("undefined")),
|
||||
pattern.right,
|
||||
tempParentId
|
||||
)
|
||||
));
|
||||
};
|
||||
|
||||
var pushObjectPattern = function (opts, nodes, pattern, parentId) {
|
||||
for (var i in pattern.properties) {
|
||||
var prop = pattern.properties[i];
|
||||
@@ -45,9 +65,11 @@ var pushObjectPattern = function (opts, nodes, pattern, parentId) {
|
||||
}
|
||||
keys = t.arrayExpression(keys);
|
||||
|
||||
var value = t.callExpression(opts.file.addDeclaration("object-without-properties"), [parentId, keys]);
|
||||
var value = t.callExpression(opts.file.addHelper("object-without-properties"), [parentId, keys]);
|
||||
nodes.push(buildVariableAssign(opts, prop.argument, value));
|
||||
} else {
|
||||
if (t.isLiteral(prop.key)) prop.computed = true;
|
||||
|
||||
var pattern2 = prop.value;
|
||||
var patternId2 = t.memberExpression(parentId, prop.key, prop.computed);
|
||||
|
||||
@@ -75,7 +97,7 @@ var pushArrayPattern = function (opts, nodes, pattern, parentId) {
|
||||
|
||||
var toArray = opts.file.toArray(parentId, !hasSpreadElement && pattern.elements.length);
|
||||
|
||||
var _parentId = t.getUid(parentId, opts.file, opts.scope);
|
||||
var _parentId = opts.scope.generateUidBasedOnNode(parentId, opts.file);
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(_parentId, toArray)
|
||||
]));
|
||||
@@ -113,7 +135,7 @@ var pushPattern = function (opts) {
|
||||
var scope = opts.scope;
|
||||
|
||||
if (!t.isMemberExpression(parentId) && !t.isIdentifier(parentId)) {
|
||||
var key = t.getUid(parentId, file, scope);
|
||||
var key = scope.generateUidBasedOnNode(parentId, file);
|
||||
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(key, parentId)
|
||||
@@ -183,6 +205,24 @@ exports.Function = function (node, parent, file, scope) {
|
||||
block.body = nodes.concat(block.body);
|
||||
};
|
||||
|
||||
exports.CatchClause = function (node, parent, file, scope) {
|
||||
var pattern = node.param;
|
||||
if (!t.isPattern(pattern)) return;
|
||||
|
||||
var ref = file.generateUidIdentifier("ref", scope);
|
||||
node.param = ref;
|
||||
|
||||
var nodes = [];
|
||||
|
||||
push({
|
||||
kind: "var",
|
||||
file: file,
|
||||
scope: scope
|
||||
}, nodes, pattern, ref);
|
||||
|
||||
node.body.body = nodes.concat(node.body.body);
|
||||
};
|
||||
|
||||
exports.ExpressionStatement = function (node, parent, file, scope) {
|
||||
var expr = node.expression;
|
||||
if (expr.type !== "AssignmentExpression") return;
|
||||
|
||||
@@ -280,7 +280,7 @@ LetScoping.prototype.checkLoop = function () {
|
||||
var replace;
|
||||
|
||||
if (t.isFunction(node) || t.isLoop(node)) {
|
||||
return this.stop();
|
||||
return this.skip();
|
||||
}
|
||||
|
||||
if (node && !node.label) {
|
||||
@@ -329,7 +329,7 @@ LetScoping.prototype.hoistVarDeclarations = function () {
|
||||
} else if (isVar(node, parent)) {
|
||||
return self.pushDeclar(node).map(t.expressionStatement);
|
||||
} else if (t.isFunction(node)) {
|
||||
return this.stop();
|
||||
return this.skip();
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -376,7 +376,7 @@ LetScoping.prototype.getLetReferences = function () {
|
||||
|
||||
// this scope has a variable with the same name so it couldn't belong
|
||||
// to our let scope
|
||||
if (scope.hasOwn(node.name)) return;
|
||||
if (scope.hasOwn(node.name, true)) return;
|
||||
|
||||
closurify = true;
|
||||
|
||||
@@ -388,9 +388,7 @@ LetScoping.prototype.getLetReferences = function () {
|
||||
}
|
||||
});
|
||||
|
||||
return this.stop();
|
||||
} else if (t.isLoop(node)) {
|
||||
return this.stop();
|
||||
return this.skip();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
var traverse = require("../../traverse");
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
|
||||
exports.Property = function (node, parent, file, scope) {
|
||||
if (!node.method) return;
|
||||
|
||||
node.method = false;
|
||||
|
||||
var key = t.toComputedKey(node, node.key);
|
||||
if (!t.isLiteral(key)) return; // we can't set a function id with this
|
||||
|
||||
var id = t.toIdentifier(key.value);
|
||||
key = t.identifier(id);
|
||||
|
||||
var selfReference = false;
|
||||
var outerDeclar = scope.get(id, true);
|
||||
|
||||
traverse(node, {
|
||||
enter: function (node, parent, scope) {
|
||||
// check if this node is an identifier that matches the same as our function id
|
||||
if (!t.isIdentifier(node, { name: id })) return;
|
||||
|
||||
// check if this node is the one referenced
|
||||
if (!t.isReferenced(node, parent)) return;
|
||||
|
||||
// check that we don't have a local variable declared as that removes the need
|
||||
// for the wrapper
|
||||
var localDeclar = scope.get(id, true);
|
||||
if (localDeclar !== outerDeclar) return;
|
||||
|
||||
selfReference = true;
|
||||
this.stop();
|
||||
}
|
||||
}, scope);
|
||||
|
||||
if (selfReference) {
|
||||
node.value = util.template("property-method-assignment-wrapper", {
|
||||
FUNCTION: node.value,
|
||||
FUNCTION_ID: key,
|
||||
FUNCTION_KEY: file.generateUidIdentifier(id, scope),
|
||||
WRAPPER_KEY: file.generateUidIdentifier(id + "Wrapper", scope)
|
||||
});
|
||||
} else {
|
||||
node.value.id = key;
|
||||
}
|
||||
};
|
||||
|
||||
exports.ObjectExpression = function (node, parent, file, scope) {
|
||||
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 {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
if (!hasAny) return;
|
||||
|
||||
if (node.properties.length) {
|
||||
var objId = scope.generateUidBasedOnNode(parent, file);
|
||||
|
||||
return util.template("object-define-properties-closure", {
|
||||
KEY: objId,
|
||||
OBJECT: node,
|
||||
CONTENT: util.template("object-define-properties", {
|
||||
OBJECT: objId,
|
||||
PROPS: util.buildDefineProperties(mutatorMap)
|
||||
})
|
||||
});
|
||||
} else {
|
||||
return util.template("object-define-properties", {
|
||||
OBJECT: node,
|
||||
PROPS: util.buildDefineProperties(mutatorMap)
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -1,4 +1,5 @@
|
||||
var t = require("../../types");
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
|
||||
exports.Function = function (node, parent, file) {
|
||||
if (!node.rest) return;
|
||||
@@ -8,15 +9,28 @@ exports.Function = function (node, parent, file) {
|
||||
|
||||
t.ensureBlock(node);
|
||||
|
||||
var call = file.toArray(t.identifier("arguments"));
|
||||
var argsId = t.identifier("arguments");
|
||||
argsId._ignoreAliasFunctions = true;
|
||||
|
||||
var start = t.literal(node.params.length);
|
||||
var key = file.generateUidIdentifier("key");
|
||||
|
||||
var arrKey = key;
|
||||
if (node.params.length) {
|
||||
call.arguments.push(t.literal(node.params.length));
|
||||
arrKey = t.binaryExpression("-", arrKey, start);
|
||||
}
|
||||
|
||||
call._ignoreAliasFunctions = true;
|
||||
node.body.body.unshift(
|
||||
t.variableDeclaration("var", [
|
||||
t.variableDeclarator(rest, t.arrayExpression([]))
|
||||
]),
|
||||
|
||||
node.body.body.unshift(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(rest, call)
|
||||
]));
|
||||
util.template("rest", {
|
||||
ARGUMENTS: argsId,
|
||||
ARRAY_KEY: arrKey,
|
||||
START: start,
|
||||
ARRAY: rest,
|
||||
KEY: key
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
var getSpreadLiteral = function (spread, file) {
|
||||
return file.toArray(spread.argument);
|
||||
@@ -58,7 +59,7 @@ exports.CallExpression = function (node, parent, file, scope) {
|
||||
var args = node.arguments;
|
||||
if (!hasSpread(args)) return;
|
||||
|
||||
var contextLiteral = t.literal(null);
|
||||
var contextLiteral = t.identifier("undefined");
|
||||
|
||||
node.arguments = [];
|
||||
|
||||
@@ -77,16 +78,15 @@ exports.CallExpression = function (node, parent, file, scope) {
|
||||
}
|
||||
|
||||
var callee = node.callee;
|
||||
var temp;
|
||||
|
||||
if (t.isMemberExpression(callee)) {
|
||||
contextLiteral = callee.object;
|
||||
|
||||
if (t.isDynamic(contextLiteral)) {
|
||||
temp = contextLiteral = scope.generateTemp(file);
|
||||
var temp = scope.generateTempBasedOnNode(callee.object, file);
|
||||
if (temp) {
|
||||
callee.object = t.assignmentExpression("=", temp, callee.object);
|
||||
contextLiteral = temp;
|
||||
} else {
|
||||
contextLiteral = callee.object;
|
||||
}
|
||||
|
||||
t.appendToMemberExpression(callee, t.identifier("apply"));
|
||||
} else {
|
||||
node.callee = t.memberExpression(node.callee, t.identifier("apply"));
|
||||
@@ -99,7 +99,14 @@ exports.NewExpression = function (node, parent, file) {
|
||||
var args = node.arguments;
|
||||
if (!hasSpread(args)) return;
|
||||
|
||||
var nativeType = t.isIdentifier(node.callee) && _.contains(t.NATIVE_TYPE_NAMES, node.callee.name);
|
||||
|
||||
var nodes = build(args, file);
|
||||
|
||||
if (nativeType) {
|
||||
nodes.unshift(t.arrayExpression([t.literal(null)]));
|
||||
}
|
||||
|
||||
var first = nodes.shift();
|
||||
|
||||
if (nodes.length) {
|
||||
@@ -108,5 +115,15 @@ exports.NewExpression = function (node, parent, file) {
|
||||
args = first;
|
||||
}
|
||||
|
||||
return t.callExpression(file.addDeclaration("apply-constructor"), [node.callee, args]);
|
||||
if (nativeType) {
|
||||
return t.newExpression(
|
||||
t.callExpression(
|
||||
t.memberExpression(file.addHelper("bind"), t.identifier("apply")),
|
||||
[node.callee, args]
|
||||
),
|
||||
[]
|
||||
);
|
||||
} else {
|
||||
return t.callExpression(file.addHelper("apply-constructor"), [node.callee, args]);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -17,7 +17,7 @@ exports.TaggedTemplateExpression = function (node, parent, file) {
|
||||
raw.push(t.literal(elem.value.raw));
|
||||
}
|
||||
|
||||
args.push(t.callExpression(file.addDeclaration("tagged-template-literal"), [
|
||||
args.push(t.callExpression(file.addHelper("tagged-template-literal"), [
|
||||
t.arrayExpression(strings),
|
||||
t.arrayExpression(raw)
|
||||
]));
|
||||
|
||||
@@ -30,10 +30,8 @@ exports.AssignmentExpression = function (node, parent, file, scope) {
|
||||
|
||||
// we need to return `node.right`
|
||||
if (!t.isExpressionStatement(parent)) {
|
||||
// `node.right` isn't a simple identifier so we need to reference it
|
||||
if (t.isDynamic(value)) {
|
||||
temp = value = scope.generateTemp(file);
|
||||
}
|
||||
temp = scope.generateTempBasedOnNode(node.right, file);
|
||||
if (temp) value = temp;
|
||||
}
|
||||
|
||||
if (node.operator !== "=") {
|
||||
@@ -80,11 +78,7 @@ exports.CallExpression = function (node, parent, file, scope) {
|
||||
var callee = node.callee;
|
||||
if (!t.isVirtualPropertyExpression(callee)) return;
|
||||
|
||||
var temp;
|
||||
if (t.isDynamic(callee.object)) {
|
||||
// we need to save `callee.object` so we can call it again
|
||||
temp = scope.generateTemp(file);
|
||||
}
|
||||
var temp = scope.generateTempBasedOnNode(callee.object, file);
|
||||
|
||||
var call = util.template("abstract-expression-call", {
|
||||
PROPERTY: callee.property,
|
||||
|
||||
@@ -5,7 +5,7 @@ var t = require("../../types");
|
||||
exports.experimental = true;
|
||||
|
||||
var build = function (node, parent, file, scope) {
|
||||
var uid = t.getUid(parent, file, scope);
|
||||
var uid = scope.generateUidBasedOnNode(parent, file);
|
||||
|
||||
var container = util.template("array-comprehension-container", {
|
||||
KEY: uid
|
||||
@@ -49,7 +49,7 @@ exports._build = function (node, buildBody) {
|
||||
}
|
||||
|
||||
return t.forOfStatement(
|
||||
t.variableDeclaration("var", [t.variableDeclarator(self.left)]),
|
||||
t.variableDeclaration("let", [t.variableDeclarator(self.left)]),
|
||||
self.right,
|
||||
t.blockStatement([child])
|
||||
);
|
||||
|
||||
@@ -7,5 +7,5 @@ exports.manipulateOptions = bluebirdCoroutines.manipulateOptions;
|
||||
exports.Function = function (node, parent, file) {
|
||||
if (!node.async || node.generator) return;
|
||||
|
||||
return bluebirdCoroutines._Function(node, file.addDeclaration("async-to-generator"));
|
||||
return bluebirdCoroutines._Function(node, file.addHelper("async-to-generator"));
|
||||
};
|
||||
|
||||
@@ -14,7 +14,7 @@ exports._Function = function (node, callId) {
|
||||
|
||||
traverse(node, {
|
||||
enter: function (node) {
|
||||
if (t.isFunction(node)) this.stop();
|
||||
if (t.isFunction(node)) this.skip();
|
||||
|
||||
if (t.isAwaitExpression(node)) {
|
||||
node.type = "YieldExpression";
|
||||
@@ -38,8 +38,6 @@ exports._Function = function (node, callId) {
|
||||
exports.Function = function (node, parent, file) {
|
||||
if (!node.async || node.generator) return;
|
||||
|
||||
var id = t.identifier("Bluebird");
|
||||
file.addImport(id, "bluebird");
|
||||
|
||||
var id = file.addImport("bluebird");
|
||||
return exports._Function(node, t.memberExpression(id, t.identifier("coroutine")));
|
||||
};
|
||||
|
||||
@@ -12,8 +12,7 @@ exports.optional = true;
|
||||
|
||||
exports.ast = {
|
||||
enter: function (ast, file) {
|
||||
file._coreId = file.generateUidIdentifier("core");
|
||||
file.addImport(file._coreId, "core-js/library");
|
||||
file._coreId = file.addImport("core-js/library", "core");
|
||||
},
|
||||
|
||||
exit: function (ast, file) {
|
||||
@@ -29,7 +28,7 @@ exports.ast = {
|
||||
if (!t.isReferenced(obj, node)) return;
|
||||
|
||||
if (!node.computed && coreHas(obj) && _.has(core[obj.name], prop.name)) {
|
||||
this.stop();
|
||||
this.skip();
|
||||
return t.prependToMemberExpression(node, file._coreId);
|
||||
}
|
||||
} else if (t.isIdentifier(node) && !t.isMemberExpression(parent) && t.isReferenced(node, parent) && coreHas(node)) {
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
var OBJECT_ASSIGN_MEMBER = t.memberExpression(t.identifier("Object"), t.identifier("assign"));
|
||||
|
||||
var isProtoKey = function (node) {
|
||||
return t.isLiteral(t.toComputedKey(node, node.key), { value: "__proto__" });
|
||||
};
|
||||
|
||||
var isProtoAssignmentExpression = function (node) {
|
||||
var left = node.left;
|
||||
return t.isMemberExpression(left) && t.isLiteral(t.toComputedKey(left, left.property), { value: "__proto__" });
|
||||
};
|
||||
|
||||
var buildDefaultsCallExpression = function (expr, ref, file) {
|
||||
return t.expressionStatement(t.callExpression(file.addHelper("defaults"), [ref, expr.right]));
|
||||
};
|
||||
|
||||
exports.optional = true;
|
||||
exports.secondPass = true;
|
||||
|
||||
exports.AssignmentExpression = function (node, parent, file, scope) {
|
||||
if (t.isExpressionStatement(parent)) return;
|
||||
if (!isProtoAssignmentExpression(node)) return;
|
||||
|
||||
var nodes = [];
|
||||
var left = node.left.object;
|
||||
var temp = scope.generateTempBasedOnNode(node.left.object, file);
|
||||
|
||||
nodes.push(t.expressionStatement(t.assignmentExpression("=", temp, left)));
|
||||
nodes.push(buildDefaultsCallExpression(node, temp, file));
|
||||
if (temp) nodes.push(temp);
|
||||
|
||||
return t.toSequenceExpression(nodes);
|
||||
};
|
||||
|
||||
exports.ExpressionStatement = function (node, parent, file) {
|
||||
var expr = node.expression;
|
||||
if (!t.isAssignmentExpression(expr, { operator: "=" })) return;
|
||||
|
||||
if (isProtoAssignmentExpression(expr)) {
|
||||
return buildDefaultsCallExpression(expr, expr.left.object, file);
|
||||
}
|
||||
};
|
||||
|
||||
exports.ObjectExpression = function (node) {
|
||||
var proto;
|
||||
|
||||
for (var i in node.properties) {
|
||||
var prop = node.properties[i];
|
||||
|
||||
if (isProtoKey(prop)) {
|
||||
proto = prop.value;
|
||||
_.pull(node.properties, prop);
|
||||
}
|
||||
}
|
||||
|
||||
if (proto) {
|
||||
var args = [t.objectExpression([]), proto];
|
||||
if (node.properties.length) args.push(node);
|
||||
return t.callExpression(OBJECT_ASSIGN_MEMBER, args);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
var t = require("../../types");
|
||||
|
||||
exports.optional = true;
|
||||
|
||||
exports.UnaryExpression = function (node, parent, file) {
|
||||
if (node.operator === "typeof") {
|
||||
return t.callExpression(file.addHelper("typeof"), [node.argument]);
|
||||
}
|
||||
};
|
||||
@@ -10,7 +10,7 @@ var getPropRef = function (nodes, prop, file, scope) {
|
||||
if (t.isIdentifier(prop)) {
|
||||
return t.literal(prop.name);
|
||||
} else {
|
||||
var temp = t.getUid(prop, file, scope);
|
||||
var temp = scope.generateUidBasedOnNode(prop, file);
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(temp, prop)
|
||||
]));
|
||||
@@ -19,22 +19,18 @@ var getPropRef = function (nodes, prop, file, scope) {
|
||||
};
|
||||
|
||||
var getObjRef = function (nodes, obj, file, scope) {
|
||||
if (t.isDynamic(obj)) {
|
||||
var temp = t.getUid(obj, file, scope);
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(temp, obj)
|
||||
]));
|
||||
return temp;
|
||||
} else {
|
||||
return obj;
|
||||
}
|
||||
var temp = scope.generateUidBasedOnNode(obj, file);
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(temp, obj)
|
||||
]));
|
||||
return temp;
|
||||
};
|
||||
|
||||
var buildHasOwn = function (obj, prop, file) {
|
||||
return t.unaryExpression(
|
||||
"!",
|
||||
t.callExpression(
|
||||
t.memberExpression(file.addDeclaration("has-own"), t.identifier("call")),
|
||||
t.memberExpression(file.addHelper("has-own"), t.identifier("call")),
|
||||
[obj, prop]
|
||||
),
|
||||
true
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
exports.BindMemberExpression = function (node, parent, file, scope) {
|
||||
var object = node.object;
|
||||
var prop = node.property;
|
||||
|
||||
var temp;
|
||||
if (t.isDynamic(object)) {
|
||||
temp = object = scope.generateTemp(file);
|
||||
}
|
||||
var temp = scope.generateTempBasedOnNode(node.object, file);
|
||||
if (temp) object = temp;
|
||||
|
||||
var call = t.callExpression(
|
||||
t.memberExpression(t.memberExpression(object, prop), t.identifier("bind")),
|
||||
@@ -33,16 +30,12 @@ exports.BindFunctionExpression = function (node, parent, file, scope) {
|
||||
]));
|
||||
};
|
||||
|
||||
if (_.find(node.arguments, t.isDynamic)) {
|
||||
var temp = scope.generateTemp(file, "args");
|
||||
var temp = scope.generateTemp(file, "args");
|
||||
|
||||
return t.sequenceExpression([
|
||||
t.assignmentExpression("=", temp, t.arrayExpression(node.arguments)),
|
||||
buildCall(node.arguments.map(function (node, i) {
|
||||
return t.memberExpression(temp, t.literal(i), true);
|
||||
}))
|
||||
]);
|
||||
} else {
|
||||
return buildCall(node.arguments);
|
||||
}
|
||||
return t.sequenceExpression([
|
||||
t.assignmentExpression("=", temp, t.arrayExpression(node.arguments)),
|
||||
buildCall(node.arguments.map(function (node, i) {
|
||||
return t.memberExpression(temp, t.literal(i), true);
|
||||
}))
|
||||
]);
|
||||
};
|
||||
|
||||
@@ -20,7 +20,7 @@ exports.MethodDefinition = function (node, parent, file) {
|
||||
if (t.isFunction(node)) return;
|
||||
|
||||
if (t.isReturnStatement(node) && node.argument) {
|
||||
node.argument = t.memberExpression(t.callExpression(file.addDeclaration("define-property"), [
|
||||
node.argument = t.memberExpression(t.callExpression(file.addHelper("define-property"), [
|
||||
t.thisExpression(),
|
||||
key,
|
||||
node.argument
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
var t = require("../../types");
|
||||
|
||||
exports.ObjectExpression = function (node, parent, file) {
|
||||
var keys = [];
|
||||
|
||||
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)) {
|
||||
key = key.name;
|
||||
} else if (t.isLiteral(key)) {
|
||||
key = key.value;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (keys.indexOf(key) >= 0) {
|
||||
throw file.errorWithNode(prop.key, "Duplicate property key");
|
||||
} else {
|
||||
keys.push(key);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,14 +1,27 @@
|
||||
var t = require("../../types");
|
||||
|
||||
exports._has = function (node) {
|
||||
var first = node.body[0];
|
||||
return t.isExpressionStatement(first) && t.isLiteral(first.expression, { value: "use strict" });
|
||||
};
|
||||
|
||||
exports._wrap = function (node, callback) {
|
||||
var useStrictNode;
|
||||
if (exports._has(node)) {
|
||||
useStrictNode = node.body.shift();
|
||||
}
|
||||
|
||||
callback();
|
||||
|
||||
if (useStrictNode) {
|
||||
node.body.unshift(useStrictNode);
|
||||
}
|
||||
};
|
||||
|
||||
exports.ast = {
|
||||
exit: function (ast) {
|
||||
var body = ast.program.body;
|
||||
var first = body[0];
|
||||
|
||||
var noStrict = !first || !t.isExpressionStatement(first) || !t.isLiteral(first.expression) || first.expression.value !== "use strict";
|
||||
|
||||
if (noStrict) {
|
||||
body.unshift(t.expressionStatement(t.literal("use strict")));
|
||||
if (!exports._has(ast.program)) {
|
||||
ast.program.body.unshift(t.expressionStatement(t.literal("use strict")));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -22,12 +22,14 @@ function traverse(parent, opts, scope) {
|
||||
|
||||
opts = opts || {};
|
||||
|
||||
var stopped = false;
|
||||
|
||||
for (var i in keys) {
|
||||
var key = keys[i];
|
||||
var nodes = parent[key];
|
||||
if (!nodes) continue;
|
||||
|
||||
var updated = false;
|
||||
var flatten = false;
|
||||
|
||||
var handle = function (obj, key) {
|
||||
var node = obj[key];
|
||||
@@ -50,7 +52,8 @@ function traverse(parent, opts, scope) {
|
||||
|
||||
// replace the node
|
||||
node = obj[key] = result;
|
||||
updated = true;
|
||||
|
||||
if (isArray) flatten = true;
|
||||
|
||||
// we're replacing a statement or block node with an array of statements so we better
|
||||
// ensure that it's a block
|
||||
@@ -59,16 +62,20 @@ function traverse(parent, opts, scope) {
|
||||
}
|
||||
};
|
||||
|
||||
var stopped = false;
|
||||
var skipped = false;
|
||||
var removed = false;
|
||||
|
||||
var context = {
|
||||
stop: function () {
|
||||
stopped = true;
|
||||
skipped = stopped = true;
|
||||
},
|
||||
|
||||
skip: function () {
|
||||
skipped = true;
|
||||
},
|
||||
|
||||
remove: function () {
|
||||
this.stop();
|
||||
this.skip();
|
||||
removed = true;
|
||||
}
|
||||
};
|
||||
@@ -84,11 +91,11 @@ function traverse(parent, opts, scope) {
|
||||
|
||||
if (removed) {
|
||||
obj[key] = null;
|
||||
updated = true;
|
||||
flatten = true;
|
||||
}
|
||||
|
||||
// stop iteration
|
||||
if (stopped) return;
|
||||
if (skipped) return;
|
||||
}
|
||||
|
||||
// traverse node
|
||||
@@ -103,9 +110,10 @@ function traverse(parent, opts, scope) {
|
||||
if (_.isArray(nodes)) {
|
||||
for (i in nodes) {
|
||||
handle(nodes, i);
|
||||
if (stopped) return;
|
||||
}
|
||||
|
||||
if (updated) {
|
||||
if (flatten) {
|
||||
parent[key] = _.flatten(parent[key]);
|
||||
|
||||
if (key === "body") {
|
||||
@@ -115,6 +123,7 @@ function traverse(parent, opts, scope) {
|
||||
}
|
||||
} else {
|
||||
handle(parent, key);
|
||||
if (stopped) return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -161,7 +170,7 @@ traverse.hasType = function (tree, type, blacklistTypes) {
|
||||
enter: function (node) {
|
||||
if (node.type === type) {
|
||||
has = true;
|
||||
this.stop();
|
||||
this.skip();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -31,6 +31,13 @@ Scope.add = function (node, references) {
|
||||
_.defaults(references, t.getIds(node, true));
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
* @param {File} file
|
||||
* @param {String} [name="temp"]
|
||||
*/
|
||||
|
||||
Scope.prototype.generateTemp = function (file, name) {
|
||||
var id = file.generateUidIdentifier(name || "temp", this);
|
||||
this.push({
|
||||
@@ -40,6 +47,70 @@ Scope.prototype.generateTemp = function (file, name) {
|
||||
return id;
|
||||
};
|
||||
|
||||
/*
|
||||
* Description
|
||||
*
|
||||
* @param {Object} parent
|
||||
* @param {File} file
|
||||
* @param {Scope} scope
|
||||
* @returns {Object}
|
||||
*/
|
||||
|
||||
Scope.prototype.generateUidBasedOnNode = function (parent, file) {
|
||||
var node = parent;
|
||||
|
||||
if (t.isAssignmentExpression(parent)) {
|
||||
node = parent.left;
|
||||
} else if (t.isVariableDeclarator(parent)) {
|
||||
node = parent.id;
|
||||
} else if (t.isProperty(node)) {
|
||||
node = node.key;
|
||||
}
|
||||
|
||||
var parts = [];
|
||||
|
||||
var add = function (node) {
|
||||
if (t.isMemberExpression(node)) {
|
||||
add(node.object);
|
||||
add(node.property);
|
||||
} else if (t.isIdentifier(node)) {
|
||||
parts.push(node.name);
|
||||
} else if (t.isLiteral(node)) {
|
||||
parts.push(node.value);
|
||||
} else if (t.isCallExpression(node)) {
|
||||
add(node.callee);
|
||||
}
|
||||
};
|
||||
|
||||
add(node);
|
||||
|
||||
var id = parts.join("$");
|
||||
id = id.replace(/^_/, "") || "ref";
|
||||
|
||||
return file.generateUidIdentifier(id, this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
* @param {Object} node
|
||||
* @param {File} file
|
||||
* @returns {Object}
|
||||
*/
|
||||
|
||||
Scope.prototype.generateTempBasedOnNode = function (node, file) {
|
||||
if (t.isIdentifier(node) && this.has(node.name, true)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var id = this.generateUidBasedOnNode(node, file);
|
||||
this.push({
|
||||
key: id.name,
|
||||
id: id
|
||||
});
|
||||
return id;
|
||||
};
|
||||
|
||||
Scope.prototype.getInfo = function () {
|
||||
var block = this.block;
|
||||
if (block._scopeInfo) return block._scopeInfo;
|
||||
@@ -93,7 +164,7 @@ Scope.prototype.getInfo = function () {
|
||||
|
||||
// this block is a function so we'll stop since none of the variables
|
||||
// declared within are accessible
|
||||
if (t.isFunction(node)) return this.stop();
|
||||
if (t.isFunction(node)) return this.skip();
|
||||
|
||||
// function identifier doesn't belong to this scope
|
||||
if (block.id && node === block.id) return;
|
||||
@@ -123,6 +194,12 @@ Scope.prototype.getInfo = function () {
|
||||
return info;
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
* @param {Object} opts
|
||||
*/
|
||||
|
||||
Scope.prototype.push = function (opts) {
|
||||
var block = this.block;
|
||||
|
||||
@@ -143,33 +220,84 @@ Scope.prototype.push = function (opts) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
* @param {Object} node
|
||||
*/
|
||||
|
||||
Scope.prototype.add = function (node) {
|
||||
Scope.add(node, this.references);
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
* @param {String} [id]
|
||||
* @param {Boolean} [decl]
|
||||
*/
|
||||
|
||||
Scope.prototype.get = function (id, decl) {
|
||||
return id && (this.getOwn(id, decl) || this.parentGet(id, decl));
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
* @param {String} [id]
|
||||
* @param {Boolean} [decl]
|
||||
*/
|
||||
|
||||
Scope.prototype.getOwn = function (id, decl) {
|
||||
var refs = this.references;
|
||||
if (decl) refs = this.declarations;
|
||||
return _.has(refs, id) && refs[id];
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
* @param {String} [id]
|
||||
* @param {Boolean} [decl]
|
||||
*/
|
||||
|
||||
Scope.prototype.parentGet = function (id, decl) {
|
||||
return this.parent && this.parent.get(id, decl);
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
* @param {String} [id]
|
||||
* @param {Boolean} [decl]
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
Scope.prototype.has = function (id, decl) {
|
||||
return (id && (this.hasOwn(id, decl) || this.parentHas(id, decl))) ||
|
||||
_.contains(Scope.defaultDeclarations, id);
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
* @param {String} [id]
|
||||
* @param {Boolean} [decl]
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
Scope.prototype.hasOwn = function (id, decl) {
|
||||
return !!this.getOwn(id, decl);
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
* @param {String} [id]
|
||||
* @param {Boolean} [decl]
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
Scope.prototype.parentHas = function (id, decl) {
|
||||
return this.parent && this.parent.has(id, decl);
|
||||
};
|
||||
|
||||
@@ -39,8 +39,9 @@
|
||||
"ForInStatement": ["Statement", "For", "Scope", "Loop"],
|
||||
"ForStatement": ["Statement", "For", "Scope", "Loop"],
|
||||
|
||||
"ObjectPattern": ["Pattern"],
|
||||
"ArrayPattern": ["Pattern"],
|
||||
"ObjectPattern": ["Pattern"],
|
||||
"ArrayPattern": ["Pattern"],
|
||||
"AssignmentPattern": ["Pattern"],
|
||||
|
||||
"Property": ["UserWhitespacable"],
|
||||
"XJSElement": ["UserWhitespacable", "Expression"],
|
||||
|
||||
@@ -3,6 +3,10 @@ var _ = require("lodash");
|
||||
|
||||
var t = exports;
|
||||
|
||||
t.NATIVE_TYPE_NAMES = ["Array", "Object", "Number", "Boolean", "Date", "Array", "String"];
|
||||
|
||||
//
|
||||
|
||||
var addAssert = function (type, is) {
|
||||
t["assert" + type] = function (node, opts) {
|
||||
opts = opts || {};
|
||||
@@ -64,6 +68,20 @@ _.each(t.FLIPPED_ALIAS_KEYS, function (types, type) {
|
||||
addAssert(type, is);
|
||||
});
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
* @param {Object} node
|
||||
* @returns {Object}
|
||||
*/
|
||||
|
||||
t.toComputedKey = function (node, key) {
|
||||
if (!node.computed) {
|
||||
if (t.isIdentifier(key)) key = t.literal(key.name);
|
||||
}
|
||||
return key;
|
||||
};
|
||||
|
||||
/*
|
||||
* Shallowly checks to see if the passed `node` will evaluate to a
|
||||
* falsy. This is if `node` is a `Literal` and `value` is falsy or
|
||||
@@ -111,7 +129,11 @@ t.toSequenceExpression = function (nodes, scope) {
|
||||
}
|
||||
});
|
||||
|
||||
return t.sequenceExpression(exprs);
|
||||
if (exprs.length === 1) {
|
||||
return exprs[0];
|
||||
} else {
|
||||
return t.sequenceExpression(exprs);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
@@ -159,25 +181,6 @@ t.prependToMemberExpression = function (member, append) {
|
||||
return member;
|
||||
};
|
||||
|
||||
/*
|
||||
* Description
|
||||
*
|
||||
* @param {Object} node
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
t.isDynamic = function (node) {
|
||||
if (t.isExpressionStatement(node)) {
|
||||
return t.isDynamic(node.expression);
|
||||
} else if (t.isIdentifier(node) || t.isLiteral(node) || t.isThisExpression(node)) {
|
||||
return false;
|
||||
} else if (t.isMemberExpression(node)) {
|
||||
return t.isDynamic(node.object) || t.isDynamic(node.property);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
@@ -215,7 +218,7 @@ t.isReferenced = function (node, parent) {
|
||||
*/
|
||||
|
||||
t.isValidIdentifier = function (name) {
|
||||
return _.isString(name) && esutils.keyword.isIdentifierName(name) && !esutils.keyword.isKeywordES6(name, true);
|
||||
return _.isString(name) && esutils.keyword.isIdentifierName(name) && !esutils.keyword.isReservedWordES6(name, true);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -228,6 +231,8 @@ t.isValidIdentifier = function (name) {
|
||||
t.toIdentifier = function (name) {
|
||||
if (t.isIdentifier(name)) return name.name;
|
||||
|
||||
name = name + "";
|
||||
|
||||
// replace all non-valid identifiers with dashes
|
||||
name = name.replace(/[^a-zA-Z0-9$_]/g, "-");
|
||||
|
||||
@@ -242,6 +247,10 @@ t.toIdentifier = function (name) {
|
||||
// remove underscores from start of name
|
||||
name = name.replace(/^\_/, "");
|
||||
|
||||
if (!t.isValidIdentifier(name)) {
|
||||
name = "_" + name;
|
||||
}
|
||||
|
||||
return name || '_';
|
||||
};
|
||||
|
||||
@@ -326,58 +335,6 @@ t.toBlock = function (node, parent) {
|
||||
return t.blockStatement(node);
|
||||
};
|
||||
|
||||
/*
|
||||
* Description
|
||||
*
|
||||
* @param {Object} parent
|
||||
* @param {File} file
|
||||
* @param {Scope} scope
|
||||
* @returns {Object}
|
||||
*/
|
||||
|
||||
t.getUid = function (parent, file, scope) {
|
||||
var node = parent;
|
||||
|
||||
if (t.isAssignmentExpression(parent)) {
|
||||
node = parent.left;
|
||||
} else if (t.isVariableDeclarator(parent)) {
|
||||
node = parent.id;
|
||||
}
|
||||
|
||||
var id = "ref";
|
||||
|
||||
if (t.isProperty(node)) {
|
||||
node = node.key;
|
||||
}
|
||||
|
||||
if (t.isIdentifier(node)) {
|
||||
id = node.name;
|
||||
} else if (t.isLiteral(node)) {
|
||||
id = node.value;
|
||||
} else if (t.isMemberExpression(node)) {
|
||||
var parts = [];
|
||||
|
||||
var add = function (node) {
|
||||
if (t.isMemberExpression(node)) {
|
||||
add(node.object);
|
||||
add(node.property);
|
||||
} else if (t.isIdentifier(node)) {
|
||||
parts.push(node.name);
|
||||
} else if (t.isLiteral(node)) {
|
||||
parts.push(node.value);
|
||||
}
|
||||
};
|
||||
|
||||
add(node);
|
||||
|
||||
id = parts.join("$");
|
||||
}
|
||||
|
||||
id = id.replace(/^_/, "");
|
||||
|
||||
return file.generateUidIdentifier(id, scope);
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
"ArrayPattern": ["elements"],
|
||||
"ArrowFunctionExpression": ["params", "defaults", "rest", "body"],
|
||||
"AssignmentExpression": ["left", "right"],
|
||||
"AssignmentPattern": ["left", "right"],
|
||||
"AwaitExpression": ["argument"],
|
||||
"BinaryExpression": ["left", "right"],
|
||||
"BindFunctionExpression": ["callee", "arguments"],
|
||||
|
||||
@@ -12,7 +12,7 @@ var _ = require("lodash");
|
||||
exports.inherits = util.inherits;
|
||||
|
||||
exports.canCompile = function (filename, altExts) {
|
||||
var exts = altExts || [".js", ".jsx", ".es6"];
|
||||
var exts = altExts || [".js", ".jsx", ".es6", ".es"];
|
||||
var ext = path.extname(filename);
|
||||
return _.contains(exts, ext);
|
||||
};
|
||||
|
||||
13
package.json
13
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "6to5",
|
||||
"description": "Turn ES6 code into readable vanilla ES5 with source maps",
|
||||
"version": "2.4.4",
|
||||
"version": "2.6.2",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||
"homepage": "https://github.com/6to5/6to5",
|
||||
"repository": {
|
||||
@@ -18,6 +18,10 @@
|
||||
"6to5-node": "./bin/6to5-node",
|
||||
"6to5-runtime": "./bin/6to5-runtime"
|
||||
},
|
||||
"browser": {
|
||||
"./lib/6to5/index.js": "./lib/6to5/browser.js",
|
||||
"./lib/6to5/register.js": "./lib/6to5/register-browser.js"
|
||||
},
|
||||
"keywords": [
|
||||
"harmony",
|
||||
"classes",
|
||||
@@ -35,19 +39,20 @@
|
||||
"test": "make test"
|
||||
},
|
||||
"dependencies": {
|
||||
"acorn-6to5": "0.11.1-3",
|
||||
"acorn-6to5": "0.11.1-11",
|
||||
"ast-types": "~0.6.1",
|
||||
"chokidar": "0.11.1",
|
||||
"commander": "2.5.0",
|
||||
"core-js": "^0.3.3",
|
||||
"core-js": "^0.4.0",
|
||||
"estraverse": "1.8.0",
|
||||
"esutils": "1.1.6",
|
||||
"esvalid": "^1.1.0",
|
||||
"fs-readdir-recursive": "0.1.0",
|
||||
"jshint": "^2.5.10",
|
||||
"lodash": "2.4.1",
|
||||
"mkdirp": "0.5.0",
|
||||
"private": "0.1.6",
|
||||
"regenerator": "^0.8.2",
|
||||
"regenerator": "^0.8.3",
|
||||
"regexpu": "0.3.0",
|
||||
"roadrunner": "^1.0.4",
|
||||
"source-map": "0.1.40",
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
var fs = require("fs");
|
||||
var _ = require("lodash");
|
||||
var path = require("path");
|
||||
var fs = require("fs");
|
||||
var _ = require("lodash");
|
||||
|
||||
var humanise = function (val) {
|
||||
return val.replace(/-/g, " ");
|
||||
return path.basename(val, path.extname(val)).replace(/-/g, " ");
|
||||
};
|
||||
|
||||
var readFile = exports.readFile = function (filename) {
|
||||
@@ -15,11 +16,11 @@ var readFile = exports.readFile = function (filename) {
|
||||
}
|
||||
};
|
||||
|
||||
exports.get = function (entryName) {
|
||||
exports.get = function (entryName, entryLoc) {
|
||||
if (exports.cache[entryName]) return exports.cache[entryName];
|
||||
|
||||
var suites = [];
|
||||
var entryLoc = __dirname + "/fixtures/" + entryName;
|
||||
var entryLoc = entryLoc || __dirname + "/fixtures/" + entryName;
|
||||
|
||||
_.each(fs.readdirSync(entryLoc), function (suiteName) {
|
||||
if (suiteName[0] === ".") return;
|
||||
@@ -35,9 +36,18 @@ exports.get = function (entryName) {
|
||||
var suiteOptsLoc = suite.filename + "/options.json";
|
||||
if (fs.existsSync(suiteOptsLoc)) suite.options = require(suiteOptsLoc);
|
||||
|
||||
_.each(fs.readdirSync(suite.filename), function (taskName) {
|
||||
var taskDir = suite.filename + "/" + taskName;
|
||||
if (fs.statSync(taskDir).isFile()) return;
|
||||
if (fs.statSync(suite.filename).isFile()) {
|
||||
push(suiteName, suite.filename);
|
||||
} else {
|
||||
_.each(fs.readdirSync(suite.filename), function (taskName) {
|
||||
var taskDir = suite.filename + "/" + taskName;
|
||||
push(taskName, taskDir);
|
||||
});
|
||||
}
|
||||
|
||||
function push(taskName, taskDir) {
|
||||
// tracuer error tests
|
||||
if (taskName.indexOf("Error_") >= 0) return;
|
||||
|
||||
var actualLocAlias = suiteName + "/" + taskName + "/actual.js";
|
||||
var expectLocAlias = suiteName + "/" + taskName + "/expected.js";
|
||||
@@ -47,6 +57,13 @@ exports.get = function (entryName) {
|
||||
var expectLoc = taskDir + "/expected.js";
|
||||
var execLoc = taskDir + "/exec.js";
|
||||
|
||||
if (fs.statSync(taskDir).isFile()) {
|
||||
var ext = path.extname(taskDir);
|
||||
if (ext !== ".js" && ext !== ".module.js") return;
|
||||
|
||||
execLoc = taskDir;
|
||||
}
|
||||
|
||||
var taskOpts = _.merge({
|
||||
filenameRelative: expectLocAlias,
|
||||
sourceFileName: actualLocAlias,
|
||||
@@ -77,6 +94,18 @@ exports.get = function (entryName) {
|
||||
}
|
||||
};
|
||||
|
||||
// traceur checks
|
||||
|
||||
var shouldSkip = function (code) {
|
||||
return code.indexOf("// Error:") >= 0 || code.indexOf("// Skip.") >= 0;
|
||||
};
|
||||
|
||||
if (shouldSkip(test.actual.code) || shouldSkip(test.exec.code)) {
|
||||
return;
|
||||
} else if (test.exec.code.indexOf("// Async.") >= 0) {
|
||||
//test.options.asyncExec = true;
|
||||
}
|
||||
|
||||
suite.tests.push(test);
|
||||
|
||||
var sourceMappingsLoc = taskDir + "/source-mappings.json";
|
||||
@@ -90,7 +119,7 @@ exports.get = function (entryName) {
|
||||
test.options.sourceMap = true;
|
||||
test.sourceMap = require(sourceMap);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return exports.cache[entryName] = suites;
|
||||
@@ -104,4 +133,5 @@ try {
|
||||
var cache = exports.cache = {};
|
||||
cache.transformation = exports.get("transformation");
|
||||
cache.generation = exports.get("generation");
|
||||
cache.esnext = exports.get("esnext");
|
||||
}
|
||||
|
||||
168
test/_transformation-helper.js
Normal file
168
test/_transformation-helper.js
Normal file
@@ -0,0 +1,168 @@
|
||||
var genHelpers = require("./_generator-helpers");
|
||||
var transform = require("../lib/6to5/transformation/transform");
|
||||
var sourceMap = require("source-map");
|
||||
var esvalid = require("esvalid");
|
||||
var Module = require("module");
|
||||
var helper = require("./_helper");
|
||||
var assert = require("assert");
|
||||
var chai = require("chai");
|
||||
var path = require("path");
|
||||
var util = require("../lib/6to5/util");
|
||||
var _ = require("lodash");
|
||||
|
||||
require("../lib/6to5/polyfill");
|
||||
|
||||
global.assertNoOwnProperties = function (obj) {
|
||||
assert.equal(Object.getOwnPropertyNames(obj).length, 0);
|
||||
};
|
||||
|
||||
global.assertArrayEquals = assert.deepEqual;
|
||||
global.assert = chai.assert;
|
||||
global.chai = chai;
|
||||
global.genHelpers = genHelpers;
|
||||
|
||||
// Different Traceur generator message
|
||||
chai.assert._throw = chai.assert.throw;
|
||||
chai.assert.throw = function (fn, msg) {
|
||||
if (msg === '"throw" on executing generator' ||
|
||||
msg === '"next" on executing generator') {
|
||||
msg = "Generator is already running";
|
||||
} else if (msg === "Sent value to newborn generator") {
|
||||
msg = /^attempt to send (.*?) to newborn generator$/;
|
||||
}
|
||||
|
||||
return chai.assert._throw(fn, msg);
|
||||
};
|
||||
|
||||
var run = function (task, done) {
|
||||
var actual = task.actual;
|
||||
var expect = task.expect;
|
||||
var exec = task.exec;
|
||||
var opts = task.options;
|
||||
|
||||
var getOpts = function (self) {
|
||||
return _.merge({
|
||||
filename: self.loc
|
||||
}, opts);
|
||||
};
|
||||
|
||||
var execCode = exec.code;
|
||||
var result;
|
||||
|
||||
var checkAst = function (result) {
|
||||
if (opts.noCheckAst) return;
|
||||
|
||||
var errors = esvalid.errors(result.ast.program);
|
||||
if (errors.length) {
|
||||
var msg = [];
|
||||
_.each(errors, function (err) {
|
||||
msg.push(err.message + " - " + JSON.stringify(err.node));
|
||||
});
|
||||
throw new Error(msg.join(". "));
|
||||
}
|
||||
};
|
||||
|
||||
if (execCode) {
|
||||
result = transform(execCode, getOpts(exec));
|
||||
checkAst(result);
|
||||
execCode = result.code;
|
||||
|
||||
try {
|
||||
var fakeRequire = function (loc) {
|
||||
if (loc === "../../../src/runtime/polyfills/Number.js") {
|
||||
return Number;
|
||||
} else if (loc === "../../../src/runtime/polyfills/Math.js") {
|
||||
return Math;
|
||||
} else {
|
||||
return require(path.resolve(exec.loc, "..", loc));
|
||||
}
|
||||
};
|
||||
|
||||
var fn = new Function("require", "done", execCode);
|
||||
fn.call(global, fakeRequire, chai.assert, done);
|
||||
} catch (err) {
|
||||
err.message = exec.loc + ": " + err.message;
|
||||
err.message += util.codeFrame(execCode);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
var actualCode = actual.code;
|
||||
var expectCode = expect.code;
|
||||
if (!execCode || actualCode) {
|
||||
result = transform(actualCode, getOpts(actual));
|
||||
checkAst(result);
|
||||
actualCode = result.code;
|
||||
|
||||
chai.expect(actualCode).to.be.equal(expectCode, actual.loc + " !== " + expect.loc);
|
||||
}
|
||||
|
||||
if (task.sourceMap) {
|
||||
chai.expect(result.map).to.deep.equal(task.sourceMap);
|
||||
}
|
||||
|
||||
if (task.sourceMappings) {
|
||||
var consumer = new sourceMap.SourceMapConsumer(result.map);
|
||||
|
||||
_.each(task.sourceMappings, function (mapping, i) {
|
||||
var expect = mapping.original;
|
||||
|
||||
var actual = consumer.originalPositionFor(mapping.generated);
|
||||
chai.expect({ line: actual.line, column: actual.column }).to.deep.equal(expect);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = function (suiteOpts, taskOpts, dynamicOpts) {
|
||||
taskOpts = taskOpts || {};
|
||||
|
||||
require("../register")(taskOpts);
|
||||
|
||||
_.each(helper.get(suiteOpts.name, suiteOpts.loc), function (testSuite) {
|
||||
if (_.contains(suiteOpts.ignoreSuites, testSuite.title)) return;
|
||||
|
||||
suite(suiteOpts.name + "/" + testSuite.title, function () {
|
||||
_.each(testSuite.tests, function (task) {
|
||||
if (_.contains(suiteOpts.ignoreTasks, task.title) || _.contains(suiteOpts.ignoreTasks, testSuite.title + "/" + task.title)) return;
|
||||
|
||||
var runTest = function (done) {
|
||||
var runTask = function () {
|
||||
try {
|
||||
run(task, done);
|
||||
} catch (err) {
|
||||
if (task.options.after) task.options.after();
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
|
||||
_.extend(task.options, taskOpts);
|
||||
if (dynamicOpts) dynamicOpts(task.options, task);
|
||||
|
||||
var throwMsg = task.options.throws;
|
||||
if (throwMsg) {
|
||||
// internal api doesn't have this option but it's best not to pollute
|
||||
// the options object with useless options
|
||||
delete task.options.throws;
|
||||
|
||||
assert.throws(runTask, function (err) {
|
||||
return throwMsg === true || err.message.indexOf(throwMsg) >= 0;
|
||||
});
|
||||
} else {
|
||||
runTask();
|
||||
}
|
||||
};
|
||||
|
||||
var callback;
|
||||
if (task.options.asyncExec) {
|
||||
callback = runTest;
|
||||
} else {
|
||||
callback = function () {
|
||||
return runTest();
|
||||
};
|
||||
}
|
||||
|
||||
test(task.title, !task.disabled && callback);
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
@@ -13,10 +13,10 @@ suite("api", function () {
|
||||
assert.ok(!result.ast);
|
||||
});
|
||||
|
||||
test("addDeclaration unknown", function () {
|
||||
test("addHelper unknown", function () {
|
||||
var file = new File;
|
||||
assert.throws(function () {
|
||||
file.addDeclaration("foob");
|
||||
file.addHelper("foob");
|
||||
}, /unknown declaration foob/);
|
||||
});
|
||||
});
|
||||
|
||||
19
test/browserify.js
Normal file
19
test/browserify.js
Normal file
@@ -0,0 +1,19 @@
|
||||
var browserify = require("browserify");
|
||||
var assert = require("assert");
|
||||
var path = require("path");
|
||||
var vm = require("vm");
|
||||
|
||||
suite("browserify", function() {
|
||||
test("6to5/register may be used without breaking browserify", function(done) {
|
||||
var bundler = browserify(path.join(__dirname, "fixtures/browserify/register.js"));
|
||||
|
||||
bundler.bundle(function(err, bundle) {
|
||||
if (err) return done(err);
|
||||
assert.ok(bundle.length, "bundle output code");
|
||||
|
||||
// ensure that the code runs without throwing an exception
|
||||
vm.runInNewContext(bundle, {});
|
||||
done();
|
||||
})
|
||||
})
|
||||
});
|
||||
5
test/esnext.js
Normal file
5
test/esnext.js
Normal file
@@ -0,0 +1,5 @@
|
||||
if (!process.env.ALL_6TO5_TESTS) return;
|
||||
|
||||
require("./_transformation-helper")({
|
||||
name: "esnext"
|
||||
});
|
||||
3
test/fixtures/browserify/register.js
vendored
Normal file
3
test/fixtures/browserify/register.js
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
require("../../../register")({
|
||||
ignore: false
|
||||
});
|
||||
57
test/fixtures/esnext/es6-arrow-functions/arguments-refers-to-parent-function.js
vendored
Normal file
57
test/fixtures/esnext/es6-arrow-functions/arguments-refers-to-parent-function.js
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
function makeMultiplier() {
|
||||
// `arguments` should refer to `makeMultiplier`'s arguments.
|
||||
return (n) => [].slice.call(arguments).reduce((a, b) => a * b) * n;
|
||||
}
|
||||
|
||||
function toArray() {
|
||||
// Intentionally nest arrow functions to ensure `arguments` is put inside
|
||||
// `toArray`'s scope.
|
||||
return (() => (arguments, (() => [].slice.call(arguments)).call())).call();
|
||||
}
|
||||
|
||||
function returnDotArguments(object) {
|
||||
// Ensure `arguments` is not treated as a reference to the magic value.
|
||||
return (() => object.arguments).call();
|
||||
}
|
||||
|
||||
function returnArgumentsObject() {
|
||||
// Ensure `arguments` is not treated as a reference to the magic value.
|
||||
return (() => ({arguments: 1})).call();
|
||||
}
|
||||
|
||||
function makeArgumentsReturner() {
|
||||
return (() => function() {
|
||||
return [].slice.call(arguments);
|
||||
}).call();
|
||||
}
|
||||
|
||||
// i.e. 2 * 3 * 4 == 24, not 16 (4 * 4)
|
||||
assert.equal(
|
||||
makeMultiplier(2, 3)(4),
|
||||
24,
|
||||
'ensure `arguments` is hoisted out to the first non-arrow scope'
|
||||
);
|
||||
|
||||
assert.deepEqual(
|
||||
toArray(1, 2, 3),
|
||||
[1, 2, 3],
|
||||
'ensure `arguments` is hoisted out to the first non-arrow scope'
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
returnDotArguments({arguments: 1}),
|
||||
1,
|
||||
'member accesses with `arguments` property should not be replaced'
|
||||
);
|
||||
|
||||
assert.deepEqual(
|
||||
returnArgumentsObject(),
|
||||
{arguments: 1},
|
||||
'object property keys named `arguments` should not be replaced'
|
||||
);
|
||||
|
||||
assert.deepEqual(
|
||||
makeArgumentsReturner()(1, 2, 3),
|
||||
[1, 2, 3],
|
||||
'arguments should not be hoisted from inside non-arrow functions'
|
||||
);
|
||||
5
test/fixtures/esnext/es6-arrow-functions/does-not-bind-this-from-standard-function.js
vendored
Normal file
5
test/fixtures/esnext/es6-arrow-functions/does-not-bind-this-from-standard-function.js
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
var dynamicThisGetter = () => function () { return this; };
|
||||
assert.equal(
|
||||
'(' + dynamicThisGetter.toString() + ')',
|
||||
'(function () {\n return function () {\n return this;\n };\n})'
|
||||
);
|
||||
2
test/fixtures/esnext/es6-arrow-functions/empty-arrow-function.js
vendored
Normal file
2
test/fixtures/esnext/es6-arrow-functions/empty-arrow-function.js
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
var empty = () => {};
|
||||
assert.equal(empty(), undefined);
|
||||
12
test/fixtures/esnext/es6-arrow-functions/handles-nested-context-bindings.js
vendored
Normal file
12
test/fixtures/esnext/es6-arrow-functions/handles-nested-context-bindings.js
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
var obj = {
|
||||
method: function() {
|
||||
return () => (this, () => this);
|
||||
},
|
||||
|
||||
method2: function() {
|
||||
return () => () => this;
|
||||
}
|
||||
};
|
||||
|
||||
assert.strictEqual(obj.method()()(), obj);
|
||||
assert.strictEqual(obj.method2()()(), obj);
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user