Compare commits
304 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
194c080c64 | ||
|
|
4c6076e529 | ||
|
|
df65ec08a2 | ||
|
|
62f11011b0 | ||
|
|
9385c7e4ad | ||
|
|
3c06e68cae | ||
|
|
e8810f5124 | ||
|
|
3c258c4716 | ||
|
|
193a3c167e | ||
|
|
4b525daf72 | ||
|
|
e46f42872a | ||
|
|
4790e4068a | ||
|
|
26cb5d5a65 | ||
|
|
031bda61cc | ||
|
|
61f1fae83b | ||
|
|
d911bdaf63 | ||
|
|
f322252c36 | ||
|
|
da16bf1e42 | ||
|
|
4a1addc558 | ||
|
|
857abf5024 | ||
|
|
6d67105bab | ||
|
|
078b09676f | ||
|
|
b719eaf6ab | ||
|
|
b63accca25 | ||
|
|
2d41b09c3b | ||
|
|
0b44137d1f | ||
|
|
8d8dd5fa37 | ||
|
|
16b7ff972c | ||
|
|
ca41612109 | ||
|
|
8fc7af5480 | ||
|
|
1c6cb7ce40 | ||
|
|
24d6c3f488 | ||
|
|
d877a04397 | ||
|
|
4844882f5e | ||
|
|
a80945cfb4 | ||
|
|
6a884c58a7 | ||
|
|
7c4701716c | ||
|
|
ecfd5fadc6 | ||
|
|
c6be5cccd7 | ||
|
|
dd256dc3f8 | ||
|
|
622da331a6 | ||
|
|
5a44793dcb | ||
|
|
9c9a9b0325 | ||
|
|
2534f7f2a0 | ||
|
|
36a933a004 | ||
|
|
62c168b13c | ||
|
|
810c97d7ab | ||
|
|
c2b20b18b3 | ||
|
|
309d19960f | ||
|
|
774cb66d9b | ||
|
|
d360bd5bb7 | ||
|
|
74f5a73d31 | ||
|
|
26395a86fa | ||
|
|
436c488ee3 | ||
|
|
93d99077e5 | ||
|
|
0bb52d6e3d | ||
|
|
320c78b815 | ||
|
|
ddd59b94b0 | ||
|
|
c210d64557 | ||
|
|
a0f605bbab | ||
|
|
f4b2768194 | ||
|
|
95d9f59668 | ||
|
|
c41d799b9b | ||
|
|
e7d4642d48 | ||
|
|
41949fd58b | ||
|
|
d0dc972840 | ||
|
|
621e66e9ac | ||
|
|
529544ce0e | ||
|
|
f298cd3f0f | ||
|
|
67029ac8e8 | ||
|
|
b54800234f | ||
|
|
ecd85f53b4 | ||
|
|
9098852897 | ||
|
|
3eb4d5b466 | ||
|
|
ddb1c718f1 | ||
|
|
8919873ea1 | ||
|
|
eb9cd95d5a | ||
|
|
4ec701fc44 | ||
|
|
ff9511d435 | ||
|
|
ac5a6da1fa | ||
|
|
616640a128 | ||
|
|
1f9ce96e43 | ||
|
|
dc6a862bec | ||
|
|
f9480b5280 | ||
|
|
8dc4996547 | ||
|
|
4f01f67dd6 | ||
|
|
938026abeb | ||
|
|
76b8945207 | ||
|
|
e78859fae0 | ||
|
|
d68f1e9910 | ||
|
|
20e97f2d9b | ||
|
|
750ec7783f | ||
|
|
14ae438735 | ||
|
|
2f8bdd7e27 | ||
|
|
87da9fcfc5 | ||
|
|
51f6cfddca | ||
|
|
b9ad4c2773 | ||
|
|
228b3dbc34 | ||
|
|
a01802300f | ||
|
|
51c6a3fffc | ||
|
|
4668e1d67b | ||
|
|
75e9097e19 | ||
|
|
0627cd94d4 | ||
|
|
71879d6e8f | ||
|
|
d7810cac08 | ||
|
|
dc9efd21d3 | ||
|
|
347e490614 | ||
|
|
e512264be7 | ||
|
|
9624663e60 | ||
|
|
3cf8a6df01 | ||
|
|
88eacecd72 | ||
|
|
fcd3c9ce65 | ||
|
|
1733bac3bb | ||
|
|
21cd063274 | ||
|
|
db5750643a | ||
|
|
60dae7a88d | ||
|
|
790c924b54 | ||
|
|
50d7a46c7f | ||
|
|
6f7da38957 | ||
|
|
80764c214a | ||
|
|
55054e45da | ||
|
|
060aa5ba0b | ||
|
|
688d619bfe | ||
|
|
6db7fce543 | ||
|
|
41ff1d4ace | ||
|
|
1c6eeba2e9 | ||
|
|
488b719fde | ||
|
|
af32080287 | ||
|
|
4c1cd13536 | ||
|
|
1002cf7796 | ||
|
|
081dd33e73 | ||
|
|
bd9dc4f15d | ||
|
|
c7ba566ad6 | ||
|
|
a1b326a0ab | ||
|
|
a452f781b8 | ||
|
|
e5463cc2a9 | ||
|
|
7d732ef503 | ||
|
|
25cb0c6344 | ||
|
|
45a52bf478 | ||
|
|
a14f971b8a | ||
|
|
da65500545 | ||
|
|
58a91ee9e9 | ||
|
|
19eaa181a5 | ||
|
|
c7c90acf3f | ||
|
|
c6f3a55c03 | ||
|
|
e01b7d288f | ||
|
|
98c0e185b8 | ||
|
|
bf66d78210 | ||
|
|
b60eca0a76 | ||
|
|
44f06c0b4c | ||
|
|
6c5606b7e8 | ||
|
|
07ddfbeb5d | ||
|
|
87b890c172 | ||
|
|
245fcfe110 | ||
|
|
4744719040 | ||
|
|
a3b814a897 | ||
|
|
f5f17f0ccb | ||
|
|
f6a2acdfb1 | ||
|
|
e8dba2ad1e | ||
|
|
8ce5c5b608 | ||
|
|
0dfea1a51b | ||
|
|
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 | ||
|
|
324a4a1b22 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -10,3 +10,4 @@ test/tmp
|
||||
/runtime.js
|
||||
coverage
|
||||
dist
|
||||
.package.json
|
||||
|
||||
@@ -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,6 @@ Makefile
|
||||
dist
|
||||
tests.json
|
||||
CHANGELOG.md
|
||||
.package.json
|
||||
coverage
|
||||
vendor
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
sudo: false
|
||||
language: node_js
|
||||
node_js:
|
||||
- "0.10"
|
||||
|
||||
196
CHANGELOG.md
196
CHANGELOG.md
@@ -11,6 +11,202 @@
|
||||
|
||||
_Note: Gaps between patch versions are faulty/broken releases._
|
||||
|
||||
## 2.13.5
|
||||
|
||||
* **Bug Fix**
|
||||
* Allow rest parameters to be destructuring patterns.
|
||||
* **Internal**
|
||||
* Upgrade `kexec` to `1.1.0`.
|
||||
|
||||
## 2.13.4
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix ordering of destructuring and default params.
|
||||
* Fix loop body scope.
|
||||
* Fix `for...of` transformation not retaining it's scope.
|
||||
* Add destructuring assignment support to scope tracking.
|
||||
* **Polish**
|
||||
* More reliable newlines for pretty printing variable declarations.
|
||||
|
||||
## 2.13.3
|
||||
|
||||
* **Internal**
|
||||
* Add `coverage` and `vendor` to npmignore.
|
||||
|
||||
## 2.13.2
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix `super` inside of nested functions.
|
||||
* **Internal**
|
||||
* Move let scoping TDZ into a separate transformer until it's more solid.
|
||||
* Use `process.stdin.write` instead of `console.log` in `bin` to avoid sprintfification.
|
||||
|
||||
## 2.13.1
|
||||
|
||||
* **New Feature**
|
||||
* Temporal dead zone for block binding.
|
||||
|
||||
## 2.13.0
|
||||
|
||||
* **New Feature**
|
||||
* Block scoped functions.
|
||||
* Add `--loose all` option.
|
||||
* Add playground mallet operator thanks to [@jridgewell](https://github.com/jridgewell).
|
||||
* **Bug Fix**
|
||||
* Rewrote large parts of the let scoping transformer. Now passes all known tests.
|
||||
* **Internal**
|
||||
* Even more optimisations thanks to the awesome [@gaearon](https://github.com/gaearon).
|
||||
* Upgrade `acorn-6to5`.
|
||||
* Fixes exponentation operator thanks to [@charliesome](https://github.com/charliesome).
|
||||
* Fix flow optional parameters with types.
|
||||
* Upgrade `chokidar` to `0.12.6`.
|
||||
* Upgrade `commander` to `2.6.0`.
|
||||
* Upgrade `core-js` to `0.4.5`.
|
||||
* Upgrade `estraverse` to `1.9.1`.
|
||||
* Upgrade `jshint` to `2.5.11`.
|
||||
* Upgrade `regenerator` to `0.8.9`.
|
||||
* Upgrade `regexpu` to `1.0.0`.
|
||||
* Upgrade `source-map` to `0.1.43`.
|
||||
* Upgrade `source-map-support` to `0.2.9`.
|
||||
* Upgrade `browserify` to `8.1.1`.
|
||||
* Upgrade `chai` to `1.10.0`.
|
||||
* Upgrade `istanbul` to `0.3.5`.
|
||||
* Upgrade `mocha` to `2.1.0`.
|
||||
* Upgrade `uglify-js` to `2.4.16`.
|
||||
|
||||
## 2.12.6
|
||||
|
||||
* **Bug Fix**
|
||||
* Add missing flow type traversal keys.
|
||||
|
||||
## 2.12.5
|
||||
|
||||
* **Internal**
|
||||
* Fix incorrect `for...in` loop still causing `ember-script` issues.
|
||||
|
||||
## 2.12.4
|
||||
|
||||
* **Polish**
|
||||
* Rest parameters now allocate the array before populating.
|
||||
* **Internal**
|
||||
* `for...in` loops have been changed to optimised `for` loops - better performance and no enumeration of protoype keys.
|
||||
* Parts of the code generator have now been optimised thanks to [gaearon](https://github.com/gaearon).
|
||||
|
||||
## 2.12.3
|
||||
|
||||
* **Spec Compliancy**
|
||||
* Optional `typeof` transformer checks for `undefined` before passing it to the helper.
|
||||
* Class methods are now named.
|
||||
|
||||
## 2.12.2
|
||||
|
||||
* **Internal**
|
||||
* Exclude nodes in function parameters and catch clauses from `isReferenced` check.
|
||||
|
||||
## 2.12.1
|
||||
|
||||
* **Internal**
|
||||
* Add `.jsx` to list of allowed extensions.
|
||||
|
||||
## 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**
|
||||
|
||||
@@ -1,6 +1,20 @@
|
||||
# Contributing
|
||||
|
||||
Before contributing, please read the [code of conduct](https://github.com/6to5/6to5/blob/master/CODE_OF_CONDUCT.md).
|
||||
Contributions are always welcome, no matter how large or small. Before contributing, please read the [code of conduct](https://github.com/6to5/6to5/blob/master/CODE_OF_CONDUCT.md).
|
||||
|
||||
## Developing
|
||||
|
||||
#### Workflow
|
||||
|
||||
* Fork the repository
|
||||
* Clone your fork and change directory to it (`git clone git@github.com:yourUserName/6to5.git && cd 6to5`)
|
||||
* Install the project dependencies (`make bootstrap`)
|
||||
* Link your forked clone (`npm link`)
|
||||
* Develop your changes ensuring you're fetching updates from upstream often
|
||||
* Ensure the test are passing (`make test`)
|
||||
* Create new pull request explaining your proposed change or reference an issue in your commit message
|
||||
|
||||
#### Code Standards
|
||||
|
||||
* **General**
|
||||
* No ES6 syntax features or methods, exclusively ES5.
|
||||
|
||||
19
Makefile
19
Makefile
@@ -1,12 +1,13 @@
|
||||
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-simple test-all test-browser publish 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
|
||||
@@ -71,6 +72,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
|
||||
@@ -79,12 +83,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:
|
||||
|
||||
5
NOTES.md
5
NOTES.md
@@ -7,3 +7,8 @@
|
||||
* 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.
|
||||
* Remove fast transformer backwards compatibility.
|
||||
* Rename let scoping transformer to block scoping.
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
var chokidar = require("chokidar");
|
||||
var mkdirp = require("mkdirp");
|
||||
var path = require("path");
|
||||
var util = require("./util");
|
||||
var fs = require("fs");
|
||||
var _ = require("lodash");
|
||||
var outputFileSync = require("output-file-sync");
|
||||
var chokidar = require("chokidar");
|
||||
var path = require("path");
|
||||
var util = require("./util");
|
||||
var fs = require("fs");
|
||||
var _ = require("lodash");
|
||||
|
||||
module.exports = function (commander, filenames, opts) {
|
||||
if (commander.sourceMapsInline) {
|
||||
@@ -15,16 +15,13 @@ module.exports = function (commander, filenames, opts) {
|
||||
|
||||
var data = util.compile(src, { sourceMapName: dest });
|
||||
|
||||
var up = path.normalize(dest + "/..");
|
||||
mkdirp.sync(up);
|
||||
|
||||
if (commander.sourceMaps) {
|
||||
var mapLoc = dest + ".map";
|
||||
data.code = util.addSourceMappingUrl(data.code, mapLoc);
|
||||
fs.writeFileSync(mapLoc, JSON.stringify(data.map));
|
||||
outputFileSync(mapLoc, JSON.stringify(data.map));
|
||||
}
|
||||
|
||||
fs.writeFileSync(dest, data.code);
|
||||
outputFileSync(dest, data.code);
|
||||
|
||||
console.log(src + " -> " + dest);
|
||||
};
|
||||
|
||||
@@ -28,7 +28,7 @@ module.exports = function (commander, filenames) {
|
||||
map.setSourceContent(filename, result.actual);
|
||||
|
||||
consumer.eachMapping(function (mapping) {
|
||||
map._mappings.push({
|
||||
map._mappings.add({
|
||||
generatedLine: mapping.generatedLine + offset,
|
||||
generatedColumn: mapping.generatedColumn,
|
||||
originalLine: mapping.originalLine,
|
||||
@@ -63,7 +63,7 @@ module.exports = function (commander, filenames) {
|
||||
|
||||
fs.writeFileSync(commander.outFile, result.code);
|
||||
} else {
|
||||
console.log(result.code);
|
||||
process.stdout.write(result.code + "\n");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -15,28 +15,29 @@ 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) {
|
||||
console.log(" " + title + ":");
|
||||
console.log();
|
||||
|
||||
var hasOptional = true;
|
||||
|
||||
_.each(_.keys(obj).sort(), function (key) {
|
||||
if (key[0] === "_") return;
|
||||
|
||||
if (obj[key].optional) {
|
||||
hasOptional = true;
|
||||
key = "[" + key + "]";
|
||||
}
|
||||
|
||||
@@ -99,17 +100,21 @@ 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))
|
||||
|
||||
@@ -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({
|
||||
@@ -94,8 +96,8 @@ function replEval(code, context, filename, callback) {
|
||||
var result;
|
||||
|
||||
try {
|
||||
if (/^\((.*?)\n\)$/.test(code)) {
|
||||
code = code.slice(1, -2); // remove "(" and "\n)"
|
||||
if (code[0] === "(" && code[code.length - 1] === ")") {
|
||||
code = code.slice(1, -1); // remove "(" and ")"
|
||||
}
|
||||
|
||||
result = _eval(code, filename);
|
||||
|
||||
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,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
var transform = module.exports = require("./transformation/transform");
|
||||
|
||||
transform.version = require("../../package").version;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = File;
|
||||
|
||||
var SHEBANG_REGEX = /^\#\!.*/;
|
||||
@@ -24,6 +26,7 @@ File.helpers = [
|
||||
"prototype-properties",
|
||||
"apply-constructor",
|
||||
"tagged-template-literal",
|
||||
"tagged-template-literal-loose",
|
||||
"interop-require",
|
||||
"to-array",
|
||||
"sliced-to-array",
|
||||
@@ -35,34 +38,38 @@ File.helpers = [
|
||||
"async-to-generator",
|
||||
"interop-require-wildcard",
|
||||
"typeof",
|
||||
"exports-wildcard",
|
||||
"extends"
|
||||
"extends",
|
||||
"get"
|
||||
];
|
||||
|
||||
File.excludeHelpersFromRuntime = [
|
||||
"async-to-generator",
|
||||
"typeof"
|
||||
"typeof",
|
||||
"tagged-template-literal-loose"
|
||||
];
|
||||
|
||||
File.normaliseOptions = function (opts) {
|
||||
opts = _.cloneDeep(opts || {});
|
||||
|
||||
_.defaults(opts, {
|
||||
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,
|
||||
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
|
||||
@@ -70,6 +77,23 @@ 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);
|
||||
|
||||
if (_.contains(opts.loose, "all")) {
|
||||
opts.loose = Object.keys(transform.transformers);
|
||||
}
|
||||
|
||||
// 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
|
||||
@@ -99,10 +123,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 = [];
|
||||
@@ -302,7 +331,10 @@ File.prototype.generateUid = function (name, scope) {
|
||||
};
|
||||
|
||||
File.prototype.generateUidIdentifier = function (name, scope) {
|
||||
return t.identifier(this.generateUid(name, scope));
|
||||
scope = scope || this.scope;
|
||||
var id = t.identifier(this.generateUid(name, scope));
|
||||
scope.add(id);
|
||||
return id;
|
||||
};
|
||||
|
||||
File.prototype._generateUid = function (name) {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = Buffer;
|
||||
|
||||
var util = require("../util");
|
||||
@@ -61,39 +63,63 @@ 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);
|
||||
};
|
||||
|
||||
Buffer.prototype.newline = function (i, removeLast) {
|
||||
if (this.format.compact) return;
|
||||
|
||||
if (_.isBoolean(i)) {
|
||||
removeLast = i;
|
||||
i = null;
|
||||
}
|
||||
removeLast = removeLast || false;
|
||||
|
||||
if (_.isNumber(i)) {
|
||||
if (this.endsWith("{\n")) i--;
|
||||
if (this.endsWith(util.repeat(i, "\n"))) return;
|
||||
|
||||
var self = this;
|
||||
_.times(i, function () {
|
||||
self.newline(null, removeLast);
|
||||
});
|
||||
while (i--) {
|
||||
this._newline(removeLast);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (_.isBoolean(i)) {
|
||||
removeLast = i;
|
||||
}
|
||||
|
||||
this._newline(removeLast);
|
||||
};
|
||||
|
||||
Buffer.prototype._newline = function (removeLast) {
|
||||
if (removeLast && this.isLast("\n")) this.removeLast("\n");
|
||||
|
||||
this.removeLast(" ");
|
||||
|
||||
// remove whitespace if last character was a newline
|
||||
this.buf = this.buf.replace(/\n +$/, "\n");
|
||||
|
||||
this._removeSpacesAfterLastNewline();
|
||||
this._push("\n");
|
||||
};
|
||||
|
||||
/**
|
||||
* If buffer ends with a newline and some spaces after it, trim those spaces.
|
||||
*/
|
||||
Buffer.prototype._removeSpacesAfterLastNewline = function () {
|
||||
var lastNewlineIndex = this.buf.lastIndexOf('\n');
|
||||
if (lastNewlineIndex === -1)
|
||||
return;
|
||||
|
||||
var index = this.buf.length - 1;
|
||||
while (index > lastNewlineIndex) {
|
||||
if (this.buf[index] !== ' ') {
|
||||
break;
|
||||
}
|
||||
|
||||
index--;
|
||||
}
|
||||
|
||||
if (index === lastNewlineIndex) {
|
||||
this.buf = this.buf.substring(0, index + 1);
|
||||
}
|
||||
};
|
||||
|
||||
Buffer.prototype.push = function (str, noIndent) {
|
||||
if (this._indent && !noIndent && str !== "\n") {
|
||||
// we have an indent level and we aren't pushing a newline
|
||||
@@ -115,13 +141,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;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = function (ast, opts, code) {
|
||||
var gen = new CodeGenerator(ast, opts, code);
|
||||
return gen.generate();
|
||||
@@ -125,7 +127,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);
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
exports.File = function (node, print) {
|
||||
print(node.program);
|
||||
};
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
exports.ClassExpression =
|
||||
exports.ClassDeclaration = function (node, print) {
|
||||
this.push("class");
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
exports.ComprehensionBlock = function (node, print) {
|
||||
this.keyword("for");
|
||||
this.push("(");
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
@@ -1,3 +1,35 @@
|
||||
exports.ClassProperty = function () {
|
||||
throw new Error("not implemented");
|
||||
"use strict";
|
||||
|
||||
exports.AnyTypeAnnotation =
|
||||
exports.ArrayTypeAnnotation =
|
||||
exports.BooleanTypeAnnotation =
|
||||
exports.ClassProperty =
|
||||
exports.DeclareClass =
|
||||
exports.DeclareFunction =
|
||||
exports.DeclareModule =
|
||||
exports.DeclareVariable =
|
||||
exports.FunctionTypeAnnotation =
|
||||
exports.FunctionTypeParam =
|
||||
exports.GenericTypeAnnotation =
|
||||
exports.InterfaceExtends =
|
||||
exports.InterfaceDeclaration =
|
||||
exports.IntersectionTypeAnnotation =
|
||||
exports.NullableTypeAnnotation =
|
||||
exports.NumberTypeAnnotation =
|
||||
exports.StringLiteralTypeAnnotation =
|
||||
exports.StringTypeAnnotation =
|
||||
exports.TupleTypeAnnotation =
|
||||
exports.TypeofTypeAnnotation =
|
||||
exports.TypeAlias =
|
||||
exports.TypeAnnotation =
|
||||
exports.TypeParameterDeclaration =
|
||||
exports.TypeParameterInstantiation =
|
||||
exports.ObjectTypeAnnotation =
|
||||
exports.ObjectTypeCallProperty =
|
||||
exports.ObjectTypeIndexer =
|
||||
exports.ObjectTypeProperty =
|
||||
exports.QualifiedTypeIdentifier =
|
||||
exports.UnionTypeAnnotation =
|
||||
exports.VoidTypeAnnotation = function () {
|
||||
// todo: implement these once we have a `--keep-types` option
|
||||
};
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
var t = require("../../types");
|
||||
|
||||
exports._params = function (node, print) {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
var _ = require("lodash");
|
||||
|
||||
_.each(["BindMemberExpression", "BindFunctionExpression"], function (type) {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
|
||||
@@ -107,7 +109,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 ");
|
||||
@@ -158,18 +169,19 @@ exports.DebuggerStatement = function () {
|
||||
exports.VariableDeclaration = function (node, print, parent) {
|
||||
this.push(node.kind + " ");
|
||||
|
||||
var inits = 0;
|
||||
var noInits = 0;
|
||||
for (var i in node.declarations) {
|
||||
if (node.declarations[i].init) {
|
||||
inits++;
|
||||
} else {
|
||||
noInits++;
|
||||
var hasInits = false;
|
||||
// don't add whitespace to loop heads
|
||||
if (!t.isFor(parent)) {
|
||||
for (var i = 0; i < node.declarations.length; i++) {
|
||||
if (node.declarations[i].init) {
|
||||
// has an init so let's split it up over multiple lines
|
||||
hasInits = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var sep = ",";
|
||||
if (inits > noInits) { // more inits than noinits
|
||||
if (hasInits) {
|
||||
sep += "\n" + util.repeat(node.kind.length + 1);
|
||||
} else {
|
||||
sep += " ";
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
var _ = require("lodash");
|
||||
|
||||
exports.TaggedTemplateExpression = function (node, print) {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
var _ = require("lodash");
|
||||
|
||||
exports.Identifier = function (node) {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = Node;
|
||||
|
||||
var whitespace = require("./whitespace");
|
||||
@@ -6,14 +8,19 @@ var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
var find = function (obj, node, parent) {
|
||||
if (!obj) return;
|
||||
var result;
|
||||
|
||||
_.each(obj, function (fn, type) {
|
||||
if (t["is" + type](node)) {
|
||||
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;
|
||||
};
|
||||
@@ -23,13 +30,11 @@ function Node(node, parent) {
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
Node.prototype.isUserWhitespacable = function () {
|
||||
return t.isUserWhitespacable(this.node);
|
||||
Node.isUserWhitespacable = function (node) {
|
||||
return t.isUserWhitespacable(node);
|
||||
};
|
||||
|
||||
Node.prototype.needsWhitespace = function (type) {
|
||||
var parent = this.parent;
|
||||
var node = this.node;
|
||||
Node.needsWhitespace = function (node, parent, type) {
|
||||
if (!node) return 0;
|
||||
|
||||
if (t.isExpressionStatement(node)) {
|
||||
@@ -46,18 +51,15 @@ Node.prototype.needsWhitespace = function (type) {
|
||||
return lines || 0;
|
||||
};
|
||||
|
||||
Node.prototype.needsWhitespaceBefore = function () {
|
||||
return this.needsWhitespace("before");
|
||||
Node.needsWhitespaceBefore = function (node, parent) {
|
||||
return Node.needsWhitespace(node, parent, "before");
|
||||
};
|
||||
|
||||
Node.prototype.needsWhitespaceAfter = function () {
|
||||
return this.needsWhitespace("after");
|
||||
Node.needsWhitespaceAfter = function (node, parent) {
|
||||
return Node.needsWhitespace(node, parent, "after");
|
||||
};
|
||||
|
||||
Node.prototype.needsParens = function () {
|
||||
var parent = this.parent;
|
||||
var node = this.node;
|
||||
|
||||
Node.needsParens = function (node, parent) {
|
||||
if (!parent) return false;
|
||||
|
||||
if (t.isNewExpression(parent) && parent.callee === node) {
|
||||
@@ -72,10 +74,7 @@ Node.prototype.needsParens = function () {
|
||||
return find(parens, node, parent);
|
||||
};
|
||||
|
||||
Node.prototype.needsParensNoLineTerminator = function () {
|
||||
var parent = this.parent;
|
||||
var node = this.node;
|
||||
|
||||
Node.needsParensNoLineTerminator = function (node, parent) {
|
||||
if (!parent) return false;
|
||||
|
||||
// no comments
|
||||
@@ -95,11 +94,18 @@ Node.prototype.needsParensNoLineTerminator = function () {
|
||||
return false;
|
||||
};
|
||||
|
||||
_.each(Node.prototype, function (fn, key) {
|
||||
Node[key] = function (node, parent) {
|
||||
var n = new Node(node, parent);
|
||||
_.each(Node, function (fn, key) {
|
||||
Node.prototype[key] = function () {
|
||||
// Avoid leaking arguments to prevent deoptimization
|
||||
var args = new Array(arguments.length + 2);
|
||||
|
||||
var args = _.toArray(arguments).slice(2);
|
||||
return n[key].apply(n, args);
|
||||
args[0] = this.node;
|
||||
args[1] = this.parent;
|
||||
|
||||
for (var i = 0; i < args.length; i++) {
|
||||
args[i + 2] = arguments[i];
|
||||
}
|
||||
|
||||
return Node[key].apply(null, args);
|
||||
};
|
||||
});
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
@@ -21,6 +23,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" });
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
var _ = require("lodash");
|
||||
var t = require("../../types");
|
||||
|
||||
@@ -62,11 +64,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,6 +1,6 @@
|
||||
module.exports = Position;
|
||||
"use strict";
|
||||
|
||||
var _ = require("lodash");
|
||||
module.exports = Position;
|
||||
|
||||
function Position() {
|
||||
this.line = 1;
|
||||
@@ -8,26 +8,22 @@ function Position() {
|
||||
}
|
||||
|
||||
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--;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = SourceMap;
|
||||
|
||||
var sourceMap = require("source-map");
|
||||
|
||||
@@ -1,25 +1,62 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = Whitespace;
|
||||
|
||||
var _ = require("lodash");
|
||||
var _ = require("lodash");
|
||||
|
||||
/**
|
||||
* Returns `i`th number from `base`, continuing from 0 when `max` is reached.
|
||||
* Useful for shifting `for` loop by a fixed number but going over all items.
|
||||
*
|
||||
* @param {Number} i Current index in the loop
|
||||
* @param {Number} base Start index for which to return 0
|
||||
* @param {Number} max Array length
|
||||
* @returns {Number} shiftedIndex
|
||||
*/
|
||||
function getLookupIndex(i, base, max) {
|
||||
i += base;
|
||||
|
||||
if (i >= max)
|
||||
i -= max;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
function Whitespace(tokens, comments) {
|
||||
this.tokens = _.sortBy(tokens.concat(comments), "start");
|
||||
this.used = [];
|
||||
this.used = {};
|
||||
|
||||
// Profiling this code shows that while generator passes over it, indexes
|
||||
// returned by `getNewlinesBefore` and `getNewlinesAfter` are always increasing.
|
||||
|
||||
// We use this implementation detail for an optimization: instead of always
|
||||
// starting to look from `this.tokens[0]`, we will start `for` loops from the
|
||||
// previous successful match. We will enumerate all tokens—but the common
|
||||
// case will be much faster.
|
||||
|
||||
this._lastFoundIndex = 0;
|
||||
}
|
||||
|
||||
Whitespace.prototype.getNewlinesBefore = function (node) {
|
||||
var startToken;
|
||||
var endToken;
|
||||
var tokens = this.tokens;
|
||||
var token;
|
||||
|
||||
for (var j = 0; j < tokens.length; j++) {
|
||||
// optimize for forward traversal by shifting for loop index
|
||||
var i = getLookupIndex(j, this._lastFoundIndex, this.tokens.length);
|
||||
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;
|
||||
|
||||
this._lastFoundIndex = i;
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return this.getNewlinesBetween(startToken, endToken);
|
||||
};
|
||||
@@ -28,32 +65,44 @@ Whitespace.prototype.getNewlinesAfter = function (node) {
|
||||
var startToken;
|
||||
var endToken;
|
||||
var tokens = this.tokens;
|
||||
var token;
|
||||
|
||||
for (var j = 0; j < tokens.length; j++) {
|
||||
// optimize for forward traversal by shifting for loop index
|
||||
var i = getLookupIndex(j, this._lastFoundIndex, this.tokens.length);
|
||||
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;
|
||||
|
||||
this._lastFoundIndex = i;
|
||||
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;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Whitespace.prototype.getNewlinesBetween = function (startToken, endToken) {
|
||||
var start = startToken ? startToken.loc.end.line : 1;
|
||||
var end = endToken.loc.start.line;
|
||||
|
||||
var lines = 0;
|
||||
|
||||
for (var line = start; line < end; line++) {
|
||||
if (!_.contains(this.used, line)) {
|
||||
this.used.push(line);
|
||||
if (typeof this.used[line] === 'undefined') {
|
||||
this.used[line] = true;
|
||||
lines++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
var transform = require("./transformation/transform");
|
||||
var util = require("./util");
|
||||
var fs = require("fs");
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
var t = require("./types");
|
||||
var _ = require("lodash");
|
||||
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
"use strict";
|
||||
|
||||
require("core-js/shim");
|
||||
require("regenerator/runtime");
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
// Required to safely use 6to5/register within a browserify codebase.
|
||||
"use strict";
|
||||
|
||||
// required to safely use 6to5/register within a browserify codebase
|
||||
|
||||
module.exports = function () {};
|
||||
|
||||
require("./polyfill");
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
require("./polyfill");
|
||||
|
||||
var sourceMapSupport = require("source-map-support");
|
||||
@@ -21,51 +23,6 @@ sourceMapSupport.install({
|
||||
}
|
||||
});
|
||||
|
||||
//
|
||||
|
||||
var blacklist = [];
|
||||
|
||||
var blacklistTest = function (transformer, code) {
|
||||
try {
|
||||
if (_.isFunction(code)) {
|
||||
code();
|
||||
} else {
|
||||
new Function(code);
|
||||
}
|
||||
blacklist.push(transformer);
|
||||
} catch (err) {
|
||||
if (err.name !== "SyntaxError") throw err;
|
||||
}
|
||||
};
|
||||
|
||||
blacklistTest("arrayComprehension", "var foo = [for (foo of bar) foo * foo];");
|
||||
blacklistTest("generatorComprehension", "var foo = (for (foo of bar) foo * foo)");
|
||||
blacklistTest("arrowFunctions", "var foo = x => x * x;");
|
||||
blacklistTest("classes", "class Foo {}");
|
||||
blacklistTest("computedPropertyNames", "var foo = { [foo]: bar };");
|
||||
blacklistTest("constants", function () {
|
||||
try {
|
||||
new Function("const foo = 'foo';\nfoo = 'wow';");
|
||||
} catch (err) {
|
||||
return; // constants are supported
|
||||
}
|
||||
throw new SyntaxError;
|
||||
});
|
||||
blacklistTest("defaultParamaters", "var foo = function (bar = 0) {};");
|
||||
blacklistTest("destructuring", "var { x, y } = { x: 0, y: 0 };");
|
||||
blacklistTest("forOf", "for (var foo of bar) {}");
|
||||
blacklistTest("generators", "function* foo() {}\nasync function bar() {}"); // generators/async functions delegated to same transformer
|
||||
blacklistTest("letScoping", "let foo = 0;");
|
||||
blacklistTest("modules", 'import foo from "from";');
|
||||
blacklistTest("propertyMethodAssignment", "{ get foo() {} }");
|
||||
blacklistTest("propertyNameShorthand", "var foo = { x, y };");
|
||||
blacklistTest("restParameters", "function foo(...bar) {}");
|
||||
blacklistTest("spread", "foo(...bar);");
|
||||
blacklistTest("templateLiterals", "var foo = `foo`;");
|
||||
blacklistTest("unicodeRegex", function () { new RegExp("foo", "u"); });
|
||||
|
||||
//
|
||||
|
||||
var transformOpts = {};
|
||||
var ignoreRegex = /node_modules/;
|
||||
var onlyRegex;
|
||||
@@ -95,7 +52,6 @@ var loader = function (m, filename) {
|
||||
|
||||
result = result || to5.transformFileSync(filename, _.extend({
|
||||
whitelist: whitelist,
|
||||
blacklist: blacklist,
|
||||
sourceMap: true,
|
||||
ast: false
|
||||
}, transformOpts));
|
||||
@@ -123,7 +79,7 @@ var hookExtensions = function (_exts) {
|
||||
});
|
||||
};
|
||||
|
||||
hookExtensions([".es6", ".es", ".js"]);
|
||||
hookExtensions(util.canCompile.EXTENSIONS);
|
||||
|
||||
module.exports = function (opts) {
|
||||
// normalise options
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
var generator = require("./generation/generator");
|
||||
var util = require("./util");
|
||||
var File = require("./file");
|
||||
@@ -20,7 +22,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));
|
||||
|
||||
17
lib/6to5/to-fast-properties.js
Normal file
17
lib/6to5/to-fast-properties.js
Normal file
@@ -0,0 +1,17 @@
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* A trick from Bluebird to force V8 to use fast properties for an object.
|
||||
* Read more: http://stackoverflow.com/questions/24987896/
|
||||
*
|
||||
* Use %HasFastProperties(obj) and --allow-natives-syntax to check whether
|
||||
* a particular object already has fast properties.
|
||||
*/
|
||||
|
||||
module.exports = function toFastProperties(obj) {
|
||||
/*jshint -W027*/
|
||||
function f() {}
|
||||
f.prototype = obj;
|
||||
return f;
|
||||
eval(obj);
|
||||
};
|
||||
@@ -0,0 +1,45 @@
|
||||
"use strict";
|
||||
|
||||
var explode = require("./explode-assignable-expression");
|
||||
var t = require("../../types");
|
||||
|
||||
module.exports = function (exports, opts) {
|
||||
var isAssignment = function (node) {
|
||||
return node.operator === opts.operator + "=";
|
||||
};
|
||||
|
||||
var buildAssignment = function (left, right) {
|
||||
return t.assignmentExpression("=", left, right);
|
||||
};
|
||||
|
||||
exports.ExpressionStatement = function (node, parent, scope, context, file) {
|
||||
var expr = node.expression;
|
||||
if (!isAssignment(expr)) return;
|
||||
|
||||
var nodes = [];
|
||||
var exploded = explode(expr.left, nodes, file, scope, true);
|
||||
|
||||
nodes.push(t.expressionStatement(
|
||||
buildAssignment(exploded.ref, opts.build(exploded.uid, expr.right))
|
||||
));
|
||||
|
||||
return nodes;
|
||||
};
|
||||
|
||||
exports.AssignmentExpression = function (node, parent, scope, context, file) {
|
||||
if (t.isExpressionStatement(parent)) return;
|
||||
if (!isAssignment(node)) return;
|
||||
|
||||
var nodes = [];
|
||||
var exploded = explode(node.left, nodes, file, scope);
|
||||
nodes.push(opts.build(exploded.uid, node.right));
|
||||
nodes.push(exploded.ref);
|
||||
|
||||
return t.toSequenceExpression(nodes, scope);
|
||||
};
|
||||
|
||||
exports.BinaryExpression = function (node) {
|
||||
if (node.operator !== opts.operator) return;
|
||||
return opts.build(node.left, node.right);
|
||||
};
|
||||
};
|
||||
25
lib/6to5/transformation/helpers/build-comprehension.js
Normal file
25
lib/6to5/transformation/helpers/build-comprehension.js
Normal file
@@ -0,0 +1,25 @@
|
||||
"use strict";
|
||||
|
||||
var t = require("../../types");
|
||||
|
||||
module.exports = function build(node, buildBody) {
|
||||
var self = node.blocks.shift();
|
||||
if (!self) return;
|
||||
|
||||
var child = build(node, buildBody);
|
||||
if (!child) {
|
||||
// last item
|
||||
child = buildBody();
|
||||
|
||||
// add a filter as this is our final stop
|
||||
if (node.filter) {
|
||||
child = t.ifStatement(node.filter, t.blockStatement([child]));
|
||||
}
|
||||
}
|
||||
|
||||
return t.forOfStatement(
|
||||
t.variableDeclaration("let", [t.variableDeclarator(self.left)]),
|
||||
self.right,
|
||||
t.blockStatement([child])
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,45 @@
|
||||
"use strict";
|
||||
|
||||
var explode = require("./explode-assignable-expression");
|
||||
var t = require("../../types");
|
||||
|
||||
module.exports = function (exports, opts) {
|
||||
var buildAssignment = function (left, right) {
|
||||
return t.assignmentExpression("=", left, right);
|
||||
};
|
||||
|
||||
exports.ExpressionStatement = function (node, parent, scope, context, file) {
|
||||
var expr = node.expression;
|
||||
if (!opts.is(expr, file)) return;
|
||||
|
||||
var nodes = [];
|
||||
|
||||
var exploded = explode(expr.left, nodes, file, scope);
|
||||
|
||||
nodes.push(t.ifStatement(
|
||||
opts.build(exploded.uid, file),
|
||||
t.expressionStatement(buildAssignment(exploded.ref, expr.right))
|
||||
));
|
||||
|
||||
return nodes;
|
||||
};
|
||||
|
||||
exports.AssignmentExpression = function (node, parent, scope, context, file) {
|
||||
if (t.isExpressionStatement(parent)) return;
|
||||
if (!opts.is(node, file)) return;
|
||||
|
||||
var nodes = [];
|
||||
var exploded = explode(node.left, nodes, file, scope);
|
||||
|
||||
nodes.push(t.logicalExpression(
|
||||
"&&",
|
||||
opts.build(exploded.uid, file),
|
||||
buildAssignment(exploded.ref, node.right)
|
||||
));
|
||||
|
||||
// todo: duplicate expression node
|
||||
nodes.push(exploded.ref);
|
||||
|
||||
return t.toSequenceExpression(nodes, scope);
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,57 @@
|
||||
"use strict";
|
||||
|
||||
var t = require("../../types");
|
||||
|
||||
var getObjRef = function (node, nodes, file, scope) {
|
||||
var ref;
|
||||
if (t.isIdentifier(node)) {
|
||||
ref = node;
|
||||
} else if (t.isMemberExpression(node)) {
|
||||
ref = node.object;
|
||||
} else {
|
||||
throw new Error("We can't explode this node type " + node.type);
|
||||
}
|
||||
|
||||
var temp = scope.generateUidBasedOnNode(ref, file);
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(temp, ref)
|
||||
]));
|
||||
return temp;
|
||||
};
|
||||
|
||||
var getPropRef = function (node, nodes, file, scope) {
|
||||
var prop = node.property;
|
||||
var key = t.toComputedKey(node, prop);
|
||||
if (t.isLiteral(key)) return key;
|
||||
|
||||
var temp = scope.generateUidBasedOnNode(prop, file);
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(temp, prop)
|
||||
]));
|
||||
return temp;
|
||||
};
|
||||
|
||||
module.exports = function (node, nodes, file, scope, allowedSingleIdent) {
|
||||
var obj;
|
||||
if (t.isIdentifier(node) && allowedSingleIdent) {
|
||||
obj = node;
|
||||
} else {
|
||||
obj = getObjRef(node, nodes, file, scope);
|
||||
}
|
||||
|
||||
var ref, uid;
|
||||
|
||||
if (t.isIdentifier(node)) {
|
||||
ref = node;
|
||||
uid = obj;
|
||||
} else {
|
||||
var prop = getPropRef(node, nodes, file, scope);
|
||||
var computed = node.computed || t.isLiteral(prop);
|
||||
uid = ref = t.memberExpression(obj, prop, computed);
|
||||
}
|
||||
|
||||
return {
|
||||
uid: uid,
|
||||
ref: ref
|
||||
};
|
||||
};
|
||||
50
lib/6to5/transformation/helpers/name-method.js
Normal file
50
lib/6to5/transformation/helpers/name-method.js
Normal file
@@ -0,0 +1,50 @@
|
||||
"use strict";
|
||||
|
||||
var traverse = require("../../traverse");
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
|
||||
var traverser = {
|
||||
enter: function (node, parent, scope, context, state) {
|
||||
// check if this node is an identifier that matches the same as our function id
|
||||
if (!t.isIdentifier(node, { name: state.id })) return;
|
||||
|
||||
// check if this node is the one referenced
|
||||
if (!t.isReferenced(node, parent)) return;
|
||||
|
||||
// check that we don't have a local variable declared as that removes the need
|
||||
// for the wrapper
|
||||
var localDeclar = scope.get(state.id, true);
|
||||
if (localDeclar !== state.outerDeclar) return;
|
||||
|
||||
state.selfReference = true;
|
||||
context.stop();
|
||||
}
|
||||
};
|
||||
|
||||
exports.property = function (node, file, scope) {
|
||||
var key = t.toComputedKey(node, node.key);
|
||||
if (!t.isLiteral(key)) return node; // we can't set a function id with this
|
||||
|
||||
var id = t.toIdentifier(key.value);
|
||||
key = t.identifier(id);
|
||||
|
||||
var state = {
|
||||
id: id,
|
||||
selfReference: false,
|
||||
outerDeclar: scope.get(id, true),
|
||||
};
|
||||
|
||||
traverse(node, traverser, scope, state);
|
||||
|
||||
if (state.selfReference) {
|
||||
node.value = util.template("property-method-assignment-wrapper", {
|
||||
FUNCTION: node.value,
|
||||
FUNCTION_ID: key,
|
||||
FUNCTION_KEY: file.generateUidIdentifier(id, scope),
|
||||
WRAPPER_KEY: file.generateUidIdentifier(id + "Wrapper", scope)
|
||||
});
|
||||
} else {
|
||||
node.value.id = key;
|
||||
}
|
||||
};
|
||||
31
lib/6to5/transformation/helpers/remap-async-to-generator.js
Normal file
31
lib/6to5/transformation/helpers/remap-async-to-generator.js
Normal file
@@ -0,0 +1,31 @@
|
||||
"use strict";
|
||||
|
||||
var traverse = require("../../traverse");
|
||||
var t = require("../../types");
|
||||
|
||||
module.exports = function (node, callId) {
|
||||
node.async = false;
|
||||
node.generator = true;
|
||||
|
||||
traverse(node, {
|
||||
enter: function (node, parent, scope, context) {
|
||||
if (t.isFunction(node)) context.skip();
|
||||
|
||||
if (t.isAwaitExpression(node)) {
|
||||
node.type = "YieldExpression";
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var call = t.callExpression(callId, [node]);
|
||||
|
||||
if (t.isFunctionDeclaration(node)) {
|
||||
var declar = t.variableDeclaration("var", [
|
||||
t.variableDeclarator(node.id, call)
|
||||
]);
|
||||
declar._blockHoist = true;
|
||||
return declar;
|
||||
} else {
|
||||
return call;
|
||||
}
|
||||
};
|
||||
246
lib/6to5/transformation/helpers/replace-supers.js
Normal file
246
lib/6to5/transformation/helpers/replace-supers.js
Normal file
@@ -0,0 +1,246 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = ReplaceSupers;
|
||||
|
||||
var traverse = require("../../traverse");
|
||||
var t = require("../../types");
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
* @param {Object} methodNode
|
||||
* @param {Object} className
|
||||
* @param {Object} superName
|
||||
* @param {Boolean} isLoose
|
||||
* @param {File} file
|
||||
*/
|
||||
|
||||
function ReplaceSupers(methodNode, className, superName, isLoose, file) {
|
||||
this.topLevelThisReference = null;
|
||||
this.methodNode = methodNode;
|
||||
this.className = className;
|
||||
this.superName = superName;
|
||||
this.isLoose = isLoose;
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a node representing the super class value of the named property.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* _get(Object.getPrototypeOf(CLASS.prototype), "METHOD", this)
|
||||
*
|
||||
* @param {Node} property
|
||||
* @param {boolean} isStatic
|
||||
* @param {boolean} isComputed
|
||||
*
|
||||
* @returns {Node}
|
||||
*/
|
||||
|
||||
ReplaceSupers.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}
|
||||
*/
|
||||
|
||||
ReplaceSupers.prototype.looseSuperProperty = function (methodNode, id, parent) {
|
||||
var methodName = methodNode.key;
|
||||
var superName = this.superName || t.identifier("Function");
|
||||
|
||||
if (parent.property === id) {
|
||||
return;
|
||||
} else if (t.isCallExpression(parent, { callee: id })) {
|
||||
// super(); -> ClassName.prototype.MethodName.call(this);
|
||||
parent.arguments.unshift(t.thisExpression());
|
||||
|
||||
if (methodName.name === "constructor") {
|
||||
// constructor() { super(); }
|
||||
return t.memberExpression(superName, t.identifier("call"));
|
||||
} else {
|
||||
id = superName;
|
||||
|
||||
// foo() { super(); }
|
||||
if (!methodNode.static) {
|
||||
id = t.memberExpression(id, t.identifier("prototype"));
|
||||
}
|
||||
|
||||
id = t.memberExpression(id, methodName, methodNode.computed);
|
||||
return t.memberExpression(id, t.identifier("call"));
|
||||
}
|
||||
} else if (t.isMemberExpression(parent) && !methodNode.static) {
|
||||
// super.test -> ClassName.prototype.test
|
||||
return t.memberExpression(superName, t.identifier("prototype"));
|
||||
} else {
|
||||
return superName;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
|
||||
ReplaceSupers.prototype.replace = function () {
|
||||
this.traverseLevel(this.methodNode.value, true);
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
* @param {Object} node
|
||||
* @param {Boolean} topLevel
|
||||
*/
|
||||
|
||||
ReplaceSupers.prototype.traverseLevel = function (node, topLevel) {
|
||||
var self = this;
|
||||
|
||||
traverse(node, {
|
||||
enter: function (node, parent, scope, context) {
|
||||
if (t.isFunction(node) && !t.isArrowFunctionExpression(node)) {
|
||||
// we need to call traverseLevel again so we're context aware
|
||||
self.traverseLevel(node, false);
|
||||
return context.skip();
|
||||
}
|
||||
|
||||
if (t.isProperty(node, { method: true }) || t.isMethodDefinition(node)) {
|
||||
// break on object methods
|
||||
return context.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 self.getThisReference();
|
||||
}
|
||||
};
|
||||
|
||||
var callback = self.specHandle;
|
||||
if (self.isLoose) callback = self.looseHandle;
|
||||
return callback.call(self, getThisReference, node, parent);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
|
||||
ReplaceSupers.prototype.getThisReference = function () {
|
||||
if (this.topLevelThisReference) {
|
||||
return this.topLevelThisReference;
|
||||
} else {
|
||||
var ref = this.topLevelThisReference = this.file.generateUidIdentifier("this");
|
||||
this.methodNode.value.body.body.unshift(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(this.topLevelThisReference, t.thisExpression())
|
||||
]));
|
||||
return ref;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
* @param {Function} getThisReference
|
||||
* @param {Object} node
|
||||
* @param {Object} parent
|
||||
*/
|
||||
|
||||
ReplaceSupers.prototype.looseHandle = function (getThisReference, node, parent) {
|
||||
if (t.isIdentifier(node, { name: "super" })) {
|
||||
return this.looseSuperProperty(this.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());
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
* @param {Function} getThisReference
|
||||
* @param {Object} node
|
||||
* @param {Object} parent
|
||||
*/
|
||||
|
||||
ReplaceSupers.prototype.specHandle = function (getThisReference, node, parent) {
|
||||
var methodNode = this.methodNode;
|
||||
var property;
|
||||
var computed;
|
||||
var args;
|
||||
|
||||
if (t.isIdentifier(node, { name: "super" })) {
|
||||
if (!(t.isMemberExpression(parent) && !parent.computed && parent.property === node)) {
|
||||
throw this.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(); -> _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 = this.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;
|
||||
}
|
||||
};
|
||||
21
lib/6to5/transformation/helpers/use-strict.js
Normal file
21
lib/6to5/transformation/helpers/use-strict.js
Normal file
@@ -0,0 +1,21 @@
|
||||
"use strict";
|
||||
|
||||
var t = require("../../types");
|
||||
|
||||
exports.has = function (node) {
|
||||
var first = node.body[0];
|
||||
return t.isExpressionStatement(first) && t.isLiteral(first.expression, { value: "use strict" });
|
||||
};
|
||||
|
||||
exports.wrap = function (node, callback) {
|
||||
var useStrictNode;
|
||||
if (exports.has(node)) {
|
||||
useStrictNode = node.body.shift();
|
||||
}
|
||||
|
||||
callback();
|
||||
|
||||
if (useStrictNode) {
|
||||
node.body.unshift(useStrictNode);
|
||||
}
|
||||
};
|
||||
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = DefaultFormatter;
|
||||
|
||||
var traverse = require("../../traverse");
|
||||
@@ -16,35 +18,51 @@ function DefaultFormatter(file) {
|
||||
//this.checkCollisions();
|
||||
}
|
||||
|
||||
var exportsTraverser = {
|
||||
enter: function (node, parent, scope, context, localExports) {
|
||||
var declar = node && node.declaration;
|
||||
if (t.isExportDeclaration(node) && declar && t.isStatement(declar)) {
|
||||
_.extend(localExports, t.getIds(declar, true));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
DefaultFormatter.prototype.getLocalExports = function () {
|
||||
var localExports = {};
|
||||
|
||||
traverse(this.file.ast, {
|
||||
enter: function (node) {
|
||||
var declar = node && node.declaration;
|
||||
if (t.isExportDeclaration(node) && declar && t.isStatement(declar)) {
|
||||
_.extend(localExports, t.getIds(declar, true));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
traverse(this.file.ast, exportsTraverser, null, localExports);
|
||||
return localExports;
|
||||
};
|
||||
|
||||
var importsTraverser = {
|
||||
enter: function (node, parent, scope, context, localImports) {
|
||||
if (t.isImportDeclaration(node)) {
|
||||
_.extend(localImports, t.getIds(node, true));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
DefaultFormatter.prototype.getLocalImports = function () {
|
||||
var localImports = {};
|
||||
|
||||
traverse(this.file.ast, {
|
||||
enter: function (node) {
|
||||
if (t.isImportDeclaration(node)) {
|
||||
_.extend(localImports, t.getIds(node, true));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
traverse(this.file.ast, importsTraverser, null, localImports);
|
||||
return localImports;
|
||||
};
|
||||
|
||||
var collissionsTraverser = {
|
||||
enter: function (node, parent, scope, context, check) {
|
||||
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.checkCollisions = function () {
|
||||
// todo: all check export collissions
|
||||
|
||||
@@ -61,21 +79,7 @@ DefaultFormatter.prototype.checkCollisions = function () {
|
||||
}
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
});
|
||||
traverse(file.ast, collissionsTraverser, null, check);
|
||||
};
|
||||
|
||||
DefaultFormatter.prototype.remapExportAssignment = function (node) {
|
||||
@@ -100,9 +104,9 @@ DefaultFormatter.prototype.remapAssignments = function () {
|
||||
};
|
||||
|
||||
traverse(this.file.ast, {
|
||||
enter: function (node, parent, scope) {
|
||||
enter: function (node, parent, scope, context, isLocalReference) {
|
||||
if (t.isUpdateExpression(node) && isLocalReference(node.argument, scope)) {
|
||||
this.skip();
|
||||
context.skip();
|
||||
|
||||
// expand to long file assignment expression
|
||||
var assign = t.assignmentExpression(node.operator[0] + "=", node.argument, t.literal(1));
|
||||
@@ -130,11 +134,11 @@ DefaultFormatter.prototype.remapAssignments = function () {
|
||||
}
|
||||
|
||||
if (t.isAssignmentExpression(node) && isLocalReference(node.left, scope)) {
|
||||
this.skip();
|
||||
context.skip();
|
||||
return self.remapExportAssignment(node);
|
||||
}
|
||||
}
|
||||
});
|
||||
}, null, isLocalReference);
|
||||
};
|
||||
|
||||
DefaultFormatter.prototype.getModuleName = function () {
|
||||
@@ -156,8 +160,10 @@ DefaultFormatter.prototype.getModuleName = function () {
|
||||
filenameRelative = filenameRelative.replace(sourceRootRegEx, "");
|
||||
}
|
||||
|
||||
// remove extension
|
||||
filenameRelative = filenameRelative.replace(/\.(.*?)$/, "");
|
||||
if (!opts.keepModuleIdExtensions) {
|
||||
// remove extension
|
||||
filenameRelative = filenameRelative.replace(/\.(.*?)$/, "");
|
||||
}
|
||||
|
||||
moduleName += filenameRelative;
|
||||
|
||||
@@ -217,7 +223,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])
|
||||
]));
|
||||
};
|
||||
@@ -241,13 +248,13 @@ DefaultFormatter.prototype.exportDeclaration = function (node, nodes) {
|
||||
var assign;
|
||||
|
||||
if (t.isVariableDeclaration(declar)) {
|
||||
for (var i in declar.declarations) {
|
||||
for (var i = 0; i < declar.declarations.length; i++) {
|
||||
var decl = declar.declarations[i];
|
||||
|
||||
decl.init = this._exportsAssign(decl.id, decl.init, node).expression;
|
||||
|
||||
var newDeclar = t.variableDeclaration(declar.kind, [decl]);
|
||||
if (i === "0") t.inherits(newDeclar, declar);
|
||||
if (i === 0) t.inherits(newDeclar, declar);
|
||||
nodes.push(newDeclar);
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
var util = require("../../util");
|
||||
|
||||
module.exports = function (Parent) {
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = require("./_strict")(require("./amd"));
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = AMDFormatter;
|
||||
|
||||
var DefaultFormatter = require("./_default");
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = require("./_strict")(require("./common"));
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = CommonJSFormatter;
|
||||
|
||||
var DefaultFormatter = require("./_default");
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = IgnoreFormatter;
|
||||
|
||||
var t = require("../../types");
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = SystemFormatter;
|
||||
|
||||
var AMDFormatter = require("./amd");
|
||||
var useStrict = require("../transformers/use-strict");
|
||||
var useStrict = require("../helpers/use-strict");
|
||||
var traverse = require("../../traverse");
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
@@ -63,28 +65,31 @@ SystemFormatter.prototype.importSpecifier = function (specifier, node, nodes) {
|
||||
|
||||
SystemFormatter.prototype.buildRunnerSetters = function (block, hoistDeclarators) {
|
||||
return t.arrayExpression(_.map(this.ids, function (uid, source) {
|
||||
var nodes = [];
|
||||
var state = {
|
||||
nodes: [],
|
||||
hoistDeclarators: hoistDeclarators
|
||||
};
|
||||
|
||||
traverse(block, {
|
||||
enter: function (node) {
|
||||
enter: function (node, parent, scope, context, state) {
|
||||
if (node._importSource === source) {
|
||||
if (t.isVariableDeclaration(node)) {
|
||||
_.each(node.declarations, function (declar) {
|
||||
hoistDeclarators.push(t.variableDeclarator(declar.id));
|
||||
nodes.push(t.expressionStatement(
|
||||
state.hoistDeclarators.push(t.variableDeclarator(declar.id));
|
||||
state.nodes.push(t.expressionStatement(
|
||||
t.assignmentExpression("=", declar.id, declar.init)
|
||||
));
|
||||
});
|
||||
} else {
|
||||
nodes.push(node);
|
||||
state.nodes.push(node);
|
||||
}
|
||||
|
||||
this.remove();
|
||||
context.remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
}, null, state);
|
||||
|
||||
return t.functionExpression(null, [uid], t.blockStatement(nodes));
|
||||
return t.functionExpression(null, [uid], t.blockStatement(state.nodes));
|
||||
}));
|
||||
};
|
||||
|
||||
@@ -112,10 +117,10 @@ SystemFormatter.prototype.transform = function (ast) {
|
||||
|
||||
// hoist up all variable declarations
|
||||
traverse(block, {
|
||||
enter: function (node, parent, scope) {
|
||||
enter: function (node, parent, scope, context, hoistDeclarators) {
|
||||
if (t.isFunction(node)) {
|
||||
// nothing inside is accessible
|
||||
return this.skip();
|
||||
return context.skip();
|
||||
}
|
||||
|
||||
if (t.isVariableDeclaration(node)) {
|
||||
@@ -150,7 +155,8 @@ SystemFormatter.prototype.transform = function (ast) {
|
||||
return nodes;
|
||||
}
|
||||
}
|
||||
});
|
||||
}, null, hoistDeclarators);
|
||||
|
||||
if (hoistDeclarators.length) {
|
||||
var hoistDeclar = t.variableDeclaration("var", hoistDeclarators);
|
||||
hoistDeclar._blockHoist = true;
|
||||
@@ -159,19 +165,19 @@ SystemFormatter.prototype.transform = function (ast) {
|
||||
|
||||
// hoist up function declarations for circular references
|
||||
traverse(block, {
|
||||
enter: function (node) {
|
||||
if (t.isFunction(node)) this.skip();
|
||||
enter: function (node, parent, scope, context, handlerBody) {
|
||||
if (t.isFunction(node)) context.skip();
|
||||
|
||||
if (t.isFunctionDeclaration(node) || node._blockHoist) {
|
||||
handlerBody.push(node);
|
||||
this.remove();
|
||||
context.remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
}, null, handlerBody);
|
||||
|
||||
handlerBody.push(returnStatement);
|
||||
|
||||
if (useStrict._has(block)) {
|
||||
if (useStrict.has(block)) {
|
||||
handlerBody.unshift(block.body.shift());
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = require("./_strict")(require("./umd"));
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = UMDFormatter;
|
||||
|
||||
var AMDFormatter = require("./amd");
|
||||
@@ -31,15 +33,17 @@ UMDFormatter.prototype.transform = function (ast) {
|
||||
|
||||
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 testModule = util.template("test-module");
|
||||
var commonTests = this.passModuleArg ? t.logicalExpression("&&", testExports, testModule) : testExports;
|
||||
|
||||
var commonArgs = [t.identifier("exports")];
|
||||
@@ -48,6 +52,12 @@ UMDFormatter.prototype.transform = function (ast) {
|
||||
return t.callExpression(t.identifier("require"), [name]);
|
||||
}));
|
||||
|
||||
// globals
|
||||
|
||||
//var umdArgs = [];
|
||||
|
||||
//
|
||||
|
||||
var moduleName = this.getModuleName();
|
||||
if (moduleName) defineArgs.unshift(t.literal(moduleName));
|
||||
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
ARRAY.forEach(function (KEY) {
|
||||
|
||||
});
|
||||
@@ -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,7 +0,0 @@
|
||||
(function (obj) {
|
||||
for (var i in obj) {
|
||||
if (exports[i] !== undefined) {
|
||||
exports[i] = obj[i];
|
||||
}
|
||||
}
|
||||
})
|
||||
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++) {
|
||||
for (var LEN = ARGUMENTS.length, ARRAY = Array(ARRAY_LEN), KEY = START; KEY < LEN; KEY++) {
|
||||
ARRAY[ARRAY_KEY] = ARGUMENTS[KEY];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
(function (strings, raw) {
|
||||
strings.raw = raw;
|
||||
return strings;
|
||||
});
|
||||
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = transform;
|
||||
|
||||
var Transformer = require("./transformer");
|
||||
@@ -20,7 +22,7 @@ transform.fromAst = function (ast, code, opts) {
|
||||
};
|
||||
|
||||
transform._ensureTransformerNames = function (type, keys) {
|
||||
for (var i in keys) {
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
var key = keys[i];
|
||||
if (!_.has(transform.transformers, key)) {
|
||||
throw new ReferenceError("unknown transformer " + key + " specified in " + type);
|
||||
@@ -43,8 +45,11 @@ transform.moduleFormatters = {
|
||||
|
||||
_.each({
|
||||
specNoForInOfAssignment: require("./transformers/spec-no-for-in-of-assignment"),
|
||||
specSetters: require("./transformers/spec-setters"),
|
||||
specBlockScopedFunctions: require("./transformers/spec-block-scoped-functions"),
|
||||
|
||||
// playground
|
||||
malletOperator: require("./transformers/playground-mallet-operator"),
|
||||
methodBinding: require("./transformers/playground-method-binding"),
|
||||
memoizationOperator: require("./transformers/playground-memoization-operator"),
|
||||
objectGetterMemoization: require("./transformers/playground-object-getter-memoization"),
|
||||
@@ -60,26 +65,26 @@ _.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"),
|
||||
destructuring: require("./transformers/es6-destructuring"),
|
||||
computedPropertyNames: require("./transformers/es6-computed-property-names"),
|
||||
defaultParameters: require("./transformers/es6-default-parameters"),
|
||||
restParameters: require("./transformers/es6-rest-parameters"),
|
||||
destructuring: require("./transformers/es6-destructuring"),
|
||||
forOf: require("./transformers/es6-for-of"),
|
||||
unicodeRegex: require("./transformers/es6-unicode-regex"),
|
||||
abstractReferences: require("./transformers/es7-abstract-references"),
|
||||
|
||||
constants: require("./transformers/es6-constants"),
|
||||
letScoping: require("./transformers/es6-let-scoping"),
|
||||
blockScopingTDZ: require("./transformers/optional-block-scoping-tdz"),
|
||||
|
||||
_blockHoist: require("./transformers/_block-hoist"),
|
||||
|
||||
generators: require("./transformers/es6-generators"),
|
||||
restParameters: require("./transformers/es6-rest-parameters"),
|
||||
|
||||
protoToAssign: require("./transformers/optional-proto-to-assign"),
|
||||
|
||||
@@ -93,6 +98,7 @@ _.each({
|
||||
typeofSymbol: require("./transformers/optional-typeof-symbol"),
|
||||
coreAliasing: require("./transformers/optional-core-aliasing"),
|
||||
undefinedToVoid: require("./transformers/optional-undefined-to-void"),
|
||||
undeclaredVariableCheck: require("./transformers/optional-undeclared-variable-check"),
|
||||
|
||||
// spec
|
||||
specPropertyLiterals: require("./transformers/spec-property-literals"),
|
||||
|
||||
@@ -1,9 +1,30 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = Transformer;
|
||||
|
||||
var traverse = require("../traverse");
|
||||
var t = require("../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
function noop() { }
|
||||
|
||||
function enter(node, parent, scope, context, args) {
|
||||
var fns = args[1][node.type];
|
||||
if (!fns) return;
|
||||
return fns.enter(node, parent, scope, context, args[0]);
|
||||
}
|
||||
|
||||
function exit(node, parent, scope, context, args) {
|
||||
var fns = args[1][node.type];
|
||||
if (!fns) return;
|
||||
return fns.exit(node, parent, scope, context, args[0]);
|
||||
}
|
||||
|
||||
var traverseOpts = {
|
||||
enter: enter,
|
||||
exit: exit
|
||||
};
|
||||
|
||||
function Transformer(key, transformer, opts) {
|
||||
this.manipulateOptions = transformer.manipulateOptions;
|
||||
this.experimental = !!transformer.experimental;
|
||||
@@ -32,6 +53,9 @@ Transformer.prototype.normalise = function (transformer) {
|
||||
|
||||
if (!_.isObject(fns)) return;
|
||||
|
||||
if (!fns.enter) fns.enter = noop;
|
||||
if (!fns.exit) fns.exit = noop;
|
||||
|
||||
transformer[type] = fns;
|
||||
|
||||
var aliases = t.FLIPPED_ALIAS_KEYS[type];
|
||||
@@ -54,28 +78,8 @@ Transformer.prototype.astRun = function (file, key) {
|
||||
};
|
||||
|
||||
Transformer.prototype.transform = function (file) {
|
||||
var transformer = this.transformer;
|
||||
|
||||
var build = function (exit) {
|
||||
return function (node, parent, scope) {
|
||||
var fns = transformer[node.type];
|
||||
if (!fns) return;
|
||||
|
||||
var fn = fns.enter;
|
||||
if (exit) fn = fns.exit;
|
||||
if (!fn) return;
|
||||
|
||||
return fn(node, parent, file, scope);
|
||||
};
|
||||
};
|
||||
|
||||
this.astRun(file, "before");
|
||||
|
||||
traverse(file.ast, {
|
||||
enter: build(),
|
||||
exit: build(true)
|
||||
});
|
||||
|
||||
traverse(file.ast, traverseOpts, null, [file, this.transformer]);
|
||||
this.astRun(file, "after");
|
||||
};
|
||||
|
||||
|
||||
@@ -1,57 +1,64 @@
|
||||
"use strict";
|
||||
|
||||
var traverse = require("../../traverse");
|
||||
var t = require("../../types");
|
||||
|
||||
var functionChildrenTraverser = {
|
||||
enter: function (node, parent, scope, context, state) {
|
||||
if (t.isFunction(node) && !node._aliasFunction) {
|
||||
return context.skip();
|
||||
}
|
||||
|
||||
if (node._ignoreAliasFunctions) return context.skip();
|
||||
|
||||
var getId;
|
||||
|
||||
if (t.isIdentifier(node) && node.name === "arguments") {
|
||||
getId = state.getArgumentsId;
|
||||
} else if (t.isThisExpression(node)) {
|
||||
getId = state.getThisId;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if (t.isReferenced(node, parent)) return getId();
|
||||
}
|
||||
};
|
||||
|
||||
var functionTraverser = {
|
||||
enter: function (node, parent, scope, context, state) {
|
||||
if (!node._aliasFunction) {
|
||||
if (t.isFunction(node)) {
|
||||
// stop traversal of this node as it'll be hit again by this transformer
|
||||
return context.skip();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// traverse all child nodes of this function and find `arguments` and `this`
|
||||
traverse(node, functionChildrenTraverser, null, state);
|
||||
|
||||
return context.skip();
|
||||
}
|
||||
};
|
||||
|
||||
var go = function (getBody, node, file, scope) {
|
||||
var argumentsId;
|
||||
var thisId;
|
||||
|
||||
var getArgumentsId = function () {
|
||||
return argumentsId = argumentsId || file.generateUidIdentifier("arguments", scope);
|
||||
};
|
||||
|
||||
var getThisId = function () {
|
||||
return thisId = thisId || file.generateUidIdentifier("this", scope);
|
||||
var state = {
|
||||
getArgumentsId: function () {
|
||||
return argumentsId = argumentsId || file.generateUidIdentifier("arguments", scope);
|
||||
},
|
||||
getThisId: function () {
|
||||
return thisId = thisId || file.generateUidIdentifier("this", scope);
|
||||
}
|
||||
};
|
||||
|
||||
// traverse the function and find all alias functions so we can alias
|
||||
// `arguments` and `this` if necessary
|
||||
traverse(node, {
|
||||
enter: function (node) {
|
||||
if (!node._aliasFunction) {
|
||||
if (t.isFunction(node)) {
|
||||
// stop traversal of this node as it'll be hit again by this transformer
|
||||
return this.skip();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// traverse all child nodes of this function and find `arguments` and `this`
|
||||
traverse(node, {
|
||||
enter: function (node, parent) {
|
||||
if (t.isFunction(node) && !node._aliasFunction) {
|
||||
return this.skip();
|
||||
}
|
||||
|
||||
if (node._ignoreAliasFunctions) return this.skip();
|
||||
|
||||
var getId;
|
||||
|
||||
if (t.isIdentifier(node) && node.name === "arguments") {
|
||||
getId = getArgumentsId;
|
||||
} else if (t.isThisExpression(node)) {
|
||||
getId = getThisId;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if (t.isReferenced(node, parent)) return getId();
|
||||
}
|
||||
});
|
||||
|
||||
return this.skip();
|
||||
}
|
||||
});
|
||||
traverse(node, functionTraverser, null, state);
|
||||
|
||||
var body;
|
||||
|
||||
@@ -71,14 +78,14 @@ var go = function (getBody, node, file, scope) {
|
||||
}
|
||||
};
|
||||
|
||||
exports.Program = function (node, parent, file, scope) {
|
||||
exports.Program = function (node, parent, scope, context, file) {
|
||||
go(function () {
|
||||
return node.body;
|
||||
}, node, file, scope);
|
||||
};
|
||||
|
||||
exports.FunctionDeclaration =
|
||||
exports.FunctionExpression = function (node, parent, file, scope) {
|
||||
exports.FunctionExpression = function (node, parent, scope, context, file) {
|
||||
go(function () {
|
||||
t.ensureBlock(node);
|
||||
return node.body.body;
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
var useStrict = require("./use-strict");
|
||||
"use strict";
|
||||
|
||||
var useStrict = require("../helpers/use-strict");
|
||||
var _ = require("lodash");
|
||||
|
||||
// Priority:
|
||||
@@ -12,13 +14,13 @@ exports.BlockStatement =
|
||||
exports.Program = {
|
||||
exit: function (node) {
|
||||
var hasChange = false;
|
||||
for (var i in node.body) {
|
||||
for (var i = 0; i < node.body.length; i++) {
|
||||
var bodyNode = node.body[i];
|
||||
if (bodyNode && bodyNode._blockHoist != null) hasChange = true;
|
||||
}
|
||||
if (!hasChange) return;
|
||||
|
||||
useStrict._wrap(node, function () {
|
||||
useStrict.wrap(node, function () {
|
||||
var nodePriorities = _.groupBy(node.body, function (bodyNode) {
|
||||
var priority = bodyNode._blockHoist;
|
||||
if (priority == null) priority = 1;
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
var useStrict = require("./use-strict");
|
||||
"use strict";
|
||||
|
||||
var useStrict = require("../helpers/use-strict");
|
||||
var t = require("../../types");
|
||||
|
||||
exports.secondPass = true;
|
||||
|
||||
exports.BlockStatement =
|
||||
exports.Program = function (node) {
|
||||
if (!node._declarations) return;
|
||||
|
||||
var kinds = {};
|
||||
var kind;
|
||||
|
||||
useStrict._wrap(node, function () {
|
||||
useStrict.wrap(node, function () {
|
||||
for (var i in node._declarations) {
|
||||
var declar = node._declarations[i];
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
var transform = require("../transform");
|
||||
|
||||
exports.ast = {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
var t = require("../../types");
|
||||
|
||||
exports.ArrowFunctionExpression = function (node) {
|
||||
|
||||
@@ -1,38 +1,28 @@
|
||||
var traverse = require("../../traverse");
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
"use strict";
|
||||
|
||||
exports.ClassDeclaration = function (node, parent, file, scope) {
|
||||
var closure = true;
|
||||
if (t.isProgram(parent) || t.isBlockStatement(parent)) {
|
||||
closure = false;
|
||||
}
|
||||
var ReplaceSupers = require("../helpers/replace-supers");
|
||||
var nameMethod = require("../helpers/name-method");
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
|
||||
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;
|
||||
}
|
||||
exports.ClassDeclaration = function (node, parent, scope, context, file) {
|
||||
return new Class(node, file, scope, true).run();
|
||||
};
|
||||
|
||||
exports.ClassExpression = function (node, parent, file, scope) {
|
||||
return new Class(node, file, scope, true).run();
|
||||
exports.ClassExpression = function (node, parent, scope, context, file) {
|
||||
if (!node.id) {
|
||||
if (t.isProperty(parent) && parent.value === node && !parent.computed && t.isIdentifier(parent.key)) {
|
||||
// var o = { foo: class {} };
|
||||
node.id = parent.key;
|
||||
}
|
||||
|
||||
if (t.isVariableDeclarator(parent) && t.isIdentifier(parent.id)) {
|
||||
// var foo = class {};
|
||||
node.id = parent.id;
|
||||
}
|
||||
}
|
||||
|
||||
return new Class(node, file, scope, false).run();
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -44,11 +34,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 +48,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 +66,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 +101,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 +133,32 @@ 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) {
|
||||
for (var i = 0; i < classBody.length; i++) {
|
||||
var node = classBody[i];
|
||||
if (t.isMethodDefinition(node)) {
|
||||
self.replaceInstanceSuperReferences(node);
|
||||
var replaceSupers = new ReplaceSupers(node, this.className, this.superName, this.isLoose, this.file);
|
||||
replaceSupers.replace();
|
||||
|
||||
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 +166,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) {
|
||||
@@ -192,95 +197,33 @@ Class.prototype.pushMethod = function (node) {
|
||||
var kind = node.kind;
|
||||
|
||||
if (kind === "") {
|
||||
// method
|
||||
nameMethod.property(node, this.file, this.scope);
|
||||
|
||||
var className = this.className;
|
||||
if (!node.static) className = t.memberExpression(className, t.identifier("prototype"));
|
||||
methodName = t.memberExpression(className, methodName, node.computed);
|
||||
if (this.isLoose) {
|
||||
// use assignments instead of define properties for loose classes
|
||||
|
||||
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 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);
|
||||
return;
|
||||
}
|
||||
util.pushMutatorMap(mutatorMap, methodName, kind, node);
|
||||
|
||||
kind = "value";
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Given a `methodNode`, produce a `MemberExpression` super class reference.
|
||||
*
|
||||
* @param {Node} methodNode MethodDefinition
|
||||
* @param {Node} node Identifier
|
||||
* @param {Node} parent
|
||||
*
|
||||
* @returns {Node}
|
||||
*/
|
||||
|
||||
Class.prototype.superIdentifier = function (methodNode, id, parent) {
|
||||
var methodName = methodNode.key;
|
||||
var superName = this.superName || t.identifier("Function");
|
||||
|
||||
if (parent.property === id) {
|
||||
return;
|
||||
} else if (t.isCallExpression(parent, { callee: id })) {
|
||||
// super(); -> ClassName.prototype.MethodName.call(this);
|
||||
parent.arguments.unshift(t.thisExpression());
|
||||
|
||||
if (methodName.name === "constructor") {
|
||||
// constructor() { super(); }
|
||||
return t.memberExpression(superName, t.identifier("call"));
|
||||
} else {
|
||||
id = superName;
|
||||
|
||||
// foo() { super(); }
|
||||
if (!methodNode.static) {
|
||||
id = t.memberExpression(id, t.identifier("prototype"));
|
||||
}
|
||||
|
||||
id = t.memberExpression(id, methodName, methodNode.computed);
|
||||
return t.memberExpression(id, t.identifier("call"));
|
||||
}
|
||||
} else if (t.isMemberExpression(parent) && !methodNode.static) {
|
||||
// super.test -> ClassName.prototype.test
|
||||
return t.memberExpression(superName, t.identifier("prototype"));
|
||||
var mutatorMap = this.instanceMutatorMap;
|
||||
if (node.static) {
|
||||
this.hasStaticMutators = true;
|
||||
mutatorMap = this.staticMutatorMap;
|
||||
} else {
|
||||
return superName;
|
||||
this.hasInstanceMutators = true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Replace all `super` references with a reference to our `superClass`.
|
||||
*
|
||||
* @param {Node} methodNode MethodDefinition
|
||||
*/
|
||||
|
||||
Class.prototype.replaceInstanceSuperReferences = function (methodNode) {
|
||||
var method = methodNode.value;
|
||||
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;
|
||||
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());
|
||||
}
|
||||
}
|
||||
});
|
||||
util.pushMutatorMap(mutatorMap, methodName, kind, node.computed, node);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -290,7 +233,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 +245,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;
|
||||
};
|
||||
|
||||
@@ -1,30 +1,69 @@
|
||||
"use strict";
|
||||
|
||||
var t = require("../../types");
|
||||
|
||||
exports.ObjectExpression = function (node, parent, file, scope) {
|
||||
exports.ObjectExpression = function (node, parent, scope, context, file) {
|
||||
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 = 0; i < node.properties.length; i++) {
|
||||
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 = 0; i < node.properties.length; i++) {
|
||||
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 = 0; i < props.length; i++) {
|
||||
prop = props[i];
|
||||
if (prop.kind !== "init") continue;
|
||||
|
||||
key = prop.key;
|
||||
|
||||
if (!prop.computed && t.isIdentifier(key)) {
|
||||
@@ -34,17 +73,16 @@ 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) {
|
||||
for (i = 0; i < props.length; i++) {
|
||||
prop = props[i];
|
||||
|
||||
if (prop.computed) {
|
||||
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;
|
||||
}
|
||||
@@ -53,7 +91,7 @@ exports.ObjectExpression = function (node, parent, file, scope) {
|
||||
// add a simple assignment for all Symbol member expressions due to symbol polyfill limitations
|
||||
// otherwise use Object.defineProperty
|
||||
|
||||
for (i in props) {
|
||||
for (i = 0; i < props.length; i++) {
|
||||
prop = props[i];
|
||||
if (!prop) continue;
|
||||
|
||||
@@ -84,14 +122,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,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
var traverse = require("../../traverse");
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
@@ -6,7 +8,7 @@ exports.Program =
|
||||
exports.BlockStatement =
|
||||
exports.ForInStatement =
|
||||
exports.ForOfStatement =
|
||||
exports.ForStatement = function (node, parent, file) {
|
||||
exports.ForStatement = function (node, parent, scope, context, file) {
|
||||
var hasConstants = false;
|
||||
var constants = {};
|
||||
|
||||
@@ -44,7 +46,7 @@ exports.ForStatement = function (node, parent, file) {
|
||||
}
|
||||
|
||||
if (t.isVariableDeclaration(child, { kind: "const" })) {
|
||||
for (var i in child.declarations) {
|
||||
for (var i = 0; i < child.declarations.length; i++) {
|
||||
var declar = child.declarations[i];
|
||||
|
||||
var ids = getIds(declar);
|
||||
@@ -69,14 +71,19 @@ exports.ForStatement = function (node, parent, file) {
|
||||
|
||||
if (!hasConstants) return;
|
||||
|
||||
var state = {
|
||||
check: check,
|
||||
getIds: getIds
|
||||
};
|
||||
|
||||
traverse(node, {
|
||||
enter: function (child, parent, scope) {
|
||||
enter: function (child, parent, scope, context, state) {
|
||||
if (child._ignoreConstant) return;
|
||||
if (t.isVariableDeclaration(child)) return;
|
||||
|
||||
if (t.isVariableDeclarator(child) || t.isDeclaration(child) || t.isAssignmentExpression(child)) {
|
||||
check(parent, getIds(child), scope);
|
||||
state.check(parent, state.getIds(child), scope);
|
||||
}
|
||||
}
|
||||
});
|
||||
}, null, state);
|
||||
};
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
"use strict";
|
||||
|
||||
var traverse = require("../../traverse");
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
exports.Function = function (node, parent, file, scope) {
|
||||
exports.Function = function (node, parent, scope, context, file) {
|
||||
if (!node.defaults || !node.defaults.length) return;
|
||||
t.ensureBlock(node);
|
||||
|
||||
@@ -12,10 +13,29 @@ exports.Function = function (node, parent, file, scope) {
|
||||
});
|
||||
|
||||
var iife = false;
|
||||
var i;
|
||||
var def;
|
||||
|
||||
for (i in node.defaults) {
|
||||
var checkTDZ = function (param, def, ids) {
|
||||
var check = function (node, parent) {
|
||||
if (!t.isReferencedIdentifier(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);
|
||||
|
||||
if (!t.isPattern(param)) {
|
||||
traverse(def, { enter: check });
|
||||
}
|
||||
};
|
||||
|
||||
for (var i = 0; i < node.defaults.length; i++) {
|
||||
def = node.defaults[i];
|
||||
if (!def) continue;
|
||||
|
||||
@@ -23,25 +43,13 @@ 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 (var i2 = 0; i2 < rightIds.length; i2++) {
|
||||
checkTDZ(param, def, rightIds[i2]);
|
||||
}
|
||||
|
||||
// we're accessing a variable that's already defined within this function
|
||||
var has = scope.get(param.name);
|
||||
var has = scope.get(param.name, true);
|
||||
if (has && node.params.indexOf(has) < 0) {
|
||||
iife = true;
|
||||
}
|
||||
@@ -54,19 +62,21 @@ exports.Function = function (node, parent, file, scope) {
|
||||
|
||||
var lastNonDefaultParam = 0;
|
||||
|
||||
for (i in node.defaults) {
|
||||
for (i = 0; i < node.defaults.length; i++) {
|
||||
def = node.defaults[i];
|
||||
if (!def) {
|
||||
lastNonDefaultParam = +i + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
body.push(util.template("default-parameter", {
|
||||
var defNode = util.template("default-parameter", {
|
||||
VARIABLE_NAME: node.params[i],
|
||||
DEFAULT_VALUE: def,
|
||||
ARGUMENT_KEY: t.literal(+i),
|
||||
ARGUMENTS: argsIdentifier
|
||||
}, true));
|
||||
}, true);
|
||||
defNode._blockHoist = node.defaults.length - i;
|
||||
body.push(defNode);
|
||||
}
|
||||
|
||||
// we need to cut off all trailing default parameters
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
// TODO: Clean up
|
||||
|
||||
var t = require("../../types");
|
||||
@@ -6,13 +8,27 @@ var buildVariableAssign = function (opts, id, init) {
|
||||
var op = opts.operator;
|
||||
if (t.isMemberExpression(id)) op = "=";
|
||||
|
||||
var node;
|
||||
|
||||
if (op) {
|
||||
return t.expressionStatement(t.assignmentExpression("=", id, init));
|
||||
node = t.expressionStatement(t.assignmentExpression(op, id, init));
|
||||
} else {
|
||||
return t.variableDeclaration(opts.kind, [
|
||||
node = t.variableDeclaration(opts.kind, [
|
||||
t.variableDeclarator(id, init)
|
||||
]);
|
||||
}
|
||||
|
||||
node._blockHoist = opts.blockHoist;
|
||||
|
||||
return node;
|
||||
};
|
||||
|
||||
var buildVariableDeclar = function (opts, id, init) {
|
||||
var declar = t.variableDeclaration("var", [
|
||||
t.variableDeclarator(id, init)
|
||||
]);
|
||||
declar._blockHoist = opts.blockHoist;
|
||||
return declar;
|
||||
};
|
||||
|
||||
var push = function (opts, nodes, elem, parentId) {
|
||||
@@ -46,12 +62,12 @@ var pushAssignmentPattern = function (opts, nodes, pattern, parentId) {
|
||||
};
|
||||
|
||||
var pushObjectPattern = function (opts, nodes, pattern, parentId) {
|
||||
for (var i in pattern.properties) {
|
||||
for (var i = 0; i < pattern.properties.length; i++) {
|
||||
var prop = pattern.properties[i];
|
||||
if (t.isSpreadProperty(prop)) {
|
||||
// get all the keys that appear in this object before the current spread
|
||||
var keys = [];
|
||||
for (var i2 in pattern.properties) {
|
||||
for (var i2 = 0; i2 < pattern.properties.length; i2++) {
|
||||
var prop2 = pattern.properties[i2];
|
||||
|
||||
if (i2 >= i) break;
|
||||
@@ -88,7 +104,7 @@ var pushArrayPattern = function (opts, nodes, pattern, parentId) {
|
||||
var i;
|
||||
|
||||
var hasSpreadElement = false;
|
||||
for (i in pattern.elements) {
|
||||
for (i = 0; i < pattern.elements.length; i++) {
|
||||
if (t.isSpreadElement(pattern.elements[i])) {
|
||||
hasSpreadElement = true;
|
||||
break;
|
||||
@@ -98,12 +114,10 @@ var pushArrayPattern = function (opts, nodes, pattern, parentId) {
|
||||
var toArray = opts.file.toArray(parentId, !hasSpreadElement && pattern.elements.length);
|
||||
|
||||
var _parentId = opts.scope.generateUidBasedOnNode(parentId, opts.file);
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(_parentId, toArray)
|
||||
]));
|
||||
nodes.push(buildVariableDeclar(opts, _parentId, toArray));
|
||||
parentId = _parentId;
|
||||
|
||||
for (i in pattern.elements) {
|
||||
for (i = 0; i < pattern.elements.length; i++) {
|
||||
var elem = pattern.elements[i];
|
||||
if (!elem) continue;
|
||||
|
||||
@@ -134,13 +148,9 @@ 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", [
|
||||
t.variableDeclarator(key, parentId)
|
||||
]));
|
||||
|
||||
nodes.push(buildVariableDeclar(opts, key, parentId));
|
||||
parentId = key;
|
||||
}
|
||||
|
||||
@@ -148,7 +158,7 @@ var pushPattern = function (opts) {
|
||||
};
|
||||
|
||||
exports.ForInStatement =
|
||||
exports.ForOfStatement = function (node, parent, file, scope) {
|
||||
exports.ForOfStatement = function (node, parent, scope, context, file) {
|
||||
var declar = node.left;
|
||||
if (!t.isVariableDeclaration(declar)) return;
|
||||
|
||||
@@ -174,24 +184,25 @@ exports.ForOfStatement = function (node, parent, file, scope) {
|
||||
block.body = nodes.concat(block.body);
|
||||
};
|
||||
|
||||
exports.Function = function (node, parent, file, scope) {
|
||||
exports.Function = function (node, parent, scope, context, file) {
|
||||
var nodes = [];
|
||||
|
||||
var hasDestructuring = false;
|
||||
|
||||
node.params = node.params.map(function (pattern) {
|
||||
node.params = node.params.map(function (pattern, i) {
|
||||
if (!t.isPattern(pattern)) return pattern;
|
||||
|
||||
hasDestructuring = true;
|
||||
var parentId = file.generateUidIdentifier("ref", scope);
|
||||
|
||||
pushPattern({
|
||||
kind: "var",
|
||||
nodes: nodes,
|
||||
pattern: pattern,
|
||||
id: parentId,
|
||||
file: file,
|
||||
scope: scope
|
||||
blockHoist: node.params.length - i,
|
||||
pattern: pattern,
|
||||
nodes: nodes,
|
||||
scope: scope,
|
||||
file: file,
|
||||
kind: "var",
|
||||
id: parentId
|
||||
});
|
||||
|
||||
return parentId;
|
||||
@@ -205,7 +216,7 @@ exports.Function = function (node, parent, file, scope) {
|
||||
block.body = nodes.concat(block.body);
|
||||
};
|
||||
|
||||
exports.CatchClause = function (node, parent, file, scope) {
|
||||
exports.CatchClause = function (node, parent, scope, context, file) {
|
||||
var pattern = node.param;
|
||||
if (!t.isPattern(pattern)) return;
|
||||
|
||||
@@ -223,7 +234,7 @@ exports.CatchClause = function (node, parent, file, scope) {
|
||||
node.body.body = nodes.concat(node.body.body);
|
||||
};
|
||||
|
||||
exports.ExpressionStatement = function (node, parent, file, scope) {
|
||||
exports.ExpressionStatement = function (node, parent, scope, context, file) {
|
||||
var expr = node.expression;
|
||||
if (expr.type !== "AssignmentExpression") return;
|
||||
|
||||
@@ -245,14 +256,13 @@ exports.ExpressionStatement = function (node, parent, file, scope) {
|
||||
return nodes;
|
||||
};
|
||||
|
||||
exports.AssignmentExpression = function (node, parent, file, scope) {
|
||||
exports.AssignmentExpression = function (node, parent, scope, context, file) {
|
||||
if (parent.type === "ExpressionStatement") return;
|
||||
if (!t.isPattern(node.left)) return;
|
||||
|
||||
var tempName = file.generateUid("temp", scope);
|
||||
var ref = t.identifier(tempName);
|
||||
var ref = file.generateUidIdentifier("temp", scope);
|
||||
scope.push({
|
||||
key: tempName,
|
||||
key: ref.name,
|
||||
id: ref
|
||||
});
|
||||
|
||||
@@ -270,7 +280,7 @@ exports.AssignmentExpression = function (node, parent, file, scope) {
|
||||
return t.toSequenceExpression(nodes, scope);
|
||||
};
|
||||
|
||||
exports.VariableDeclaration = function (node, parent, file, scope) {
|
||||
exports.VariableDeclaration = function (node, parent, scope, context, file) {
|
||||
if (t.isForInStatement(parent) || t.isForOfStatement(parent)) return;
|
||||
|
||||
var nodes = [];
|
||||
@@ -278,7 +288,7 @@ exports.VariableDeclaration = function (node, parent, file, scope) {
|
||||
var declar;
|
||||
|
||||
var hasPattern = false;
|
||||
for (i in node.declarations) {
|
||||
for (i = 0; i < node.declarations.length; i++) {
|
||||
declar = node.declarations[i];
|
||||
if (t.isPattern(declar.id)) {
|
||||
hasPattern = true;
|
||||
@@ -287,18 +297,18 @@ exports.VariableDeclaration = function (node, parent, file, scope) {
|
||||
}
|
||||
if (!hasPattern) return;
|
||||
|
||||
for (i in node.declarations) {
|
||||
for (i = 0; i < node.declarations.length; i++) {
|
||||
declar = node.declarations[i];
|
||||
|
||||
var patternId = declar.init;
|
||||
var pattern = declar.id;
|
||||
var opts = {
|
||||
kind: node.kind,
|
||||
nodes: nodes,
|
||||
pattern: pattern,
|
||||
id: patternId,
|
||||
nodes: nodes,
|
||||
scope: scope,
|
||||
kind: node.kind,
|
||||
file: file,
|
||||
scope: scope
|
||||
id: patternId,
|
||||
};
|
||||
|
||||
if (t.isPattern(pattern) && patternId) {
|
||||
@@ -317,7 +327,7 @@ exports.VariableDeclaration = function (node, parent, file, scope) {
|
||||
if (!t.isProgram(parent) && !t.isBlockStatement(parent)) {
|
||||
declar = null;
|
||||
|
||||
for (i in nodes) {
|
||||
for (i = 0; i < nodes.length; i++) {
|
||||
node = nodes[i];
|
||||
declar = declar || t.variableDeclaration(node.kind, []);
|
||||
|
||||
|
||||
@@ -1,16 +1,85 @@
|
||||
"use strict";
|
||||
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
|
||||
exports.ForOfStatement = function (node, parent, file, scope) {
|
||||
exports.ForOfStatement = function (node, parent, scope, context, file) {
|
||||
var callback = spec;
|
||||
if (file.isLoose("forOf")) callback = loose;
|
||||
|
||||
var build = callback(node, parent, scope, context, file);
|
||||
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);
|
||||
|
||||
// todo: find out why this is necessary? #538
|
||||
loop._scopeInfo = node._scopeInfo;
|
||||
|
||||
return loop;
|
||||
};
|
||||
|
||||
var loose = function (node, parent, scope, context, file) {
|
||||
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, scope, context, file) {
|
||||
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 +87,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,11 @@
|
||||
"use strict";
|
||||
|
||||
var regenerator = require("regenerator");
|
||||
|
||||
exports.ast = {
|
||||
before: require("regenerator").transform
|
||||
before: function (ast, file) {
|
||||
regenerator.transform(ast, {
|
||||
includeRuntime: file.opts.includeRegenerator && "if used"
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
var traverse = require("../../traverse");
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
@@ -25,7 +27,7 @@ var isVar = function (node, parent) {
|
||||
};
|
||||
|
||||
var standardiseLets = function (declars) {
|
||||
for (var i in declars) {
|
||||
for (var i = 0; i < declars.length; i++) {
|
||||
delete declars[i]._let;
|
||||
}
|
||||
};
|
||||
@@ -34,7 +36,7 @@ exports.VariableDeclaration = function (node, parent) {
|
||||
isLet(node, parent);
|
||||
};
|
||||
|
||||
exports.Loop = function (node, parent, file, scope) {
|
||||
exports.Loop = function (node, parent, scope, context, file) {
|
||||
var init = node.left || node.init;
|
||||
if (isLet(init, node)) {
|
||||
t.ensureBlock(node);
|
||||
@@ -46,7 +48,7 @@ exports.Loop = function (node, parent, file, scope) {
|
||||
node.label = parent.label;
|
||||
}
|
||||
|
||||
var letScoping = new LetScoping(node, node.body, parent, file, scope);
|
||||
var letScoping = new LetScoping(node, node.body, parent, scope, file);
|
||||
letScoping.run();
|
||||
|
||||
if (node.label && !t.isLabeledStatement(parent)) {
|
||||
@@ -55,9 +57,10 @@ exports.Loop = function (node, parent, file, scope) {
|
||||
}
|
||||
};
|
||||
|
||||
exports.BlockStatement = function (block, parent, file, scope) {
|
||||
exports.Program =
|
||||
exports.BlockStatement = function (block, parent, scope, context, file) {
|
||||
if (!t.isLoop(parent)) {
|
||||
var letScoping = new LetScoping(false, block, parent, file, scope);
|
||||
var letScoping = new LetScoping(false, block, parent, scope, file);
|
||||
letScoping.run();
|
||||
}
|
||||
};
|
||||
@@ -68,19 +71,21 @@ exports.BlockStatement = function (block, parent, file, scope) {
|
||||
* @param {Boolean|Node} loopParent
|
||||
* @param {Node} block
|
||||
* @param {Node} parent
|
||||
* @param {File} file
|
||||
* @param {Scope} scope
|
||||
* @param {File} file
|
||||
*/
|
||||
|
||||
function LetScoping(loopParent, block, parent, file, scope) {
|
||||
function LetScoping(loopParent, block, parent, scope, file) {
|
||||
this.loopParent = loopParent;
|
||||
this.parent = parent;
|
||||
this.scope = scope;
|
||||
this.block = block;
|
||||
this.file = file;
|
||||
|
||||
this.letReferences = {};
|
||||
this.body = [];
|
||||
this.outsideLetReferences = {};
|
||||
this.hasLetReferences = false;
|
||||
this.letReferences = block._letReferences = {};
|
||||
this.body = [];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,27 +94,98 @@ function LetScoping(loopParent, block, parent, file, scope) {
|
||||
|
||||
LetScoping.prototype.run = function () {
|
||||
var block = this.block;
|
||||
|
||||
if (block._letDone) return;
|
||||
block._letDone = true;
|
||||
|
||||
this.info = this.getInfo();
|
||||
var needsClosure = this.getLetReferences();
|
||||
|
||||
// remap all let references that exist in upper scopes to their uid
|
||||
this.remap();
|
||||
// this is a block within a `Function/Program` so we can safely leave it be
|
||||
if (t.isFunction(this.parent) || t.isProgram(this.block)) return;
|
||||
|
||||
// this is a block within a `Function` so we can safely leave it be
|
||||
if (t.isFunction(this.parent)) return this.noClosure();
|
||||
// we can skip everything
|
||||
if (!this.hasLetReferences) return;
|
||||
|
||||
// this block has no let references so let's clean up
|
||||
if (!this.info.keys.length) return this.noClosure();
|
||||
if (needsClosure) {
|
||||
this.needsClosure();
|
||||
} else {
|
||||
this.remap();
|
||||
}
|
||||
};
|
||||
|
||||
// returns whether or not there are any outside let references within any
|
||||
// functions
|
||||
var referencesInClosure = this.getLetReferences();
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
|
||||
// no need for a closure so let's clean up
|
||||
if (!referencesInClosure) return this.noClosure();
|
||||
LetScoping.prototype.remap = function () {
|
||||
var hasRemaps = false;
|
||||
var letRefs = this.letReferences;
|
||||
var scope = this.scope;
|
||||
var file = this.file;
|
||||
|
||||
// alright, so since we aren't wrapping this block in a closure
|
||||
// we have to check if any of our let variables collide with
|
||||
// those in upper scopes and then if they do, generate a uid
|
||||
// for them and replace all references with it
|
||||
var remaps = {};
|
||||
|
||||
for (var key in letRefs) {
|
||||
// just an Identifier node we collected in `getLetReferences`
|
||||
// this is the defining identifier of a declaration
|
||||
var ref = letRefs[key];
|
||||
|
||||
if (scope.parentHas(key)) {
|
||||
var uid = file.generateUidIdentifier(ref.name, scope).name;
|
||||
ref.name = uid;
|
||||
|
||||
hasRemaps = true;
|
||||
remaps[key] = remaps[uid] = {
|
||||
node: ref,
|
||||
uid: uid
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasRemaps) return;
|
||||
|
||||
//
|
||||
|
||||
var replace = function (node, parent, scope, context, remaps) {
|
||||
if (!t.isReferencedIdentifier(node, parent)) return;
|
||||
|
||||
var remap = remaps[node.name];
|
||||
if (!remap) return;
|
||||
|
||||
var own = scope.get(node.name, true);
|
||||
if (own === remap.node) {
|
||||
node.name = remap.uid;
|
||||
} else {
|
||||
// scope already has it's own declaration that doesn't
|
||||
// match the one we have a stored replacement for
|
||||
if (context) context.skip();
|
||||
}
|
||||
};
|
||||
|
||||
var traverseReplace = function (node, parent) {
|
||||
replace(node, parent, scope, null, remaps);
|
||||
traverse(node, { enter: replace }, scope, remaps);
|
||||
};
|
||||
|
||||
var loopParent = this.loopParent;
|
||||
if (loopParent) {
|
||||
traverseReplace(loopParent.right, loopParent);
|
||||
traverseReplace(loopParent.test, loopParent);
|
||||
traverseReplace(loopParent.update, loopParent);
|
||||
}
|
||||
|
||||
traverse(this.block, { enter: replace }, scope, remaps);
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
|
||||
LetScoping.prototype.needsClosure = function () {
|
||||
var block = this.block;
|
||||
|
||||
// if we're inside of a for loop then we search to see if there are any
|
||||
// `break`s, `continue`s, `return`s etc
|
||||
@@ -118,22 +194,16 @@ LetScoping.prototype.run = function () {
|
||||
// hoist var references to retain scope
|
||||
this.hoistVarDeclarations();
|
||||
|
||||
// set let references to plain var references
|
||||
standardiseLets(this.info.declarators);
|
||||
|
||||
// turn letReferences into an array
|
||||
var letReferences = _.values(this.letReferences);
|
||||
// turn outsideLetReferences into an array
|
||||
var params = _.values(this.outsideLetReferences);
|
||||
|
||||
// build the closure that we're going to wrap the block with
|
||||
var fn = t.functionExpression(null, letReferences, t.blockStatement(block.body));
|
||||
var fn = t.functionExpression(null, params, t.blockStatement(block.body));
|
||||
fn._aliasFunction = true;
|
||||
|
||||
// replace the current block body with the one we're going to build
|
||||
block.body = this.body;
|
||||
|
||||
// change upper scope references with their uid if they have one
|
||||
var params = this.getParams(letReferences);
|
||||
|
||||
// build a call and a unique id that we can assign the return value to
|
||||
var call = t.callExpression(fn, params);
|
||||
var ret = this.file.generateUidIdentifier("ret", this.scope);
|
||||
@@ -147,116 +217,78 @@ LetScoping.prototype.run = function () {
|
||||
this.build(ret, call);
|
||||
};
|
||||
|
||||
/**
|
||||
* There are no let references accessed within a closure so we can just turn the
|
||||
* lets into vars.
|
||||
*/
|
||||
|
||||
LetScoping.prototype.noClosure = function () {
|
||||
standardiseLets(this.info.declarators);
|
||||
};
|
||||
|
||||
/**
|
||||
* Traverse through block and replace all references that exist in a higher
|
||||
* scope to their uids.
|
||||
*/
|
||||
|
||||
LetScoping.prototype.remap = function () {
|
||||
var replacements = this.info.duplicates;
|
||||
var block = this.block;
|
||||
|
||||
if (!this.info.hasDuplicates) return;
|
||||
|
||||
var replace = function (node, parent, scope) {
|
||||
if (!t.isIdentifier(node)) return;
|
||||
if (!t.isReferenced(node, parent)) return;
|
||||
if (scope && scope.hasOwn(node.name)) return;
|
||||
node.name = replacements[node.name] || node.name;
|
||||
};
|
||||
|
||||
var traverseReplace = function (node, parent) {
|
||||
replace(node, parent);
|
||||
traverse(node, { enter: replace });
|
||||
};
|
||||
|
||||
var loopParent = this.loopParent;
|
||||
if (loopParent) {
|
||||
traverseReplace(loopParent.right, loopParent);
|
||||
traverseReplace(loopParent.test, loopParent);
|
||||
traverseReplace(loopParent.update, loopParent);
|
||||
}
|
||||
|
||||
traverse(block, { enter: replace });
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
* @returns {Object}
|
||||
*/
|
||||
|
||||
LetScoping.prototype.getInfo = function () {
|
||||
LetScoping.prototype.getLetReferences = function () {
|
||||
var block = this.block;
|
||||
var scope = this.scope;
|
||||
var file = this.file;
|
||||
|
||||
var opts = {
|
||||
// array of `Identifier` names of let variables that appear lexically out of
|
||||
// this scope but should be accessible - eg. `ForOfStatement`.left
|
||||
outsideKeys: [],
|
||||
|
||||
// array of let `VariableDeclarator`s that are a part of this block
|
||||
declarators: block._letDeclars || [],
|
||||
|
||||
// object of duplicate ids and their aliases - if there's an `Identifier`
|
||||
// name that's used in an upper scope we generate a unique id and replace
|
||||
// all references with it
|
||||
duplicates: {},
|
||||
|
||||
hasDuplicates: false,
|
||||
|
||||
// array of `Identifier` names of let variables that are accessible within
|
||||
// the current block
|
||||
keys: []
|
||||
};
|
||||
|
||||
var duplicates = function (id, key) {
|
||||
var has = scope.parentGet(key);
|
||||
|
||||
if (has && has !== id) {
|
||||
// there's a variable with this exact name in an upper scope so we need
|
||||
// to generate a new name
|
||||
opts.duplicates[key] = id.name = file.generateUid(key, scope);
|
||||
opts.hasDuplicates = true;
|
||||
}
|
||||
};
|
||||
|
||||
var i;
|
||||
var declarators = block._letDeclars || [];
|
||||
var declar;
|
||||
|
||||
for (i in opts.declarators) {
|
||||
declar = opts.declarators[i];
|
||||
opts.declarators.push(declar);
|
||||
//
|
||||
for (var i = 0; i < declarators.length; i++) {
|
||||
declar = declarators[i];
|
||||
_.extend(this.outsideLetReferences, t.getIds(declar, true));
|
||||
}
|
||||
|
||||
//
|
||||
if (block.body) {
|
||||
for (i = 0; i < block.body.length; i++) {
|
||||
declar = block.body[i];
|
||||
if (isLet(declar, block)) {
|
||||
declarators = declarators.concat(declar.declarations);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
for (i = 0; i < declarators.length; i++) {
|
||||
declar = declarators[i];
|
||||
var keys = t.getIds(declar, true);
|
||||
_.each(keys, duplicates);
|
||||
keys = Object.keys(keys);
|
||||
|
||||
opts.outsideKeys = opts.outsideKeys.concat(keys);
|
||||
opts.keys = opts.keys.concat(keys);
|
||||
_.extend(this.letReferences, keys);
|
||||
this.hasLetReferences = true;
|
||||
}
|
||||
|
||||
for (i in block.body) {
|
||||
declar = block.body[i];
|
||||
if (!isLet(declar, block)) continue;
|
||||
// no let references so we can just quit
|
||||
if (!this.hasLetReferences) return;
|
||||
|
||||
_.each(t.getIds(declar, true), function (id, key) {
|
||||
duplicates(id, key);
|
||||
opts.keys.push(key);
|
||||
});
|
||||
}
|
||||
// set let references to plain var references
|
||||
standardiseLets(declarators);
|
||||
|
||||
return opts;
|
||||
var state = {
|
||||
letReferences: this.letReferences,
|
||||
closurify: false
|
||||
};
|
||||
|
||||
// traverse through this block, stopping on functions and checking if they
|
||||
// contain any local let references
|
||||
traverse(this.block, {
|
||||
enter: function (node, parent, scope, context, state) {
|
||||
if (t.isFunction(node)) {
|
||||
traverse(node, {
|
||||
enter: function (node, parent) {
|
||||
// not a direct reference
|
||||
if (!t.isReferencedIdentifier(node, parent)) return;
|
||||
|
||||
// this scope has a variable with the same name so it couldn't belong
|
||||
// to our let scope
|
||||
if (scope.hasOwn(node.name, true)) return;
|
||||
|
||||
// not a part of our scope
|
||||
if (!state.letReferences[node.name]) return;
|
||||
|
||||
state.closurify = true;
|
||||
}
|
||||
}, scope, state);
|
||||
|
||||
return context.skip();
|
||||
}
|
||||
}
|
||||
}, this.scope, state);
|
||||
|
||||
return state.closurify;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -276,11 +308,11 @@ LetScoping.prototype.checkLoop = function () {
|
||||
};
|
||||
|
||||
traverse(this.block, {
|
||||
enter: function (node, parent) {
|
||||
enter: function (node, parent, scope, context) {
|
||||
var replace;
|
||||
|
||||
if (t.isFunction(node) || t.isLoop(node)) {
|
||||
return this.skip();
|
||||
return context.skip();
|
||||
}
|
||||
|
||||
if (node && !node.label) {
|
||||
@@ -304,7 +336,7 @@ LetScoping.prototype.checkLoop = function () {
|
||||
|
||||
if (replace) return t.inherits(replace, node);
|
||||
}
|
||||
});
|
||||
}, this.scope, has);
|
||||
|
||||
return has;
|
||||
};
|
||||
@@ -315,9 +347,8 @@ LetScoping.prototype.checkLoop = function () {
|
||||
*/
|
||||
|
||||
LetScoping.prototype.hoistVarDeclarations = function () {
|
||||
var self = this;
|
||||
traverse(this.block, {
|
||||
enter: function (node, parent) {
|
||||
enter: function (node, parent, scope, context, self) {
|
||||
if (t.isForStatement(node)) {
|
||||
if (isVar(node.init, node)) {
|
||||
node.init = t.sequenceExpression(self.pushDeclar(node.init));
|
||||
@@ -329,71 +360,10 @@ LetScoping.prototype.hoistVarDeclarations = function () {
|
||||
} else if (isVar(node, parent)) {
|
||||
return self.pushDeclar(node).map(t.expressionStatement);
|
||||
} else if (t.isFunction(node)) {
|
||||
return this.skip();
|
||||
return context.skip();
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Build up a parameter list that we'll call our closure wrapper with, replacing
|
||||
* all duplicate ids with their uid.
|
||||
*
|
||||
* @param {Array} params
|
||||
* @returns {Array}
|
||||
*/
|
||||
|
||||
LetScoping.prototype.getParams = function (params) {
|
||||
var info = this.info;
|
||||
params = _.cloneDeep(params);
|
||||
_.each(params, function (param) {
|
||||
param.name = info.duplicates[param.name] || param.name;
|
||||
});
|
||||
return params;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get all let references within this block. Stopping whenever we reach another
|
||||
* block.
|
||||
*/
|
||||
|
||||
LetScoping.prototype.getLetReferences = function () {
|
||||
var closurify = false;
|
||||
var self = this;
|
||||
|
||||
// traverse through this block, stopping on functions and checking if they
|
||||
// contain any outside let references
|
||||
traverse(this.block, {
|
||||
enter: function (node, parent, scope) {
|
||||
if (t.isFunction(node)) {
|
||||
traverse(node, {
|
||||
enter: function (node, parent) {
|
||||
// not an identifier so we have no use
|
||||
if (!t.isIdentifier(node)) return;
|
||||
|
||||
// not a direct reference
|
||||
if (!t.isReferenced(node, parent)) return;
|
||||
|
||||
// this scope has a variable with the same name so it couldn't belong
|
||||
// to our let scope
|
||||
if (scope.hasOwn(node.name, true)) return;
|
||||
|
||||
closurify = true;
|
||||
|
||||
// this key doesn't appear just outside our scope
|
||||
if (!_.contains(self.info.outsideKeys, node.name)) return;
|
||||
|
||||
// push this badboy
|
||||
self.letReferences[node.name] = node;
|
||||
}
|
||||
});
|
||||
|
||||
return this.skip();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return closurify;
|
||||
}, this.scope, this);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -411,7 +381,7 @@ LetScoping.prototype.pushDeclar = function (node) {
|
||||
|
||||
var replace = [];
|
||||
|
||||
for (var i in node.declarations) {
|
||||
for (var i = 0; i < node.declarations.length; i++) {
|
||||
var declar = node.declarations[i];
|
||||
if (!declar.init) continue;
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
var t = require("../../types");
|
||||
|
||||
exports.ast = {
|
||||
@@ -6,11 +8,11 @@ exports.ast = {
|
||||
}
|
||||
};
|
||||
|
||||
exports.ImportDeclaration = function (node, parent, file) {
|
||||
exports.ImportDeclaration = function (node, parent, scope, context, file) {
|
||||
var nodes = [];
|
||||
|
||||
if (node.specifiers.length) {
|
||||
for (var i in node.specifiers) {
|
||||
for (var i = 0; i < node.specifiers.length; i++) {
|
||||
file.moduleFormatter.importSpecifier(node.specifiers[i], node, nodes, parent);
|
||||
}
|
||||
} else {
|
||||
@@ -26,7 +28,7 @@ exports.ImportDeclaration = function (node, parent, file) {
|
||||
return nodes;
|
||||
};
|
||||
|
||||
exports.ExportDeclaration = function (node, parent, file) {
|
||||
exports.ExportDeclaration = function (node, parent, scope, context, file) {
|
||||
var nodes = [];
|
||||
|
||||
if (node.declaration) {
|
||||
@@ -39,7 +41,7 @@ exports.ExportDeclaration = function (node, parent, file) {
|
||||
|
||||
file.moduleFormatter.exportDeclaration(node, nodes, parent);
|
||||
} else {
|
||||
for (var i in node.specifiers) {
|
||||
for (var i = 0; i < node.specifiers.length; i++) {
|
||||
file.moduleFormatter.exportSpecifier(node.specifiers[i], node, nodes, parent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,59 +1,25 @@
|
||||
var traverse = require("../../traverse");
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
"use strict";
|
||||
|
||||
exports.Property = function (node, parent, file, scope) {
|
||||
var nameMethod = require("../helpers/name-method");
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
|
||||
exports.Property = function (node, parent, scope, context, file) {
|
||||
if (!node.method) return;
|
||||
|
||||
node.method = false;
|
||||
|
||||
var key = t.toComputedKey(node, node.key);
|
||||
if (!t.isLiteral(key)) return; // we can't set a function id with this
|
||||
|
||||
var id = t.toIdentifier(key.value);
|
||||
key = t.identifier(id);
|
||||
|
||||
var selfReference = false;
|
||||
var outerDeclar = scope.get(id, true);
|
||||
|
||||
traverse(node, {
|
||||
enter: function (node, parent, scope) {
|
||||
// check if this node is an identifier that matches the same as our function id
|
||||
if (!t.isIdentifier(node, { name: id })) return;
|
||||
|
||||
// check if this node is the one referenced
|
||||
if (!t.isReferenced(node, parent)) return;
|
||||
|
||||
// check that we don't have a local variable declared as that removes the need
|
||||
// for the wrapper
|
||||
var localDeclar = scope.get(id, true);
|
||||
if (localDeclar !== outerDeclar) return;
|
||||
|
||||
selfReference = true;
|
||||
this.stop();
|
||||
}
|
||||
}, scope);
|
||||
|
||||
if (selfReference) {
|
||||
node.value = util.template("property-method-assignment-wrapper", {
|
||||
FUNCTION: node.value,
|
||||
FUNCTION_ID: key,
|
||||
FUNCTION_KEY: file.generateUidIdentifier(id, scope),
|
||||
WRAPPER_KEY: file.generateUidIdentifier(id + "Wrapper", scope)
|
||||
});
|
||||
} else {
|
||||
node.value.id = key;
|
||||
}
|
||||
nameMethod.property(node, 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 +28,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)]
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
|
||||
@@ -1,36 +1,71 @@
|
||||
"use strict";
|
||||
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
|
||||
exports.Function = function (node, parent, file) {
|
||||
exports.Function = function (node, parent, scope, context, file) {
|
||||
if (!node.rest) return;
|
||||
|
||||
var rest = node.rest;
|
||||
delete node.rest;
|
||||
node.rest = null;
|
||||
|
||||
t.ensureBlock(node);
|
||||
|
||||
var argsId = t.identifier("arguments");
|
||||
|
||||
// otherwise `arguments` will be remapped in arrow functions
|
||||
argsId._ignoreAliasFunctions = true;
|
||||
|
||||
var start = t.literal(node.params.length);
|
||||
var key = file.generateUidIdentifier("key");
|
||||
var len = file.generateUidIdentifier("len");
|
||||
|
||||
var arrKey = key;
|
||||
var arrLen = len;
|
||||
if (node.params.length) {
|
||||
arrKey = t.binaryExpression("-", arrKey, start);
|
||||
// this method has additional params, so we need to subtract
|
||||
// the index of the current argument position from the
|
||||
// position in the array that we want to populate
|
||||
arrKey = t.binaryExpression("-", key, start);
|
||||
|
||||
// we need to work out the size of the array that we're
|
||||
// going to store all the rest parameters
|
||||
//
|
||||
// we need to add a check to avoid constructing the array
|
||||
// with <0 if there are less arguments than params as it'll
|
||||
// cause an error
|
||||
arrLen = t.conditionalExpression(
|
||||
t.binaryExpression(">", len, start),
|
||||
t.binaryExpression("-", len, start),
|
||||
t.literal(0)
|
||||
);
|
||||
}
|
||||
|
||||
// support patterns
|
||||
if (t.isPattern(rest)) {
|
||||
var pattern = rest;
|
||||
rest = file.generateUidIdentifier("ref", scope);
|
||||
|
||||
// let the destructuring transformer handle this
|
||||
var restDeclar = t.variableDeclaration("var", [
|
||||
t.variableDeclarator(pattern, rest)
|
||||
]);
|
||||
|
||||
// retain evaluation position
|
||||
restDeclar._blockHoist = node.params.length + 1;
|
||||
|
||||
node.body.body.unshift(restDeclar);
|
||||
}
|
||||
|
||||
node.body.body.unshift(
|
||||
t.variableDeclaration("var", [
|
||||
t.variableDeclarator(rest, t.arrayExpression([]))
|
||||
]),
|
||||
|
||||
util.template("rest", {
|
||||
ARGUMENTS: argsId,
|
||||
ARRAY_KEY: arrKey,
|
||||
ARRAY_LEN: arrLen,
|
||||
START: start,
|
||||
ARRAY: rest,
|
||||
KEY: key
|
||||
KEY: key,
|
||||
LEN: len,
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
@@ -6,7 +8,7 @@ var getSpreadLiteral = function (spread, file) {
|
||||
};
|
||||
|
||||
var hasSpread = function (nodes) {
|
||||
for (var i in nodes) {
|
||||
for (var i = 0; i < nodes.length; i++) {
|
||||
if (t.isSpreadElement(nodes[i])) {
|
||||
return true;
|
||||
}
|
||||
@@ -25,7 +27,7 @@ var build = function (props, file) {
|
||||
_props = [];
|
||||
};
|
||||
|
||||
for (var i in props) {
|
||||
for (var i = 0; i < props.length; i++) {
|
||||
var prop = props[i];
|
||||
if (t.isSpreadElement(prop)) {
|
||||
push();
|
||||
@@ -40,7 +42,7 @@ var build = function (props, file) {
|
||||
return nodes;
|
||||
};
|
||||
|
||||
exports.ArrayExpression = function (node, parent, file) {
|
||||
exports.ArrayExpression = function (node, parent, scope, context, file) {
|
||||
var elements = node.elements;
|
||||
if (!hasSpread(elements)) return;
|
||||
|
||||
@@ -55,7 +57,7 @@ exports.ArrayExpression = function (node, parent, file) {
|
||||
return t.callExpression(t.memberExpression(first, t.identifier("concat")), nodes);
|
||||
};
|
||||
|
||||
exports.CallExpression = function (node, parent, file, scope) {
|
||||
exports.CallExpression = function (node, parent, scope, context, file) {
|
||||
var args = node.arguments;
|
||||
if (!hasSpread(args)) return;
|
||||
|
||||
@@ -95,7 +97,7 @@ exports.CallExpression = function (node, parent, file, scope) {
|
||||
node.arguments.unshift(contextLiteral);
|
||||
};
|
||||
|
||||
exports.NewExpression = function (node, parent, file) {
|
||||
exports.NewExpression = function (node, parent, scope, context, file) {
|
||||
var args = node.arguments;
|
||||
if (!hasSpread(args)) return;
|
||||
|
||||
|
||||
@@ -1,26 +1,30 @@
|
||||
"use strict";
|
||||
|
||||
var t = require("../../types");
|
||||
|
||||
var buildBinaryExpression = function (left, right) {
|
||||
return t.binaryExpression("+", left, right);
|
||||
};
|
||||
|
||||
exports.TaggedTemplateExpression = function (node, parent, file) {
|
||||
exports.TaggedTemplateExpression = function (node, parent, scope, context, file) {
|
||||
var args = [];
|
||||
var quasi = node.quasi;
|
||||
|
||||
var strings = [];
|
||||
var raw = [];
|
||||
|
||||
for (var i in quasi.quasis) {
|
||||
for (var i = 0; i < quasi.quasis.length; i++) {
|
||||
var elem = quasi.quasis[i];
|
||||
strings.push(t.literal(elem.value.cooked));
|
||||
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);
|
||||
|
||||
@@ -31,7 +35,7 @@ exports.TemplateLiteral = function (node) {
|
||||
var nodes = [];
|
||||
var i;
|
||||
|
||||
for (i in node.quasis) {
|
||||
for (i = 0; i < node.quasis.length; i++) {
|
||||
var elem = node.quasis[i];
|
||||
|
||||
nodes.push(t.literal(elem.value.cooked));
|
||||
@@ -47,7 +51,7 @@ exports.TemplateLiteral = function (node) {
|
||||
|
||||
var root = buildBinaryExpression(nodes.shift(), nodes.shift());
|
||||
|
||||
for (i in nodes) {
|
||||
for (i = 0; i < nodes.length; i++) {
|
||||
root = buildBinaryExpression(root, nodes[i]);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
var rewritePattern = require("regexpu/rewrite-pattern");
|
||||
var _ = require("lodash");
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
// https://github.com/zenparsing/es-abstract-refs
|
||||
|
||||
var util = require("../../util");
|
||||
@@ -21,7 +23,7 @@ var container = function (parent, call, ret) {
|
||||
}
|
||||
};
|
||||
|
||||
exports.AssignmentExpression = function (node, parent, file, scope) {
|
||||
exports.AssignmentExpression = function (node, parent, scope, context, file) {
|
||||
var left = node.left;
|
||||
if (!t.isVirtualPropertyExpression(left)) return;
|
||||
|
||||
@@ -74,7 +76,7 @@ exports.UnaryExpression = function (node, parent) {
|
||||
return container(parent, call, t.literal(true));
|
||||
};
|
||||
|
||||
exports.CallExpression = function (node, parent, file, scope) {
|
||||
exports.CallExpression = function (node, parent, scope, context, file) {
|
||||
var callee = node.callee;
|
||||
if (!t.isVirtualPropertyExpression(callee)) return;
|
||||
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
var traverse = require("../../traverse");
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
"use strict";
|
||||
|
||||
var buildComprehension = require("../helpers/build-comprehension");
|
||||
var traverse = require("../../traverse");
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
|
||||
exports.experimental = true;
|
||||
|
||||
var build = function (node, parent, file, scope) {
|
||||
var build = function (node, parent, scope, context, file) {
|
||||
var uid = scope.generateUidBasedOnNode(parent, file);
|
||||
|
||||
var container = util.template("array-comprehension-container", {
|
||||
@@ -22,7 +25,7 @@ var build = function (node, parent, file, scope) {
|
||||
|
||||
var returnStatement = body.pop();
|
||||
|
||||
body.push(exports._build(node, function () {
|
||||
body.push(buildComprehension(node, function () {
|
||||
return util.template("array-push", {
|
||||
STATEMENT: node.body,
|
||||
KEY: uid
|
||||
@@ -33,30 +36,8 @@ var build = function (node, parent, file, scope) {
|
||||
return container;
|
||||
};
|
||||
|
||||
exports._build = function (node, buildBody) {
|
||||
var self = node.blocks.shift();
|
||||
if (!self) return;
|
||||
|
||||
var child = exports._build(node, buildBody);
|
||||
if (!child) {
|
||||
// last item
|
||||
child = buildBody();
|
||||
|
||||
// add a filter as this is our final stop
|
||||
if (node.filter) {
|
||||
child = t.ifStatement(node.filter, t.blockStatement([child]));
|
||||
}
|
||||
}
|
||||
|
||||
return t.forOfStatement(
|
||||
t.variableDeclaration("let", [t.variableDeclarator(self.left)]),
|
||||
self.right,
|
||||
t.blockStatement([child])
|
||||
);
|
||||
};
|
||||
|
||||
exports.ComprehensionExpression = function (node, parent, file, scope) {
|
||||
exports.ComprehensionExpression = function (node, parent, scope, context, file) {
|
||||
if (node.generator) return;
|
||||
|
||||
return build(node, parent, file, scope);
|
||||
return build(node, parent, scope, context, file);
|
||||
};
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
"use strict";
|
||||
|
||||
// https://github.com/rwaldron/exponentiation-operator
|
||||
|
||||
exports.experimental = true;
|
||||
|
||||
var t = require("../../types");
|
||||
var pow = t.memberExpression(t.identifier("Math"), t.identifier("pow"));
|
||||
var build = require("../helpers/build-binary-assignment-operator-transformer");
|
||||
var t = require("../../types");
|
||||
|
||||
exports.AssignmentExpression = function (node) {
|
||||
if (node.operator !== "**=") return;
|
||||
node.operator = "=";
|
||||
node.right = t.callExpression(pow, [node.left, node.right]);
|
||||
};
|
||||
var MATH_POW = t.memberExpression(t.identifier("Math"), t.identifier("pow"));
|
||||
|
||||
exports.BinaryExpression = function (node) {
|
||||
if (node.operator !== "**") return;
|
||||
build(exports, {
|
||||
operator: "**",
|
||||
|
||||
return t.callExpression(pow, [node.left, node.right]);
|
||||
};
|
||||
build: function (left, right) {
|
||||
return t.callExpression(MATH_POW, [left, right]);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
var arrayComprehension = require("./es7-array-comprehension");
|
||||
"use strict";
|
||||
|
||||
var buildComprehension = require("../helpers/build-comprehension");
|
||||
var t = require("../../types");
|
||||
|
||||
exports.experimental = true;
|
||||
@@ -10,7 +12,7 @@ exports.ComprehensionExpression = function (node) {
|
||||
var container = t.functionExpression(null, [], t.blockStatement(body), true);
|
||||
container._aliasFunction = true;
|
||||
|
||||
body.push(arrayComprehension._build(node, function () {
|
||||
body.push(buildComprehension(node, function () {
|
||||
return t.expressionStatement(t.yieldExpression(node.body));
|
||||
}));
|
||||
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
"use strict";
|
||||
|
||||
// https://github.com/sebmarkbage/ecmascript-rest-spread
|
||||
|
||||
var t = require("../../types");
|
||||
|
||||
exports.experimental = true;
|
||||
|
||||
exports.ObjectExpression = function (node, parent, file) {
|
||||
exports.ObjectExpression = function (node, parent, scope, context, file) {
|
||||
var hasSpread = false;
|
||||
var i;
|
||||
var prop;
|
||||
for (i in node.properties) {
|
||||
for (i = 0; i < node.properties.length; i++) {
|
||||
prop = node.properties[i];
|
||||
if (t.isSpreadProperty(prop)) {
|
||||
hasSpread = true;
|
||||
@@ -26,7 +28,7 @@ exports.ObjectExpression = function (node, parent, file) {
|
||||
props = [];
|
||||
};
|
||||
|
||||
for (i in node.properties) {
|
||||
for (i = 0; i < node.properties.length; i++) {
|
||||
prop = node.properties[i];
|
||||
if (t.isSpreadProperty(prop)) {
|
||||
push();
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
var bluebirdCoroutines = require("./optional-bluebird-coroutines");
|
||||
"use strict";
|
||||
|
||||
var remapAsyncToGenerator = require("../helpers/remap-async-to-generator");
|
||||
var bluebirdCoroutines = require("./optional-bluebird-coroutines");
|
||||
|
||||
exports.optional = true;
|
||||
|
||||
exports.manipulateOptions = bluebirdCoroutines.manipulateOptions;
|
||||
|
||||
exports.Function = function (node, parent, file) {
|
||||
exports.Function = function (node, parent, scope, context, file) {
|
||||
if (!node.async || node.generator) return;
|
||||
|
||||
return bluebirdCoroutines._Function(node, file.addHelper("async-to-generator"));
|
||||
return remapAsyncToGenerator(node, file.addHelper("async-to-generator"));
|
||||
};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user