Compare commits
243 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a4e528e2b3 | ||
|
|
99ca9b7e9a | ||
|
|
313e932e7c | ||
|
|
6a57a4e565 | ||
|
|
fc3a5f25fb | ||
|
|
e258b85420 | ||
|
|
6b836de306 | ||
|
|
fe6f53d471 | ||
|
|
3b259c6b1e | ||
|
|
2005df3fa2 | ||
|
|
4fdcf685d3 | ||
|
|
afd3af834d | ||
|
|
8afec8b12a | ||
|
|
f25ed0b5de | ||
|
|
4898770d60 | ||
|
|
bd2fa77446 | ||
|
|
1c2bafe0e1 | ||
|
|
f8915333b0 | ||
|
|
f8275adc6f | ||
|
|
2a97a4233d | ||
|
|
70eae9f6ce | ||
|
|
f560062d82 | ||
|
|
0f55a66f5b | ||
|
|
f14f72b635 | ||
|
|
9aa010d987 | ||
|
|
bd179ace86 | ||
|
|
4df6d6043e | ||
|
|
7ed7475c46 | ||
|
|
b2dc560a2d | ||
|
|
010dbe1cce | ||
|
|
75cd0bab02 | ||
|
|
3283991ed0 | ||
|
|
a66ce5b6ce | ||
|
|
9620f50f22 | ||
|
|
cc049ea851 | ||
|
|
e5a04ae117 | ||
|
|
e07e74f010 | ||
|
|
7b04c501eb | ||
|
|
70349dd4b3 | ||
|
|
2cedc843a8 | ||
|
|
cf40fe3430 | ||
|
|
09ffeed139 | ||
|
|
18f79d6253 | ||
|
|
6f5270f38f | ||
|
|
aac7aac373 | ||
|
|
9361470dc7 | ||
|
|
cf579f4b6e | ||
|
|
2e497eef98 | ||
|
|
7867daaa04 | ||
|
|
eabbcd31ad | ||
|
|
17d198f3d6 | ||
|
|
afd5376c8d | ||
|
|
02a50c9f7e | ||
|
|
df9fa32b82 | ||
|
|
831b420df3 | ||
|
|
123186003c | ||
|
|
ea627ed57c | ||
|
|
157bb48776 | ||
|
|
76a3771943 | ||
|
|
54f8889a30 | ||
|
|
bab159bc08 | ||
|
|
23950963e5 | ||
|
|
d1daac5550 | ||
|
|
d93ece5ccf | ||
|
|
c8c667bf16 | ||
|
|
49cdacbcb4 | ||
|
|
f97bd584f7 | ||
|
|
f1328aa82f | ||
|
|
e298a5d350 | ||
|
|
89a6ef0b26 | ||
|
|
c7ac9b7815 | ||
|
|
55c99b9122 | ||
|
|
545c8c3adb | ||
|
|
d093dc8231 | ||
|
|
eaf9d58b8d | ||
|
|
6131cea5b2 | ||
|
|
ca4831febe | ||
|
|
9cf8d05a19 | ||
|
|
2a4f03330b | ||
|
|
83bc614bad | ||
|
|
99ccb4111a | ||
|
|
f6c72e9ae9 | ||
|
|
a90730d4bf | ||
|
|
29503d2d37 | ||
|
|
35451ed408 | ||
|
|
7167aeb65a | ||
|
|
29d0489443 | ||
|
|
82aa2686f9 | ||
|
|
24616fa08a | ||
|
|
9f3e1eabfd | ||
|
|
286d2f84bd | ||
|
|
7fc484d82e | ||
|
|
ad6ab57fe3 | ||
|
|
348fe045d3 | ||
|
|
980b20316b | ||
|
|
5b52e507ca | ||
|
|
9853c9d78d | ||
|
|
72ec771725 | ||
|
|
75e97d9f7e | ||
|
|
295faf185c | ||
|
|
54b05f33f2 | ||
|
|
1985146760 | ||
|
|
13a52dd300 | ||
|
|
9d4bea70e6 | ||
|
|
421906bcc1 | ||
|
|
508b3531e5 | ||
|
|
c67c407cd0 | ||
|
|
aa552fea0d | ||
|
|
9bbf109dc8 | ||
|
|
393d52088a | ||
|
|
5783973734 | ||
|
|
55e01afd0d | ||
|
|
1231dc6cef | ||
|
|
b08f2061b5 | ||
|
|
1536d3de91 | ||
|
|
fddacb1612 | ||
|
|
9d1ff2b71b | ||
|
|
1c8d24f78c | ||
|
|
b619e843a9 | ||
|
|
e6a71c5849 | ||
|
|
682668c219 | ||
|
|
dd64297838 | ||
|
|
944a9d3908 | ||
|
|
d6922c9b75 | ||
|
|
fb0fcc7138 | ||
|
|
89148e6029 | ||
|
|
28d10b8eb4 | ||
|
|
3509990563 | ||
|
|
c5960fb9f7 | ||
|
|
07131576cf | ||
|
|
e75e778300 | ||
|
|
f6cb14c975 | ||
|
|
af1912ab7a | ||
|
|
8c478f29bc | ||
|
|
5b4d6d7ba9 | ||
|
|
1776b072b0 | ||
|
|
726fad1b6c | ||
|
|
23c16b0094 | ||
|
|
24f70ee4d0 | ||
|
|
fe9b0afd95 | ||
|
|
47695a8710 | ||
|
|
e1c7584280 | ||
|
|
3e63e6cd4b | ||
|
|
ba643680e5 | ||
|
|
611137c7d7 | ||
|
|
6240e5111f | ||
|
|
324a4a1b22 | ||
|
|
035f667a8f | ||
|
|
98985dd253 | ||
|
|
0a207903ce | ||
|
|
90437d262b | ||
|
|
4aba7ec192 | ||
|
|
a924c9c218 | ||
|
|
a2ed0ea9c5 | ||
|
|
c5cd729c3d | ||
|
|
b065d43a6d | ||
|
|
281003c7bd | ||
|
|
6650336c64 | ||
|
|
f904734695 | ||
|
|
0528560d81 | ||
|
|
4362ba93de | ||
|
|
ca12e87370 | ||
|
|
ebaa735adc | ||
|
|
62e406a6fe | ||
|
|
0d45a8975c | ||
|
|
8f64fe2332 | ||
|
|
a8a7587c1f | ||
|
|
7736fa11f2 | ||
|
|
d203924541 | ||
|
|
cd23e500a1 | ||
|
|
bf24a0d6b5 | ||
|
|
279d1affea | ||
|
|
2a1e012240 | ||
|
|
a307a961a6 | ||
|
|
fe5b1dc542 | ||
|
|
f057347ae9 | ||
|
|
98f2287267 | ||
|
|
e60e0e0b0e | ||
|
|
81fb8647b6 | ||
|
|
e8387c7de5 | ||
|
|
655196f3ce | ||
|
|
eef371c3df | ||
|
|
a3d21f02c6 | ||
|
|
ad4386c0ed | ||
|
|
3c82a61af1 | ||
|
|
3c154f9f6d | ||
|
|
22c972e85b | ||
|
|
6d7e14fb2b | ||
|
|
9287449372 | ||
|
|
44a35400f5 | ||
|
|
2305e2447f | ||
|
|
c420d1ffc3 | ||
|
|
fa42b076a7 | ||
|
|
0d23c1cfdb | ||
|
|
0dafdd6969 | ||
|
|
a9af8d39a2 | ||
|
|
1cc606d4d0 | ||
|
|
2a09c0a5a5 | ||
|
|
92359520cd | ||
|
|
50e5bd4680 | ||
|
|
64ef26a937 | ||
|
|
bfd6ffe471 | ||
|
|
8c1760bea2 | ||
|
|
bdb8f87480 | ||
|
|
7f6bc54920 | ||
|
|
b6af2f826d | ||
|
|
7455b6d9b9 | ||
|
|
0d2e876178 | ||
|
|
57ce1b201d | ||
|
|
5f56da457c | ||
|
|
ed988dc2bb | ||
|
|
2c471968ea | ||
|
|
fd1a91bf9c | ||
|
|
9e7de5ad2e | ||
|
|
06927288ba | ||
|
|
9342aee6bd | ||
|
|
4f5669f53c | ||
|
|
262fd995da | ||
|
|
1696f77980 | ||
|
|
dfa51954b8 | ||
|
|
216b8c2fd1 | ||
|
|
ca2cbb02f1 | ||
|
|
b72427cdd0 | ||
|
|
44e9812ad4 | ||
|
|
b7814e5e24 | ||
|
|
ec67a83326 | ||
|
|
6a560cea25 | ||
|
|
46f9ed7d74 | ||
|
|
92366dfc7b | ||
|
|
f520a46175 | ||
|
|
88bec1196b | ||
|
|
ff0098f3f3 | ||
|
|
d01d7722f4 | ||
|
|
abc90778e8 | ||
|
|
56f1683f06 | ||
|
|
520dd7e947 | ||
|
|
17ce21509d | ||
|
|
a4c8895dc3 | ||
|
|
af4009694a | ||
|
|
941a8cc5ea | ||
|
|
359c4e8786 | ||
|
|
7ac98c1532 | ||
|
|
61c3e0a3de |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -10,3 +10,4 @@ test/tmp
|
||||
/runtime.js
|
||||
coverage
|
||||
dist
|
||||
.package.json
|
||||
|
||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -4,3 +4,6 @@
|
||||
[submodule "vendor/regenerator"]
|
||||
path = vendor/regenerator
|
||||
url = https://github.com/facebook/regenerator
|
||||
[submodule "vendor/test262"]
|
||||
path = vendor/test262
|
||||
url = https://github.com/tc39/test262
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
"camelcase": true,
|
||||
"unused": true,
|
||||
"eqnull": true,
|
||||
"proto": true,
|
||||
"newcap": true,
|
||||
"supernew": true,
|
||||
"noyield": true,
|
||||
@@ -14,8 +13,6 @@
|
||||
"boss": true,
|
||||
"expr": true,
|
||||
"undef": true,
|
||||
"loopfunc": true,
|
||||
"white": true,
|
||||
"maxparams": 5,
|
||||
"maxdepth": 4,
|
||||
|
||||
|
||||
@@ -9,3 +9,4 @@ Makefile
|
||||
dist
|
||||
tests.json
|
||||
CHANGELOG.md
|
||||
.package.json
|
||||
|
||||
185
CHANGELOG.md
185
CHANGELOG.md
@@ -7,25 +7,182 @@
|
||||
> - [Breaking Change]
|
||||
> - [Documentation]
|
||||
> - [Internal]
|
||||
> - [Misc]
|
||||
> - [Polish]
|
||||
|
||||
_Note: Gaps between patch versions are faulty/broken releases._
|
||||
|
||||
## 2.12.0
|
||||
|
||||
* **Bug Fix**
|
||||
* Support non-string JSX literals.
|
||||
* **New Feature**
|
||||
* Loose mode for some transformers that enables non-spec behaviour.
|
||||
* **Internal**
|
||||
* Uglify `--mangle sort` has been added to the build script, cutting minified scripts in half.
|
||||
|
||||
## 2.11.4
|
||||
|
||||
* **Internal**
|
||||
* Make all dependency versions fixed.
|
||||
|
||||
## 2.11.3
|
||||
|
||||
* **Bug Fix**
|
||||
* Allow a string to be passed as the `optional` option.
|
||||
|
||||
## 2.11.2
|
||||
|
||||
* **Bug Fix**
|
||||
* Support esprima-style catch clause handlers.
|
||||
* **Polish**
|
||||
* Don't print a stacktrace for syntax errors in the CLI.
|
||||
|
||||
## 2.11.1
|
||||
|
||||
* **Bug Fix**
|
||||
* Remove stray `console.log` outputting debug code.
|
||||
* Remove `Dict` from `coreAliasing`.
|
||||
|
||||
## 2.11.0
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix unnecessary IIFE in default parameters on method calls.
|
||||
* Add support for supers inside of closures.
|
||||
* **New Feature**
|
||||
* Add `--keep-module-id-extensions`/`keepModuleIdExtensions` option to keep extensions in module ids.
|
||||
* **Polish**
|
||||
* Special case single argument spread properties in `super` inside classes.
|
||||
* Don't use a variable declaration for class declaration IFFE.
|
||||
* Rename `inherits` helper parameters.
|
||||
* `coreAliasing` transformer now aliases `Promise`, `Set`, `Map` and more. Thanks [@AluisioASG](https://github.com/AluisioASG).
|
||||
|
||||
## 2.10.1
|
||||
|
||||
* **Internal**
|
||||
* Upgrade `core-js` to `0.4.4`.
|
||||
* **New Feature**
|
||||
* Added `--include-regenerator` option to CLI and `includeRegenerator` option to API that includes the regenerator runtime if necessary.
|
||||
|
||||
## 2.10.0
|
||||
|
||||
* **New Feature**
|
||||
* Add `classesFastSuper` optional transformer that doesn't support parent getters and prototype changing.
|
||||
* Add `forOfFast` transformer that speeds up `for...of` on arrays but produces more code.
|
||||
* Add `--react-compat` to `bin/6to5`.
|
||||
* **Spec Compliancy**
|
||||
* Disallow setters without a single parameter.
|
||||
* Add `configurable` and `writable` to defined properties.
|
||||
* Use define instead of assignment for class methods.
|
||||
* **Polish**
|
||||
* Fix bin name in `6to5-node --help`.
|
||||
* Fix shorthand `--whitelist` name in `bin/6to5`.
|
||||
* **Internal**
|
||||
* Hot code optimisation of traversal etc thanks to [gaearon](https://github.com/gaearon).
|
||||
|
||||
## 2.9.4
|
||||
|
||||
* **Bug Fix**
|
||||
* Support `UpdateExpression`s as `MemberExpression` objects.
|
||||
|
||||
## 2.9.3
|
||||
|
||||
* **Bug Fix**
|
||||
* Remove `exportsWildcard` helper in favor of `defaults`.
|
||||
|
||||
## 2.9.2
|
||||
|
||||
* **Bug Fix**
|
||||
* Pass `exports` to `exportWildcard` helper to allow for use inside the optional runtime.
|
||||
|
||||
## 2.9.1
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix runtime generator breaking the helper inclusion loop.
|
||||
|
||||
## 2.9.0
|
||||
|
||||
* **Internal**
|
||||
* Upgrade `acorn-6to5`.
|
||||
* Now supports destructuring shorthand properties.
|
||||
|
||||
## 2.8.1
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix computed accessors on object literals.
|
||||
|
||||
## 2.8.0
|
||||
|
||||
* **New Feature**
|
||||
* Add `commonStrict`, `amdStrict` and `umdStrict` module formatters that remove `module.exports` interop assignment.
|
||||
* Add `--indent` option to the 6to5 CLI.
|
||||
|
||||
## 2.7.4
|
||||
|
||||
* **Polish**
|
||||
* Inherit assignments from their declaration in destructuring.
|
||||
* Properly align multi-declarator variable declarations.
|
||||
|
||||
## 2.7.3
|
||||
|
||||
* **Polish**
|
||||
* Indent and add newlines to `React.createElement` calls in `react` transformer.
|
||||
* Remove `Object.assign` calls and replace it with an `extends` helper.
|
||||
|
||||
## 2.7.1
|
||||
|
||||
* **New Feature**
|
||||
* Expose `version` on browser and node API.
|
||||
* **Internal**
|
||||
* Upgrade `core-js` to 0.4.1
|
||||
|
||||
## 2.7.0
|
||||
|
||||
* **Spec Compliancy**
|
||||
* Disallow reassignments of imports.
|
||||
* **New Feature**
|
||||
* `reactCompat` option to enable pre-v0.12 react components.
|
||||
|
||||
## 2.6.3
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix 2.6.0 regression caused by faulty export default from a source handling.
|
||||
|
||||
## 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
|
||||
|
||||
* [Internal] Fix incorrect AST node `identifier("this")`.
|
||||
* [Spec Compliancy] Add `interopRequireWildcard` around wildcard imports and exports to handle non-object exports.
|
||||
* [Internal] Upgrade `acorn-6to5`.
|
||||
* [New Feature] Basic destructuring defaults
|
||||
* [New Feature] Add `.es` to list of supported extensions.
|
||||
* [New Feature] Add optional `typeofSymbol` transformer.
|
||||
* [Bug Fix] Better handling of number literal property keys.
|
||||
* [Bug Fix] [Internal] Better `toIdentifier` method that handles reserved words.
|
||||
* [Internal] Upgrade to `core-js` 4.0.0.
|
||||
* [Internal] Upgrade to `regenerator` 0.8.3.
|
||||
* [Bug Fix] Handle `NewExpression` paren insertion edegcases better.
|
||||
* [Spec Compliancy] Class inheritance now has a `function` or `null` type check.
|
||||
* [Misc] Move `"use strict";` to inside module bodies instead of at the top of the file.
|
||||
* **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
|
||||
|
||||
|
||||
43
Makefile
43
Makefile
@@ -1,12 +1,12 @@
|
||||
BROWSERIFY_CMD = node_modules/browserify/bin/cmd.js
|
||||
ISTANBUL_CMD = node_modules/istanbul/lib/cli.js cover
|
||||
UGLIFY_CMD = node_modules/uglify-js/bin/uglifyjs
|
||||
UGLIFY_CMD = node_modules/uglify-js/bin/uglifyjs --mangle sort
|
||||
JSHINT_CMD = node_modules/jshint/bin/jshint
|
||||
MOCHA_CMD = node_modules/mocha/bin/_mocha
|
||||
|
||||
export NODE_ENV = test
|
||||
|
||||
.PHONY: clean test test-cov test-clean lint test-travis test-spec test-browser publish bench build bootstrap
|
||||
.PHONY: clean test test-cov test-clean lint test-travis test-simple test-all test-browser publish build bootstrap publish-core
|
||||
|
||||
build:
|
||||
mkdir -p dist
|
||||
@@ -27,12 +27,8 @@ build:
|
||||
clean:
|
||||
rm -rf coverage templates.json test/tmp dist
|
||||
|
||||
bench:
|
||||
npm install es6-transpiler traceur esnext es6now jstransform
|
||||
node node_modules/matcha/bin/_matcha
|
||||
|
||||
lint:
|
||||
$(JSHINT_CMD) --reporter node_modules/jshint-stylish/stylish.js lib bin benchmark/index.js
|
||||
$(JSHINT_CMD) --reporter node_modules/jshint-stylish/stylish.js lib bin
|
||||
|
||||
test-clean:
|
||||
rm -rf test/tmp
|
||||
@@ -41,14 +37,23 @@ test: lint
|
||||
$(MOCHA_CMD)
|
||||
make test-clean
|
||||
|
||||
test-simple:
|
||||
# excludes test262
|
||||
export SIMPLE_6TO5_TESTS=1
|
||||
make test
|
||||
|
||||
test-all:
|
||||
# includes traceur, esnext, regenerator
|
||||
export ALL_6TO5_TESTS=1
|
||||
make test
|
||||
|
||||
test-cov:
|
||||
export SIMPLE_6TO5_TESTS=1
|
||||
rm -rf coverage
|
||||
node $(ISTANBUL_CMD) $(MOCHA_CMD) --
|
||||
|
||||
test-spec:
|
||||
node $(ISTANBUL_CMD) $(MOCHA_CMD) -- --reporter spec
|
||||
|
||||
test-travis: test-spec
|
||||
test-travis: bootstrap
|
||||
node $(ISTANBUL_CMD) $(MOCHA_CMD) --
|
||||
if test -n "$$CODECLIMATE_REPO_TOKEN"; then codeclimate < coverage/lcov.info; fi
|
||||
|
||||
test-browser:
|
||||
@@ -66,6 +71,9 @@ publish:
|
||||
|
||||
make test
|
||||
|
||||
read -p "Version: " version; \
|
||||
npm version $$version --message "v%s"
|
||||
|
||||
make build
|
||||
cp dist/6to5.min.js browser.js
|
||||
cp dist/polyfill.min.js browser-polyfill.js
|
||||
@@ -74,12 +82,21 @@ publish:
|
||||
node bin/cache-templates
|
||||
test -f templates.json
|
||||
|
||||
read -p "Version: " version; \
|
||||
npm version $$version --message "v%s"
|
||||
npm publish
|
||||
|
||||
git push --follow-tags
|
||||
|
||||
# generate
|
||||
bin/generate-core-package-json >package2.json
|
||||
mv package.json .package.json
|
||||
mv package2.json package.json
|
||||
|
||||
npm publish
|
||||
|
||||
# restore
|
||||
rm -rf package.json
|
||||
mv .package.json package.json
|
||||
|
||||
rm -rf templates.json browser.js runtime.js browser-polyfill.js
|
||||
|
||||
bootstrap:
|
||||
|
||||
12
NOTES.md
12
NOTES.md
@@ -1,3 +1,13 @@
|
||||
# Notes
|
||||
|
||||
* Wildcard exports/imports wont normalise if `export default` is a non-object.
|
||||
* Wildcard exports/imports wont normalise if `export default` is a non-object. See [#224](https://github.com/6to5/6to5/issues/224).
|
||||
|
||||
## 3.0.0 breaking changes
|
||||
|
||||
* Remove `allowImportExportEverywhere` option from acorn.
|
||||
* Remove this shorthand from playground.
|
||||
* Remove `super()` inside non-constructors - add descriptive error message.
|
||||
* Split up ES5 getter/setter transforming and ES6 property methods into separate transformers.
|
||||
* Add autoindentation.
|
||||
* Move `super` transformation from classes into a separate transformer that also supports object expressions.
|
||||
* Prefix all fast transformers with `fast`, make them declare that they're a fast transformer similar to optional transformers and add a `--fast` flag to enable them all.
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||
var obj = {};
|
||||
var foo = "foo";
|
||||
var bar = "bar";
|
||||
|
||||
// constants
|
||||
const MULTIPLIER = 5;
|
||||
|
||||
// classes
|
||||
class Foo {
|
||||
constructor() {
|
||||
this.foo = "bar";
|
||||
}
|
||||
}
|
||||
|
||||
class Bar extends Foo {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
// default parameters
|
||||
go(foo = "bar", bar = "foo") {
|
||||
|
||||
}
|
||||
|
||||
// not supported by jstransform
|
||||
//get foo() {
|
||||
// return this._foo;
|
||||
//}
|
||||
//set foo(val) {
|
||||
// this._foo = val + " foo!";
|
||||
//}
|
||||
}
|
||||
|
||||
// arrow functions
|
||||
arr.map(x => x * x);
|
||||
|
||||
// block binding
|
||||
for (let key in arr) {
|
||||
let val = arr[key];
|
||||
console.log(key, val);
|
||||
}
|
||||
|
||||
// computed property names
|
||||
obj = {
|
||||
["foo" + bar]: "foobar"
|
||||
};
|
||||
|
||||
// destructuring
|
||||
var [a, [b], c, d] = ["hello", [", ", "junk"], ["world"]];
|
||||
console.log(a + b + c);
|
||||
|
||||
// array comprehension
|
||||
// [for (i of [1, 2, 3]) i * i]; // not supported by es6now
|
||||
|
||||
// for-of
|
||||
for (var i of [1, 2, 3]) {
|
||||
console.log(i * i);
|
||||
}
|
||||
|
||||
// property method assignment
|
||||
obj = {
|
||||
foo() {
|
||||
return "foobar";
|
||||
},
|
||||
|
||||
get bar() {
|
||||
return this._bar;
|
||||
},
|
||||
|
||||
set bar(val) {
|
||||
this._bar = val;
|
||||
}
|
||||
};
|
||||
|
||||
// property name shorthand
|
||||
function f(x, y) {
|
||||
return { x, y };
|
||||
}
|
||||
|
||||
// rest parameters
|
||||
function printList(name, ...items) {
|
||||
console.log("list %s has the following items", name);
|
||||
items.forEach(function (item) {
|
||||
console.log(item);
|
||||
});
|
||||
}
|
||||
|
||||
// spread
|
||||
function add(x, y) {
|
||||
return x + y;
|
||||
}
|
||||
var numbers = [5, 10];
|
||||
add(...numbers);
|
||||
|
||||
// template literals
|
||||
var x = 5;
|
||||
var y = 10;
|
||||
console.log(`${x} + ${y} = ${x + y}`);
|
||||
@@ -1,168 +0,0 @@
|
||||
Error.stackTraceLimit = Infinity;
|
||||
|
||||
var jsTrans = require("jstransform");
|
||||
var traceur = require("traceur");
|
||||
//var es6tr = require("es6-transpiler");
|
||||
var es6now = require("es6now");
|
||||
//var esnext = require("esnext");
|
||||
var to5 = require("../lib/6to5");
|
||||
|
||||
//var uglify = require("uglify-js");
|
||||
var matcha = require("matcha");
|
||||
var path = require("path");
|
||||
var fs = require("fs");
|
||||
var _ = require("lodash");
|
||||
|
||||
var readResolve = function (filename) {
|
||||
try {
|
||||
filename = require.resolve(filename);
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
return fs.readFileSync(filename, "utf8");
|
||||
};
|
||||
|
||||
var getVersion = function (name) {
|
||||
return require(name + "/package.json").version;
|
||||
};
|
||||
|
||||
var jsTransVisitors = [];
|
||||
|
||||
_.each([
|
||||
"arrow-function-visitors", "class-visitors", "destructuring-visitors",
|
||||
"object-concise-method-visitors", "object-short-notation-visitors",
|
||||
"rest-param-visitors", "template-visitors"
|
||||
], function (name) {
|
||||
var mod = require("jstransform/visitors/es6-" + name);
|
||||
jsTransVisitors = jsTransVisitors.concat(mod.visitorList);
|
||||
});
|
||||
|
||||
|
||||
var compilers = {
|
||||
"6to5": {
|
||||
version: getVersion(".."),
|
||||
compile: function (code, filename) {
|
||||
return to5.transform(code, { filename: filename }).code;
|
||||
}
|
||||
},
|
||||
|
||||
traceur: {
|
||||
runtime: readResolve("traceur/bin/traceur-runtime.js"),
|
||||
compile: function (code) {
|
||||
return traceur.compile(code, {
|
||||
modules: "commonjs",
|
||||
experimental: true
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/*esnext: {
|
||||
runtime: readResolve("esnext/node_modules/regenerator/runtime.js") || readResolve("regenerator/runtime.js"),
|
||||
compile: function (code) {
|
||||
return esnext.compile(code).code;
|
||||
}
|
||||
},*/
|
||||
|
||||
es6now: {
|
||||
runtime: readResolve("es6now/runtime/ES6.js"),
|
||||
compile: function (code) {
|
||||
return es6now.translate(code);
|
||||
}
|
||||
},
|
||||
|
||||
/*"es6-transpiler": {
|
||||
compile: function (code) {
|
||||
var result = es6tr.run({ src: code });
|
||||
if (result.errors.length) throw new Error(result.join("; "));
|
||||
return result.src;
|
||||
}
|
||||
},*/
|
||||
|
||||
jstransform: {
|
||||
compile: function (code) {
|
||||
return jsTrans.transform(jsTransVisitors, code).code;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// versions
|
||||
|
||||
//var uglifyTitle = "uglify v" + getVersion("uglify-js");
|
||||
|
||||
_.each(compilers, function (compiler, name) {
|
||||
compiler.title = name + " v" + (compiler.version || getVersion(name));
|
||||
});
|
||||
|
||||
//
|
||||
|
||||
var sizeBenchmark = function (code, loc, name, compiler) {
|
||||
var log = function (output, title) {
|
||||
title = [compiler.title].concat(title || []).join(" + ");
|
||||
|
||||
var text;
|
||||
var color;
|
||||
if (output.stack) {
|
||||
text = "error";
|
||||
color = "red";
|
||||
} else {
|
||||
var kilo = (output.length / 1024).toFixed(2);
|
||||
text = kilo + "KB";
|
||||
color = "cyan";
|
||||
}
|
||||
|
||||
text = matcha.utils.color(matcha.utils.padBefore(text, 22), color);
|
||||
|
||||
console.log(text, matcha.utils.color("» " + title, "gray"));
|
||||
|
||||
if (output.stack) {
|
||||
console.error(output.stack);
|
||||
}
|
||||
};
|
||||
|
||||
var go = function (getOutput, title) {
|
||||
var code;
|
||||
try {
|
||||
code = getOutput();
|
||||
} catch (err) {
|
||||
log(err, title);
|
||||
return;
|
||||
}
|
||||
|
||||
log(code, title);
|
||||
};
|
||||
|
||||
var output;
|
||||
go(function () {
|
||||
return output = compiler.compile(code, loc);
|
||||
});
|
||||
if (!output) return;
|
||||
|
||||
//go(function () {
|
||||
// return uglify.minify(output, { fromString: true }).code;
|
||||
//}, uglifyTitle);
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
_.each(fs.readdirSync(__dirname + "/fixtures"), function (name) {
|
||||
var alias = path.basename(name, path.extname(name));
|
||||
|
||||
suite(alias, function () {
|
||||
set("delay", 0);
|
||||
|
||||
var loc = __dirname + "/fixtures/" + name;
|
||||
var code = fs.readFileSync(loc, "utf8");
|
||||
|
||||
before(function () {
|
||||
_.each(compilers, function (compiler, name) {
|
||||
sizeBenchmark(code, loc, name, compiler);
|
||||
});
|
||||
});
|
||||
|
||||
_.each(compilers, function (compiler) {
|
||||
bench(compiler.title, function () {
|
||||
compiler.compile(code, loc);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -15,14 +15,19 @@ commander.option("-e, --experimental", "Enable experimental support for proposed
|
||||
commander.option("-p, --playground", "Enable playground support");
|
||||
|
||||
commander.option("-m, --modules [modules]", "Module formatter type to use [common]", "common");
|
||||
commander.option("-w, --whitelist [whitelist]", "Whitelist of transformers to ONLY use", util.list);
|
||||
commander.option("-l, --whitelist [whitelist]", "Whitelist of transformers to ONLY use", util.list);
|
||||
commander.option("-b, --blacklist [blacklist]", "Blacklist of transformers to NOT use", util.list);
|
||||
commander.option("-i, --optional [list]", "List of optional transformers to enable", util.list);
|
||||
commander.option("--loose [list]", "List of transformers to enable their loose mode", util.list);
|
||||
commander.option("-o, --out-file [out]", "Compile all input files into a single file");
|
||||
commander.option("-d, --out-dir [out]", "Compile an input directory of modules into an output directory");
|
||||
commander.option("-c, --remove-comments", "Remove comments from the compiled code", false);
|
||||
commander.option("-I, --indent [width]", "Indent width [2]", 2);
|
||||
commander.option("-a, --amd-module-ids", "Insert module id in AMD modules", false); // todo: remove in 3.0.0
|
||||
commander.option("-m, --module-ids", "Insert module id in modules", false);
|
||||
commander.option("-R, --react-compat", "Makes the react transformer produce pre-v0.12 code");
|
||||
commander.option("-E, --include-regenerator", "Include the regenerator runtime if necessary", false);
|
||||
commander.option("--keep-module-id-extensions", "Keep extensions when generating module ids", false);
|
||||
|
||||
commander.on("--help", function(){
|
||||
var outKeys = function (title, obj) {
|
||||
@@ -98,17 +103,26 @@ if (errors.length) {
|
||||
//
|
||||
|
||||
exports.opts = {
|
||||
sourceMapName: commander.outFile,
|
||||
experimental: commander.experimental,
|
||||
playground: commander.playground,
|
||||
moduleIds: commander.amdModuleIds || commander.moduleIds,
|
||||
blacklist: commander.blacklist,
|
||||
whitelist: commander.whitelist,
|
||||
sourceMap: commander.sourceMaps || commander.sourceMapsInline,
|
||||
optional: commander.optional,
|
||||
comments: !commander.removeComments,
|
||||
runtime: commander.runtime,
|
||||
modules: commander.modules
|
||||
keepModuleIdExtensions: commander.keepModuleIdExtensions,
|
||||
includeRegenerator: commander.includeRegenerator,
|
||||
sourceMapName: commander.outFile,
|
||||
experimental: commander.experimental,
|
||||
reactCompat: commander.reactCompat,
|
||||
playground: commander.playground,
|
||||
moduleIds: commander.amdModuleIds || commander.moduleIds,
|
||||
blacklist: commander.blacklist,
|
||||
whitelist: commander.whitelist,
|
||||
sourceMap: commander.sourceMaps || commander.sourceMapsInline,
|
||||
optional: commander.optional,
|
||||
comments: !commander.removeComments,
|
||||
runtime: commander.runtime,
|
||||
modules: commander.modules,
|
||||
loose: commander.loose,
|
||||
format: {
|
||||
indent: {
|
||||
style: util.repeat(parseInt(commander.indent))
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var fn;
|
||||
|
||||
@@ -20,7 +20,17 @@ exports.transform = function (filename, code, opts) {
|
||||
opts = _.extend(opts || {}, index.opts);
|
||||
opts.filename = filename;
|
||||
|
||||
var result = to5.transform(code, opts);
|
||||
var result;
|
||||
try {
|
||||
result = to5.transform(code, opts);
|
||||
} catch (e) {
|
||||
if (e instanceof SyntaxError) {
|
||||
console.error("SyntaxError:", e.message);
|
||||
process.exit(1);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
result.filename = filename;
|
||||
result.actual = code;
|
||||
return result;
|
||||
|
||||
@@ -10,29 +10,31 @@ var util = require("../lib/6to5/util");
|
||||
var vm = require("vm");
|
||||
var _ = require("lodash");
|
||||
|
||||
commander.option("-e, --eval [script]", "Evaluate script");
|
||||
commander.option("-p, --print", "Evaluate script and print result");
|
||||
commander.option("-i, --ignore [regex]", "Ignore all files that match this regex when using the require hook");
|
||||
commander.option("-x, --extensions [extensions]", "List of extensions to hook into [.es6,.js]");
|
||||
commander.option("-r, --experimental", "Enable experimental support for proposed ES7 features");
|
||||
commander.option("-g, --playground", "Enable playground support");
|
||||
commander.option("-c, --cache", "Cache compiled files and require paths");
|
||||
var program = new commander.Command("6to5-node");
|
||||
|
||||
program.option("-e, --eval [script]", "Evaluate script");
|
||||
program.option("-p, --print", "Evaluate script and print result");
|
||||
program.option("-i, --ignore [regex]", "Ignore all files that match this regex when using the require hook");
|
||||
program.option("-x, --extensions [extensions]", "List of extensions to hook into [.es6,.js]");
|
||||
program.option("-r, --experimental", "Enable experimental support for proposed ES7 features");
|
||||
program.option("-g, --playground", "Enable playground support");
|
||||
program.option("-c, --cache", "Cache compiled files and require paths");
|
||||
|
||||
var pkg = require("../package.json");
|
||||
commander.version(pkg.version);
|
||||
commander.usage("[options] [ -e script | script.js ] [arguments]");
|
||||
commander.parse(process.argv);
|
||||
program.version(pkg.version);
|
||||
program.usage("[options] [ -e script | script.js ] [arguments]");
|
||||
program.parse(process.argv);
|
||||
|
||||
if (commander.cache) roadrunner.load();
|
||||
if (program.cache) roadrunner.load();
|
||||
|
||||
//
|
||||
|
||||
to5.register({
|
||||
experimental: commander.experimental,
|
||||
extensions: commander.extensions,
|
||||
playground: commander.playground,
|
||||
ignore: commander.ignore,
|
||||
cache: commander.cache && roadrunner.get("6to5")
|
||||
experimental: program.experimental,
|
||||
extensions: program.extensions,
|
||||
playground: program.playground,
|
||||
ignore: program.ignore,
|
||||
cache: program.cache && roadrunner.get("6to5")
|
||||
});
|
||||
|
||||
//
|
||||
@@ -41,17 +43,17 @@ var _eval = function (code, filename) {
|
||||
code = to5.transform(code, {
|
||||
filename: filename,
|
||||
blacklist: ["useStrict"],
|
||||
experimental: commander.experimental,
|
||||
playground: commander.playground
|
||||
experimental: program.experimental,
|
||||
playground: program.playground
|
||||
}).code;
|
||||
return vm.runInThisContext(code, filename);
|
||||
};
|
||||
|
||||
if (commander.eval) {
|
||||
var result = _eval(commander.eval, "eval");
|
||||
if (commander.print) console.log(result);
|
||||
if (program.eval) {
|
||||
var result = _eval(program.eval, "eval");
|
||||
if (program.print) console.log(result);
|
||||
} else {
|
||||
if (commander.args.length) {
|
||||
if (program.args.length) {
|
||||
// slice all arguments up to the first filename since they're 6to5 args that we handle
|
||||
var args = process.argv.slice(2);
|
||||
|
||||
@@ -77,7 +79,7 @@ if (commander.eval) {
|
||||
}
|
||||
}
|
||||
|
||||
if (commander.cache) roadrunner.save();
|
||||
if (program.cache) roadrunner.save();
|
||||
|
||||
function replStart() {
|
||||
repl.start({
|
||||
|
||||
11
bin/generate-core-package-json
Executable file
11
bin/generate-core-package-json
Executable file
@@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
var pkg = require("../package.json");
|
||||
pkg.name += "-core";
|
||||
delete pkg.dependencies.chokidar;
|
||||
delete pkg.optionalDependencies;
|
||||
delete pkg.devDependencies;
|
||||
delete pkg.preferGlobal;
|
||||
delete pkg.scripts;
|
||||
delete pkg.bin;
|
||||
console.log(JSON.stringify(pkg, null, " "));
|
||||
@@ -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,62 +0,0 @@
|
||||
# Caveats
|
||||
|
||||
In order for certain features to work they require certain polyfills. You can
|
||||
satisfy **all** 6to5 feature requirements by using the included
|
||||
[polyfill](polyfill.md).
|
||||
|
||||
You may alternatively selectively include what you need:
|
||||
|
||||
| Feature | Requirements |
|
||||
| --------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
|
||||
| Abstract References | [experimental](experimental.md), `Symbol` |
|
||||
| Array destructuring | `Array.from` |
|
||||
| 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
|
||||
functions. So if you're using an environment that has limited or no support for
|
||||
ES5 such as lower versions of IE then using the
|
||||
[es5-shim](https://github.com/es-shims/es5-shim) along with the
|
||||
[6to5 polyfill](polyfill.md) will add support for these methods.
|
||||
|
||||
## Internet Explorer
|
||||
|
||||
### Classes (10 and below)
|
||||
|
||||
If you're inheriting from a class then static properties are inherited from it
|
||||
via [\_\_proto\_\_](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto),
|
||||
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();`:
|
||||
|
||||
```javascript
|
||||
class Foo {
|
||||
static foo() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class Bar extends Foo {
|
||||
static foo() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 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
|
||||
you plan on supporting IE8 or below then the user of getters and setters
|
||||
isn't recommended.
|
||||
|
||||
**Reference**: [MDN](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty#Internet_Explorer_8_specific_notes).
|
||||
@@ -1,137 +0,0 @@
|
||||
# Differences
|
||||
|
||||
There are three main points that separate 6to5 from all other transpilers.
|
||||
|
||||
### Readable code
|
||||
|
||||
The fundamental concept behind 6to5 is that the generated code must be close as
|
||||
possible to the original, retaining all the same formatting and readability.
|
||||
|
||||
Many other transpilers are just concerned with making the code work while 6to5
|
||||
is concerned with making sure it works **and** is readable at the same time.
|
||||
|
||||
For example, given the following array comprehension:
|
||||
|
||||
```javascript
|
||||
var seattlers = [for (c of customers) if (c.city == "Seattle") { name: c.name, age: c.age }];
|
||||
```
|
||||
|
||||
is generated to the following with 6to5:
|
||||
|
||||
```javascript
|
||||
var seattlers = Array.from(customers).filter(function (c) {
|
||||
return c.city == "Seattle";
|
||||
}).map(function (c) {
|
||||
return {
|
||||
name: c.name,
|
||||
age: c.age
|
||||
};
|
||||
});
|
||||
```
|
||||
|
||||
The following is what Traceur generates:
|
||||
|
||||
```javascript
|
||||
var seattlers = (function() {
|
||||
var c;
|
||||
var $__20 = 0,
|
||||
$__21 = [];
|
||||
for (var $__22 = customers[$traceurRuntime.toProperty(Symbol.iterator)](),
|
||||
$__23; !($__23 = $__22.next()).done; ) {
|
||||
c = $__23.value;
|
||||
if (c.city == "Seattle")
|
||||
$traceurRuntime.setProperty($__21, $__20++, {
|
||||
name: c.name,
|
||||
age: c.age
|
||||
});
|
||||
}
|
||||
return $__21;
|
||||
}());
|
||||
```
|
||||
|
||||
As you can tell, it's not very pretty. 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
|
||||
bother you then you can use the [optional runtime](optional-runtime.md).
|
||||
We promise that these inline functions will never be significant and will
|
||||
always be used as little as possible.
|
||||
|
||||
### Static analysis
|
||||
|
||||
6to5 uses a lot of static analysis to simplify code as much as possible.
|
||||
Not many other transpilers do this, and those that do don't do it nearly
|
||||
as much as 6to5. This process is pretty intensive but it leads to higher
|
||||
quality code.
|
||||
|
||||
### Spec compliancy
|
||||
|
||||
6to5 prides itself on
|
||||
[spec compliancy](https://kangax.github.io/compat-table/es6/). We have
|
||||
excellent support for edgecases, something that many other transpilers
|
||||
suffer from, including Traceur. When you use 6to5 you can be confident
|
||||
that when you turn it off and use your code in a full ES6 environment
|
||||
**it'll just work**.
|
||||
|
||||
## Comparison to other transpilers
|
||||
|
||||
### Features
|
||||
|
||||
| | 6to5 | Traceur | es6-transpiler | es6now | jstransform |
|
||||
| ---------------------------- | ---- | ------- | -------------- | ------ | ----------- |
|
||||
| Source maps | ✓ | ✓ | ✓ | | ✓ |
|
||||
| No compiler global pollution | ✓ | | ✓ | | ✓ |
|
||||
| Optional runtime | ✓ | | ✓ | | ✓ |
|
||||
| Browser compiler | ✓ | ✓ | | | |
|
||||
|
||||
### Language Support
|
||||
|
||||
| | 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)
|
||||
|
||||
Traceur requires quite a bulky runtime (~75KB) and produces quite verbose code.
|
||||
While this can be trimmed down by selectively building the runtime, it's an
|
||||
unnecessary step when a large runtime can be eliminated entirely.
|
||||
|
||||
### [es6now](https://github.com/zenparsing/es6now)
|
||||
|
||||
es6now doesn't output sourcemaps. This is cited as a positive as line-to-line
|
||||
mapping is the goal. This however obviously doesn't retain column mapping
|
||||
resulting in the output code not being very pleasant.
|
||||
|
||||
### [es6-transpiler](https://github.com/termi/es6-transpiler)
|
||||
|
||||
The es6-transpiler compiler requires shims to operate which pollutes the global
|
||||
scope resulting in possible collisions.
|
||||
|
||||
es6-transpiler maps line-by-line, just like es6now, this results in the same
|
||||
issues such as lack of column information and unpleasant code output.
|
||||
@@ -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]);
|
||||
```
|
||||
63
doc/index.md
63
doc/index.md
@@ -1,62 +1 @@
|
||||
**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)
|
||||
See [6to5.github.io/docs](https://github.com/6to5/6to5.github.io/tree/master/docs).
|
||||
|
||||
257
doc/modules.md
257
doc/modules.md
@@ -1,257 +0,0 @@
|
||||
# Modules
|
||||
|
||||
## Usage
|
||||
|
||||
### CLI
|
||||
|
||||
```sh
|
||||
$ 6to5 --modules common script.js
|
||||
```
|
||||
|
||||
### Node
|
||||
|
||||
```javascript
|
||||
var to5 = require("6to5");
|
||||
to5.transform('import "foo";', { modules: "common" });
|
||||
```
|
||||
|
||||
## Formats
|
||||
|
||||
* [AMD](#amd)
|
||||
* [Common (Default)](#common-default)
|
||||
* [Ignore](#ignore)
|
||||
* [System](#system)
|
||||
* [UMD](#umd)
|
||||
|
||||
### Common
|
||||
|
||||
```sh
|
||||
$ 6to5 --modules common
|
||||
```
|
||||
|
||||
**In**
|
||||
|
||||
```javascript
|
||||
export default test;
|
||||
|
||||
export {test};
|
||||
export var test = 5;
|
||||
|
||||
import "foo";
|
||||
|
||||
import foo from "foo";
|
||||
import * as foo from "foo";
|
||||
|
||||
import {bar} from "foo";
|
||||
import {foo as bar} from "foo";
|
||||
```
|
||||
|
||||
**Out**
|
||||
|
||||
```javascript
|
||||
"use strict";
|
||||
|
||||
var _interopRequire = function (obj) {
|
||||
return obj && (obj["default"] || obj);
|
||||
};
|
||||
|
||||
exports = module.exports = test;
|
||||
|
||||
exports.test = test;
|
||||
var test = exports.test = 5;
|
||||
|
||||
require("foo");
|
||||
|
||||
var foo = _interopRequire(require("foo"));
|
||||
|
||||
var foo = require("foo");
|
||||
|
||||
var bar = require("foo").bar;
|
||||
var bar = require("foo").foo;
|
||||
```
|
||||
|
||||
### AMD
|
||||
|
||||
```sh
|
||||
$ 6to5 --modules amd
|
||||
```
|
||||
|
||||
**In**
|
||||
|
||||
```javascript
|
||||
import foo from "foo";
|
||||
|
||||
export function bar() {
|
||||
return foo("foobar");
|
||||
}
|
||||
```
|
||||
|
||||
**Out**
|
||||
|
||||
```javascript
|
||||
define(["exports", "foo"], function (exports, _foo) {
|
||||
"use strict";
|
||||
|
||||
var _interopRequire = function (obj) {
|
||||
return obj && (obj["default"] || obj);
|
||||
};
|
||||
|
||||
exports.bar = bar;
|
||||
var foo = _interopRequire(_foo);
|
||||
|
||||
function bar() {
|
||||
return foo("foobar");
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
You can optionally specify to include the module id (using the `--amd-module-id` argument):
|
||||
|
||||
```javascript
|
||||
define("filename", ["exports", "foo"], function (exports, _foo) {})
|
||||
```
|
||||
|
||||
### UMD
|
||||
|
||||
```sh
|
||||
$ 6to5 --modules umd
|
||||
```
|
||||
|
||||
**In**
|
||||
|
||||
```javascript
|
||||
import foo from "foo";
|
||||
|
||||
export function bar() {
|
||||
return foo("foobar");
|
||||
}
|
||||
```
|
||||
|
||||
**Out**
|
||||
|
||||
```javascript
|
||||
(function (factory) {
|
||||
if (typeof define === "function" && define.amd) {
|
||||
define(["exports", "foo"], factory);
|
||||
} else if (typeof exports !== "undefined") {
|
||||
factory(exports, require("foo"));
|
||||
}
|
||||
})(function (exports, _foo) {
|
||||
"use strict";
|
||||
|
||||
var _interopRequire = function (obj) {
|
||||
return obj && (obj["default"] || obj);
|
||||
};
|
||||
|
||||
exports.bar = bar;
|
||||
var foo = _interopRequire(_foo);
|
||||
|
||||
function bar() {
|
||||
return foo("foobar");
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### Ignore
|
||||
|
||||
```sh
|
||||
$ 6to5 --modules ignore
|
||||
```
|
||||
|
||||
**In**
|
||||
|
||||
```javascript
|
||||
import foo from "foo";
|
||||
|
||||
export function bar() {
|
||||
return foo("foobar");
|
||||
}
|
||||
```
|
||||
|
||||
**Out**
|
||||
|
||||
```javascript
|
||||
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
|
||||
|
||||
You can alternatively specify module names instead of one of the built-in types.
|
||||
|
||||
```sh
|
||||
$ 6to5 --modules custom-module-formatter
|
||||
```
|
||||
|
||||
**node_modules/custom-module-formatter/index.js**
|
||||
|
||||
```javascript
|
||||
module.exports = ModuleFormatter;
|
||||
|
||||
function ModuleFormatter() {
|
||||
|
||||
}
|
||||
|
||||
ModuleFormatter.prototype.transform = function (ast) {
|
||||
// this is ran after all transformers have had their turn at modifying the ast
|
||||
// feel free to modify this however
|
||||
};
|
||||
|
||||
ModuleFormatter.prototype.importDeclaration = function (node, nodes) {
|
||||
// node is an ImportDeclaration
|
||||
};
|
||||
|
||||
ModuleFormatter.prototype.importSpecifier = function (specifier, node, nodes) {
|
||||
// specifier is an ImportSpecifier
|
||||
// node is an ImportDeclaration
|
||||
};
|
||||
|
||||
ModuleFormatter.prototype.exportDeclaration = function (node, nodes) {
|
||||
// node is an ExportDeclaration
|
||||
};
|
||||
|
||||
ModuleFormatter.prototype.exportSpecifier = function (specifier, node, nodes) {
|
||||
// specifier is an ExportSpecifier
|
||||
// node is an ExportDeclaration
|
||||
};
|
||||
```
|
||||
@@ -1,57 +0,0 @@
|
||||
# Optional runtime
|
||||
|
||||
6to5 has a few helper functions that'll be placed at the top of the generated
|
||||
code if needed so it's not inlined multiple times throughout that file. This may
|
||||
become an issue if you have multiple files, especially when you're sending them
|
||||
to the browser. gzip alleviates most of this concern but it's still not ideal.
|
||||
|
||||
You can tell 6to5 to not place any declarations at the top of your files and
|
||||
instead just point them to a reference contained within the runtime.
|
||||
|
||||
Simply use the following option if you're using the [Node API](usage.md#node):
|
||||
|
||||
```javascript
|
||||
{
|
||||
runtime: true
|
||||
}
|
||||
```
|
||||
|
||||
or the following flag if you're using the [CLI](usage.md#cli):
|
||||
|
||||
```ssh
|
||||
$ 6to5 --runtime
|
||||
```
|
||||
|
||||
Then just include the runtime before your generated code.
|
||||
|
||||
## Getting the runtime
|
||||
|
||||
You can get the runtime via either:
|
||||
|
||||
```sh
|
||||
$ 6to5-runtime
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```javascript
|
||||
require("6to5").runtime();
|
||||
```
|
||||
|
||||
or from an npm release in `runtime.js` from the 6to5 directory.
|
||||
|
||||
## Customising namespace
|
||||
|
||||
You can also customise the runtime namespace by passing an optional namespace
|
||||
argument:
|
||||
|
||||
```javascript
|
||||
require("6to5").runtime("myCustomNamespace");
|
||||
```
|
||||
|
||||
```sh
|
||||
$ 6to5-runtime myCustomNamespace
|
||||
```
|
||||
|
||||
See [Options - runtime](usage.md#options) for documentation on changing the
|
||||
reference in generated code.
|
||||
@@ -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
|
||||
```
|
||||
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`, `.es` 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
|
||||
});
|
||||
```
|
||||
@@ -1,5 +1,7 @@
|
||||
var transform = module.exports = require("./transformation/transform");
|
||||
|
||||
transform.version = require("../../package").version;
|
||||
|
||||
transform.transform = transform;
|
||||
|
||||
transform.run = function (code, opts) {
|
||||
|
||||
@@ -24,6 +24,7 @@ File.helpers = [
|
||||
"prototype-properties",
|
||||
"apply-constructor",
|
||||
"tagged-template-literal",
|
||||
"tagged-template-literal-loose",
|
||||
"interop-require",
|
||||
"to-array",
|
||||
"sliced-to-array",
|
||||
@@ -35,32 +36,38 @@ File.helpers = [
|
||||
"async-to-generator",
|
||||
"interop-require-wildcard",
|
||||
"typeof",
|
||||
"exports-wildcard"
|
||||
"extends",
|
||||
"get"
|
||||
];
|
||||
|
||||
File.excludeHelpersFromRuntime = [
|
||||
"async-to-generator",
|
||||
"typeof"
|
||||
"typeof",
|
||||
"tagged-template-literal-loose"
|
||||
];
|
||||
|
||||
File.normaliseOptions = function (opts) {
|
||||
opts = _.cloneDeep(opts || {});
|
||||
|
||||
_.defaults(opts, {
|
||||
experimental: false,
|
||||
playground: false,
|
||||
whitespace: true,
|
||||
moduleIds: opts.amdModuleIds || false,
|
||||
blacklist: [],
|
||||
whitelist: [],
|
||||
sourceMap: false,
|
||||
optional: [],
|
||||
comments: true,
|
||||
filename: "unknown",
|
||||
modules: "common",
|
||||
runtime: false,
|
||||
code: true,
|
||||
ast: true
|
||||
keepModuleIdExtensions: false,
|
||||
includeRegenerator: false,
|
||||
experimental: false,
|
||||
reactCompat: false,
|
||||
playground: false,
|
||||
whitespace: true,
|
||||
moduleIds: opts.amdModuleIds || false,
|
||||
blacklist: [],
|
||||
whitelist: [],
|
||||
sourceMap: false,
|
||||
optional: [],
|
||||
comments: true,
|
||||
filename: "unknown",
|
||||
modules: "common",
|
||||
runtime: false,
|
||||
loose: [],
|
||||
code: true,
|
||||
ast: true
|
||||
});
|
||||
|
||||
// normalise windows path separators to unix
|
||||
@@ -68,6 +75,19 @@ File.normaliseOptions = function (opts) {
|
||||
|
||||
opts.blacklist = util.arrayify(opts.blacklist);
|
||||
opts.whitelist = util.arrayify(opts.whitelist);
|
||||
opts.optional = util.arrayify(opts.optional);
|
||||
opts.loose = util.arrayify(opts.loose);
|
||||
|
||||
// todo: remove in 3.0.0
|
||||
_.each({
|
||||
fastForOf: "forOf",
|
||||
classesFastSuper: "classes"
|
||||
}, function (newTransformer, oldTransformer) {
|
||||
if (_.contains(opts.optional, oldTransformer)) {
|
||||
_.pull(opts.optional, oldTransformer);
|
||||
opts.loose.push(newTransformer);
|
||||
}
|
||||
});
|
||||
|
||||
_.defaults(opts, {
|
||||
moduleRoot: opts.sourceRoot
|
||||
@@ -97,10 +117,15 @@ File.normaliseOptions = function (opts) {
|
||||
transform._ensureTransformerNames("blacklist", opts.blacklist);
|
||||
transform._ensureTransformerNames("whitelist", opts.whitelist);
|
||||
transform._ensureTransformerNames("optional", opts.optional);
|
||||
transform._ensureTransformerNames("loose", opts.loose);
|
||||
|
||||
return opts;
|
||||
};
|
||||
|
||||
File.prototype.isLoose = function (key) {
|
||||
return _.contains(this.opts.loose, key);
|
||||
};
|
||||
|
||||
File.prototype.getTransformers = function () {
|
||||
var file = this;
|
||||
var transformers = [];
|
||||
|
||||
@@ -61,7 +61,7 @@ Buffer.prototype.space = function () {
|
||||
Buffer.prototype.removeLast = function (cha) {
|
||||
if (!this.isLast(cha)) return;
|
||||
|
||||
this.buf = this.buf.slice(0, -1);
|
||||
this.buf = this.buf.substr(0, this.buf.length - 1);
|
||||
this.position.unshift(cha);
|
||||
};
|
||||
|
||||
@@ -77,10 +77,9 @@ Buffer.prototype.newline = function (i, removeLast) {
|
||||
if (this.endsWith("{\n")) i--;
|
||||
if (this.endsWith(util.repeat(i, "\n"))) return;
|
||||
|
||||
var self = this;
|
||||
_.times(i, function () {
|
||||
self.newline(null, removeLast);
|
||||
});
|
||||
for (var j = 0; j < i; j++) {
|
||||
this.newline(null, removeLast);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -115,13 +114,18 @@ Buffer.prototype._push = function (str) {
|
||||
};
|
||||
|
||||
Buffer.prototype.endsWith = function (str) {
|
||||
return this.buf.slice(-str.length) === str;
|
||||
var d = this.buf.length - str.length;
|
||||
return d >= 0 && this.buf.lastIndexOf(str) === d;
|
||||
};
|
||||
|
||||
Buffer.prototype.isLast = function (cha, trimRight) {
|
||||
var buf = this.buf;
|
||||
if (trimRight) buf = util.trimRight(buf);
|
||||
var last = buf[buf.length - 1];
|
||||
|
||||
var chars = [].concat(cha);
|
||||
return _.contains(chars, _.last(buf));
|
||||
if (Array.isArray(cha)) {
|
||||
return _.contains(cha, last);
|
||||
} else {
|
||||
return cha === last;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -125,7 +125,7 @@ CodeGenerator.prototype.print = function (node, parent, opts) {
|
||||
|
||||
var lines = 0;
|
||||
|
||||
if (node.start != null) {
|
||||
if (node.start != null && !node._ignoreUserWhitespace) {
|
||||
// user node
|
||||
if (leading) {
|
||||
lines = self.whitespace.getNewlinesBefore(node);
|
||||
|
||||
@@ -57,8 +57,28 @@ exports.ThisExpression = function () {
|
||||
|
||||
exports.CallExpression = function (node, print) {
|
||||
print(node.callee);
|
||||
|
||||
this.push("(");
|
||||
print.join(node.arguments, { separator: ", " });
|
||||
|
||||
var separator = ",";
|
||||
|
||||
if (node._prettyCall) {
|
||||
separator += "\n";
|
||||
this.newline();
|
||||
this.indent();
|
||||
} else {
|
||||
separator += " ";
|
||||
}
|
||||
|
||||
print.join(node.arguments, {
|
||||
separator: separator
|
||||
});
|
||||
|
||||
if (node._prettyCall) {
|
||||
this.newline();
|
||||
this.dedent();
|
||||
}
|
||||
|
||||
this.push(")");
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
var t = require("../../types");
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
|
||||
exports.WithStatement = function (node, print) {
|
||||
this.keyword("with");
|
||||
@@ -106,7 +107,16 @@ exports.TryStatement = function (node, print) {
|
||||
this.keyword("try");
|
||||
print(node.block);
|
||||
this.space();
|
||||
print(node.handler);
|
||||
|
||||
// Esprima bug puts the catch clause in a `handlers` array.
|
||||
// see https://code.google.com/p/esprima/issues/detail?id=433
|
||||
// We run into this from regenerator generated ast.
|
||||
if (node.handlers) {
|
||||
print(node.handlers[0]);
|
||||
} else {
|
||||
print(node.handler);
|
||||
}
|
||||
|
||||
if (node.finalizer) {
|
||||
this.space();
|
||||
this.push("finally ");
|
||||
@@ -157,7 +167,24 @@ exports.DebuggerStatement = function () {
|
||||
exports.VariableDeclaration = function (node, print, parent) {
|
||||
this.push(node.kind + " ");
|
||||
|
||||
print.join(node.declarations, { separator: ", " });
|
||||
var inits = 0;
|
||||
var noInits = 0;
|
||||
for (var i in node.declarations) {
|
||||
if (node.declarations[i].init) {
|
||||
inits++;
|
||||
} else {
|
||||
noInits++;
|
||||
}
|
||||
}
|
||||
|
||||
var sep = ",";
|
||||
if (inits > noInits) { // more inits than noinits
|
||||
sep += "\n" + util.repeat(node.kind.length + 1);
|
||||
} else {
|
||||
sep += " ";
|
||||
}
|
||||
|
||||
print.join(node.declarations, { separator: sep });
|
||||
|
||||
if (!t.isFor(parent)) {
|
||||
this.semicolon();
|
||||
|
||||
@@ -6,14 +6,19 @@ var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
var find = function (obj, node, parent) {
|
||||
if (!obj) return;
|
||||
var result;
|
||||
|
||||
_.each(obj, function (fn, type) {
|
||||
var types = Object.keys(obj);
|
||||
for (var i = 0; i < types.length; i++) {
|
||||
var type = types[i];
|
||||
|
||||
if (t["is" + type](node)) {
|
||||
var fn = obj[type];
|
||||
result = fn(node, parent);
|
||||
if (result != null) return false;
|
||||
if (result != null) break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
@@ -99,7 +104,13 @@ _.each(Node.prototype, function (fn, key) {
|
||||
Node[key] = function (node, parent) {
|
||||
var n = new Node(node, parent);
|
||||
|
||||
var args = _.toArray(arguments).slice(2);
|
||||
// Avoid leaking arguments to prevent deoptimization
|
||||
var skipCount = 2;
|
||||
var args = new Array(arguments.length - skipCount);
|
||||
for (var i = 0; i < args.length; i++) {
|
||||
args[i] = arguments[i + 2];
|
||||
}
|
||||
|
||||
return n[key].apply(n, args);
|
||||
};
|
||||
});
|
||||
|
||||
@@ -21,6 +21,13 @@ _.each([
|
||||
});
|
||||
});
|
||||
|
||||
exports.UpdateExpression = function (node, parent) {
|
||||
if (t.isMemberExpression(parent) && parent.object === node) {
|
||||
// (foo++).test()
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
exports.ObjectExpression = function (node, parent) {
|
||||
if (t.isExpressionStatement(parent)) {
|
||||
// ({ foo: "bar" });
|
||||
|
||||
@@ -62,11 +62,15 @@ _.each({
|
||||
CallExpression: { after: 1 },
|
||||
Literal: { after: 1 }
|
||||
}, function (amounts, type) {
|
||||
if (_.isNumber(amounts)) amounts = { after: amounts, before: amounts };
|
||||
if (_.isNumber(amounts)) {
|
||||
amounts = { after: amounts, before: amounts };
|
||||
}
|
||||
|
||||
_.each(amounts, function (amount, key) {
|
||||
exports[key].nodes[type] = function () {
|
||||
return amount;
|
||||
};
|
||||
_.each([type].concat(t.FLIPPED_ALIAS_KEYS[type] || []), function (type) {
|
||||
_.each(amounts, function (amount, key) {
|
||||
exports[key].nodes[type] = function () {
|
||||
return amount;
|
||||
};
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,33 +1,27 @@
|
||||
module.exports = Position;
|
||||
|
||||
var _ = require("lodash");
|
||||
|
||||
function Position() {
|
||||
this.line = 1;
|
||||
this.column = 0;
|
||||
}
|
||||
|
||||
Position.prototype.push = function (str) {
|
||||
var self = this;
|
||||
|
||||
_.each(str, function (cha) {
|
||||
if (cha === "\n") {
|
||||
self.line++;
|
||||
self.column = 0;
|
||||
for (var i = 0; i < str.length; i++) {
|
||||
if (str[i] === "\n") {
|
||||
this.line++;
|
||||
this.column = 0;
|
||||
} else {
|
||||
self.column++;
|
||||
this.column++;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Position.prototype.unshift = function (str) {
|
||||
var self = this;
|
||||
|
||||
_.each(str, function (cha) {
|
||||
if (cha === "\n") {
|
||||
self.line--;
|
||||
for (var i = 0; i < str.length; i++) {
|
||||
if (str[i] === "\n") {
|
||||
this.line--;
|
||||
} else {
|
||||
self.column--;
|
||||
this.column--;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -11,15 +11,18 @@ Whitespace.prototype.getNewlinesBefore = function (node) {
|
||||
var startToken;
|
||||
var endToken;
|
||||
var tokens = this.tokens;
|
||||
var token;
|
||||
|
||||
for (var i = 0; i < tokens.length; i++) {
|
||||
token = tokens[i];
|
||||
|
||||
_.each(tokens, function (token, i) {
|
||||
// this is the token this node starts with
|
||||
if (node.start === token.start) {
|
||||
startToken = tokens[i - 1];
|
||||
endToken = token;
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return this.getNewlinesBetween(startToken, endToken);
|
||||
};
|
||||
@@ -28,20 +31,29 @@ Whitespace.prototype.getNewlinesAfter = function (node) {
|
||||
var startToken;
|
||||
var endToken;
|
||||
var tokens = this.tokens;
|
||||
var token;
|
||||
|
||||
for (var i = 0; i < tokens.length; i++) {
|
||||
token = tokens[i];
|
||||
|
||||
_.each(tokens, function (token, i) {
|
||||
// this is the token this node ends with
|
||||
if (node.end === token.end) {
|
||||
startToken = token;
|
||||
endToken = tokens[i + 1];
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (endToken.type.type === "eof") {
|
||||
return 1;
|
||||
} else {
|
||||
return this.getNewlinesBetween(startToken, endToken);
|
||||
var lines = this.getNewlinesBetween(startToken, endToken);
|
||||
if (node.type === "Line" && !lines) {
|
||||
// line comment
|
||||
return 1;
|
||||
} else {
|
||||
return lines;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ var util = require("./util");
|
||||
var fs = require("fs");
|
||||
var _ = require("lodash");
|
||||
|
||||
exports.version = require("../../package").version;
|
||||
|
||||
exports.types = require("./types");
|
||||
|
||||
exports.runtime = require("./runtime-generator");
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// Required to safely use 6to5/register within a browserify codebase.
|
||||
// required to safely use 6to5/register within a browserify codebase
|
||||
|
||||
module.exports = function () {};
|
||||
|
||||
require("./polyfill");
|
||||
|
||||
@@ -20,7 +20,7 @@ module.exports = function (namespace) {
|
||||
|
||||
_.each(File.helpers, function (name) {
|
||||
if (_.contains(File.excludeHelpersFromRuntime, name)) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
var key = t.identifier(t.toIdentifier(name));
|
||||
|
||||
@@ -9,7 +9,11 @@ function DefaultFormatter(file) {
|
||||
this.file = file;
|
||||
|
||||
this.localExports = this.getLocalExports();
|
||||
this.localImports = this.getLocalImports();
|
||||
|
||||
this.remapAssignments();
|
||||
|
||||
//this.checkCollisions();
|
||||
}
|
||||
|
||||
DefaultFormatter.prototype.getLocalExports = function () {
|
||||
@@ -27,6 +31,53 @@ DefaultFormatter.prototype.getLocalExports = function () {
|
||||
return localExports;
|
||||
};
|
||||
|
||||
DefaultFormatter.prototype.getLocalImports = function () {
|
||||
var localImports = {};
|
||||
|
||||
traverse(this.file.ast, {
|
||||
enter: function (node) {
|
||||
if (t.isImportDeclaration(node)) {
|
||||
_.extend(localImports, t.getIds(node, true));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return localImports;
|
||||
};
|
||||
|
||||
DefaultFormatter.prototype.checkCollisions = function () {
|
||||
// todo: all check export collissions
|
||||
|
||||
var localImports = this.localImports;
|
||||
var file = this.file;
|
||||
|
||||
var isLocalReference = function (node) {
|
||||
return t.isIdentifier(node) && _.has(localImports, node.name) && localImports[node.name] !== node;
|
||||
};
|
||||
|
||||
var check = function (node) {
|
||||
if (isLocalReference(node)) {
|
||||
throw file.errorWithNode(node, "Illegal assignment of module import");
|
||||
}
|
||||
};
|
||||
|
||||
traverse(file.ast, {
|
||||
enter: function (node) {
|
||||
if (t.isAssignmentExpression(node)) {
|
||||
|
||||
var left = node.left;
|
||||
if (t.isMemberExpression(left)) {
|
||||
while (left.object) left = left.object;
|
||||
}
|
||||
|
||||
check(left);
|
||||
} else if (t.isDeclaration(node)) {
|
||||
_.each(t.getIds(node, true), check);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
DefaultFormatter.prototype.remapExportAssignment = function (node) {
|
||||
return t.assignmentExpression(
|
||||
"=",
|
||||
@@ -105,11 +156,16 @@ DefaultFormatter.prototype.getModuleName = function () {
|
||||
filenameRelative = filenameRelative.replace(sourceRootRegEx, "");
|
||||
}
|
||||
|
||||
// remove extension
|
||||
filenameRelative = filenameRelative.replace(/\.(.*?)$/, "");
|
||||
if (!opts.keepModuleIdExtensions) {
|
||||
// remove extension
|
||||
filenameRelative = filenameRelative.replace(/\.(.*?)$/, "");
|
||||
}
|
||||
|
||||
moduleName += filenameRelative;
|
||||
|
||||
// normalise path separators
|
||||
moduleName = moduleName.replace(/\\/g, "/");
|
||||
|
||||
return moduleName;
|
||||
};
|
||||
|
||||
@@ -142,10 +198,11 @@ DefaultFormatter.prototype._exportSpecifier = function (getRef, specifier, node,
|
||||
nodes.push(this._exportsWildcard(getRef(), node));
|
||||
} else {
|
||||
var ref;
|
||||
if (t.isSpecifierDefault(specifier.id) || this.noInteropRequire) {
|
||||
ref = t.memberExpression(getRef(), specifier.id);
|
||||
} else {
|
||||
if (t.isSpecifierDefault(specifier) && !this.noInteropRequire) {
|
||||
// importing a default so we need to normalise it
|
||||
ref = t.callExpression(this.file.addHelper("interop-require"), [getRef()]);
|
||||
} else {
|
||||
ref = t.memberExpression(getRef(), specifier.id);
|
||||
}
|
||||
|
||||
// export { foo } from "test";
|
||||
@@ -162,7 +219,8 @@ DefaultFormatter.prototype._exportSpecifier = function (getRef, specifier, node,
|
||||
};
|
||||
|
||||
DefaultFormatter.prototype._exportsWildcard = function (objectIdentifier) {
|
||||
return t.expressionStatement(t.callExpression(this.file.addHelper("exports-wildcard"), [
|
||||
return t.expressionStatement(t.callExpression(this.file.addHelper("defaults"), [
|
||||
t.identifier("exports"),
|
||||
t.callExpression(this.file.addHelper("interop-require-wildcard"), [objectIdentifier])
|
||||
]));
|
||||
};
|
||||
|
||||
12
lib/6to5/transformation/modules/_strict.js
Normal file
12
lib/6to5/transformation/modules/_strict.js
Normal file
@@ -0,0 +1,12 @@
|
||||
var util = require("../../util");
|
||||
|
||||
module.exports = function (Parent) {
|
||||
var Constructor = function () {
|
||||
this.noInteropExport = true;
|
||||
Parent.apply(this, arguments);
|
||||
};
|
||||
|
||||
util.inherits(Constructor, Parent);
|
||||
|
||||
return Constructor;
|
||||
};
|
||||
1
lib/6to5/transformation/modules/amd-strict.js
Normal file
1
lib/6to5/transformation/modules/amd-strict.js
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = require("./_strict")(require("./amd"));
|
||||
@@ -1,13 +1,14 @@
|
||||
module.exports = AMDFormatter;
|
||||
|
||||
var DefaultFormatter = require("./_default");
|
||||
var CommonFormatter = require("./common");
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
function AMDFormatter() {
|
||||
DefaultFormatter.apply(this, arguments);
|
||||
this.ids = {};
|
||||
CommonFormatter.apply(this, arguments);
|
||||
this.ids = {};
|
||||
}
|
||||
|
||||
util.inherits(AMDFormatter, DefaultFormatter);
|
||||
@@ -30,12 +31,15 @@ AMDFormatter.prototype.transform = function (ast) {
|
||||
|
||||
// build an array of module names
|
||||
|
||||
var names = [t.literal("exports")].concat(this.buildDependencyLiterals());
|
||||
var names = [t.literal("exports")];
|
||||
if (this.passModuleArg) names.push(t.literal("module"));
|
||||
names = names.concat(this.buildDependencyLiterals());
|
||||
names = t.arrayExpression(names);
|
||||
|
||||
// build up define container
|
||||
|
||||
var params = _.values(this.ids);
|
||||
if (this.passModuleArg) params.unshift(t.identifier("module"));
|
||||
params.unshift(t.identifier("exports"));
|
||||
|
||||
var container = t.functionExpression(null, params, t.blockStatement(body));
|
||||
@@ -96,6 +100,14 @@ AMDFormatter.prototype.importSpecifier = function (specifier, node, nodes) {
|
||||
]));
|
||||
};
|
||||
|
||||
AMDFormatter.prototype.exportDeclaration = function (node) {
|
||||
if (node.default && !this.noInteropExport) {
|
||||
this.passModuleArg = true;
|
||||
}
|
||||
|
||||
CommonFormatter.prototype.exportDeclaration.apply(this, arguments);
|
||||
};
|
||||
|
||||
AMDFormatter.prototype.exportSpecifier = function (specifier, node, nodes) {
|
||||
var self = this;
|
||||
return this._exportSpecifier(function () {
|
||||
|
||||
1
lib/6to5/transformation/modules/common-strict.js
Normal file
1
lib/6to5/transformation/modules/common-strict.js
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = require("./_strict")(require("./common"));
|
||||
@@ -61,7 +61,7 @@ CommonJSFormatter.prototype.importDeclaration = function (node, nodes) {
|
||||
};
|
||||
|
||||
CommonJSFormatter.prototype.exportDeclaration = function (node, nodes) {
|
||||
if (node.default) {
|
||||
if (node.default && !this.noInteropRequire && !this.noInteropExport) {
|
||||
var declar = node.declaration;
|
||||
var assign;
|
||||
|
||||
@@ -83,10 +83,12 @@ CommonJSFormatter.prototype.exportDeclaration = function (node, nodes) {
|
||||
// this export isn't a function so we can't hoist it to the top so we need to set it
|
||||
// at the very end of the file with something like:
|
||||
//
|
||||
// module.exports = Object.assign(exports["default"], exports)
|
||||
// module.exports = _extends(exports["default"], exports)
|
||||
//
|
||||
|
||||
assign = util.template("common-export-default-assign", true);
|
||||
assign = util.template("common-export-default-assign", {
|
||||
EXTENDS_HELPER: this.file.addHelper("extends")
|
||||
}, true);
|
||||
assign._blockHoist = 0;
|
||||
|
||||
nodes.push(assign);
|
||||
|
||||
1
lib/6to5/transformation/modules/umd-strict.js
Normal file
1
lib/6to5/transformation/modules/umd-strict.js
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = require("./_strict")(require("./umd"));
|
||||
@@ -25,22 +25,44 @@ UMDFormatter.prototype.transform = function (ast) {
|
||||
// factory
|
||||
|
||||
var ids = _.values(this.ids);
|
||||
var args = [t.identifier("exports")].concat(ids);
|
||||
var args = [t.identifier("exports")];
|
||||
if (this.passModuleArg) args.push(t.identifier("module"));
|
||||
args = args.concat(ids);
|
||||
|
||||
var factory = t.functionExpression(null, args, t.blockStatement(body));
|
||||
|
||||
// runner
|
||||
// amd
|
||||
|
||||
var defineArgs = [t.literal("exports")];
|
||||
if (this.passModuleArg) defineArgs.push(t.literal("module"));
|
||||
defineArgs = defineArgs.concat(names);
|
||||
defineArgs = [t.arrayExpression(defineArgs)];
|
||||
|
||||
// common
|
||||
|
||||
var testExports = util.template("test-exports");
|
||||
var testModule = util.template("test-module");
|
||||
var commonTests = this.passModuleArg ? t.logicalExpression("&&", testExports, testModule) : testExports;
|
||||
|
||||
var commonArgs = [t.identifier("exports")];
|
||||
if (this.passModuleArg) commonArgs.push(t.identifier("module"));
|
||||
commonArgs = commonArgs.concat(names.map(function (name) {
|
||||
return t.callExpression(t.identifier("require"), [name]);
|
||||
}));
|
||||
|
||||
// globals
|
||||
|
||||
//var umdArgs = [];
|
||||
|
||||
//
|
||||
|
||||
var defineArgs = [t.arrayExpression([t.literal("exports")].concat(names))];
|
||||
var moduleName = this.getModuleName();
|
||||
if (moduleName) defineArgs.unshift(t.literal(moduleName));
|
||||
|
||||
var runner = util.template("umd-runner-body", {
|
||||
AMD_ARGUMENTS: defineArgs,
|
||||
|
||||
COMMON_ARGUMENTS: names.map(function (name) {
|
||||
return t.callExpression(t.identifier("require"), [name]);
|
||||
})
|
||||
COMMON_TEST: commonTests,
|
||||
COMMON_ARGUMENTS: commonArgs
|
||||
});
|
||||
|
||||
//
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
if (SUPER_NAME != null) {
|
||||
SUPER_NAME.apply(this, arguments);
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
if (SUPER_NAME !== null) {
|
||||
SUPER_NAME.apply(this, arguments);
|
||||
if (Object.getPrototypeOf(CLASS_NAME) !== null) {
|
||||
Object.getPrototypeOf(CLASS_NAME).apply(this, arguments);
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
module.exports = Object.assign(exports["default"], exports);
|
||||
module.exports = EXTENDS_HELPER(exports["default"], exports);
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
(function (obj) {
|
||||
for (var i in obj) {
|
||||
if (exports[i] !== undefined) {
|
||||
exports[i] = obj[i];
|
||||
}
|
||||
}
|
||||
})
|
||||
9
lib/6to5/transformation/templates/extends.js
Normal file
9
lib/6to5/transformation/templates/extends.js
Normal file
@@ -0,0 +1,9 @@
|
||||
(function (target) {
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
var source = arguments[i];
|
||||
for (var key in source) {
|
||||
target[key] = source[key];
|
||||
}
|
||||
}
|
||||
return target;
|
||||
})
|
||||
13
lib/6to5/transformation/templates/for-of-loose.js
Normal file
13
lib/6to5/transformation/templates/for-of-loose.js
Normal file
@@ -0,0 +1,13 @@
|
||||
for (var LOOP_OBJECT = OBJECT,
|
||||
IS_ARRAY = Array.isArray(LOOP_OBJECT),
|
||||
INDEX = 0,
|
||||
LOOP_OBJECT = IS_ARRAY ? LOOP_OBJECT : LOOP_OBJECT[Symbol.iterator]();;) {
|
||||
if (IS_ARRAY) {
|
||||
if (INDEX >= LOOP_OBJECT.length) break;
|
||||
ID = LOOP_OBJECT[INDEX++];
|
||||
} else {
|
||||
INDEX = LOOP_OBJECT.next();
|
||||
if (INDEX.done) break;
|
||||
ID = INDEX.value;
|
||||
}
|
||||
}
|
||||
23
lib/6to5/transformation/templates/get.js
Normal file
23
lib/6to5/transformation/templates/get.js
Normal file
@@ -0,0 +1,23 @@
|
||||
(function get(object, property, receiver) {
|
||||
var desc = Object.getOwnPropertyDescriptor(object, property);
|
||||
|
||||
if (desc === undefined) {
|
||||
var parent = Object.getPrototypeOf(object);
|
||||
|
||||
if (parent === null) {
|
||||
return undefined;
|
||||
} else {
|
||||
return get(parent, property, receiver);
|
||||
}
|
||||
} else if ("value" in desc && desc.writable) {
|
||||
return desc.value;
|
||||
} else {
|
||||
var getter = desc.get;
|
||||
|
||||
if (getter === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return getter.call(receiver);
|
||||
}
|
||||
});
|
||||
@@ -1,14 +1,14 @@
|
||||
(function (child, parent) {
|
||||
if (typeof parent !== "function" && parent !== null) {
|
||||
throw new TypeError("Super expression must either be null or a function, not " + typeof parent);
|
||||
(function (subClass, superClass) {
|
||||
if (typeof superClass !== "function" && superClass !== null) {
|
||||
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
|
||||
}
|
||||
child.prototype = Object.create(parent && parent.prototype, {
|
||||
subClass.prototype = Object.create(superClass && superClass.prototype, {
|
||||
constructor: {
|
||||
value: child,
|
||||
value: subClass,
|
||||
enumerable: false,
|
||||
writable: true,
|
||||
configurable: true
|
||||
}
|
||||
});
|
||||
if (parent) child.__proto__ = parent;
|
||||
if (superClass) subClass.__proto__ = superClass;
|
||||
})
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
|
||||
(function (KEY) {
|
||||
CONTENT;
|
||||
return KEY;
|
||||
})(OBJECT);
|
||||
@@ -1 +0,0 @@
|
||||
Object.defineProperties(OBJECT, PROPS);
|
||||
@@ -1,3 +1,3 @@
|
||||
for (var KEY = START; KEY < ARGUMENTS.length; KEY++) {
|
||||
ARRAY[$__0] = ARGUMENTS[KEY];
|
||||
ARRAY[ARRAY_KEY] = ARGUMENTS[KEY];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
(function (strings, raw) {
|
||||
strings.raw = raw;
|
||||
return strings;
|
||||
});
|
||||
1
lib/6to5/transformation/templates/test-exports.js
Normal file
1
lib/6to5/transformation/templates/test-exports.js
Normal file
@@ -0,0 +1 @@
|
||||
typeof exports !== "undefined"
|
||||
1
lib/6to5/transformation/templates/test-module.js
Normal file
1
lib/6to5/transformation/templates/test-module.js
Normal file
@@ -0,0 +1 @@
|
||||
typeof module !== "undefined"
|
||||
@@ -1,7 +1,7 @@
|
||||
(function (factory) {
|
||||
if (typeof define === "function" && define.amd) {
|
||||
define(AMD_ARGUMENTS, factory);
|
||||
} else if (typeof exports !== "undefined") {
|
||||
factory(exports, COMMON_ARGUMENTS);
|
||||
} else if (COMMON_TEST) {
|
||||
factory(COMMON_ARGUMENTS);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -31,17 +31,19 @@ transform._ensureTransformerNames = function (type, keys) {
|
||||
transform.transformers = {};
|
||||
|
||||
transform.moduleFormatters = {
|
||||
common: require("./modules/common"),
|
||||
system: require("./modules/system"),
|
||||
ignore: require("./modules/ignore"),
|
||||
amd: require("./modules/amd"),
|
||||
umd: require("./modules/umd")
|
||||
commonStrict: require("./modules/common-strict"),
|
||||
umdStrict: require("./modules/umd-strict"),
|
||||
amdStrict: require("./modules/amd-strict"),
|
||||
common: require("./modules/common"),
|
||||
system: require("./modules/system"),
|
||||
ignore: require("./modules/ignore"),
|
||||
amd: require("./modules/amd"),
|
||||
umd: require("./modules/umd")
|
||||
};
|
||||
|
||||
_.each({
|
||||
// spec
|
||||
specBlockHoistFunctions: require("./transformers/spec-block-hoist-functions"),
|
||||
specNoForInOfAssignment: require("./transformers/spec-no-for-in-of-assignment"),
|
||||
specSetters: require("./transformers/spec-setters"),
|
||||
|
||||
// playground
|
||||
methodBinding: require("./transformers/playground-method-binding"),
|
||||
@@ -59,13 +61,12 @@ _.each({
|
||||
arrowFunctions: require("./transformers/es6-arrow-functions"),
|
||||
classes: require("./transformers/es6-classes"),
|
||||
|
||||
computedPropertyNames: require("./transformers/es6-computed-property-names"),
|
||||
|
||||
objectSpread: require("./transformers/es7-object-spread"),
|
||||
exponentiationOperator: require("./transformers/es7-exponentiation-operator"),
|
||||
spread: require("./transformers/es6-spread"),
|
||||
templateLiterals: require("./transformers/es6-template-literals"),
|
||||
propertyMethodAssignment: require("./transformers/es6-property-method-assignment"),
|
||||
computedPropertyNames: require("./transformers/es6-computed-property-names"),
|
||||
destructuring: require("./transformers/es6-destructuring"),
|
||||
defaultParameters: require("./transformers/es6-default-parameters"),
|
||||
forOf: require("./transformers/es6-for-of"),
|
||||
|
||||
@@ -3,36 +3,11 @@ var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
|
||||
exports.ClassDeclaration = function (node, parent, file, scope) {
|
||||
var closure = true;
|
||||
if (t.isProgram(parent) || t.isBlockStatement(parent)) {
|
||||
closure = false;
|
||||
}
|
||||
|
||||
var factory = new Class(node, file, scope, closure);
|
||||
var newNode = factory.run();
|
||||
if (factory.closure) {
|
||||
if (closure) {
|
||||
// declaration in an expression context...
|
||||
// export default class Foo {}
|
||||
scope.push({
|
||||
kind: "var",
|
||||
key: node.id.key,
|
||||
id: node.id
|
||||
});
|
||||
return t.assignmentExpression("=", node.id, newNode);
|
||||
} else {
|
||||
// has a super class or PrivateDeclaration etc
|
||||
return t.variableDeclaration("let", [
|
||||
t.variableDeclarator(node.id, newNode)
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
return newNode;
|
||||
}
|
||||
return new Class(node, file, scope, true).run();
|
||||
};
|
||||
|
||||
exports.ClassExpression = function (node, parent, file, scope) {
|
||||
return new Class(node, file, scope, true).run();
|
||||
return new Class(node, file, scope, false).run();
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -44,11 +19,11 @@ exports.ClassExpression = function (node, parent, file, scope) {
|
||||
* @param {Boolean} closure
|
||||
*/
|
||||
|
||||
function Class(node, file, scope, closure) {
|
||||
this.closure = closure;
|
||||
this.scope = scope;
|
||||
this.node = node;
|
||||
this.file = file;
|
||||
function Class(node, file, scope, isStatement) {
|
||||
this.isStatement = isStatement;
|
||||
this.scope = scope;
|
||||
this.node = node;
|
||||
this.file = file;
|
||||
|
||||
this.hasInstanceMutators = false;
|
||||
this.hasStaticMutators = false;
|
||||
@@ -58,6 +33,7 @@ function Class(node, file, scope, closure) {
|
||||
this.hasConstructor = false;
|
||||
this.className = node.id || file.generateUidIdentifier("class", scope);
|
||||
this.superName = node.superClass;
|
||||
this.isLoose = file.isLoose("classes");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,25 +51,32 @@ Class.prototype.run = function () {
|
||||
|
||||
var body = this.body = [];
|
||||
|
||||
var constructor = t.functionExpression(null, [], t.blockStatement([]));
|
||||
if (this.node.id) constructor.id = className;
|
||||
var constructor;
|
||||
if (this.node.id) {
|
||||
constructor = t.functionDeclaration(className, [], t.blockStatement([]));
|
||||
body.push(constructor);
|
||||
} else {
|
||||
constructor = t.functionExpression(null, [], t.blockStatement([]));
|
||||
body.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(className, constructor)
|
||||
]));
|
||||
}
|
||||
this.constructor = constructor;
|
||||
|
||||
body.push(t.variableDeclaration("let", [
|
||||
t.variableDeclarator(className, constructor)
|
||||
]));
|
||||
var closureParams = [];
|
||||
var closureArgs = [];
|
||||
|
||||
//
|
||||
|
||||
if (superName) {
|
||||
this.closure = true;
|
||||
closureArgs.push(superName);
|
||||
|
||||
// so we're only evaluating it once
|
||||
var superRef = this.scope.generateUidBasedOnNode(superName, this.file);
|
||||
body.unshift(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(superRef, superName)
|
||||
]));
|
||||
superName = superRef;
|
||||
if (!t.isIdentifier(superName)) {
|
||||
var superRef = this.scope.generateUidBasedOnNode(superName, this.file);
|
||||
superName = superRef;
|
||||
}
|
||||
|
||||
closureParams.push(superName);
|
||||
|
||||
this.superName = superName;
|
||||
body.push(t.expressionStatement(t.callExpression(file.addHelper("inherits"), [className, superName])));
|
||||
@@ -103,19 +86,25 @@ Class.prototype.run = function () {
|
||||
|
||||
t.inheritsComments(body[0], this.node);
|
||||
|
||||
if (this.closure) {
|
||||
if (body.length === 1) {
|
||||
// only a constructor so no need for a closure container
|
||||
return constructor;
|
||||
} else {
|
||||
body.push(t.returnStatement(className));
|
||||
return t.callExpression(
|
||||
t.functionExpression(null, [], t.blockStatement(body)),
|
||||
[]
|
||||
);
|
||||
}
|
||||
var init;
|
||||
|
||||
if (body.length === 1) {
|
||||
// only a constructor so no need for a closure container
|
||||
init = t.toExpression(constructor);
|
||||
} else {
|
||||
return body;
|
||||
body.push(t.returnStatement(className));
|
||||
init = t.callExpression(
|
||||
t.functionExpression(null, closureParams, t.blockStatement(body)),
|
||||
closureArgs
|
||||
);
|
||||
}
|
||||
|
||||
if (this.isStatement) {
|
||||
return t.variableDeclaration("let", [
|
||||
t.variableDeclarator(className, init)
|
||||
]);
|
||||
} else {
|
||||
return init;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -129,27 +118,31 @@ Class.prototype.buildBody = function () {
|
||||
var superName = this.superName;
|
||||
var classBody = this.node.body.body;
|
||||
var body = this.body;
|
||||
var self = this;
|
||||
|
||||
for (var i in classBody) {
|
||||
var node = classBody[i];
|
||||
if (t.isMethodDefinition(node)) {
|
||||
self.replaceInstanceSuperReferences(node);
|
||||
this.replaceInstanceSuperReferences(node);
|
||||
|
||||
if (node.key.name === "constructor") {
|
||||
self.pushConstructor(node);
|
||||
this.pushConstructor(node);
|
||||
} else {
|
||||
self.pushMethod(node);
|
||||
this.pushMethod(node);
|
||||
}
|
||||
} else if (t.isPrivateDeclaration(node)) {
|
||||
self.closure = true;
|
||||
this.closure = true;
|
||||
body.unshift(node);
|
||||
}
|
||||
}
|
||||
|
||||
// we have no constructor, we have a super, and the super doesn't appear to be falsy
|
||||
if (!this.hasConstructor && superName && !t.isFalsyExpression(superName)) {
|
||||
constructor.body.body.push(util.template("class-super-constructor-call", {
|
||||
SUPER_NAME: superName
|
||||
var defaultConstructorTemplate = "class-super-constructor-call";
|
||||
if (this.isLoose) defaultConstructorTemplate += "-loose";
|
||||
|
||||
constructor.body.body.push(util.template(defaultConstructorTemplate, {
|
||||
CLASS_NAME: className,
|
||||
SUPER_NAME: this.superName
|
||||
}, true));
|
||||
}
|
||||
|
||||
@@ -157,15 +150,11 @@ Class.prototype.buildBody = function () {
|
||||
var staticProps;
|
||||
|
||||
if (this.hasInstanceMutators) {
|
||||
var protoId = util.template("prototype-identifier", {
|
||||
CLASS_NAME: className
|
||||
});
|
||||
|
||||
instanceProps = util.buildDefineProperties(this.instanceMutatorMap, protoId);
|
||||
instanceProps = util.buildDefineProperties(this.instanceMutatorMap);
|
||||
}
|
||||
|
||||
if (this.hasStaticMutators) {
|
||||
staticProps = util.buildDefineProperties(this.staticMutatorMap, className);
|
||||
staticProps = util.buildDefineProperties(this.staticMutatorMap);
|
||||
}
|
||||
|
||||
if (instanceProps || staticProps) {
|
||||
@@ -190,41 +179,74 @@ Class.prototype.pushMethod = function (node) {
|
||||
var methodName = node.key;
|
||||
|
||||
var kind = node.kind;
|
||||
var mutatorMap = this.instanceMutatorMap;
|
||||
if (node.static) {
|
||||
this.hasStaticMutators = true;
|
||||
mutatorMap = this.staticMutatorMap;
|
||||
} else {
|
||||
this.hasInstanceMutators = true;
|
||||
}
|
||||
|
||||
if (kind === "") {
|
||||
// method
|
||||
if (this.isLoose) {
|
||||
// use assignments instead of define properties for loose classes
|
||||
|
||||
var className = this.className;
|
||||
if (!node.static) className = t.memberExpression(className, t.identifier("prototype"));
|
||||
methodName = t.memberExpression(className, methodName, node.computed);
|
||||
var className = this.className;
|
||||
if (!node.static) className = t.memberExpression(className, t.identifier("prototype"));
|
||||
methodName = t.memberExpression(className, methodName, node.computed);
|
||||
|
||||
var expr = t.expressionStatement(t.assignmentExpression("=", methodName, node.value));
|
||||
t.inheritsComments(expr, node);
|
||||
this.body.push(expr);
|
||||
} else {
|
||||
// mutator
|
||||
var mutatorMap = this.instanceMutatorMap;
|
||||
if (node.static) {
|
||||
this.hasStaticMutators = true;
|
||||
mutatorMap = this.staticMutatorMap;
|
||||
} else {
|
||||
this.hasInstanceMutators = true;
|
||||
var expr = t.expressionStatement(t.assignmentExpression("=", methodName, node.value));
|
||||
t.inheritsComments(expr, node);
|
||||
this.body.push(expr);
|
||||
return;
|
||||
}
|
||||
util.pushMutatorMap(mutatorMap, methodName, kind, node);
|
||||
|
||||
kind = "value";
|
||||
}
|
||||
|
||||
util.pushMutatorMap(mutatorMap, methodName, kind, node.computed, node);
|
||||
};
|
||||
|
||||
/**
|
||||
* Given a `methodNode`, produce a `MemberExpression` super class reference.
|
||||
* Gets a node representing the super class value of the named property.
|
||||
*
|
||||
* @param {Node} methodNode MethodDefinition
|
||||
* @param {Node} node Identifier
|
||||
* @param {Node} parent
|
||||
* @example
|
||||
*
|
||||
* _get(Object.getPrototypeOf(CLASS.prototype), "METHOD", this)
|
||||
*
|
||||
* @param {Node} property
|
||||
* @param {boolean} isStatic
|
||||
* @param {boolean} isComputed
|
||||
*
|
||||
* @returns {Node}
|
||||
*/
|
||||
|
||||
Class.prototype.superIdentifier = function (methodNode, id, parent) {
|
||||
Class.prototype.superProperty = function (property, isStatic, isComputed, thisExpression) {
|
||||
return t.callExpression(
|
||||
this.file.addHelper("get"),
|
||||
[
|
||||
t.callExpression(
|
||||
t.memberExpression(t.identifier("Object"), t.identifier("getPrototypeOf")),
|
||||
[
|
||||
isStatic ? this.className : t.memberExpression(this.className, t.identifier("prototype"))
|
||||
]
|
||||
),
|
||||
isComputed ? property : t.literal(property.name),
|
||||
thisExpression
|
||||
]
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
* @param {Object} node
|
||||
* @param {Object} id
|
||||
* @param {Object} parent
|
||||
* @returns {Object}
|
||||
*/
|
||||
|
||||
Class.prototype.looseSuperProperty = function (methodNode, id, parent) {
|
||||
var methodName = methodNode.key;
|
||||
var superName = this.superName || t.identifier("Function");
|
||||
|
||||
@@ -264,23 +286,112 @@ Class.prototype.superIdentifier = function (methodNode, id, parent) {
|
||||
|
||||
Class.prototype.replaceInstanceSuperReferences = function (methodNode) {
|
||||
var method = methodNode.value;
|
||||
var self = this;
|
||||
var self = this;
|
||||
|
||||
traverse(method, {
|
||||
enter: function (node, parent) {
|
||||
if (t.isIdentifier(node, { name: "super" })) {
|
||||
return self.superIdentifier(methodNode, node, parent);
|
||||
} else if (t.isCallExpression(node)) {
|
||||
var callee = node.callee;
|
||||
var topLevelThisReference;
|
||||
|
||||
traverseLevel(method, true);
|
||||
|
||||
if (topLevelThisReference) {
|
||||
method.body.body.unshift(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(topLevelThisReference, t.thisExpression())
|
||||
]));
|
||||
}
|
||||
|
||||
function traverseLevel(node, topLevel) {
|
||||
traverse(node, {
|
||||
enter: function (node, parent) {
|
||||
if (t.isFunction(node) && !t.isArrowFunctionExpression(node)) {
|
||||
// we need to call traverseLevel again so we're context aware
|
||||
traverseLevel(node, false);
|
||||
return this.skip();
|
||||
}
|
||||
|
||||
var getThisReference = function () {
|
||||
if (topLevel) {
|
||||
// top level so `this` is the instance
|
||||
return t.thisExpression();
|
||||
} else {
|
||||
// not in the top level so we need to create a reference
|
||||
return topLevelThisReference = topLevelThisReference || self.file.generateUidIdentifier("this");
|
||||
}
|
||||
};
|
||||
|
||||
var callback = specHandle;
|
||||
if (self.isLoose) callback = looseHandle;
|
||||
return callback(getThisReference, node, parent);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function looseHandle(getThisReference, node, parent) {
|
||||
if (t.isIdentifier(node, { name: "super" })) {
|
||||
return self.looseSuperProperty(methodNode, node, parent);
|
||||
} else if (t.isCallExpression(node)) {
|
||||
var callee = node.callee;
|
||||
if (!t.isMemberExpression(callee)) return;
|
||||
if (callee.object.name !== "super") return;
|
||||
|
||||
// super.test(); -> ClassName.prototype.MethodName.call(this);
|
||||
t.appendToMemberExpression(callee, t.identifier("call"));
|
||||
node.arguments.unshift(getThisReference());
|
||||
}
|
||||
}
|
||||
|
||||
function specHandle(getThisReference, node, parent) {
|
||||
var property;
|
||||
var computed;
|
||||
var args;
|
||||
|
||||
if (t.isIdentifier(node, { name: "super" })) {
|
||||
if (!(t.isMemberExpression(parent) && !parent.computed && parent.property === node)) {
|
||||
throw self.file.errorWithNode(node, "illegal use of bare super");
|
||||
}
|
||||
} else if (t.isCallExpression(node)) {
|
||||
var callee = node.callee;
|
||||
if (t.isIdentifier(callee, { name: "super" })) {
|
||||
// super(); -> _get(Object.getPrototypeOf(ClassName), "MethodName", this).call(this);
|
||||
property = methodNode.key;
|
||||
computed = methodNode.computed;
|
||||
args = node.arguments;
|
||||
} else {
|
||||
if (!t.isMemberExpression(callee)) return;
|
||||
if (callee.object.name !== "super") return;
|
||||
|
||||
// super.test(); -> ClassName.prototype.MethodName.call(this);
|
||||
t.appendToMemberExpression(callee, t.identifier("call"));
|
||||
node.arguments.unshift(t.thisExpression());
|
||||
// super.test(); -> _get(Object.getPrototypeOf(ClassName.prototype), "test", this).call(this);
|
||||
property = callee.property;
|
||||
computed = callee.computed;
|
||||
args = node.arguments;
|
||||
}
|
||||
} else if (t.isMemberExpression(node)) {
|
||||
if (!t.isIdentifier(node.object, { name: "super" })) return;
|
||||
|
||||
// super.name; -> _get(Object.getPrototypeOf(ClassName.prototype), "name", this);
|
||||
property = node.property;
|
||||
computed = node.computed;
|
||||
}
|
||||
});
|
||||
|
||||
if (!property) return;
|
||||
|
||||
var thisReference = getThisReference();
|
||||
var superProperty = self.superProperty(property, methodNode.static, computed, thisReference);
|
||||
if (args) {
|
||||
if (args.length === 1 && t.isSpreadElement(args[0])) {
|
||||
// super(...arguments);
|
||||
return t.callExpression(
|
||||
t.memberExpression(superProperty, t.identifier("apply")),
|
||||
[thisReference, args[0].argument]
|
||||
);
|
||||
} else {
|
||||
return t.callExpression(
|
||||
t.memberExpression(superProperty, t.identifier("call")),
|
||||
[thisReference].concat(args)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
return superProperty;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -290,7 +401,7 @@ Class.prototype.replaceInstanceSuperReferences = function (methodNode) {
|
||||
*/
|
||||
|
||||
Class.prototype.pushConstructor = function (method) {
|
||||
if (method.kind !== "") {
|
||||
if (method.kind) {
|
||||
throw this.file.errorWithNode(method, "illegal kind for constructor method");
|
||||
}
|
||||
|
||||
@@ -302,8 +413,9 @@ Class.prototype.pushConstructor = function (method) {
|
||||
t.inherits(construct, fn);
|
||||
t.inheritsComments(construct, method);
|
||||
|
||||
construct.defaults = fn.defaults;
|
||||
construct.params = fn.params;
|
||||
construct.body = fn.body;
|
||||
construct.rest = fn.rest;
|
||||
construct._ignoreUserWhitespace = true;
|
||||
construct.defaults = fn.defaults;
|
||||
construct.params = fn.params;
|
||||
construct.body = fn.body;
|
||||
construct.rest = fn.rest;
|
||||
};
|
||||
|
||||
@@ -2,29 +2,66 @@ var t = require("../../types");
|
||||
|
||||
exports.ObjectExpression = function (node, parent, file, scope) {
|
||||
var hasComputed = false;
|
||||
var prop;
|
||||
var key;
|
||||
var i;
|
||||
|
||||
for (i in node.properties) {
|
||||
hasComputed = t.isProperty(node.properties[i], { computed: true });
|
||||
for (var i in node.properties) {
|
||||
hasComputed = t.isProperty(node.properties[i], { computed: true, kind: "init" });
|
||||
if (hasComputed) break;
|
||||
}
|
||||
|
||||
if (!hasComputed) return;
|
||||
|
||||
var initProps = [];
|
||||
var objId = scope.generateUidBasedOnNode(parent, file);
|
||||
|
||||
//
|
||||
|
||||
var body = [];
|
||||
var container = t.functionExpression(null, [], t.blockStatement(body));
|
||||
container._aliasFunction = true;
|
||||
|
||||
//
|
||||
|
||||
var callback = spec;
|
||||
if (file.isLoose("computedPropertyNames")) callback = loose;
|
||||
|
||||
var result = callback(node, body, objId, initProps, file);
|
||||
if (result) return result;
|
||||
|
||||
//
|
||||
|
||||
body.unshift(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(objId, t.objectExpression(initProps))
|
||||
]));
|
||||
|
||||
body.push(t.returnStatement(objId));
|
||||
|
||||
return t.callExpression(container, []);
|
||||
};
|
||||
|
||||
var loose = function (node, body, objId) {
|
||||
for (var i in node.properties) {
|
||||
var prop = node.properties[i];
|
||||
|
||||
body.push(t.expressionStatement(
|
||||
t.assignmentExpression(
|
||||
"=",
|
||||
t.memberExpression(objId, prop.key, prop.computed),
|
||||
prop.value
|
||||
)
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
var spec = function (node, body, objId, initProps, file) {
|
||||
var props = node.properties;
|
||||
var prop, key;
|
||||
|
||||
// normalise key
|
||||
|
||||
for (i in props) {
|
||||
for (var i in props) {
|
||||
prop = props[i];
|
||||
if (prop.kind !== "init") continue;
|
||||
|
||||
key = prop.key;
|
||||
|
||||
if (!prop.computed && t.isIdentifier(key)) {
|
||||
@@ -34,7 +71,6 @@ exports.ObjectExpression = function (node, parent, file, scope) {
|
||||
|
||||
// add all non-computed properties and `__proto__` properties to the initializer
|
||||
|
||||
var initProps = [];
|
||||
var broken = false;
|
||||
|
||||
for (i in props) {
|
||||
@@ -44,7 +80,7 @@ exports.ObjectExpression = function (node, parent, file, scope) {
|
||||
broken = true;
|
||||
}
|
||||
|
||||
if (!broken || t.isLiteral(t.toComputedKey(prop, prop.key), { value: "__proto__" })) {
|
||||
if (prop.kind !== "init" || !broken || t.isLiteral(t.toComputedKey(prop, prop.key), { value: "__proto__" })) {
|
||||
initProps.push(prop);
|
||||
props[i] = null;
|
||||
}
|
||||
@@ -84,14 +120,4 @@ exports.ObjectExpression = function (node, parent, file, scope) {
|
||||
return first;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
body.unshift(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(objId, t.objectExpression(initProps))
|
||||
]));
|
||||
|
||||
body.push(t.returnStatement(objId));
|
||||
|
||||
return t.callExpression(container, []);
|
||||
};
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
var traverse = require("../../traverse");
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
exports.Function = function (node, parent, file, scope) {
|
||||
if (!node.defaults || !node.defaults.length) return;
|
||||
@@ -15,6 +14,23 @@ exports.Function = function (node, parent, file, scope) {
|
||||
var i;
|
||||
var def;
|
||||
|
||||
var checkTDZ = function (ids) {
|
||||
var check = function (node, parent) {
|
||||
if (!t.isIdentifier(node) || !t.isReferenced(node, parent)) return;
|
||||
|
||||
if (ids.indexOf(node.name) >= 0) {
|
||||
throw file.errorWithNode(node, "Temporal dead zone - accessing a variable before it's initialized");
|
||||
}
|
||||
|
||||
if (scope.has(node.name, true)) {
|
||||
iife = true;
|
||||
}
|
||||
};
|
||||
|
||||
check(def, node);
|
||||
traverse(def, { enter: check });
|
||||
};
|
||||
|
||||
for (i in node.defaults) {
|
||||
def = node.defaults[i];
|
||||
if (!def) continue;
|
||||
@@ -23,22 +39,10 @@ exports.Function = function (node, parent, file, scope) {
|
||||
|
||||
// temporal dead zone check - here we prevent accessing of params that
|
||||
// are to the right - ie. uninitialized parameters
|
||||
_.each(ids.slice(i), function (ids) {
|
||||
var check = function (node, parent) {
|
||||
if (!t.isIdentifier(node) || !t.isReferenced(node, parent)) return;
|
||||
|
||||
if (ids.indexOf(node.name) >= 0) {
|
||||
throw file.errorWithNode(node, "Temporal dead zone - accessing a variable before it's initialized");
|
||||
}
|
||||
|
||||
if (scope.has(node.name)) {
|
||||
iife = true;
|
||||
}
|
||||
};
|
||||
|
||||
check(def, node);
|
||||
traverse(def, { enter: check });
|
||||
});
|
||||
var rightIds = ids.slice(i);
|
||||
for (i in rightIds) {
|
||||
checkTDZ(rightIds[i]);
|
||||
}
|
||||
|
||||
// we're accessing a variable that's already defined within this function
|
||||
var has = scope.get(param.name);
|
||||
|
||||
@@ -134,7 +134,7 @@ var pushPattern = function (opts) {
|
||||
var file = opts.file;
|
||||
var scope = opts.scope;
|
||||
|
||||
if (!t.isMemberExpression(parentId) && !t.isIdentifier(parentId)) {
|
||||
if (!t.isArrayExpression(parentId) && !t.isMemberExpression(parentId) && !t.isIdentifier(parentId)) {
|
||||
var key = scope.generateUidBasedOnNode(parentId, file);
|
||||
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
@@ -300,10 +300,17 @@ exports.VariableDeclaration = function (node, parent, file, scope) {
|
||||
file: file,
|
||||
scope: scope
|
||||
};
|
||||
|
||||
if (t.isPattern(pattern) && patternId) {
|
||||
pushPattern(opts);
|
||||
|
||||
if (+i !== node.declarations.length - 1) {
|
||||
// we aren't the last declarator so let's just make the
|
||||
// last transformed node inherit from us
|
||||
t.inherits(nodes[nodes.length - 1], declar);
|
||||
}
|
||||
} else {
|
||||
nodes.push(buildVariableAssign(opts, declar.id, declar.init));
|
||||
nodes.push(t.inherits(buildVariableAssign(opts, declar.id, declar.init), declar));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,15 +2,79 @@ var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
|
||||
exports.ForOfStatement = function (node, parent, file, scope) {
|
||||
var callback = spec;
|
||||
if (file.isLoose("forOf")) callback = loose;
|
||||
|
||||
var build = callback(node, parent, file, scope);
|
||||
var declar = build.declar;
|
||||
var loop = build.loop;
|
||||
var block = loop.body;
|
||||
|
||||
// inherit comments from the original loop
|
||||
t.inheritsComments(loop, node);
|
||||
|
||||
// ensure that it's a block so we can take all it's statemetns
|
||||
t.ensureBlock(node);
|
||||
|
||||
// add the value declaration to the new loop body
|
||||
if (declar){
|
||||
if (build.shouldUnshift) {
|
||||
block.body.unshift(declar);
|
||||
} else {
|
||||
block.body.push(declar);
|
||||
}
|
||||
}
|
||||
|
||||
// push the rest of the original loop body onto our new body
|
||||
block.body = block.body.concat(node.body.body);
|
||||
|
||||
return loop;
|
||||
};
|
||||
|
||||
var loose = function (node, parent, file, scope) {
|
||||
var left = node.left;
|
||||
var declar, id;
|
||||
|
||||
if (t.isIdentifier(left) || t.isPattern(left)) {
|
||||
// for (i of test), for ({ i } of test)
|
||||
id = left;
|
||||
} else if (t.isVariableDeclaration(left)) {
|
||||
// for (var i of test)
|
||||
id = left.declarations[0].id;
|
||||
declar = t.variableDeclaration(left.kind, [
|
||||
t.variableDeclarator(id)
|
||||
]);
|
||||
} else {
|
||||
throw file.errorWithNode(left, "Unknown node type " + left.type + " in ForOfStatement");
|
||||
}
|
||||
|
||||
var loop = util.template("for-of-loose", {
|
||||
LOOP_OBJECT: file.generateUidIdentifier("iterator", scope),
|
||||
IS_ARRAY: file.generateUidIdentifier("isArray", scope),
|
||||
OBJECT: node.right,
|
||||
INDEX: file.generateUidIdentifier("i", scope),
|
||||
ID: id
|
||||
});
|
||||
|
||||
return {
|
||||
shouldUnshift: true,
|
||||
declar: declar,
|
||||
loop: loop
|
||||
};
|
||||
};
|
||||
|
||||
var spec = function (node, parent, file, scope) {
|
||||
var left = node.left;
|
||||
var declar;
|
||||
|
||||
var stepKey = file.generateUidIdentifier("step", scope);
|
||||
var stepValue = t.memberExpression(stepKey, t.identifier("value"));
|
||||
|
||||
if (t.isIdentifier(left)) {
|
||||
if (t.isIdentifier(left) || t.isPattern(left)) {
|
||||
// for (i of test), for ({ i } of test)
|
||||
declar = t.expressionStatement(t.assignmentExpression("=", left, stepValue));
|
||||
} else if (t.isVariableDeclaration(left)) {
|
||||
// for (var i of test)
|
||||
declar = t.variableDeclaration(left.kind, [
|
||||
t.variableDeclarator(left.declarations[0].id, stepValue)
|
||||
]);
|
||||
@@ -18,18 +82,14 @@ exports.ForOfStatement = function (node, parent, file, scope) {
|
||||
throw file.errorWithNode(left, "Unknown node type " + left.type + " in ForOfStatement");
|
||||
}
|
||||
|
||||
var node2 = util.template("for-of", {
|
||||
var loop = util.template("for-of", {
|
||||
ITERATOR_KEY: file.generateUidIdentifier("iterator", scope),
|
||||
STEP_KEY: stepKey,
|
||||
OBJECT: node.right
|
||||
});
|
||||
|
||||
t.inheritsComments(node2, node);
|
||||
t.ensureBlock(node);
|
||||
|
||||
var block = node2.body;
|
||||
block.body.push(declar);
|
||||
block.body = block.body.concat(node.body.body);
|
||||
|
||||
return node2;
|
||||
return {
|
||||
declar: declar,
|
||||
loop: loop
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
var regenerator = require("regenerator");
|
||||
|
||||
exports.ast = {
|
||||
before: require("regenerator").transform
|
||||
before: function (ast, file) {
|
||||
regenerator.transform(ast, {
|
||||
includeRuntime: file.opts.includeRegenerator && "if used"
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -250,10 +250,11 @@ LetScoping.prototype.getInfo = function () {
|
||||
declar = block.body[i];
|
||||
if (!isLet(declar, block)) continue;
|
||||
|
||||
_.each(t.getIds(declar, true), function (id, key) {
|
||||
duplicates(id, key);
|
||||
var declars = t.getIds(declar, true);
|
||||
for (var key in declars) {
|
||||
duplicates(declars[key], key);
|
||||
opts.keys.push(key);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return opts;
|
||||
|
||||
@@ -46,14 +46,14 @@ exports.Property = function (node, parent, file, scope) {
|
||||
}
|
||||
};
|
||||
|
||||
exports.ObjectExpression = function (node, parent, file, scope) {
|
||||
exports.ObjectExpression = function (node) {
|
||||
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);
|
||||
util.pushMutatorMap(mutatorMap, prop.key, prop.kind, prop.computed, prop.value);
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
@@ -62,21 +62,8 @@ exports.ObjectExpression = function (node, parent, file, scope) {
|
||||
|
||||
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)
|
||||
});
|
||||
}
|
||||
return t.callExpression(
|
||||
t.memberExpression(t.identifier("Object"), t.identifier("defineProperties")),
|
||||
[node, util.buildDefineProperties(mutatorMap)]
|
||||
);
|
||||
};
|
||||
|
||||
@@ -12,6 +12,14 @@ exports.Function = function (node, parent, file) {
|
||||
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) {
|
||||
arrKey = t.binaryExpression("-", arrKey, start);
|
||||
}
|
||||
|
||||
node.body.body.unshift(
|
||||
t.variableDeclaration("var", [
|
||||
t.variableDeclarator(rest, t.arrayExpression([]))
|
||||
@@ -19,9 +27,10 @@ exports.Function = function (node, parent, file) {
|
||||
|
||||
util.template("rest", {
|
||||
ARGUMENTS: argsId,
|
||||
START: t.literal(node.params.length),
|
||||
ARRAY_KEY: arrKey,
|
||||
START: start,
|
||||
ARRAY: rest,
|
||||
KEY: file.generateUidIdentifier("key")
|
||||
KEY: key
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
@@ -17,10 +17,12 @@ exports.TaggedTemplateExpression = function (node, parent, file) {
|
||||
raw.push(t.literal(elem.value.raw));
|
||||
}
|
||||
|
||||
args.push(t.callExpression(file.addHelper("tagged-template-literal"), [
|
||||
t.arrayExpression(strings),
|
||||
t.arrayExpression(raw)
|
||||
]));
|
||||
strings = t.arrayExpression(strings);
|
||||
raw = t.arrayExpression(raw);
|
||||
|
||||
var templateName = "tagged-template-literal";
|
||||
if (file.isLoose("templateLiterals")) templateName += "-loose";
|
||||
args.push(t.callExpression(file.addHelper(templateName), [strings, raw]));
|
||||
|
||||
args = args.concat(quasi.expressions);
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ var t = require("../../types");
|
||||
|
||||
exports.experimental = true;
|
||||
|
||||
exports.ObjectExpression = function (node) {
|
||||
exports.ObjectExpression = function (node, parent, file) {
|
||||
var hasSpread = false;
|
||||
var i;
|
||||
var prop;
|
||||
@@ -42,5 +42,5 @@ exports.ObjectExpression = function (node) {
|
||||
args.unshift(t.objectExpression([]));
|
||||
}
|
||||
|
||||
return t.callExpression(t.memberExpression(t.identifier("Object"), t.identifier("assign")), args);
|
||||
return t.callExpression(file.addHelper("extends"), args);
|
||||
};
|
||||
|
||||
@@ -8,6 +8,15 @@ var coreHas = function (node) {
|
||||
return node.name !== "_" && _.has(core, node.name);
|
||||
};
|
||||
|
||||
var ALIASABLE_CONSTRUCTORS = [
|
||||
"Symbol",
|
||||
"Promise",
|
||||
"Map",
|
||||
"WeakMap",
|
||||
"Set",
|
||||
"WeakSet"
|
||||
];
|
||||
|
||||
exports.optional = true;
|
||||
|
||||
exports.ast = {
|
||||
@@ -31,8 +40,8 @@ exports.ast = {
|
||||
this.skip();
|
||||
return t.prependToMemberExpression(node, file._coreId);
|
||||
}
|
||||
} else if (t.isIdentifier(node) && !t.isMemberExpression(parent) && t.isReferenced(node, parent) && coreHas(node)) {
|
||||
// new Promise -> new _core.Promise
|
||||
} else if (t.isIdentifier(node) && !t.isMemberExpression(parent) && t.isReferenced(node, parent) && _.contains(ALIASABLE_CONSTRUCTORS, node.name)) {
|
||||
// Symbol() -> _core.Symbol(); new Promise -> new _core.Promise
|
||||
return t.memberExpression(file._coreId, node);
|
||||
} else if (t.isCallExpression(node)) {
|
||||
// arr[Symbol.iterator]() -> _core.$for.getIterator(arr)
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
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__" });
|
||||
};
|
||||
@@ -43,7 +41,7 @@ exports.ExpressionStatement = function (node, parent, file) {
|
||||
}
|
||||
};
|
||||
|
||||
exports.ObjectExpression = function (node) {
|
||||
exports.ObjectExpression = function (node, parent, file) {
|
||||
var proto;
|
||||
|
||||
for (var i in node.properties) {
|
||||
@@ -58,6 +56,6 @@ exports.ObjectExpression = function (node) {
|
||||
if (proto) {
|
||||
var args = [t.objectExpression([]), proto];
|
||||
if (node.properties.length) args.push(node);
|
||||
return t.callExpression(OBJECT_ASSIGN_MEMBER, args);
|
||||
return t.callExpression(file.addHelper("extends"), args);
|
||||
}
|
||||
};
|
||||
|
||||
72
lib/6to5/transformation/transformers/react.js
vendored
72
lib/6to5/transformation/transformers/react.js
vendored
@@ -5,6 +5,7 @@
|
||||
|
||||
var esutils = require("esutils");
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
exports.XJSIdentifier = function (node) {
|
||||
if (esutils.keyword.isIdentifierName(node.name)) {
|
||||
@@ -32,12 +33,17 @@ exports.XJSExpressionContainer = function (node) {
|
||||
exports.XJSAttribute = {
|
||||
exit: function (node) {
|
||||
var value = node.value || t.literal(true);
|
||||
return t.property("init", node.name, value);
|
||||
return t.inherits(t.property("init", node.name, value), node);
|
||||
}
|
||||
};
|
||||
|
||||
var isTag = function(tagName) {
|
||||
return (/^[a-z]|\-/).test(tagName);
|
||||
};
|
||||
|
||||
exports.XJSOpeningElement = {
|
||||
exit: function (node) {
|
||||
exit: function (node, parent, file) {
|
||||
var reactCompat = file.opts.reactCompat;
|
||||
var tagExpr = node.name;
|
||||
var args = [];
|
||||
|
||||
@@ -48,17 +54,24 @@ exports.XJSOpeningElement = {
|
||||
tagName = tagExpr.value;
|
||||
}
|
||||
|
||||
if (tagName && (/[a-z]/.exec(tagName[0]) || tagName.indexOf("-") >= 0)) {
|
||||
args.push(t.literal(tagName));
|
||||
} else {
|
||||
args.push(tagExpr);
|
||||
if (!reactCompat) {
|
||||
if (tagName && isTag(tagName)) {
|
||||
args.push(t.literal(tagName));
|
||||
} else {
|
||||
args.push(tagExpr);
|
||||
}
|
||||
}
|
||||
|
||||
var props = node.attributes;
|
||||
if (props.length) {
|
||||
var attribs = node.attributes;
|
||||
if (attribs.length) {
|
||||
var _props = [];
|
||||
var objs = [];
|
||||
|
||||
// so basically in order to support spread elements we
|
||||
// loop over all the attributes, breaking on spreads
|
||||
// we then push a new object containing all prior attributes
|
||||
// to an array for later processing
|
||||
|
||||
var pushProps = function () {
|
||||
if (!_props.length) return;
|
||||
|
||||
@@ -66,8 +79,8 @@ exports.XJSOpeningElement = {
|
||||
_props = [];
|
||||
};
|
||||
|
||||
while (props.length) {
|
||||
var prop = props.shift();
|
||||
while (attribs.length) {
|
||||
var prop = attribs.shift();
|
||||
if (t.isXJSSpreadAttribute(prop)) {
|
||||
pushProps();
|
||||
objs.push(prop.argument);
|
||||
@@ -79,24 +92,41 @@ exports.XJSOpeningElement = {
|
||||
pushProps();
|
||||
|
||||
if (objs.length === 1) {
|
||||
props = objs[0];
|
||||
// only one object
|
||||
attribs = objs[0];
|
||||
} else {
|
||||
// looks like we have multiple objects
|
||||
if (!t.isObjectExpression(objs[0])) {
|
||||
objs.unshift(t.objectExpression([]));
|
||||
}
|
||||
|
||||
props = t.callExpression(
|
||||
// spread it
|
||||
attribs = t.callExpression(
|
||||
t.memberExpression(t.identifier("React"), t.identifier("__spread")),
|
||||
objs
|
||||
);
|
||||
}
|
||||
} else {
|
||||
props = t.literal(null);
|
||||
attribs = t.literal(null);
|
||||
}
|
||||
|
||||
args.push(props);
|
||||
args.push(attribs);
|
||||
|
||||
if (reactCompat) {
|
||||
if (tagName && isTag(tagName)) {
|
||||
return t.callExpression(
|
||||
t.memberExpression(
|
||||
t.memberExpression(t.identifier("React"), t.identifier("DOM")),
|
||||
tagExpr,
|
||||
t.isLiteral(tagExpr)
|
||||
),
|
||||
args
|
||||
);
|
||||
}
|
||||
} else {
|
||||
tagExpr = t.memberExpression(t.identifier("React"), t.identifier("createElement"));
|
||||
}
|
||||
|
||||
tagExpr = t.memberExpression(t.identifier("React"), t.identifier("createElement"));
|
||||
return t.callExpression(tagExpr, args);
|
||||
}
|
||||
};
|
||||
@@ -109,7 +139,7 @@ exports.XJSElement = {
|
||||
for (i in node.children) {
|
||||
var child = node.children[i];
|
||||
|
||||
if (t.isLiteral(child)) {
|
||||
if (t.isLiteral(child) && _.isString(child.value)) {
|
||||
var lines = child.value.split(/\r\n|\n|\r/);
|
||||
|
||||
for (i in lines) {
|
||||
@@ -119,16 +149,16 @@ exports.XJSElement = {
|
||||
var isLastLine = +i === lines.length - 1;
|
||||
|
||||
// replace rendered whitespace tabs with spaces
|
||||
var trimmedLine = line.replace(/\t/g, ' ');
|
||||
var trimmedLine = line.replace(/\t/g, " ");
|
||||
|
||||
// trim whitespace touching a newline
|
||||
if (!isFirstLine) {
|
||||
trimmedLine = trimmedLine.replace(/^[ ]+/, '');
|
||||
trimmedLine = trimmedLine.replace(/^[ ]+/, "");
|
||||
}
|
||||
|
||||
// trim whitespace touching an endline
|
||||
if (!isLastLine) {
|
||||
trimmedLine = trimmedLine.replace(/[ ]+$/, '');
|
||||
trimmedLine = trimmedLine.replace(/[ ]+$/, "");
|
||||
}
|
||||
|
||||
if (trimmedLine) {
|
||||
@@ -144,6 +174,10 @@ exports.XJSElement = {
|
||||
callExpr.arguments.push(child);
|
||||
}
|
||||
|
||||
if (callExpr.arguments.length >= 3) {
|
||||
callExpr._prettyCall = true;
|
||||
}
|
||||
|
||||
return t.inherits(callExpr, node);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
var t = require("../../types");
|
||||
|
||||
exports.BlockStatement = function (node, parent) {
|
||||
if (t.isFunction(parent)) return;
|
||||
|
||||
node.body = node.body.map(function (node) {
|
||||
if (t.isFunction(node)) {
|
||||
node.type = "FunctionExpression";
|
||||
var declar = t.variableDeclaration("let", [
|
||||
t.variableDeclarator(node.id, node)
|
||||
]);
|
||||
declar._blockHoist = true;
|
||||
return declar;
|
||||
} else {
|
||||
return node;
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -1,5 +1,4 @@
|
||||
var esutils = require("esutils");
|
||||
var t = require("../../types");
|
||||
var t = require("../../types");
|
||||
|
||||
exports.MemberExpression = function (node) {
|
||||
var prop = node.property;
|
||||
@@ -7,7 +6,7 @@ exports.MemberExpression = function (node) {
|
||||
// computed literal that is a valid identifier
|
||||
node.property = t.identifier(prop.value);
|
||||
node.computed = false;
|
||||
} else if (!node.computed && t.isIdentifier(prop) && esutils.keyword.isKeywordES6(prop.name, true)) {
|
||||
} else if (!node.computed && t.isIdentifier(prop) && !t.isValidIdentifier(prop.name)) {
|
||||
node.property = t.literal(prop.name);
|
||||
node.computed = true;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
var esutils = require("esutils");
|
||||
var t = require("../../types");
|
||||
var t = require("../../types");
|
||||
|
||||
exports.Property = function (node) {
|
||||
var key = node.key;
|
||||
@@ -7,7 +6,7 @@ exports.Property = function (node) {
|
||||
// property key is a literal but a valid identifier
|
||||
node.key = t.identifier(key.value);
|
||||
node.computed = false;
|
||||
} else if (!node.computed && t.isIdentifier(key) && esutils.keyword.isKeywordES6(key.name, true)) {
|
||||
} else if (!node.computed && t.isIdentifier(key) && !t.isValidIdentifier(key.name)) {
|
||||
// property key is a keyword
|
||||
node.key = t.literal(key.name);
|
||||
}
|
||||
|
||||
6
lib/6to5/transformation/transformers/spec-setters.js
Normal file
6
lib/6to5/transformation/transformers/spec-setters.js
Normal file
@@ -0,0 +1,6 @@
|
||||
exports.MethodDefinition =
|
||||
exports.Property = function (node, parent, file) {
|
||||
if (node.kind === "set" && node.value.params.length !== 1) {
|
||||
throw file.errorWithNode(node.value, "Setters must have only one parameter");
|
||||
}
|
||||
};
|
||||
@@ -4,15 +4,101 @@ var Scope = require("./scope");
|
||||
var t = require("../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
function TraversalContext(previousContext) {
|
||||
this.didSkip = false;
|
||||
this.didRemove = false;
|
||||
this.didStop = false;
|
||||
this.didFlatten = previousContext ? previousContext.didFlatten : false;
|
||||
}
|
||||
|
||||
TraversalContext.prototype.flatten = function () {
|
||||
this.didFlatten = true;
|
||||
};
|
||||
|
||||
TraversalContext.prototype.remove = function () {
|
||||
this.didRemove = true;
|
||||
this.skip();
|
||||
};
|
||||
|
||||
TraversalContext.prototype.skip = function () {
|
||||
this.didSkip = true;
|
||||
};
|
||||
|
||||
TraversalContext.prototype.stop = function () {
|
||||
this.didStop = true;
|
||||
this.skip();
|
||||
};
|
||||
|
||||
TraversalContext.prototype.maybeReplace = function (result, obj, key, node) {
|
||||
if (result === false) return node;
|
||||
if (result == null) return node;
|
||||
|
||||
var isArray = Array.isArray(result);
|
||||
|
||||
// inherit comments from original node to the first replacement node
|
||||
var inheritTo = result;
|
||||
if (isArray) inheritTo = result[0];
|
||||
if (inheritTo) t.inheritsComments(inheritTo, node);
|
||||
|
||||
// replace the node
|
||||
node = obj[key] = result;
|
||||
|
||||
// we're replacing a statement or block node with an array of statements so we better
|
||||
// ensure that it's a block
|
||||
if (isArray && _.contains(t.STATEMENT_OR_BLOCK_KEYS, key) && !t.isBlockStatement(obj)) {
|
||||
t.ensureBlock(obj, key);
|
||||
}
|
||||
|
||||
if (isArray) {
|
||||
this.flatten();
|
||||
}
|
||||
|
||||
return node;
|
||||
};
|
||||
|
||||
TraversalContext.prototype.visit = function (obj, key, opts, scope, parent) {
|
||||
var node = obj[key];
|
||||
if (!node) return;
|
||||
|
||||
// type is blacklisted
|
||||
if (opts.blacklist && opts.blacklist.indexOf(node.type) > -1) return;
|
||||
|
||||
var result;
|
||||
var ourScope = scope;
|
||||
if (t.isScope(node)) ourScope = new Scope(node, scope);
|
||||
|
||||
// enter
|
||||
if (opts.enter) {
|
||||
result = opts.enter.call(this, node, parent, ourScope);
|
||||
node = this.maybeReplace(result, obj, key, node);
|
||||
|
||||
if (this.didRemove) {
|
||||
obj[key] = null;
|
||||
this.flatten();
|
||||
}
|
||||
|
||||
// stop traversal
|
||||
if (this.didSkip) return;
|
||||
}
|
||||
|
||||
// traverse node
|
||||
traverse(node, opts, ourScope);
|
||||
|
||||
// exit
|
||||
if (opts.exit) {
|
||||
result = opts.exit.call(this, node, parent, ourScope);
|
||||
node = this.maybeReplace(result, obj, key, node);
|
||||
}
|
||||
};
|
||||
|
||||
function traverse(parent, opts, scope) {
|
||||
// falsy node
|
||||
if (!parent) return;
|
||||
|
||||
// array of nodes
|
||||
if (_.isArray(parent)) {
|
||||
_.each(parent, function (node) {
|
||||
traverse(node, opts, scope);
|
||||
});
|
||||
if (Array.isArray(parent)) {
|
||||
for (var i = 0; i < parent.length; i++)
|
||||
traverse(parent[i], opts, scope);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -21,99 +107,21 @@ function traverse(parent, opts, scope) {
|
||||
if (!keys) return;
|
||||
|
||||
opts = opts || {};
|
||||
var context = null;
|
||||
|
||||
var stopped = false;
|
||||
|
||||
for (var i in keys) {
|
||||
var key = keys[i];
|
||||
for (var j = 0; j < keys.length; j++) {
|
||||
var key = keys[j];
|
||||
var nodes = parent[key];
|
||||
if (!nodes) continue;
|
||||
|
||||
var flatten = false;
|
||||
|
||||
var handle = function (obj, key) {
|
||||
var node = obj[key];
|
||||
if (!node) return;
|
||||
|
||||
// type is blacklisted
|
||||
if (opts.blacklist && opts.blacklist.indexOf(node.type) > -1) return;
|
||||
|
||||
// replace node
|
||||
var maybeReplace = function (result) {
|
||||
if (result === false) return;
|
||||
if (result == null) return;
|
||||
|
||||
var isArray = _.isArray(result);
|
||||
|
||||
// inherit comments from original node to the first replacement node
|
||||
var inheritTo = result;
|
||||
if (isArray) inheritTo = result[0];
|
||||
if (inheritTo) t.inheritsComments(inheritTo, node);
|
||||
|
||||
// replace the node
|
||||
node = obj[key] = result;
|
||||
|
||||
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
|
||||
if (isArray && _.contains(t.STATEMENT_OR_BLOCK_KEYS, key) && !t.isBlockStatement(obj)) {
|
||||
t.ensureBlock(obj, key);
|
||||
}
|
||||
};
|
||||
|
||||
var skipped = false;
|
||||
var removed = false;
|
||||
|
||||
var context = {
|
||||
stop: function () {
|
||||
skipped = stopped = true;
|
||||
},
|
||||
|
||||
skip: function () {
|
||||
skipped = true;
|
||||
},
|
||||
|
||||
remove: function () {
|
||||
this.skip();
|
||||
removed = true;
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
var ourScope = scope;
|
||||
if (t.isScope(node)) ourScope = new Scope(node, scope);
|
||||
|
||||
// enter
|
||||
if (opts.enter) {
|
||||
var result = opts.enter.call(context, node, parent, ourScope);
|
||||
maybeReplace(result);
|
||||
|
||||
if (removed) {
|
||||
obj[key] = null;
|
||||
flatten = true;
|
||||
}
|
||||
|
||||
// stop iteration
|
||||
if (skipped) return;
|
||||
if (Array.isArray(nodes)) {
|
||||
for (var k = 0; k < nodes.length; k++) {
|
||||
context = new TraversalContext(context);
|
||||
context.visit(nodes, k, opts, scope, parent);
|
||||
if (context.didStop) return;
|
||||
}
|
||||
|
||||
// traverse node
|
||||
traverse(node, opts, ourScope);
|
||||
|
||||
// exit
|
||||
if (opts.exit) {
|
||||
maybeReplace(opts.exit.call(context, node, parent, ourScope));
|
||||
}
|
||||
};
|
||||
|
||||
if (_.isArray(nodes)) {
|
||||
for (i in nodes) {
|
||||
handle(nodes, i);
|
||||
if (stopped) return;
|
||||
}
|
||||
|
||||
if (flatten) {
|
||||
if (context && context.didFlatten) {
|
||||
parent[key] = _.flatten(parent[key]);
|
||||
|
||||
if (key === "body") {
|
||||
@@ -122,8 +130,9 @@ function traverse(parent, opts, scope) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
handle(parent, key);
|
||||
if (stopped) return;
|
||||
context = new TraversalContext(context);
|
||||
context.visit(parent, key, opts, scope, parent);
|
||||
if (context.didStop) return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,13 @@ function Scope(block, parent) {
|
||||
}
|
||||
|
||||
var vars = require("jshint/src/vars");
|
||||
Scope.defaultDeclarations = _.flatten([vars.newEcmaIdentifiers, vars.node, vars.ecmaIdentifiers, vars.reservedVars].map(_.keys));
|
||||
|
||||
Scope.defaultDeclarations = _.flatten([
|
||||
vars.newEcmaIdentifiers,
|
||||
vars.node,
|
||||
vars.ecmaIdentifiers,
|
||||
vars.reservedVars
|
||||
].map(_.keys));
|
||||
|
||||
Scope.add = function (node, references) {
|
||||
if (!node) return;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
"ExpressionStatement": ["expression"],
|
||||
"File": ["program", "comments", "tokens"],
|
||||
"FunctionExpression": ["id", "params", "body", "generator"],
|
||||
"FunctionDeclaration": ["id", "params", "body", "generator"],
|
||||
"Identifier": ["name"],
|
||||
"IfStatement": ["test", "consequent", "alternate"],
|
||||
"ImportDeclaration": ["specifiers", "source"],
|
||||
@@ -16,6 +17,7 @@
|
||||
"Literal": ["value"],
|
||||
"LogicalExpression": ["operator", "left", "right"],
|
||||
"MemberExpression": ["object", "property", "computed"],
|
||||
"MethodDefinition": ["key", "value", "computed", "kind"],
|
||||
"NewExpression": ["callee", "arguments"],
|
||||
"ObjectExpression": ["properties"],
|
||||
"Program": ["body"],
|
||||
|
||||
@@ -307,6 +307,31 @@ t.toStatement = function (node, ignore) {
|
||||
return node;
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
* @param {Object} node
|
||||
* @returns {Object}
|
||||
*/
|
||||
|
||||
exports.toExpression = function (node) {
|
||||
if (t.isExpressionStatement(node)) {
|
||||
node = node.expression;
|
||||
}
|
||||
|
||||
if (t.isClass(node)) {
|
||||
node.type = "ClassExpression";
|
||||
} else if (t.isFunction(node)) {
|
||||
node.type = "FunctionExpression";
|
||||
}
|
||||
|
||||
if (t.isExpression(node)) {
|
||||
return node;
|
||||
} else {
|
||||
throw new Error("cannot turn " + node.type + " to an expression");
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
@@ -320,7 +345,11 @@ t.toBlock = function (node, parent) {
|
||||
return node;
|
||||
}
|
||||
|
||||
if (!_.isArray(node)) {
|
||||
if (t.isEmptyStatement(node)) {
|
||||
node = [];
|
||||
}
|
||||
|
||||
if (!Array.isArray(node)) {
|
||||
if (!t.isStatement(node)) {
|
||||
if (t.isFunction(parent)) {
|
||||
node = t.returnStatement(node);
|
||||
@@ -355,16 +384,24 @@ t.getIds = function (node, map, ignoreTypes) {
|
||||
if (!id) continue;
|
||||
if (_.contains(ignoreTypes, id.type)) continue;
|
||||
|
||||
var nodeKey = t.getIds.nodes[id.type];
|
||||
var nodeKeys = t.getIds.nodes[id.type];
|
||||
var arrKeys = t.getIds.arrays[id.type];
|
||||
|
||||
var i, key;
|
||||
|
||||
if (t.isIdentifier(id)) {
|
||||
ids[id.name] = id;
|
||||
} else if (nodeKey) {
|
||||
if (id[nodeKey]) search.push(id[nodeKey]);
|
||||
} else if (nodeKeys) {
|
||||
for (i in nodeKeys) {
|
||||
key = nodeKeys[i];
|
||||
if (id[key]) {
|
||||
search.push(id[key]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (arrKeys) {
|
||||
for (var i in arrKeys) {
|
||||
var key = arrKeys[i];
|
||||
for (i in arrKeys) {
|
||||
key = arrKeys[i];
|
||||
search = search.concat(id[key] || []);
|
||||
}
|
||||
}
|
||||
@@ -375,15 +412,16 @@ t.getIds = function (node, map, ignoreTypes) {
|
||||
};
|
||||
|
||||
t.getIds.nodes = {
|
||||
AssignmentExpression: "left",
|
||||
ImportSpecifier: "name",
|
||||
ExportSpecifier: "name",
|
||||
VariableDeclarator: "id",
|
||||
FunctionDeclaration: "id",
|
||||
ClassDeclaration: "id",
|
||||
MemeberExpression: "object",
|
||||
SpreadElement: "argument",
|
||||
Property: "value"
|
||||
AssignmentExpression: ["left"],
|
||||
ImportBatchSpecifier: ["name"],
|
||||
ImportSpecifier: ["name", "id"],
|
||||
ExportSpecifier: ["name", "id"],
|
||||
VariableDeclarator: ["id"],
|
||||
FunctionDeclaration: ["id"],
|
||||
ClassDeclaration: ["id"],
|
||||
MemeberExpression: ["object"],
|
||||
SpreadElement: ["argument"],
|
||||
Property: ["value"]
|
||||
};
|
||||
|
||||
t.getIds.arrays = {
|
||||
|
||||
@@ -39,7 +39,7 @@ exports.list = function (val) {
|
||||
|
||||
exports.regexify = function (val) {
|
||||
if (!val) return new RegExp(/.^/);
|
||||
if (_.isArray(val)) val = val.join("|");
|
||||
if (Array.isArray(val)) val = val.join("|");
|
||||
if (_.isString(val)) return new RegExp(val);
|
||||
if (_.isRegExp(val)) return val;
|
||||
throw new TypeError("illegal type for regexify");
|
||||
@@ -48,7 +48,7 @@ exports.regexify = function (val) {
|
||||
exports.arrayify = function (val) {
|
||||
if (!val) return [];
|
||||
if (_.isString(val)) return exports.list(val);
|
||||
if (_.isArray(val)) return val;
|
||||
if (Array.isArray(val)) return val;
|
||||
throw new TypeError("illegal type for arrayify");
|
||||
};
|
||||
|
||||
@@ -65,12 +65,12 @@ exports.sourceMapToComment = function (map) {
|
||||
return "//# sourceMappingURL=data:application/json;base64," + base64;
|
||||
};
|
||||
|
||||
exports.pushMutatorMap = function (mutatorMap, key, kind, method) {
|
||||
exports.pushMutatorMap = function (mutatorMap, key, kind, computed, method) {
|
||||
var alias;
|
||||
|
||||
if (t.isIdentifier(key)) {
|
||||
alias = key.name;
|
||||
if (method.computed) alias = "computed:" + alias;
|
||||
if (computed) alias = "computed:" + alias;
|
||||
} else if (t.isLiteral(key)) {
|
||||
alias = String(key.value);
|
||||
} else {
|
||||
@@ -86,7 +86,7 @@ exports.pushMutatorMap = function (mutatorMap, key, kind, method) {
|
||||
mutatorMap[alias] = map;
|
||||
|
||||
map._key = key;
|
||||
if (method.computed) {
|
||||
if (computed) {
|
||||
map._computed = true;
|
||||
}
|
||||
|
||||
@@ -101,7 +101,12 @@ exports.buildDefineProperties = function (mutatorMap) {
|
||||
|
||||
var propNode = t.property("init", map._key, mapNode, map._computed);
|
||||
|
||||
if (!map.get && !map.set) {
|
||||
map.writable = t.literal(true);
|
||||
}
|
||||
|
||||
map.enumerable = t.literal(true);
|
||||
map.configurable = t.literal(true);
|
||||
|
||||
_.each(map, function (node, key) {
|
||||
if (key[0] === "_") return;
|
||||
@@ -146,10 +151,10 @@ exports.template = function (name, nodes, keepExpression) {
|
||||
var node = template.body[0];
|
||||
|
||||
if (!keepExpression && t.isExpressionStatement(node)) {
|
||||
node = node.expression;
|
||||
return node.expression;
|
||||
} else {
|
||||
return node;
|
||||
}
|
||||
|
||||
return node;
|
||||
};
|
||||
|
||||
exports.codeFrame = function (lines, lineNumber, colNumber) {
|
||||
@@ -188,7 +193,13 @@ exports.codeFrame = function (lines, lineNumber, colNumber) {
|
||||
|
||||
exports.repeat = function (width, cha) {
|
||||
cha = cha || " ";
|
||||
return new Array(width + 1).join(cha);
|
||||
|
||||
var result = "";
|
||||
for (var i = 0; i < width; i++) {
|
||||
result += cha;
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
exports.normaliseAst = function (ast, comments, tokens) {
|
||||
@@ -256,7 +267,7 @@ var loadTemplates = function () {
|
||||
if (!fs.existsSync(templatesLoc)) {
|
||||
throw new Error("no templates directory - this is most likely the " +
|
||||
"result of a broken `npm publish`. Please report to " +
|
||||
"https://githut.com/6to5/6to5/issues");
|
||||
"https://github.com/6to5/6to5/issues");
|
||||
}
|
||||
|
||||
_.each(fs.readdirSync(templatesLoc), function (name) {
|
||||
|
||||
20
package.json
20
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "6to5",
|
||||
"description": "Turn ES6 code into readable vanilla ES5 with source maps",
|
||||
"version": "2.6.0",
|
||||
"version": "2.12.0",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||
"homepage": "https://github.com/6to5/6to5",
|
||||
"repository": {
|
||||
@@ -39,36 +39,36 @@
|
||||
"test": "make test"
|
||||
},
|
||||
"dependencies": {
|
||||
"acorn-6to5": "0.11.1-11",
|
||||
"acorn-6to5": "0.11.1-14",
|
||||
"ast-types": "~0.6.1",
|
||||
"chokidar": "0.11.1",
|
||||
"commander": "2.5.0",
|
||||
"core-js": "^0.4.0",
|
||||
"core-js": "0.4.4",
|
||||
"estraverse": "1.8.0",
|
||||
"esutils": "1.1.6",
|
||||
"esvalid": "^1.1.0",
|
||||
"esvalid": "1.1.0",
|
||||
"fs-readdir-recursive": "0.1.0",
|
||||
"jshint": "^2.5.10",
|
||||
"jshint": "2.5.10",
|
||||
"lodash": "2.4.1",
|
||||
"mkdirp": "0.5.0",
|
||||
"private": "0.1.6",
|
||||
"regenerator": "^0.8.3",
|
||||
"regenerator": "0.8.3",
|
||||
"regexpu": "0.3.0",
|
||||
"roadrunner": "^1.0.4",
|
||||
"roadrunner": "1.0.4",
|
||||
"source-map": "0.1.40",
|
||||
"source-map-support": "0.2.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"browserify": "6.3.2",
|
||||
"chai": "^1.9.2",
|
||||
"chai": "1.9.2",
|
||||
"istanbul": "0.3.2",
|
||||
"jshint-stylish": "^1.0.0",
|
||||
"jshint-stylish": "1.0.0",
|
||||
"matcha": "0.6.0",
|
||||
"mocha": "1.21.4",
|
||||
"rimraf": "2.2.8",
|
||||
"uglify-js": "2.4.15"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"kexec": "^0.2.0"
|
||||
"kexec": "0.2.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// skip these tests under instanbul since they're useless
|
||||
if (process.env.running_under_istanbul === '1') return;
|
||||
if (process.env.running_under_istanbul) return;
|
||||
|
||||
var readdir = require("fs-readdir-recursive");
|
||||
var helper = require("./_helper");
|
||||
|
||||
@@ -12,7 +12,7 @@ suite("browserify", function() {
|
||||
assert.ok(bundle.length, "bundle output code");
|
||||
|
||||
// ensure that the code runs without throwing an exception
|
||||
vm.runInNewContext(bundle, {});
|
||||
vm.runInNewContext("var global = this;\n" + bundle, {});
|
||||
done();
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
if (!process.env.ALL_6TO5_TESTS) return;
|
||||
|
||||
require("./_transformation-helper")({
|
||||
name: "esnext"
|
||||
});
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
class Animal {
|
||||
class Base {
|
||||
get sound() {
|
||||
return 'I am a ' + this.type + '.';
|
||||
}
|
||||
}
|
||||
|
||||
class Animal extends Base {}
|
||||
|
||||
class Cat extends Animal {
|
||||
get type() { return 'cat'; }
|
||||
|
||||
|
||||
@@ -7,4 +7,5 @@ var test = {
|
||||
* Inside bracket init
|
||||
*/
|
||||
"b"]: "2"
|
||||
}, ok = 42;
|
||||
},
|
||||
ok = 42;
|
||||
|
||||
@@ -3,6 +3,7 @@ function test() {
|
||||
// Leading to VariableDeclarator
|
||||
// Leading to VariableDeclarator
|
||||
i = 20,
|
||||
|
||||
// Leading to VariableDeclarator
|
||||
// Leading to VariableDeclarator
|
||||
j = 20;
|
||||
|
||||
@@ -5,6 +5,7 @@ function test() {
|
||||
* Leading to VariableDeclarator
|
||||
*/
|
||||
i = 20,
|
||||
|
||||
/*
|
||||
* Leading to VariableDeclarator
|
||||
* Leading to VariableDeclarator
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
function* foo() {
|
||||
var a = yield wat(), b = 2;
|
||||
var a = yield wat(),
|
||||
b = 2;
|
||||
var c = yield a = b;
|
||||
yield a, yield b;
|
||||
yield a = b;
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
++i;
|
||||
i++;
|
||||
(foo++).test();
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
++i;
|
||||
i++;
|
||||
(foo++).test();
|
||||
|
||||
@@ -8,6 +8,9 @@ const foo = "foo";
|
||||
let foo, bar = "bar";
|
||||
var foo, bar = "bar";
|
||||
|
||||
let foo = "foo", bar = "bar";
|
||||
var foo = "foo", bar = "bar";
|
||||
const foo = "foo", bar = "bar";
|
||||
let foo = "foo",
|
||||
bar = "bar";
|
||||
var foo = "foo",
|
||||
bar = "bar";
|
||||
const foo = "foo",
|
||||
bar = "bar";
|
||||
|
||||
25
test/fixtures/transformation/es6-classes-loose/accessing-super-class/actual.js
vendored
Normal file
25
test/fixtures/transformation/es6-classes-loose/accessing-super-class/actual.js
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
class Test extends Foo {
|
||||
constructor() {
|
||||
woops.super.test();
|
||||
super();
|
||||
super.test();
|
||||
|
||||
super(...arguments);
|
||||
super("test", ...arguments);
|
||||
|
||||
super.test(...arguments);
|
||||
super.test("test", ...arguments);
|
||||
}
|
||||
|
||||
test() {
|
||||
super();
|
||||
super(...arguments);
|
||||
super("test", ...arguments);
|
||||
}
|
||||
|
||||
static foo() {
|
||||
super();
|
||||
super(...arguments);
|
||||
super("test", ...arguments);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user