Compare commits
283 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a5f00aa3f6 | ||
|
|
a47723c66c | ||
|
|
ab2f652bdf | ||
|
|
5aff7709f7 | ||
|
|
06ba731452 | ||
|
|
f4c81531ad | ||
|
|
19b115c76b | ||
|
|
96b08bf7df | ||
|
|
8f435d59da | ||
|
|
6df03c00a8 | ||
|
|
4ec134814e | ||
|
|
4fb50cfe20 | ||
|
|
bac952e036 | ||
|
|
9844540bb0 | ||
|
|
1a9a60e010 | ||
|
|
e26812e622 | ||
|
|
7f306388e4 | ||
|
|
b217453d49 | ||
|
|
463165e0c8 | ||
|
|
85d7da9a7c | ||
|
|
48f6c5c649 | ||
|
|
d1187dde82 | ||
|
|
f21a6b36ac | ||
|
|
407bb9278f | ||
|
|
70b3d88455 | ||
|
|
98df094e60 | ||
|
|
4bae820a5a | ||
|
|
4e8afa18da | ||
|
|
fbf0c25bbe | ||
|
|
a90da9908c | ||
|
|
bd51215316 | ||
|
|
e3c6ee5c88 | ||
|
|
8c40db5658 | ||
|
|
4d59976d82 | ||
|
|
83286cccd2 | ||
|
|
de7edcaeb0 | ||
|
|
6c8db61b23 | ||
|
|
e3d2748970 | ||
|
|
fa8c570e77 | ||
|
|
677f9805c6 | ||
|
|
eff5efaf10 | ||
|
|
a909a6febd | ||
|
|
61ee0ef6f6 | ||
|
|
07c15f02e6 | ||
|
|
3f4068ae00 | ||
|
|
dce41bb989 | ||
|
|
896663056d | ||
|
|
dfe4ce86e0 | ||
|
|
24f0120e01 | ||
|
|
0108562e88 | ||
|
|
e4e4ae5b1d | ||
|
|
ba04377ed8 | ||
|
|
cd9e289dee | ||
|
|
0b86a2fef8 | ||
|
|
b84cb1828b | ||
|
|
aedc013ab8 | ||
|
|
ab9cd4e630 | ||
|
|
8ef5148870 | ||
|
|
4cb90cb1e0 | ||
|
|
d0a33ab933 | ||
|
|
9ea4431ba3 | ||
|
|
08580edda8 | ||
|
|
5c6d57c51b | ||
|
|
744d1af485 | ||
|
|
591b78b159 | ||
|
|
49ea641314 | ||
|
|
37a7c92500 | ||
|
|
35b7b140da | ||
|
|
159f5217e3 | ||
|
|
795e38e4f4 | ||
|
|
2a9af21e93 | ||
|
|
e327e041ab | ||
|
|
f8e8cd3979 | ||
|
|
b3206d94a6 | ||
|
|
fcbd315bc1 | ||
|
|
71646f4ade | ||
|
|
56ac964e54 | ||
|
|
e5f1eb64b6 | ||
|
|
6145f0a03b | ||
|
|
54f901f131 | ||
|
|
df70be4ebb | ||
|
|
99ba77bb0b | ||
|
|
346f72be05 | ||
|
|
c0e6cda071 | ||
|
|
c054ff7bbb | ||
|
|
771d3dc8a0 | ||
|
|
e8d4806b45 | ||
|
|
469a522300 | ||
|
|
4068a8bf68 | ||
|
|
a04513a3c7 | ||
|
|
6f0ca947a7 | ||
|
|
dd62244e10 | ||
|
|
12f68b05c3 | ||
|
|
62fe128132 | ||
|
|
bf632ca20b | ||
|
|
26428cde41 | ||
|
|
9bb8a16d93 | ||
|
|
44cd044586 | ||
|
|
765899a521 | ||
|
|
1d40cac52f | ||
|
|
fb0325a4d8 | ||
|
|
1df25a633c | ||
|
|
cfbaae456b | ||
|
|
95ace3220d | ||
|
|
2e0f3de72c | ||
|
|
732c21d42a | ||
|
|
a535007a35 | ||
|
|
5ff6f445b2 | ||
|
|
d7ae3b506a | ||
|
|
287cbbb6a1 | ||
|
|
d1088583ba | ||
|
|
c967cded78 | ||
|
|
71d87f5b97 | ||
|
|
56271efada | ||
|
|
89fbb06658 | ||
|
|
43ee3b77f3 | ||
|
|
9ef826b53e | ||
|
|
6519ceaa63 | ||
|
|
d28496006e | ||
|
|
5f9710e61f | ||
|
|
c4cadd8a64 | ||
|
|
d3c5b8ef0b | ||
|
|
120df2c611 | ||
|
|
719d23eb3b | ||
|
|
364abf60ea | ||
|
|
0f5a141c91 | ||
|
|
fca3a0c56f | ||
|
|
e88505aba6 | ||
|
|
500a0bdfb6 | ||
|
|
2a0efceef5 | ||
|
|
225754ae12 | ||
|
|
6f230de01c | ||
|
|
3c3746b21f | ||
|
|
f49f057b33 | ||
|
|
e3b9a0dd38 | ||
|
|
f540c3f4b7 | ||
|
|
6e5917e537 | ||
|
|
816c1d304b | ||
|
|
5deeae1aa2 | ||
|
|
718e342e86 | ||
|
|
cb98605520 | ||
|
|
600513bcab | ||
|
|
620e5791af | ||
|
|
47ee2cc99f | ||
|
|
6cc70f7465 | ||
|
|
20484c66c5 | ||
|
|
171bcad870 | ||
|
|
c963c30107 | ||
|
|
795183569d | ||
|
|
9a3c973280 | ||
|
|
95f3ca6348 | ||
|
|
c17878913b | ||
|
|
c8139317ee | ||
|
|
6d6039aeb6 | ||
|
|
74f11dfddf | ||
|
|
4c63b4ea1e | ||
|
|
6332e725fe | ||
|
|
f3d371869d | ||
|
|
89ecd46b77 | ||
|
|
9f8e8d96a8 | ||
|
|
a7bbd1dd3e | ||
|
|
6d961c1857 | ||
|
|
e13a650d05 | ||
|
|
3cd7ed69a3 | ||
|
|
93c6d69e21 | ||
|
|
57d3c836bd | ||
|
|
115282d57b | ||
|
|
72d924d85b | ||
|
|
6838062279 | ||
|
|
bc79cec15a | ||
|
|
85f0f6fb14 | ||
|
|
bf61c1e85d | ||
|
|
bd2e3d784f | ||
|
|
7e8c5cd20f | ||
|
|
ddbb522392 | ||
|
|
288cfd1f00 | ||
|
|
435b9434ea | ||
|
|
2409b017db | ||
|
|
99f2864048 | ||
|
|
5351057557 | ||
|
|
1a5ee7d5da | ||
|
|
ebea86c527 | ||
|
|
bf58004947 | ||
|
|
f0c78102ca | ||
|
|
da1512eeb0 | ||
|
|
43ea593677 | ||
|
|
629cea497f | ||
|
|
9475dc681f | ||
|
|
6e41309ede | ||
|
|
42322e1ce7 | ||
|
|
400fa8ed97 | ||
|
|
07e2842226 | ||
|
|
7d46b7c465 | ||
|
|
fcf6c9e066 | ||
|
|
a5523664fc | ||
|
|
1841f5c8a0 | ||
|
|
33f8988313 | ||
|
|
1d3544eadc | ||
|
|
646bdfd04c | ||
|
|
aba9bba7db | ||
|
|
e77382582f | ||
|
|
af997b9945 | ||
|
|
a2332f08bc | ||
|
|
bbffde374e | ||
|
|
115dca56b6 | ||
|
|
251e4d01c8 | ||
|
|
0fbf0e2a77 | ||
|
|
e8628ea1a7 | ||
|
|
a5a8f08bb8 | ||
|
|
d376bd3c0e | ||
|
|
20818b086c | ||
|
|
f9ef1723a6 | ||
|
|
6e7b8a14fe | ||
|
|
622bb2e962 | ||
|
|
5c5348537d | ||
|
|
0def62b918 | ||
|
|
530ad78428 | ||
|
|
daced12baa | ||
|
|
51f18a152e | ||
|
|
51f72ace57 | ||
|
|
2fa36b30d5 | ||
|
|
11270e0803 | ||
|
|
6f8cbf0ad1 | ||
|
|
6696d5fcf4 | ||
|
|
591f123670 | ||
|
|
1f7270720f | ||
|
|
ec3a3cbbc9 | ||
|
|
8a1ea82e97 | ||
|
|
6953b6e8b6 | ||
|
|
378832d31b | ||
|
|
85703eb5b8 | ||
|
|
d0fdd3bf41 | ||
|
|
a7385bdf1b | ||
|
|
9c7c385ee8 | ||
|
|
7c84af2ba8 | ||
|
|
009d063790 | ||
|
|
5483c4ef6f | ||
|
|
5558f61518 | ||
|
|
96bc95d6d9 | ||
|
|
11dd13b7e0 | ||
|
|
976e6782a2 | ||
|
|
febc3062cc | ||
|
|
efff5e5aab | ||
|
|
eefab7f80f | ||
|
|
1a3d306949 | ||
|
|
e5ae2f8eaf | ||
|
|
e797be518f | ||
|
|
45cb755845 | ||
|
|
3b9a339c79 | ||
|
|
ea7ac4cd2d | ||
|
|
e141a8b875 | ||
|
|
6768fc3800 | ||
|
|
0af5e00b5f | ||
|
|
ecedc23892 | ||
|
|
163c68dd6a | ||
|
|
4dc6147348 | ||
|
|
4b3ebc62b1 | ||
|
|
cc094efe1b | ||
|
|
8f4a3f77a0 | ||
|
|
b31f3666c8 | ||
|
|
b1495832d7 | ||
|
|
fa6e50ea28 | ||
|
|
a72c839a73 | ||
|
|
32b5edb711 | ||
|
|
8cbb121e3f | ||
|
|
75ece96475 | ||
|
|
b016fda8af | ||
|
|
2cffad61fa | ||
|
|
4e248c0a16 | ||
|
|
4f5026101b | ||
|
|
4ce38eab37 | ||
|
|
0a7ce115ff | ||
|
|
21ed438fd8 | ||
|
|
5f9e954d21 | ||
|
|
a03fd0f43a | ||
|
|
dcc5eaa95e | ||
|
|
3b7ce5aaa1 | ||
|
|
6811f071a9 | ||
|
|
9abda34e59 | ||
|
|
417ba2bd92 | ||
|
|
e23f8e92ba | ||
|
|
ef2638eb89 | ||
|
|
a7d860aab4 |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -4,5 +4,9 @@ test/tmp
|
||||
*.log
|
||||
*.cache
|
||||
/templates.json
|
||||
/tests.json
|
||||
/browser.js
|
||||
/polyfill.js
|
||||
/runtime.js
|
||||
coverage
|
||||
dist
|
||||
|
||||
10
.jshintrc
10
.jshintrc
@@ -17,5 +17,13 @@
|
||||
"loopfunc": true,
|
||||
"white": true,
|
||||
"maxparams": 5,
|
||||
"maxdepth": 4
|
||||
"maxdepth": 4,
|
||||
|
||||
"globals": {
|
||||
"window": true,
|
||||
"suite": true,
|
||||
"set": true,
|
||||
"before": true,
|
||||
"bench": true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,4 +7,5 @@ benchmark
|
||||
Makefile
|
||||
.*
|
||||
dist
|
||||
tests.json
|
||||
!README.md
|
||||
|
||||
@@ -3,10 +3,9 @@ node_js:
|
||||
- "0.10"
|
||||
- "0.11"
|
||||
|
||||
branches:
|
||||
except:
|
||||
- experimental
|
||||
|
||||
before_script: "npm install -g codeclimate-test-reporter"
|
||||
script: "make test-travis"
|
||||
|
||||
addons:
|
||||
code_climate:
|
||||
repo_token:
|
||||
secure: "PfP9sDUJzSznDb+ZEPO2cignXabSTXJxEVm5ESRPgEcFr+/4b0pt3hI8R9b+9mLtBEwtw3DLUq48MOeqEKnq29csQmpjPVcN6gT4uR2DdNa1JpVgDuwxT05NB3fBea9U2reM73iV8ylCgPHExr2uGR9/87JzR2beY/56EUL5NjY="
|
||||
|
||||
25
MODULES.md
25
MODULES.md
@@ -109,10 +109,35 @@ export function bar() {
|
||||
});
|
||||
```
|
||||
|
||||
### Ignore
|
||||
|
||||
|
||||
**In**
|
||||
|
||||
```javascript
|
||||
import foo from "foo";
|
||||
|
||||
export function bar() {
|
||||
return foo("foobar");
|
||||
}
|
||||
```
|
||||
|
||||
**Out**
|
||||
|
||||
```javascript
|
||||
function bar() {
|
||||
return foo("foobar");
|
||||
}
|
||||
```
|
||||
|
||||
## Custom
|
||||
|
||||
You can alternatively specify module names instead of one of the built-in types.
|
||||
|
||||
$ 6to5 --modules custom-module-formatter
|
||||
|
||||
**node_modules/custom-module-formatter/index.js**
|
||||
|
||||
```javascript
|
||||
module.exports = ModuleFormatter;
|
||||
|
||||
|
||||
30
Makefile
30
Makefile
@@ -1,4 +1,6 @@
|
||||
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
|
||||
JSHINT_CMD = node_modules/jshint/bin/jshint
|
||||
MOCHA_CMD = node_modules/mocha/bin/_mocha
|
||||
|
||||
@@ -14,7 +16,7 @@ bench:
|
||||
node node_modules/matcha/bin/_matcha
|
||||
|
||||
test:
|
||||
$(JSHINT_CMD) lib
|
||||
$(JSHINT_CMD) lib bin benchmark/index.js
|
||||
$(MOCHA_CMD)
|
||||
|
||||
test-cov:
|
||||
@@ -26,8 +28,13 @@ test-travis:
|
||||
if test -n "$$CODECLIMATE_REPO_TOKEN"; then codeclimate < coverage/lcov.info; fi
|
||||
|
||||
test-browser:
|
||||
make build
|
||||
node bin/generate-browser-test >dist/6to5-test.js
|
||||
mkdir -p dist
|
||||
|
||||
node bin/cache-templates
|
||||
node bin/cache-tests
|
||||
node $(BROWSERIFY_CMD) -e test/_browser.js >dist/6to5-test.js
|
||||
rm -rf templates.json tests.json
|
||||
|
||||
test -n "`which open`" && open test/browser.html
|
||||
|
||||
build:
|
||||
@@ -35,8 +42,14 @@ build:
|
||||
|
||||
node bin/cache-templates
|
||||
|
||||
browserify lib/6to5/transform.js -s to5 >dist/6to5.js
|
||||
uglifyjs dist/6to5.js >dist/6to5.min.js
|
||||
node $(BROWSERIFY_CMD) -e lib/6to5/polyfill.js >dist/polyfill.js
|
||||
node $(UGLIFY_CMD) dist/polyfill.js >dist/polyfill.min.js
|
||||
|
||||
node $(BROWSERIFY_CMD) lib/6to5/browser.js -s to5 >dist/6to5.js
|
||||
node $(UGLIFY_CMD) dist/6to5.js >dist/6to5.min.js
|
||||
|
||||
node bin/6to5-runtime >dist/runtime.js
|
||||
node $(UGLIFY_CMD) dist/runtime.js >dist/runtime.min.js
|
||||
|
||||
rm -rf templates.json
|
||||
|
||||
@@ -45,6 +58,11 @@ publish:
|
||||
|
||||
make test
|
||||
|
||||
make build
|
||||
cp dist/6to5.min.js browser.js
|
||||
cp dist/polyfill.min.js polyfill.js
|
||||
cp dist/runtime.min.js runtime.js
|
||||
|
||||
node bin/cache-templates
|
||||
test -f templates.json
|
||||
|
||||
@@ -54,4 +72,4 @@ publish:
|
||||
|
||||
git push --follow-tags
|
||||
|
||||
rm -rf templates.json
|
||||
rm -rf templates.json browser.js runtime.js polyfill.js
|
||||
|
||||
207
README.md
207
README.md
@@ -1,22 +1,22 @@
|
||||
<p align="center">
|
||||
<img alt="6to5" src="http://i.imgur.com/hVl9KRw.png">
|
||||
<img alt="6to5" src="https://raw.githubusercontent.com/6to5/logo/master/logo.png" width="546">
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://travis-ci.org/sebmck/6to5">
|
||||
<img alt="Travis Status" src="http://img.shields.io/travis/sebmck/6to5.svg?style=flat&label=travis">
|
||||
<a href="https://travis-ci.org/6to5/6to5">
|
||||
<img alt="Travis Status" src="http://img.shields.io/travis/6to5/6to5.svg?branch=master&style=flat&label=travis">
|
||||
</a>
|
||||
|
||||
<a href="https://codeclimate.com/github/sebmck/6to5">
|
||||
<img alt="Code Climate Score" src="http://img.shields.io/codeclimate/github/sebmck/6to5.svg?style=flat">
|
||||
<a href="https://codeclimate.com/github/6to5/6to5">
|
||||
<img alt="Code Climate Score" src="http://img.shields.io/codeclimate/github/6to5/6to5.svg?style=flat">
|
||||
</a>
|
||||
|
||||
<a href="https://codeclimate.com/github/sebmck/6to5">
|
||||
<img alt="Coverage" src="http://img.shields.io/codeclimate/coverage/github/sebmck/6to5.svg?style=flat">
|
||||
<a href="https://codeclimate.com/github/6to5/6to5">
|
||||
<img alt="Coverage" src="http://img.shields.io/codeclimate/coverage/github/6to5/6to5.svg?style=flat">
|
||||
</a>
|
||||
|
||||
<a href="https://david-dm.org/sebmck/6to5">
|
||||
<img alt="Dependency Status" src="http://img.shields.io/david/sebmck/6to5.svg?style=flat">
|
||||
<a href="https://david-dm.org/6to5/6to5">
|
||||
<img alt="Dependency Status" src="http://img.shields.io/david/6to5/6to5.svg?style=flat">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
@@ -43,6 +43,8 @@ It's as easy as:
|
||||
- [Browser](#browser)
|
||||
- [Modules](#modules)
|
||||
- [Caveats](#caveats)
|
||||
- [Polyfill](#polyfill)
|
||||
- [Optional runtime](#optional-runtime)
|
||||
- [Differences](#differences)
|
||||
|
||||
## [Features](FEATURES.md)
|
||||
@@ -71,12 +73,14 @@ It's as easy as:
|
||||
### Plugins
|
||||
|
||||
- [Broccoli](https://github.com/very-geek/broccoli-6to5-transpiler)
|
||||
- [Browserify](https://github.com/sebmck/6to5-browserify)
|
||||
- [Browserify](https://github.com/6to5/6to5-browserify)
|
||||
- [Brunch](https://github.com/es128/6to5-brunch)
|
||||
- [Connect](https://github.com/sebmck/6to5-connect)
|
||||
- [Duo](https://github.com/bdo-labs/duo6to5)
|
||||
- [Connect](https://github.com/6to5/6to5-connect)
|
||||
- [Gulp](https://github.com/sindresorhus/gulp-6to5)
|
||||
- [Grunt](https://github.com/sindresorhus/grunt-6to5)
|
||||
- [Jade](https://github.com/Apoxx/jade-6to5)
|
||||
- [Karma](https://github.com/shuhei/karma-6to5-preprocessor)
|
||||
- [webpack](https://github.com/Couto/6to5-loader)
|
||||
|
||||
### CLI
|
||||
@@ -103,6 +107,10 @@ Compile the entire `src` directory and output it to the `lib` directory.
|
||||
|
||||
$ 6to5 src --out-dir lib
|
||||
|
||||
Compile the entire `src` directory and output it to the one concatenated file.
|
||||
|
||||
$ 6to5 src --out-file script-compiled.js
|
||||
|
||||
Pipe a file in via stdin and output it to `script-compiled.js`
|
||||
|
||||
$ 6to5 --out-file script-compiled.js < script.js
|
||||
@@ -171,7 +179,12 @@ to5.transformFile("filename.js", options, function (err, result) {
|
||||
|
||||
// Set `sources[0]` on returned source map.
|
||||
// Default: `filename` option.
|
||||
sourceFileName: "filename"
|
||||
sourceFileName: "filename",
|
||||
|
||||
// Optionally replace all 6to5 helper declarations with a referenece to this
|
||||
// variable. If set to `true` then the default namespace is used "to5Runtime".
|
||||
// Default: false
|
||||
runtime: true
|
||||
}
|
||||
```
|
||||
|
||||
@@ -189,24 +202,64 @@ require("6to5/register");
|
||||
override this by passing an ignore regex via:
|
||||
|
||||
```javascript
|
||||
require("6to5/register")(/regex/);
|
||||
require("6to5/register")({
|
||||
// This will override `node_modules` ignoring - you can alternatively pass
|
||||
// a regex
|
||||
ignore: false
|
||||
});
|
||||
```
|
||||
|
||||
You can also customise the file extensions that the require hook will use via:
|
||||
##### Options
|
||||
|
||||
```javascript
|
||||
require("6to5/register")({
|
||||
// optional ignore regex
|
||||
ignoreRegex: /regex/,
|
||||
// Optional ignore regex - if any filenames **do** match this regex then they
|
||||
// aren't compiled
|
||||
ignore: /regex/,
|
||||
|
||||
// this will remove the currently hooked extensions of .es6 and .js so you'll
|
||||
// have to add them back if you want them to be used again
|
||||
// Optional only regex - if any filenames **don't** match this regex then they
|
||||
// aren't compiled
|
||||
only: /my_es6_folder/,
|
||||
|
||||
// See options above for usage
|
||||
whitelist: [],
|
||||
blacklist: [],
|
||||
|
||||
// This will remove the currently hooked extensions of .es6 and .js so you'll
|
||||
// have to add them back if you want them to be used again.
|
||||
extensions: [".js", ".es6"]
|
||||
});
|
||||
```
|
||||
|
||||
### Browser
|
||||
|
||||
A browser version of 6to5 is available from `browser.js` inside the 6to5
|
||||
directory in an npm release.
|
||||
|
||||
#### Scripts
|
||||
|
||||
While it's not recommended for serious use, when the browser version is included
|
||||
all scripts with the type `text/ecmascript-6` and `text/6to5` are automatically
|
||||
compiled and ran.
|
||||
|
||||
For example:
|
||||
|
||||
```html
|
||||
<script src="node_modules/6to5/browser.js"></script>
|
||||
<script type="text/6to5">
|
||||
class Test {
|
||||
test() {
|
||||
return "test";
|
||||
}
|
||||
}
|
||||
|
||||
var test = new Test;
|
||||
test.test();
|
||||
</script>
|
||||
```
|
||||
|
||||
#### Build
|
||||
|
||||
You can build a browser version of the compiler by running the following in the
|
||||
6to5 directory:
|
||||
|
||||
@@ -214,11 +267,10 @@ You can build a browser version of the compiler by running the following in the
|
||||
|
||||
This will output the files `dist/6to5.js` and `dist/6to5.min.js`.
|
||||
|
||||
Just include one of those in the browser and access the transform method via the
|
||||
global `to5`.
|
||||
#### API
|
||||
|
||||
```javascript
|
||||
to5("class Test {}").code;
|
||||
to5.transform("class Test {}").code;
|
||||
```
|
||||
|
||||
#### Test
|
||||
@@ -238,32 +290,6 @@ Alternatively see [Modules](MODULES.md) for all other supported module formattin
|
||||
|
||||
## Caveats
|
||||
|
||||
### Polyfill
|
||||
|
||||
6to5 does not include a runtime nor polyfill and it's up to the developer to
|
||||
include one in compiled browser code.
|
||||
|
||||
#### Node
|
||||
|
||||
A polyfill is included with the 6to5 module that can be included in node like
|
||||
so:
|
||||
|
||||
```javascript
|
||||
require("6to5/polyfill");
|
||||
```
|
||||
|
||||
This is simply a wrapper around the
|
||||
[regenerator runtime](https://github.com/facebook/regenerator/blob/master/runtime.js) and the
|
||||
[es6-shim](https://github.com/paulmillr/es6-shim) and
|
||||
[es6-symbol](https://github.com/medikoo/es6-symbol) polyfills.
|
||||
|
||||
#### Browser
|
||||
|
||||
If you're planning on using 6to5 output in the browser then it's up to you
|
||||
to include polyfills. [es6-symbol](https://github.com/medikoo/es6-symbol#browser)
|
||||
and [es6-shim](https://raw.githubusercontent.com/paulmillr/es6-shim/master/es6-shim.js)
|
||||
fill the vast majority of polyfill concerns.
|
||||
|
||||
### For-of
|
||||
|
||||
A polyfill is required for for-of functionality that implements `Symbol` and
|
||||
@@ -279,11 +305,98 @@ If you're inheriting from a class then static properties are inherited from it
|
||||
via [\_\_proto\_\_](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto),
|
||||
this is widely supported but you may run into problems with much older browsers.
|
||||
|
||||
**NOTE:** `__proto__` is not supported on IE <= 9 so static properties
|
||||
**will not** be inherited. A possible workaround is to use `super();`:
|
||||
|
||||
```javascript
|
||||
class Foo {
|
||||
static foo() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class Bar extends Foo {
|
||||
static foo() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Generators
|
||||
|
||||
The [regenerator runtime](https://github.com/facebook/regenerator/blob/master/runtime.js)
|
||||
and an [ES6 polyfill](#polyfill) are required in order for generators to work.
|
||||
|
||||
## Polyfill
|
||||
|
||||
6to5 includes a polyfill that includes the
|
||||
[regenerator runtime](https://github.com/facebook/regenerator/blob/master/runtime.js) and the
|
||||
[es6-shim](https://github.com/paulmillr/es6-shim) and
|
||||
[es6-symbol](https://github.com/medikoo/es6-symbol) polyfills.
|
||||
|
||||
### Node
|
||||
|
||||
```javascript
|
||||
require("6to5/polyfill");
|
||||
```
|
||||
|
||||
### Browser
|
||||
|
||||
Available from the `polyfill.js` file within the 6to5 directory of an npm
|
||||
release.
|
||||
|
||||
## Optional runtime
|
||||
|
||||
6to5 has a few helper functions that'll be placed at the top of the generated
|
||||
code if needed so it's not inlined multiple times throughout that file. This may
|
||||
become an issue if you have multiple files, especially when you're sending them
|
||||
to the browser. gzip alleviates most of this concern but it's still not ideal.
|
||||
|
||||
You can tell 6to5 to not place any declarations at the top of your files and
|
||||
instead just point them to a reference contained within the runtime.
|
||||
|
||||
Simply use the following option if you're using the [Node API](#node-1):
|
||||
|
||||
```javascript
|
||||
{
|
||||
runtime: true
|
||||
}
|
||||
```
|
||||
|
||||
or the following flag if you're using the [CLI](#cli):
|
||||
|
||||
$ 6to5 --runtime
|
||||
|
||||
Then just include the runtime before your generated code.
|
||||
|
||||
### Getting the runtime
|
||||
|
||||
You can get the runtime via either:
|
||||
|
||||
$ 6to5-runtime
|
||||
|
||||
or
|
||||
|
||||
```javascript
|
||||
require("6to5").runtime();
|
||||
```
|
||||
|
||||
or from an npm release in `runtime.js` from the 6to5 directory.
|
||||
|
||||
### Customising namespace
|
||||
|
||||
You can also customise the runtime namespace by passing an optional namespace
|
||||
argument:
|
||||
|
||||
```javascript
|
||||
require("6to5").runtime("myCustomNamespace");
|
||||
```
|
||||
|
||||
$ 6to5-runtime myCustomNamespace
|
||||
|
||||
See [Options - runtime](#options) for documentation on changing the reference in
|
||||
generated code.
|
||||
|
||||
## Differences
|
||||
|
||||
### Philosophy
|
||||
|
||||
@@ -7,13 +7,10 @@ var es6now = require("es6now");
|
||||
var esnext = require("esnext");
|
||||
var to5 = require("../lib/6to5");
|
||||
|
||||
var uglify = require("uglify-js");
|
||||
//var uglify = require("uglify-js");
|
||||
var matcha = require("matcha");
|
||||
var stream = require("stream");
|
||||
var path = require("path");
|
||||
var zlib = require("zlib");
|
||||
var fs = require("fs");
|
||||
var vm = require("vm");
|
||||
var _ = require("lodash");
|
||||
|
||||
var readResolve = function (filename) {
|
||||
@@ -51,7 +48,7 @@ var compilers = {
|
||||
|
||||
traceur: {
|
||||
runtime: readResolve("traceur/bin/traceur-runtime.js"),
|
||||
compile: function (code, filename) {
|
||||
compile: function (code) {
|
||||
return traceur.compile(code, {
|
||||
modules: "commonjs",
|
||||
experimental: true
|
||||
@@ -61,20 +58,20 @@ var compilers = {
|
||||
|
||||
esnext: {
|
||||
runtime: readResolve("esnext/node_modules/regenerator/runtime.js") || readResolve("regenerator/runtime.js"),
|
||||
compile: function (code, filename) {
|
||||
compile: function (code) {
|
||||
return esnext.compile(code).code;
|
||||
}
|
||||
},
|
||||
|
||||
es6now: {
|
||||
runtime: readResolve("es6now/runtime/ES6.js"),
|
||||
compile: function (code, filename) {
|
||||
compile: function (code) {
|
||||
return es6now.translate(code);
|
||||
}
|
||||
},
|
||||
|
||||
"es6-transpiler": {
|
||||
compile: function (code, filename) {
|
||||
compile: function (code) {
|
||||
var result = es6tr.run({ src: code });
|
||||
if (result.errors.length) throw new Error(result.join("; "));
|
||||
return result.src;
|
||||
@@ -82,7 +79,7 @@ var compilers = {
|
||||
},
|
||||
|
||||
jstransform: {
|
||||
compile: function (code, filename) {
|
||||
compile: function (code) {
|
||||
return jsTrans.transform(jsTransVisitors, code).code;
|
||||
}
|
||||
}
|
||||
@@ -90,7 +87,7 @@ var compilers = {
|
||||
|
||||
// versions
|
||||
|
||||
var uglifyTitle = "uglify v" + getVersion("uglify-js");
|
||||
//var uglifyTitle = "uglify v" + getVersion("uglify-js");
|
||||
|
||||
_.each(compilers, function (compiler, name) {
|
||||
compiler.title = name + " v" + (compiler.version || getVersion(name));
|
||||
@@ -140,9 +137,9 @@ var sizeBenchmark = function (code, loc, name, compiler) {
|
||||
});
|
||||
if (!output) return;
|
||||
|
||||
go(function () {
|
||||
return uglify.minify(output, { fromString: true }).code;
|
||||
}, uglifyTitle);
|
||||
//go(function () {
|
||||
// return uglify.minify(output, { fromString: true }).code;
|
||||
//}, uglifyTitle);
|
||||
};
|
||||
|
||||
//
|
||||
@@ -162,7 +159,7 @@ _.each(fs.readdirSync(__dirname + "/fixtures"), function (name) {
|
||||
});
|
||||
});
|
||||
|
||||
_.each(compilers, function (compiler, name) {
|
||||
_.each(compilers, function (compiler) {
|
||||
bench(compiler.title, function () {
|
||||
compiler.compile(code, loc);
|
||||
});
|
||||
|
||||
124
bin/6to5-node
124
bin/6to5-node
@@ -1,84 +1,56 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
var commander = require("commander");
|
||||
var Module = require("module");
|
||||
var util = require("../lib/6to5/util");
|
||||
var path = require("path");
|
||||
var repl = require("repl");
|
||||
var to5 = require("../lib/6to5");
|
||||
var vm = require("vm");
|
||||
var _ = require("lodash");
|
||||
/**
|
||||
* This tiny wrapper file checks for known node flags and appends them
|
||||
* when found, before invoking the "real" _6to5-node(1) executable.
|
||||
*/
|
||||
|
||||
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]", util.list);
|
||||
var spawn = require("child_process").spawn;
|
||||
var args = ["--harmony", __dirname + "/_6to5-node"];
|
||||
|
||||
var pkg = require("../package.json");
|
||||
commander.version(pkg.version);
|
||||
commander.usage("[options] [ -e script | script.js ] [arguments]");
|
||||
commander.parse(process.argv);
|
||||
process.argv.slice(2).forEach(function(arg){
|
||||
var flag = arg.split("=")[0];
|
||||
|
||||
//
|
||||
|
||||
var registerOpts = {};
|
||||
|
||||
if (commander.ignore) {
|
||||
registerOpts.ignoreRegex = new RegExp(commander.ignore);
|
||||
}
|
||||
|
||||
if (commander.extensions && commander.extensions.length) {
|
||||
registerOpts.extensions = commander.extensions
|
||||
}
|
||||
|
||||
to5.register(registerOpts);
|
||||
|
||||
//
|
||||
|
||||
var _eval = function (code, filename) {
|
||||
code = to5.transform(code, { filename: filename }).code;
|
||||
return vm.runInThisContext(code, filename);
|
||||
};
|
||||
|
||||
if (commander.eval) {
|
||||
var result = _eval(commander.eval, "eval");
|
||||
if (commander.print) console.log(result);
|
||||
} else {
|
||||
var filenames = commander.args;
|
||||
|
||||
if (filenames.length) {
|
||||
_.each(filenames, function (filename) {
|
||||
if (!util.isAbsolute(filename)) {
|
||||
filename = path.join(process.cwd(), filename);
|
||||
}
|
||||
|
||||
require(require.resolve(filename));
|
||||
});
|
||||
} else {
|
||||
replStart();
|
||||
switch (flag) {
|
||||
case "-d":
|
||||
args.unshift("--debug");
|
||||
args.push("--no-timeouts");
|
||||
break;
|
||||
case "debug":
|
||||
case "--debug":
|
||||
case "--debug-brk":
|
||||
args.unshift(arg);
|
||||
args.push("--no-timeouts");
|
||||
break;
|
||||
case "-gc":
|
||||
case "--expose-gc":
|
||||
args.unshift("--expose-gc");
|
||||
break;
|
||||
case "--gc-global":
|
||||
case "--harmony":
|
||||
case "--harmony-proxies":
|
||||
case "--harmony-collections":
|
||||
case "--harmony-generators":
|
||||
case "--no-deprecation":
|
||||
case "--prof":
|
||||
case "--throw-deprecation":
|
||||
case "--trace-deprecation":
|
||||
args.unshift(arg);
|
||||
break;
|
||||
default:
|
||||
if (0 == arg.indexOf("--trace")) args.unshift(arg);
|
||||
else args.push(arg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function replStart() {
|
||||
repl.start({
|
||||
prompt: "> ",
|
||||
input: process.stdin,
|
||||
output: process.stdout,
|
||||
eval: replEval,
|
||||
useGlobal: true
|
||||
var proc = spawn(process.argv[0], args, { stdio: "inherit" });
|
||||
proc.on("exit", function (code, signal) {
|
||||
process.on("exit", function (){
|
||||
if (signal) {
|
||||
process.kill(process.pid, signal);
|
||||
} else {
|
||||
process.exit(code);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function replEval(code, context, filename, callback) {
|
||||
var err;
|
||||
var result;
|
||||
|
||||
try {
|
||||
code = code.slice(1, -2); // remove "(" and "\n)"
|
||||
result = _eval(code, filename);
|
||||
} catch (e) {
|
||||
err = e;
|
||||
}
|
||||
|
||||
callback(err, result);
|
||||
}
|
||||
});
|
||||
|
||||
4
bin/6to5-runtime
Executable file
4
bin/6to5-runtime
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
var runtime = require("../lib/6to5/runtime");
|
||||
console.log(runtime(process.argv[2]));
|
||||
@@ -6,7 +6,7 @@ var util = require("./util");
|
||||
var fs = require("fs");
|
||||
var _ = require("lodash");
|
||||
|
||||
module.exports = function (commander, filenames, opts) {
|
||||
module.exports = function (commander, filenames) {
|
||||
var results = [];
|
||||
|
||||
var buildResult = function () {
|
||||
@@ -48,7 +48,7 @@ module.exports = function (commander, filenames, opts) {
|
||||
return {
|
||||
map: map,
|
||||
code: code
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
var output = function () {
|
||||
@@ -100,8 +100,8 @@ module.exports = function (commander, filenames, opts) {
|
||||
}
|
||||
});
|
||||
|
||||
_.each(_filenames, function (filename, i) {
|
||||
results.push(util.compile(filename, { _noStrict: i != 0 }));
|
||||
_.each(_filenames, function (filename) {
|
||||
results.push(util.compile(filename));
|
||||
});
|
||||
|
||||
output();
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
var commander = require("commander");
|
||||
var sourceMap = require("source-map");
|
||||
var transform = require("../../lib/6to5/transform");
|
||||
var chokidar = require("chokidar");
|
||||
var mkdirp = require("mkdirp");
|
||||
var util2 = require("../../lib/6to5/util");
|
||||
var util = require("./util");
|
||||
var path = require("path");
|
||||
var transform = require("../../lib/6to5/transformation/transform");
|
||||
var util = require("../../lib/6to5/util");
|
||||
var fs = require("fs");
|
||||
var _ = require("lodash");
|
||||
|
||||
@@ -15,10 +10,11 @@ commander.option("-t, --source-maps-inline", "Append sourceMappingURL comment to
|
||||
commander.option("-s, --source-maps", "Save source map alongside the compiled code");
|
||||
commander.option("-f, --filename [filename]", "Filename to use when reading from stdin - this will be used in source-maps, errors etc [stdin]", "stdin");
|
||||
commander.option("-w, --watch", "Recompile files on changes");
|
||||
commander.option("-r, --runtime", "Replace 6to5 declarations with references to a runtime");
|
||||
|
||||
commander.option("-m, --modules [modules]", "Module formatter type to use [common]", "common");
|
||||
commander.option("-w, --whitelist [whitelist]", "Whitelist of transformers to ONLY use", util2.list);
|
||||
commander.option("-b, --blacklist [blacklist]", "Blacklist of transformers to NOT use", util2.list);
|
||||
commander.option("-w, --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("-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");
|
||||
|
||||
@@ -92,6 +88,7 @@ exports.opts = {
|
||||
blacklist: commander.blacklist,
|
||||
whitelist: commander.whitelist,
|
||||
sourceMap: commander.sourceMaps || commander.sourceMapsInline,
|
||||
runtime: commander.runtime,
|
||||
modules: commander.modules
|
||||
};
|
||||
|
||||
|
||||
86
bin/_6to5-node
Normal file
86
bin/_6to5-node
Normal file
@@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
var commander = require("commander");
|
||||
var util = require("../lib/6to5/util");
|
||||
var path = require("path");
|
||||
var repl = require("repl");
|
||||
var to5 = require("../lib/6to5");
|
||||
var 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]", util.list);
|
||||
|
||||
var pkg = require("../package.json");
|
||||
commander.version(pkg.version);
|
||||
commander.usage("[options] [ -e script | script.js ] [arguments]");
|
||||
commander.parse(process.argv);
|
||||
|
||||
//
|
||||
|
||||
var registerOpts = {};
|
||||
|
||||
if (commander.ignore) {
|
||||
registerOpts.ignoreRegex = new RegExp(commander.ignore);
|
||||
}
|
||||
|
||||
if (commander.extensions && commander.extensions.length) {
|
||||
registerOpts.extensions = commander.extensions;
|
||||
}
|
||||
|
||||
to5.register(registerOpts);
|
||||
|
||||
//
|
||||
|
||||
var _eval = function (code, filename) {
|
||||
code = to5.transform(code, { filename: filename, blacklist: ["useStrict"] }).code;
|
||||
return vm.runInThisContext(code, filename);
|
||||
};
|
||||
|
||||
if (commander.eval) {
|
||||
var result = _eval(commander.eval, "eval");
|
||||
if (commander.print) console.log(result);
|
||||
} else {
|
||||
var filenames = commander.args;
|
||||
|
||||
if (filenames.length) {
|
||||
_.each(filenames, function (filename) {
|
||||
if (!util.isAbsolute(filename)) {
|
||||
filename = path.join(process.cwd(), filename);
|
||||
}
|
||||
|
||||
require(require.resolve(filename));
|
||||
});
|
||||
} else {
|
||||
replStart();
|
||||
}
|
||||
}
|
||||
|
||||
function replStart() {
|
||||
repl.start({
|
||||
prompt: "> ",
|
||||
input: process.stdin,
|
||||
output: process.stdout,
|
||||
eval: replEval,
|
||||
useGlobal: true
|
||||
});
|
||||
}
|
||||
|
||||
function replEval(code, context, filename, callback) {
|
||||
var err;
|
||||
var result;
|
||||
|
||||
try {
|
||||
if (/^\((.*?)\n\)$/.test(code)) {
|
||||
code = code.slice(1, -2); // remove "(" and "\n)"
|
||||
}
|
||||
|
||||
result = _eval(code, filename);
|
||||
} catch (e) {
|
||||
err = e;
|
||||
}
|
||||
|
||||
callback(err, result);
|
||||
}
|
||||
5
bin/cache-tests
Normal file
5
bin/cache-tests
Normal file
@@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
var fs = require("fs");
|
||||
var cache = require("../test/_helper").cache;
|
||||
fs.writeFileSync("tests.json", JSON.stringify(cache));
|
||||
@@ -1,6 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
var helper = require("../test/_helper");
|
||||
var util = require("../lib/6to5/util");
|
||||
|
||||
console.log("(" + helper.run + ")(" + JSON.stringify(helper.getTests()) + ", to5, proclaim)");
|
||||
87
lib/6to5/browser.js
Normal file
87
lib/6to5/browser.js
Normal file
@@ -0,0 +1,87 @@
|
||||
var transform = module.exports = require("./transformation/transform");
|
||||
|
||||
transform.transform = transform;
|
||||
|
||||
transform.eval = function (code, opts) {
|
||||
opts = opts || {};
|
||||
opts.filename = opts.filename || "eval";
|
||||
opts.sourceMap = "inline";
|
||||
return eval(transform(code, opts).code);
|
||||
};
|
||||
|
||||
transform.run = function (code, opts) {
|
||||
opts = opts || {};
|
||||
opts.sourceMap = "inline";
|
||||
return new Function(transform(code, opts).code)();
|
||||
};
|
||||
|
||||
transform.load = function (url, callback, opts, hold) {
|
||||
opts = opts || {};
|
||||
opts.filename = opts.filename || url;
|
||||
|
||||
var xhr = window.ActiveXObject ? new window.ActiveXObject("Microsoft.XMLHTTP") : new window.XMLHttpRequest();
|
||||
xhr.open("GET", url, true);
|
||||
if ("overrideMimeType" in xhr) xhr.overrideMimeType("text/plain");
|
||||
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState !== 4) return;
|
||||
|
||||
var status = xhr.status;
|
||||
if (status === 0 || status === 200) {
|
||||
var param = [xhr.responseText, opts];
|
||||
if (!hold) transform.run.apply(transform, param);
|
||||
if (callback) callback(param);
|
||||
} else {
|
||||
throw new Error("Could not load " + url);
|
||||
}
|
||||
};
|
||||
|
||||
xhr.send(null);
|
||||
};
|
||||
|
||||
var runScripts = function () {
|
||||
var scripts = [];
|
||||
var types = ["text/ecmascript-6", "text/6to5"];
|
||||
var index = 0;
|
||||
|
||||
var exec = function () {
|
||||
var param = scripts[index];
|
||||
if (param instanceof Array) {
|
||||
transform.run.apply(transform, param);
|
||||
index++;
|
||||
exec();
|
||||
}
|
||||
};
|
||||
|
||||
var run = function (script, i) {
|
||||
var opts = {};
|
||||
|
||||
if (script.src) {
|
||||
transform.load(script.src, function (param) {
|
||||
scripts[i] = param;
|
||||
exec();
|
||||
}, opts, true);
|
||||
} else {
|
||||
opts.filename = "embedded";
|
||||
scripts[i] = [script.innerHTML, opts];
|
||||
}
|
||||
};
|
||||
|
||||
var _scripts = window.document.getElementsByTagName("script");
|
||||
for (var i in _scripts) {
|
||||
var _script = _scripts[i];
|
||||
if (types.indexOf(_script.type) >= 0) scripts.push(_script);
|
||||
}
|
||||
|
||||
for (i in scripts) {
|
||||
run(scripts[i], i);
|
||||
}
|
||||
|
||||
exec();
|
||||
};
|
||||
|
||||
if (window.addEventListener) {
|
||||
window.addEventListener("DOMContentLoaded", runScripts, false);
|
||||
} else {
|
||||
window.attachEvent("onload", runScripts);
|
||||
}
|
||||
107
lib/6to5/file.js
107
lib/6to5/file.js
@@ -2,10 +2,11 @@ module.exports = File;
|
||||
|
||||
var SHEBANG_REGEX = /^\#\!.*/;
|
||||
|
||||
var transform = require("./transform");
|
||||
var recast = require("acorn-recast");
|
||||
var transform = require("./transformation/transform");
|
||||
var generate = require("./generation/generator");
|
||||
var Scope = require("./traverse/scope");
|
||||
var util = require("./util");
|
||||
var b = require("acorn-ast-types").builders;
|
||||
var t = require("./types");
|
||||
var _ = require("lodash");
|
||||
|
||||
function File(opts) {
|
||||
@@ -17,15 +18,19 @@ function File(opts) {
|
||||
this.ast = {};
|
||||
}
|
||||
|
||||
File.declarations = ["extends", "class-props", "slice"];
|
||||
|
||||
File.normaliseOptions = function (opts) {
|
||||
opts = opts || {};
|
||||
|
||||
_.defaults(opts, {
|
||||
blacklist: [],
|
||||
whitelist: [],
|
||||
sourceMap: false,
|
||||
filename: "unknown",
|
||||
modules: "common"
|
||||
whitespace: true,
|
||||
blacklist: [],
|
||||
whitelist: [],
|
||||
sourceMap: false,
|
||||
filename: "unknown",
|
||||
modules: "common",
|
||||
runtime: false
|
||||
});
|
||||
|
||||
_.defaults(opts, {
|
||||
@@ -33,6 +38,10 @@ File.normaliseOptions = function (opts) {
|
||||
sourceMapName: opts.filename
|
||||
});
|
||||
|
||||
if (opts.runtime === true) {
|
||||
opts.runtime = "to5Runtime";
|
||||
}
|
||||
|
||||
transform._ensureTransformerNames("blacklist", opts.blacklist);
|
||||
transform._ensureTransformerNames("whitelist", opts.whitelist);
|
||||
|
||||
@@ -40,18 +49,18 @@ File.normaliseOptions = function (opts) {
|
||||
};
|
||||
|
||||
File.prototype.getModuleFormatter = function (type) {
|
||||
var ModuleLoader = transform.moduleFormatters[type];
|
||||
var ModuleFormatter = transform.moduleFormatters[type];
|
||||
|
||||
if (!ModuleLoader) {
|
||||
if (!ModuleFormatter) {
|
||||
var loc = util.resolve(type);
|
||||
if (loc) ModuleLoader = require(loc);
|
||||
if (loc) ModuleFormatter = require(loc);
|
||||
}
|
||||
|
||||
if (!ModuleLoader) {
|
||||
if (!ModuleFormatter) {
|
||||
throw new ReferenceError("unknown module formatter type " + type);
|
||||
}
|
||||
|
||||
return new ModuleLoader(this);
|
||||
return new ModuleFormatter(this);
|
||||
};
|
||||
|
||||
File.prototype.parseShebang = function (code) {
|
||||
@@ -67,80 +76,94 @@ File.prototype.parseShebang = function (code) {
|
||||
};
|
||||
|
||||
File.prototype.addDeclaration = function (name) {
|
||||
if (!_.contains(File.declarations, name)) {
|
||||
throw new ReferenceError("unknown declaration " + name);
|
||||
}
|
||||
|
||||
var declar = this.declarations[name];
|
||||
if (declar) return declar.uid;
|
||||
|
||||
var uid = b.identifier(this.generateUid(name));
|
||||
var ref;
|
||||
var runtimeNamespace = this.opts.runtime;
|
||||
if (runtimeNamespace) {
|
||||
name = t.identifier(t.toIdentifier(name));
|
||||
return t.memberExpression(t.identifier(runtimeNamespace), name);
|
||||
} else {
|
||||
ref = util.template(name);
|
||||
}
|
||||
|
||||
var uid = t.identifier(this.generateUid(name));
|
||||
this.declarations[name] = {
|
||||
uid: uid,
|
||||
node: util.template(name)
|
||||
node: ref
|
||||
};
|
||||
return uid;
|
||||
};
|
||||
|
||||
File.prototype.errorWithNode = function (node, msg, Error) {
|
||||
Error = Error || SyntaxError;
|
||||
|
||||
var loc = node.loc.start;
|
||||
var err = new Error("Line " + loc.line + ": " + msg);
|
||||
err.loc = loc;
|
||||
return err;
|
||||
};
|
||||
|
||||
File.prototype.parse = function (code) {
|
||||
var self = this;
|
||||
|
||||
this.code = code;
|
||||
|
||||
code = this.parseShebang(code);
|
||||
|
||||
return util.parse(this.opts, code, function (tree) {
|
||||
return self.transform(tree);
|
||||
self.transform(tree);
|
||||
return self.generate();
|
||||
});
|
||||
};
|
||||
|
||||
File.prototype.transform = function (ast) {
|
||||
this.ast = ast;
|
||||
this.scope = new Scope(null, ast.program);
|
||||
|
||||
var self = this;
|
||||
|
||||
_.each(transform.transformers, function (transformer) {
|
||||
transformer.transform(self);
|
||||
});
|
||||
|
||||
return this.generate();
|
||||
};
|
||||
|
||||
File.prototype.generate = function () {
|
||||
var opts = this.opts;
|
||||
var ast = this.ast;
|
||||
|
||||
var printOpts = { tabWidth: 2 };
|
||||
|
||||
if (opts.sourceMap) {
|
||||
printOpts.sourceMapName = opts.sourceMapName;
|
||||
}
|
||||
|
||||
var result = recast.print(ast, printOpts);
|
||||
var code = result.code;
|
||||
var result = generate(ast, opts, this.code);
|
||||
|
||||
if (this.shebang) {
|
||||
// add back shebang
|
||||
code = this.shebang + code;
|
||||
result.code = this.shebang + result.code;
|
||||
}
|
||||
|
||||
if (opts.sourceMap === "inline") {
|
||||
code += "\n" + util.sourceMapToComment(result.map);
|
||||
result.code += "\n" + util.sourceMapToComment(result.map);
|
||||
}
|
||||
|
||||
return {
|
||||
code: code,
|
||||
map: result.map || null,
|
||||
ast: ast
|
||||
};
|
||||
return result;
|
||||
};
|
||||
|
||||
File.prototype.generateUid = function (name) {
|
||||
// replace all non-valid identifiers with dashes
|
||||
name = name.replace(/[^a-zA-Z0-9]/g, "-");
|
||||
File.prototype.generateUid = function (name, scope) {
|
||||
name = t.toIdentifier(name);
|
||||
|
||||
// remove all dashes and numbers from start of name
|
||||
name = name.replace(/^[-0-9]+/, "");
|
||||
scope = scope || this.scope;
|
||||
|
||||
// camel case
|
||||
name = name.replace(/[-_\s]+(.)?/g, function (match, c) {
|
||||
return c ? c.toUpperCase() : "";
|
||||
});
|
||||
var uid;
|
||||
do {
|
||||
uid = this._generateUid(name);
|
||||
} while (scope.has(uid));
|
||||
return uid;
|
||||
};
|
||||
|
||||
File.prototype._generateUid = function (name) {
|
||||
var uids = this.uids;
|
||||
var i = uids[name] || 1;
|
||||
|
||||
|
||||
396
lib/6to5/generation/generator.js
Normal file
396
lib/6to5/generation/generator.js
Normal file
@@ -0,0 +1,396 @@
|
||||
module.exports = function (ast, opts, code) {
|
||||
var gen = new CodeGenerator(ast, opts, code);
|
||||
return gen.generate();
|
||||
};
|
||||
|
||||
module.exports.CodeGenerator = CodeGenerator;
|
||||
|
||||
var Whitespace = require("./whitespace");
|
||||
var SourceMap = require("./source-map");
|
||||
var Position = require("./position");
|
||||
var util = require("../util");
|
||||
var n = require("./node");
|
||||
var t = require("../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
function CodeGenerator(ast, opts, code) {
|
||||
opts = opts || {};
|
||||
|
||||
this.style = {
|
||||
semicolons: true,
|
||||
comments: true,
|
||||
compact: false,
|
||||
indent: {
|
||||
char: " ",
|
||||
width: 2
|
||||
}
|
||||
};
|
||||
|
||||
this.comments = ast.comments || [];
|
||||
this.tokens = ast.tokens || [];
|
||||
this.opts = opts;
|
||||
this.ast = ast;
|
||||
this.buf = "";
|
||||
|
||||
this._indent = 0;
|
||||
|
||||
this.whitespace = new Whitespace(this.tokens, this.comments);
|
||||
this.position = new Position;
|
||||
this.map = new SourceMap(this.position, opts, code);
|
||||
}
|
||||
|
||||
CodeGenerator.generators = {
|
||||
arrayComprehensions: require("./generators/array-comprehensions"),
|
||||
templateLiterals: require("./generators/template-literals"),
|
||||
expressions: require("./generators/expressions"),
|
||||
statements: require("./generators/statements"),
|
||||
classes: require("./generators/classes"),
|
||||
methods: require("./generators/methods"),
|
||||
modules: require("./generators/modules"),
|
||||
types: require("./generators/types"),
|
||||
base: require("./generators/base"),
|
||||
jsx: require("./generators/jsx")
|
||||
};
|
||||
|
||||
_.each(CodeGenerator.generators, function (generator) {
|
||||
_.extend(CodeGenerator.prototype, generator);
|
||||
});
|
||||
|
||||
CodeGenerator.prototype.newline = function (i, removeLast) {
|
||||
if (!this.buf) return;
|
||||
if (this.style.compact) return;
|
||||
if (this.endsWith("{\n")) return;
|
||||
|
||||
if (_.isBoolean(i)) {
|
||||
removeLast = i;
|
||||
i = null;
|
||||
}
|
||||
|
||||
if (_.isNumber(i)) {
|
||||
var self = this;
|
||||
_.times(i, function () {
|
||||
self.newline(null, removeLast);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (removeLast && this.isLast("\n")) this.removeLast("\n");
|
||||
|
||||
this.removeLast(" ");
|
||||
this.buf = this.buf.replace(/\n(\s+)$/, "\n");
|
||||
this._push("\n");
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.removeLast = function (cha) {
|
||||
if (!this.isLast(cha)) return;
|
||||
|
||||
this.buf = this.buf.slice(0, -1);
|
||||
this.position.unshift(cha);
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.semicolon = function () {
|
||||
if (this.style.semicolons) this.push(";");
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.ensureSemicolon = function () {
|
||||
if (!this.isLast(";")) this.semicolon();
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.rightBrace = function () {
|
||||
this.newline(true);
|
||||
this.push("}");
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.keyword = function (name) {
|
||||
this.push(name);
|
||||
this.push(" ");
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.space = function () {
|
||||
if (this.buf && !this.isLast([" ", "\n"])) {
|
||||
this.push(" ");
|
||||
}
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.push = function (str, noIndent) {
|
||||
if (this._indent && !noIndent && str !== "\n") {
|
||||
// we have an indent level and we aren't pushing a newline
|
||||
var indent = this.getIndent();
|
||||
|
||||
// replace all newlines with newlines with the indentation
|
||||
str = str.replace(/\n/g, "\n" + indent);
|
||||
|
||||
// we've got a newline before us so prepend on the indentation
|
||||
if (this.isLast("\n")) str = indent + str;
|
||||
}
|
||||
|
||||
this._push(str);
|
||||
};
|
||||
|
||||
CodeGenerator.prototype._push = function (str) {
|
||||
this.position.push(str);
|
||||
this.buf += str;
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.endsWith = function (str) {
|
||||
return this.buf.slice(-str.length) === str;
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.isLast = function (cha, trimRight) {
|
||||
var buf = this.buf;
|
||||
if (trimRight) buf = buf.trimRight();
|
||||
|
||||
var chars = [].concat(cha);
|
||||
return _.contains(chars, _.last(buf));
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.getIndent = function () {
|
||||
if (this.style.compact) {
|
||||
return "";
|
||||
} else {
|
||||
return util.repeat(this.indentSize(), this.style.indent.char);
|
||||
}
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.indentSize = function () {
|
||||
return this._indent * this.style.indent.width;
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.indent = function () {
|
||||
this._indent++;
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.dedent = function () {
|
||||
this._indent--;
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.generate = function () {
|
||||
var ast = this.ast;
|
||||
|
||||
this.print(ast);
|
||||
|
||||
this.buf = this.buf.trimRight();
|
||||
|
||||
return {
|
||||
map: this.map.get(),
|
||||
ast: ast,
|
||||
code: this.buf
|
||||
};
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.buildPrint = function (parent) {
|
||||
var self = this;
|
||||
|
||||
var print = function (node, opts) {
|
||||
return self.print(node, parent, opts);
|
||||
};
|
||||
|
||||
print.sequence = function (nodes, opts) {
|
||||
opts = opts || {};
|
||||
opts.statement = true;
|
||||
return self.printJoin(print, nodes, opts);
|
||||
};
|
||||
|
||||
print.join = function (nodes, opts) {
|
||||
return self.printJoin(print, nodes, opts);
|
||||
};
|
||||
|
||||
print.block = function (node) {
|
||||
return self.printBlock(print, node);
|
||||
};
|
||||
|
||||
print.indentOnComments = function (node) {
|
||||
return self.printAndIndentOnComments(print, node);
|
||||
};
|
||||
|
||||
return print;
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.print = function (node, parent, opts) {
|
||||
if (!node) return "";
|
||||
|
||||
var self = this;
|
||||
opts = opts || {};
|
||||
|
||||
var newline = function (leading) {
|
||||
var ignoreDuplicates = false;
|
||||
|
||||
if (!opts.statement && !n.isUserWhitespacable(node, parent)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var lines = 0;
|
||||
|
||||
if (node.start != null) {
|
||||
// user node
|
||||
if (leading) {
|
||||
lines = self.whitespace.getNewlinesBefore(node);
|
||||
} else {
|
||||
lines = self.whitespace.getNewlinesAfter(node);
|
||||
}
|
||||
} else {
|
||||
// generated node
|
||||
if (!leading) lines++; // always include at least a single line after
|
||||
|
||||
var needs = n.needsWhitespaceAfter;
|
||||
if (leading) needs = n.needsWhitespaceBefore;
|
||||
lines += needs(node, parent);
|
||||
}
|
||||
|
||||
self.newline(lines, ignoreDuplicates);
|
||||
};
|
||||
|
||||
if (this[node.type]) {
|
||||
this.printLeadingComments(node, parent);
|
||||
|
||||
newline(true);
|
||||
|
||||
if (opts.before) opts.before();
|
||||
this.map.mark(node, "start");
|
||||
|
||||
// only compute if this node needs parens if our parent has been changed
|
||||
// since acorn would've wrapped us in a ParanthesizedExpression
|
||||
var needsParens = parent !== node._parent && n.needsParens(node, parent);
|
||||
if (needsParens) this.push("(");
|
||||
|
||||
this[node.type](node, this.buildPrint(node), parent);
|
||||
|
||||
if (needsParens) this.push(")");
|
||||
|
||||
this.map.mark(node, "end");
|
||||
if (opts.after) opts.after();
|
||||
|
||||
newline(false);
|
||||
|
||||
this.printTrailingComments(node, parent);
|
||||
} else {
|
||||
throw new ReferenceError("unknown node " + node.type + " " + JSON.stringify(node));
|
||||
}
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.printJoin = function (print, nodes, opts) {
|
||||
opts = opts || {};
|
||||
|
||||
var self = this;
|
||||
var len = nodes.length;
|
||||
|
||||
if (opts.indent) self.indent();
|
||||
|
||||
_.each(nodes, function (node, i) {
|
||||
print(node, {
|
||||
statement: opts.statement,
|
||||
after: function () {
|
||||
if (opts.iterator) {
|
||||
opts.iterator(node, i);
|
||||
}
|
||||
|
||||
if (opts.separator && i < len - 1) {
|
||||
self.push(opts.separator);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if (opts.indent) self.dedent();
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.printAndIndentOnComments = function (print, node) {
|
||||
var indent = !!node.leadingComments;
|
||||
if (indent) this.indent();
|
||||
print(node);
|
||||
if (indent) this.dedent();
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.printBlock = function (print, node) {
|
||||
if (t.isEmptyStatement(node)) {
|
||||
this.semicolon();
|
||||
} else {
|
||||
this.push(" ");
|
||||
print(node);
|
||||
}
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.generateComment = function (comment) {
|
||||
var val = comment.value;
|
||||
if (comment.type === "Line") {
|
||||
val = "//" + val;
|
||||
} else {
|
||||
val = "/*" + val + "*/";
|
||||
}
|
||||
return val;
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.printTrailingComments = function (node, parent) {
|
||||
this._printComments(this.getComments("trailingComments", node, parent));
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.printLeadingComments = function (node, parent) {
|
||||
this._printComments(this.getComments("leadingComments", node, parent));
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.getComments = function (key, node, parent) {
|
||||
if (t.isExpressionStatement(parent)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
var comments = [];
|
||||
var nodes = [node];
|
||||
var self = this;
|
||||
|
||||
if (t.isExpressionStatement(node)) {
|
||||
nodes.push(node.argument);
|
||||
}
|
||||
|
||||
_.each(nodes, function (node) {
|
||||
comments = comments.concat(self._getComments(key, node));
|
||||
});
|
||||
|
||||
return comments;
|
||||
};
|
||||
|
||||
CodeGenerator.prototype._getComments = function (key, node) {
|
||||
return (node && node[key]) || [];
|
||||
};
|
||||
|
||||
CodeGenerator.prototype._printComments = function (comments) {
|
||||
if (this.style.compact) return;
|
||||
if (!this.style.comments) return;
|
||||
if (!comments || !comments.length) return;
|
||||
|
||||
var self = this;
|
||||
|
||||
_.each(comments, function (comment) {
|
||||
// whitespace before
|
||||
self.newline(self.whitespace.getNewlinesBefore(comment));
|
||||
|
||||
var column = self.position.column;
|
||||
var val = self.generateComment(comment);
|
||||
|
||||
if (column && !self.isLast(["\n", " ", "[", "{"])) {
|
||||
self._push(" ");
|
||||
column++;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
var offset = comment.loc.start.column;
|
||||
if (offset) {
|
||||
var newlineRegex = new RegExp("\\n\\s{1," + offset + "}", "g");
|
||||
val = val.replace(newlineRegex, "\n");
|
||||
}
|
||||
|
||||
var indent = Math.max(self.indentSize(), column);
|
||||
val = val.replace(/\n/g, "\n" + util.repeat(indent));
|
||||
|
||||
if (column === 0) {
|
||||
val = self.getIndent() + val;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
self._push(val);
|
||||
|
||||
// whitespace after
|
||||
self.newline(self.whitespace.getNewlinesAfter(comment));
|
||||
});
|
||||
};
|
||||
25
lib/6to5/generation/generators/array-comprehensions.js
Normal file
25
lib/6to5/generation/generators/array-comprehensions.js
Normal file
@@ -0,0 +1,25 @@
|
||||
exports.ComprehensionBlock = function (node, print) {
|
||||
this.keyword("for");
|
||||
this.push("(");
|
||||
print(node.left);
|
||||
this.push(" of ");
|
||||
print(node.right);
|
||||
this.push(")");
|
||||
};
|
||||
|
||||
exports.ComprehensionExpression = function (node, print) {
|
||||
this.push("[");
|
||||
print.join(node.blocks, { separator: " " });
|
||||
this.space();
|
||||
|
||||
if (node.filter) {
|
||||
this.keyword("if");
|
||||
this.push("(");
|
||||
print(node.filter);
|
||||
this.push(")");
|
||||
this.space();
|
||||
}
|
||||
|
||||
print(node.body);
|
||||
this.push("]");
|
||||
};
|
||||
19
lib/6to5/generation/generators/base.js
Normal file
19
lib/6to5/generation/generators/base.js
Normal file
@@ -0,0 +1,19 @@
|
||||
exports.File = function (node, print) {
|
||||
print(node.program);
|
||||
};
|
||||
|
||||
exports.Program = function (node, print) {
|
||||
print.sequence(node.body);
|
||||
};
|
||||
|
||||
exports.BlockStatement = function (node, print) {
|
||||
if (node.body.length === 0) {
|
||||
this.push("{}");
|
||||
} else {
|
||||
this.push("{");
|
||||
this.newline();
|
||||
print.sequence(node.body, { indent: true });
|
||||
this.removeLast("\n");
|
||||
this.rightBrace();
|
||||
}
|
||||
};
|
||||
32
lib/6to5/generation/generators/classes.js
Normal file
32
lib/6to5/generation/generators/classes.js
Normal file
@@ -0,0 +1,32 @@
|
||||
exports.ClassExpression =
|
||||
exports.ClassDeclaration = function (node, print) {
|
||||
this.push("class");
|
||||
|
||||
if (node.id) {
|
||||
this.space();
|
||||
print(node.id);
|
||||
}
|
||||
|
||||
if (node.superClass) {
|
||||
this.push(" extends ");
|
||||
print(node.superClass);
|
||||
}
|
||||
|
||||
this.space();
|
||||
print(node.body);
|
||||
};
|
||||
|
||||
exports.ClassBody = function (node, print) {
|
||||
if (node.body.length === 0) {
|
||||
this.push("{}");
|
||||
} else {
|
||||
this.push("{");
|
||||
this.newline();
|
||||
|
||||
this.indent();
|
||||
print.sequence(node.body);
|
||||
this.dedent();
|
||||
|
||||
this.rightBrace();
|
||||
}
|
||||
};
|
||||
104
lib/6to5/generation/generators/expressions.js
Normal file
104
lib/6to5/generation/generators/expressions.js
Normal file
@@ -0,0 +1,104 @@
|
||||
var t = require("../../types");
|
||||
|
||||
exports.UnaryExpression = function (node, print) {
|
||||
var hasSpace = /[a-z]$/.test(node.operator);
|
||||
var arg = node.argument;
|
||||
|
||||
if (t.isUpdateExpression(arg) || t.isUnaryExpression(arg)) {
|
||||
hasSpace = true;
|
||||
}
|
||||
|
||||
if (t.isUnaryExpression(arg) && arg.operator === "!") {
|
||||
hasSpace = false;
|
||||
}
|
||||
|
||||
this.push(node.operator);
|
||||
if (hasSpace) this.space();
|
||||
print(node.argument);
|
||||
};
|
||||
|
||||
exports.ParenthesizedExpression = function (node, print) {
|
||||
this.push("(");
|
||||
print(node.expression);
|
||||
this.push(")");
|
||||
};
|
||||
|
||||
exports.UpdateExpression = function (node, print) {
|
||||
if (node.prefix) {
|
||||
this.push(node.operator);
|
||||
print(node.argument);
|
||||
} else {
|
||||
print(node.argument);
|
||||
this.push(node.operator);
|
||||
}
|
||||
};
|
||||
|
||||
exports.ConditionalExpression = function (node, print) {
|
||||
print(node.test);
|
||||
this.push(" ? ");
|
||||
print(node.consequent);
|
||||
this.push(" : ");
|
||||
print(node.alternate);
|
||||
};
|
||||
|
||||
exports.NewExpression = function (node, print) {
|
||||
this.push("new ");
|
||||
print(node.callee);
|
||||
this.push("(");
|
||||
print.join(node.arguments, { separator: ", " });
|
||||
this.push(")");
|
||||
};
|
||||
|
||||
exports.SequenceExpression = function (node, print) {
|
||||
print.join(node.expressions, { separator: ", " });
|
||||
};
|
||||
|
||||
exports.ThisExpression = function () {
|
||||
this.push("this");
|
||||
};
|
||||
|
||||
exports.CallExpression = function (node, print) {
|
||||
print(node.callee);
|
||||
this.push("(");
|
||||
print.join(node.arguments, { separator: ", " });
|
||||
this.push(")");
|
||||
};
|
||||
|
||||
exports.YieldExpression = function (node, print) {
|
||||
this.push("yield");
|
||||
if (node.delegate) this.push("*");
|
||||
if (node.argument) {
|
||||
this.space();
|
||||
print(node.argument);
|
||||
}
|
||||
};
|
||||
|
||||
exports.EmptyStatement = function () {
|
||||
this.semicolon();
|
||||
};
|
||||
|
||||
exports.ExpressionStatement = function (node, print) {
|
||||
print(node.expression);
|
||||
this.semicolon();
|
||||
};
|
||||
|
||||
exports.BinaryExpression =
|
||||
exports.LogicalExpression =
|
||||
exports.AssignmentExpression = function (node, print) {
|
||||
print(node.left);
|
||||
this.push(" " + node.operator + " ");
|
||||
print(node.right);
|
||||
};
|
||||
|
||||
exports.MemberExpression = function (node, print) {
|
||||
print(node.object);
|
||||
|
||||
if (node.computed) {
|
||||
this.push("[");
|
||||
print(node.property);
|
||||
this.push("]");
|
||||
} else {
|
||||
this.push(".");
|
||||
print(node.property);
|
||||
}
|
||||
};
|
||||
82
lib/6to5/generation/generators/jsx.js
Normal file
82
lib/6to5/generation/generators/jsx.js
Normal file
@@ -0,0 +1,82 @@
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
exports.XJSAttribute = function (node, print) {
|
||||
print(node.name);
|
||||
if (node.value) {
|
||||
this.push("=");
|
||||
print(node.value);
|
||||
}
|
||||
};
|
||||
|
||||
exports.XJSIdentifier = function (node) {
|
||||
this.push(node.name);
|
||||
};
|
||||
|
||||
exports.XJSNamespacedName = function (node, print) {
|
||||
print(node.namespace);
|
||||
this.push(":");
|
||||
print(node.name);
|
||||
};
|
||||
|
||||
exports.XJSMemberExpression = function (node, print) {
|
||||
print(node.object);
|
||||
this.push(".");
|
||||
print(node.property);
|
||||
};
|
||||
|
||||
exports.XJSSpreadAttribute = function (node, print) {
|
||||
this.push("{...");
|
||||
print(node.argument);
|
||||
this.push("}");
|
||||
};
|
||||
|
||||
exports.XJSExpressionContainer = function (node, print) {
|
||||
this.push("{");
|
||||
print(node.expression);
|
||||
this.push("}");
|
||||
};
|
||||
|
||||
exports.XJSElement = function (node, print) {
|
||||
var self = this;
|
||||
|
||||
var open = node.openingElement;
|
||||
print(open);
|
||||
if (open.selfClosing) return;
|
||||
|
||||
this.indent();
|
||||
_.each(node.children, function (child) {
|
||||
if (t.isLiteral(child) && typeof child.value === "string") {
|
||||
if (/\S/.test(child.value)) {
|
||||
return self.push(child.value.replace(/^\s+|\s+$/g, ""));
|
||||
} else if (/\n/.test(child.value)) {
|
||||
return self.newline();
|
||||
}
|
||||
}
|
||||
|
||||
print(child);
|
||||
});
|
||||
this.dedent();
|
||||
|
||||
print(node.closingElement);
|
||||
};
|
||||
|
||||
exports.XJSOpeningElement = function (node, print) {
|
||||
this.push("<");
|
||||
print(node.name);
|
||||
if (node.attributes.length > 0) {
|
||||
this.space();
|
||||
print.join(node.attributes, { separator: " " });
|
||||
}
|
||||
this.push(node.selfClosing ? " />" : ">");
|
||||
};
|
||||
|
||||
exports.XJSClosingElement = function (node, print) {
|
||||
this.push("</");
|
||||
print(node.name);
|
||||
this.push(">");
|
||||
};
|
||||
|
||||
exports.XJSEmptyExpression = function () {
|
||||
this.push("null");
|
||||
};
|
||||
85
lib/6to5/generation/generators/methods.js
Normal file
85
lib/6to5/generation/generators/methods.js
Normal file
@@ -0,0 +1,85 @@
|
||||
var t = require("../../types");
|
||||
|
||||
exports._params = function (node, print) {
|
||||
var self = this;
|
||||
|
||||
this.push("(");
|
||||
|
||||
print.join(node.params, {
|
||||
separator: ", ",
|
||||
iterator: function (param, i) {
|
||||
var def = node.defaults && node.defaults[i];
|
||||
if (def) {
|
||||
self.push(" = ");
|
||||
print(def);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (node.rest) {
|
||||
if (node.params.length) {
|
||||
this.push(", ");
|
||||
}
|
||||
|
||||
this.push("...");
|
||||
print(node.rest);
|
||||
}
|
||||
|
||||
this.push(")");
|
||||
};
|
||||
|
||||
exports._method = function (node, print) {
|
||||
var value = node.value;
|
||||
var kind = node.kind;
|
||||
var key = node.key;
|
||||
|
||||
if (!kind || kind === "init") {
|
||||
if (value.generator) {
|
||||
this.push("*");
|
||||
}
|
||||
} else {
|
||||
this.push(kind + " ");
|
||||
}
|
||||
|
||||
if (node.computed) {
|
||||
this.push("[");
|
||||
print(key);
|
||||
this.push("]");
|
||||
} else {
|
||||
print(key);
|
||||
}
|
||||
|
||||
this._params(value, print);
|
||||
this.space();
|
||||
print(value.body);
|
||||
};
|
||||
|
||||
exports.MethodDefinition = function (node, print) {
|
||||
if (node.static) {
|
||||
this.push("static ");
|
||||
}
|
||||
|
||||
this._method(node, print);
|
||||
};
|
||||
|
||||
exports.FunctionDeclaration =
|
||||
exports.FunctionExpression = function (node, print) {
|
||||
this.push("function");
|
||||
if (node.generator) this.push("*");
|
||||
this.space();
|
||||
if (node.id) print(node.id);
|
||||
this._params(node, print);
|
||||
this.space();
|
||||
print(node.body);
|
||||
};
|
||||
|
||||
exports.ArrowFunctionExpression = function (node, print) {
|
||||
if (node.params.length === 1 && !node.defaults.length && !node.rest && t.isIdentifier(node.params[0])) {
|
||||
print(node.params[0]);
|
||||
} else {
|
||||
this._params(node, print);
|
||||
}
|
||||
|
||||
this.push(" => ");
|
||||
print(node.body);
|
||||
};
|
||||
86
lib/6to5/generation/generators/modules.js
Normal file
86
lib/6to5/generation/generators/modules.js
Normal file
@@ -0,0 +1,86 @@
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
exports.ImportSpecifier =
|
||||
exports.ExportSpecifier = function (node, print) {
|
||||
print(node.id);
|
||||
if (node.name) {
|
||||
this.push(" as ");
|
||||
print(node.name);
|
||||
}
|
||||
};
|
||||
|
||||
exports.ExportBatchSpecifier = function () {
|
||||
this.push("*");
|
||||
};
|
||||
|
||||
exports.ExportDeclaration = function (node, print) {
|
||||
this.push("export ");
|
||||
|
||||
var specifiers = node.specifiers;
|
||||
|
||||
if (node.default) {
|
||||
this.push("default ");
|
||||
}
|
||||
|
||||
if (node.declaration) {
|
||||
print(node.declaration);
|
||||
} else {
|
||||
if (specifiers.length === 1 && t.isExportBatchSpecifier(specifiers[0])) {
|
||||
this.push("*");
|
||||
} else {
|
||||
this.push("{");
|
||||
if (specifiers.length) {
|
||||
this.space();
|
||||
print.join(specifiers, { separator: ", " });
|
||||
this.space();
|
||||
}
|
||||
this.push("}");
|
||||
}
|
||||
|
||||
if (node.source) {
|
||||
this.push(" from ");
|
||||
print(node.source);
|
||||
}
|
||||
}
|
||||
|
||||
this.ensureSemicolon();
|
||||
};
|
||||
|
||||
exports.ImportDeclaration = function (node, print) {
|
||||
var self = this;
|
||||
|
||||
this.push("import ");
|
||||
|
||||
var specfiers = node.specifiers;
|
||||
if (specfiers && specfiers.length) {
|
||||
var foundImportSpecifier = false;
|
||||
|
||||
_.each(node.specifiers, function (spec, i) {
|
||||
if (+i > 0) {
|
||||
self.push(", ");
|
||||
}
|
||||
|
||||
if (!spec.default && spec.type !== "ImportBatchSpecifier" && !foundImportSpecifier) {
|
||||
foundImportSpecifier = true;
|
||||
self.push("{ ");
|
||||
}
|
||||
|
||||
print(spec);
|
||||
});
|
||||
|
||||
if (foundImportSpecifier) {
|
||||
this.push(" }");
|
||||
}
|
||||
|
||||
this.push(" from ");
|
||||
}
|
||||
|
||||
print(node.source);
|
||||
this.semicolon();
|
||||
};
|
||||
|
||||
exports.ImportBatchSpecifier = function (node, print) {
|
||||
this.push("* as ");
|
||||
print(node.name);
|
||||
};
|
||||
188
lib/6to5/generation/generators/statements.js
Normal file
188
lib/6to5/generation/generators/statements.js
Normal file
@@ -0,0 +1,188 @@
|
||||
var t = require("../../types");
|
||||
|
||||
exports.WithStatement = function (node, print) {
|
||||
this.keyword("with");
|
||||
this.push("(");
|
||||
print(node.object);
|
||||
print.block(node.body);
|
||||
};
|
||||
|
||||
exports.IfStatement = function (node, print) {
|
||||
this.keyword("if");
|
||||
this.push("(");
|
||||
print(node.test);
|
||||
this.push(") ");
|
||||
|
||||
print.indentOnComments(node.consequent);
|
||||
|
||||
if (node.alternate) {
|
||||
if (this.isLast("}")) this.space();
|
||||
this.keyword("else");
|
||||
print.indentOnComments(node.alternate);
|
||||
}
|
||||
};
|
||||
|
||||
exports.ForStatement = function (node, print) {
|
||||
this.keyword("for");
|
||||
this.push("(");
|
||||
|
||||
print(node.init);
|
||||
this.push(";");
|
||||
|
||||
if (node.test) {
|
||||
this.space();
|
||||
print(node.test);
|
||||
}
|
||||
this.push(";");
|
||||
|
||||
if (node.update) {
|
||||
this.space();
|
||||
print(node.update);
|
||||
}
|
||||
|
||||
this.push(")");
|
||||
print.block(node.body);
|
||||
};
|
||||
|
||||
exports.WhileStatement = function (node, print) {
|
||||
this.keyword("while");
|
||||
this.push("(");
|
||||
print(node.test);
|
||||
this.push(")");
|
||||
print.block(node.body);
|
||||
};
|
||||
|
||||
var buildForXStatement = function (op) {
|
||||
return function (node, print) {
|
||||
this.keyword("for");
|
||||
this.push("(");
|
||||
print(node.left);
|
||||
this.push(" " + op + " ");
|
||||
print(node.right);
|
||||
this.push(")");
|
||||
print.block(node.body);
|
||||
};
|
||||
};
|
||||
|
||||
exports.ForInStatement = buildForXStatement("in");
|
||||
exports.ForOfStatement = buildForXStatement("of");
|
||||
|
||||
exports.DoWhileStatement = function (node, print) {
|
||||
this.keyword("do");
|
||||
print(node.body);
|
||||
this.space();
|
||||
this.keyword("while");
|
||||
this.push("(");
|
||||
print(node.test);
|
||||
this.push(");");
|
||||
};
|
||||
|
||||
var buildLabelStatement = function (prefix, key) {
|
||||
return function (node, print) {
|
||||
this.push(prefix);
|
||||
|
||||
var label = node[key || "label"];
|
||||
if (label) {
|
||||
this.space();
|
||||
print(label);
|
||||
}
|
||||
|
||||
this.semicolon();
|
||||
};
|
||||
};
|
||||
|
||||
exports.ContinueStatement = buildLabelStatement("continue");
|
||||
exports.ReturnStatement = buildLabelStatement("return", "argument");
|
||||
exports.BreakStatement = buildLabelStatement("break");
|
||||
|
||||
exports.LabeledStatement = function (node, print) {
|
||||
print(node.label);
|
||||
this.push(": ");
|
||||
print(node.body);
|
||||
};
|
||||
|
||||
exports.TryStatement = function (node, print) {
|
||||
this.keyword("try");
|
||||
print(node.block);
|
||||
this.space();
|
||||
print(node.handler);
|
||||
if (node.finalizer) {
|
||||
this.space();
|
||||
this.push("finally ");
|
||||
print(node.finalizer);
|
||||
}
|
||||
};
|
||||
|
||||
exports.CatchClause = function (node, print) {
|
||||
this.keyword("catch");
|
||||
this.push("(");
|
||||
print(node.param);
|
||||
this.push(") ");
|
||||
print(node.body);
|
||||
};
|
||||
|
||||
exports.ThrowStatement = function (node, print) {
|
||||
this.push("throw ");
|
||||
print(node.argument);
|
||||
this.semicolon();
|
||||
};
|
||||
|
||||
exports.SwitchStatement = function (node, print) {
|
||||
this.keyword("switch");
|
||||
this.push("(");
|
||||
print(node.discriminant);
|
||||
this.push(") {");
|
||||
print.sequence(node.cases, { indent: true });
|
||||
this.push("}");
|
||||
|
||||
//if (node.cases.length) {
|
||||
// this.newline();
|
||||
// print.sequence(node.cases, { indent: true });
|
||||
// this.newline();
|
||||
// this.rightBrace();
|
||||
//} else {
|
||||
// this.push("}");
|
||||
//}
|
||||
};
|
||||
|
||||
exports.SwitchCase = function (node, print) {
|
||||
if (node.test) {
|
||||
this.push("case ");
|
||||
print(node.test);
|
||||
this.push(":");
|
||||
} else {
|
||||
this.push("default:");
|
||||
}
|
||||
|
||||
if (node.consequent.length === 1) {
|
||||
this.space();
|
||||
print(node.consequent[0]);
|
||||
} else if (node.consequent.length > 1) {
|
||||
this.newline();
|
||||
print.sequence(node.consequent, { indent: true });
|
||||
}
|
||||
};
|
||||
|
||||
exports.DebuggerStatement = function () {
|
||||
this.push("debugger;");
|
||||
};
|
||||
|
||||
exports.VariableDeclaration = function (node, print, parent) {
|
||||
this.push(node.kind + " ");
|
||||
|
||||
print.join(node.declarations, { separator: ", " });
|
||||
|
||||
if (!t.isFor(parent)) {
|
||||
this.semicolon();
|
||||
}
|
||||
};
|
||||
|
||||
exports.VariableDeclarator = function (node, print) {
|
||||
if (node.init) {
|
||||
print(node.id);
|
||||
this.push(" = ");
|
||||
print(node.init);
|
||||
} else {
|
||||
print(node.id);
|
||||
}
|
||||
};
|
||||
30
lib/6to5/generation/generators/template-literals.js
Normal file
30
lib/6to5/generation/generators/template-literals.js
Normal file
@@ -0,0 +1,30 @@
|
||||
var _ = require("lodash");
|
||||
|
||||
exports.TaggedTemplateExpression = function (node, print) {
|
||||
print(node.tag);
|
||||
print(node.quasi);
|
||||
};
|
||||
|
||||
exports.TemplateElement = function (node) {
|
||||
this._push(node.value.raw);
|
||||
};
|
||||
|
||||
exports.TemplateLiteral = function (node, print) {
|
||||
this.push("`");
|
||||
|
||||
var quasis = node.quasis;
|
||||
var self = this;
|
||||
var len = quasis.length;
|
||||
|
||||
_.each(quasis, function (quasi, i) {
|
||||
print(quasi);
|
||||
|
||||
if (i + 1 < len) {
|
||||
self.push("${ ");
|
||||
print(node.expressions[i]);
|
||||
self.push(" }");
|
||||
}
|
||||
});
|
||||
|
||||
this._push("`");
|
||||
};
|
||||
86
lib/6to5/generation/generators/types.js
Normal file
86
lib/6to5/generation/generators/types.js
Normal file
@@ -0,0 +1,86 @@
|
||||
var _ = require("lodash");
|
||||
|
||||
exports.Identifier = function (node) {
|
||||
this.push(node.name);
|
||||
};
|
||||
|
||||
exports.SpreadElement = function (node, print) {
|
||||
this.push("...");
|
||||
print(node.argument);
|
||||
};
|
||||
|
||||
exports.ObjectExpression =
|
||||
exports.ObjectPattern = function (node, print) {
|
||||
var props = node.properties;
|
||||
|
||||
if (props.length) {
|
||||
this.push("{");
|
||||
this.space();
|
||||
|
||||
print.join(props, { separator: ", ", indent: true });
|
||||
|
||||
this.space();
|
||||
this.push("}");
|
||||
} else {
|
||||
this.push("{}");
|
||||
}
|
||||
};
|
||||
|
||||
exports.Property = function (node, print) {
|
||||
if (node.method || node.kind === "get" || node.kind === "set") {
|
||||
this._method(node, print);
|
||||
} else {
|
||||
if (node.computed) {
|
||||
this.push("[");
|
||||
print(node.key);
|
||||
this.push("]");
|
||||
} else {
|
||||
print(node.key);
|
||||
if (node.shorthand) return;
|
||||
}
|
||||
|
||||
this.push(": ");
|
||||
print(node.value);
|
||||
}
|
||||
};
|
||||
|
||||
exports.ArrayExpression =
|
||||
exports.ArrayPattern = function (node, print) {
|
||||
var elems = node.elements;
|
||||
var self = this;
|
||||
var len = elems.length;
|
||||
|
||||
this.push("[");
|
||||
|
||||
_.each(elems, function (elem, i) {
|
||||
if (!elem) {
|
||||
// If the array expression ends with a hole, that hole
|
||||
// will be ignored by the interpreter, but if it ends with
|
||||
// two (or more) holes, we need to write out two (or more)
|
||||
// commas so that the resulting code is interpreted with
|
||||
// both (all) of the holes.
|
||||
self.push(",");
|
||||
} else {
|
||||
if (i > 0) self.push(" ");
|
||||
print(elem);
|
||||
if (i < len - 1) self.push(",");
|
||||
}
|
||||
});
|
||||
|
||||
this.push("]");
|
||||
};
|
||||
|
||||
exports.Literal = function (node) {
|
||||
var val = node.value;
|
||||
var type = typeof val;
|
||||
|
||||
if (type === "boolean" || type === "number" || type === "string") {
|
||||
this.push(JSON.stringify(val));
|
||||
} else if (node.regex) {
|
||||
this.push("/" + node.regex.pattern + "/" + node.regex.flags);
|
||||
} else if (val === null) {
|
||||
this.push("null");
|
||||
} else if (node.raw) {
|
||||
this.push(node.raw);
|
||||
}
|
||||
};
|
||||
290
lib/6to5/generation/node.js
Normal file
290
lib/6to5/generation/node.js
Normal file
@@ -0,0 +1,290 @@
|
||||
module.exports = Node;
|
||||
|
||||
var t = require("../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
function Node(node, parent) {
|
||||
this.parent = parent;
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
Node.whitespace = {
|
||||
FunctionExpression: 1,
|
||||
FunctionStatement: 1,
|
||||
ClassExpression: 1,
|
||||
ClassStatement: 1,
|
||||
ForOfStatement: 1,
|
||||
ForInStatement: 1,
|
||||
ForStatement: 1,
|
||||
SwitchStatement: 1,
|
||||
IfStatement: { before: 1 },
|
||||
//Property: { before: 1 },
|
||||
Literal: { after: 1 }
|
||||
};
|
||||
|
||||
_.each(Node.whitespace, function (amounts, type) {
|
||||
if (_.isNumber(amounts)) amounts = { after: amounts, before: amounts };
|
||||
Node.whitespace[type] = amounts;
|
||||
});
|
||||
|
||||
//
|
||||
|
||||
Node.PRECEDENCE = {};
|
||||
|
||||
_.each([
|
||||
["||"],
|
||||
["&&"],
|
||||
["|"],
|
||||
["^"],
|
||||
["&"],
|
||||
["==", "===", "!=", "!=="],
|
||||
["<", ">", "<=", ">=", "in", "instanceof"],
|
||||
[">>", "<<", ">>>"],
|
||||
["+", "-"],
|
||||
["*", "/", "%"]
|
||||
], function (tier, i) {
|
||||
_.each(tier, function (op) {
|
||||
Node.PRECEDENCE[op] = i;
|
||||
});
|
||||
});
|
||||
|
||||
//
|
||||
|
||||
Node.prototype.isUserWhitespacable = function () {
|
||||
//var parent = this.parent;
|
||||
var node = this.node;
|
||||
|
||||
if (t.isUserWhitespacable(node)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//if (t.isArrayExpression(parent)) {
|
||||
// return true;
|
||||
//}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
Node.prototype.needsWhitespace = function (type) {
|
||||
var parent = this.parent;
|
||||
var node = this.node;
|
||||
if (!node) return 0;
|
||||
|
||||
if (t.isExpressionStatement(node)) {
|
||||
node = node.expression;
|
||||
}
|
||||
|
||||
if (type === "before") {
|
||||
if (t.isProperty(node) && parent.properties[0] === node) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (type === "after") {
|
||||
if (t.isCallExpression(node)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
var exprs = [];
|
||||
|
||||
if (t.isVariableDeclaration(node)) {
|
||||
exprs = _.map(node.declarations, "init");
|
||||
}
|
||||
|
||||
if (t.isArrayExpression(node)) {
|
||||
exprs = node.elements;
|
||||
}
|
||||
|
||||
if (t.isObjectExpression(node)) {
|
||||
exprs = node.properties;
|
||||
}
|
||||
|
||||
var lines = 0;
|
||||
|
||||
_.each(exprs, function (expr) {
|
||||
lines = Node.needsWhitespace(expr, node, type);
|
||||
if (lines) return false;
|
||||
});
|
||||
|
||||
if (lines) return lines;
|
||||
}
|
||||
|
||||
if (t.isCallExpression(node) && t.isFunction(node.callee)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
var opts = Node.whitespace[node.type];
|
||||
return (opts && opts[type]) || 0;
|
||||
};
|
||||
|
||||
Node.prototype.needsWhitespaceBefore = function () {
|
||||
return this.needsWhitespace("before");
|
||||
};
|
||||
|
||||
Node.prototype.needsWhitespaceAfter = function () {
|
||||
return this.needsWhitespace("after");
|
||||
};
|
||||
|
||||
Node.prototype.needsParens = function () {
|
||||
var parent = this.parent;
|
||||
var node = this.node;
|
||||
|
||||
if (!parent) return false;
|
||||
|
||||
//
|
||||
if (t.isUnaryLike(node)) {
|
||||
return t.isMemberExpression(parent) && parent.object === node;
|
||||
}
|
||||
|
||||
if (t.isBinary(node)) {
|
||||
//
|
||||
if (t.isCallExpression(parent) && parent.callee === node) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
if (t.isUnaryLike(parent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
if (t.isMemberExpression(parent) && parent.object === node) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (t.isBinary(parent)) {
|
||||
var parentOp = parent.operator;
|
||||
var parentPos = Node.PRECEDENCE[parentOp];
|
||||
|
||||
var nodeOp = node.operator;
|
||||
var nodePos = Node.PRECEDENCE[nodeOp];
|
||||
|
||||
if (parentPos > nodePos) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (parentPos === nodePos && parent.right === node) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (t.isBinaryExpression(node) && node.operator === "in") {
|
||||
// var i = (1 in []);
|
||||
if (t.isVariableDeclarator(parent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// for ((1 in []);;);
|
||||
if (t.isFor(parent)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// (class {});
|
||||
if (t.isClassExpression(node) && t.isExpressionStatement(parent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (t.isSequenceExpression(node)) {
|
||||
if (t.isForStatement(parent)) {
|
||||
// Although parentheses wouldn't hurt around sequence
|
||||
// expressions in the head of for loops, traditional style
|
||||
// dictates that e.g. i++, j++ should not be wrapped with
|
||||
// parentheses.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (t.isExpressionStatement(parent) && parent.expression === node) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Otherwise err on the side of overparenthesization, adding
|
||||
// explicit exceptions above if this proves overzealous.
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
if (t.isYieldExpression(node)) {
|
||||
return t.isBinary(parent) ||
|
||||
t.isUnaryLike(parent) ||
|
||||
t.isCallExpression(parent) ||
|
||||
t.isMemberExpression(parent) ||
|
||||
t.isNewExpression(parent) ||
|
||||
t.isConditionalExpression(parent) ||
|
||||
t.isYieldExpression(parent);
|
||||
}
|
||||
|
||||
if (t.isNewExpression(parent) && parent.callee === node) {
|
||||
return t.isCallExpression(node) || _.some(node, function (val) {
|
||||
return t.isCallExpression(val);
|
||||
});
|
||||
}
|
||||
|
||||
// (1).valueOf()
|
||||
if (t.isLiteral(node) && _.isNumber(node.value) && t.isMemberExpression(parent) && parent.object === node) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (t.isAssignmentExpression(node) || t.isConditionalExpression(node)) {
|
||||
//
|
||||
if (t.isUnaryLike(parent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
if (t.isBinary(parent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
if (t.isCallExpression(parent) && parent.callee === node) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
if (t.isConditionalExpression(parent) && parent.test === node) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
if (t.isMemberExpression(parent) && parent.object === node) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (t.isFunctionExpression(node)) {
|
||||
// function () {};
|
||||
if (t.isExpressionStatement(parent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// (function test() {}).name;
|
||||
if (t.isMemberExpression(parent) && parent.object === node) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// (function () {})();
|
||||
if (t.isCallExpression(parent) && parent.callee === node) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// ({ x, y }) = { x: 5, y: 6 };
|
||||
if (t.isObjectPattern(node) && t.isAssignmentExpression(parent) && parent.left == node) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
_.each(Node.prototype, function (fn, key) {
|
||||
Node[key] = function (node, parent) {
|
||||
var n = new Node(node, parent);
|
||||
|
||||
var args = _.toArray(arguments).slice(2);
|
||||
return n[key].apply(n, args);
|
||||
};
|
||||
});
|
||||
33
lib/6to5/generation/position.js
Normal file
33
lib/6to5/generation/position.js
Normal file
@@ -0,0 +1,33 @@
|
||||
module.exports = Position;
|
||||
|
||||
var _ = require("lodash");
|
||||
|
||||
function Position() {
|
||||
this.line = 1;
|
||||
this.column = 0;
|
||||
}
|
||||
|
||||
Position.prototype.push = function (str) {
|
||||
var self = this;
|
||||
|
||||
_.each(str, function (cha) {
|
||||
if (cha === "\n") {
|
||||
self.line++;
|
||||
self.column = 0;
|
||||
} else {
|
||||
self.column++;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
Position.prototype.unshift = function (str) {
|
||||
var self = this;
|
||||
|
||||
_.each(str, function (cha) {
|
||||
if (cha === "\n") {
|
||||
self.line--;
|
||||
} else {
|
||||
self.column--;
|
||||
}
|
||||
});
|
||||
};
|
||||
55
lib/6to5/generation/source-map.js
Normal file
55
lib/6to5/generation/source-map.js
Normal file
@@ -0,0 +1,55 @@
|
||||
module.exports = SourceMap;
|
||||
|
||||
var sourceMap = require("source-map");
|
||||
var t = require("../types");
|
||||
|
||||
function SourceMap(position, opts, code) {
|
||||
this.position = position;
|
||||
this.opts = opts;
|
||||
|
||||
if (opts.sourceMap) {
|
||||
this.map = new sourceMap.SourceMapGenerator({
|
||||
file: opts.sourceMapName
|
||||
});
|
||||
|
||||
this.map.setSourceContent(opts.sourceFileName, code);
|
||||
} else {
|
||||
this.map = null;
|
||||
}
|
||||
}
|
||||
|
||||
SourceMap.prototype.get = function () {
|
||||
var map = this.map;
|
||||
if (map) {
|
||||
return map.toJSON();
|
||||
} else {
|
||||
return map;
|
||||
}
|
||||
};
|
||||
|
||||
SourceMap.prototype.mark = function (node, type) {
|
||||
var loc = node.loc;
|
||||
if (!loc) return; // no location info
|
||||
|
||||
var map = this.map;
|
||||
if (!map) return; // no source map
|
||||
|
||||
if (t.isProgram(node) || t.isFile(node)) return; // illegal mapping nodes
|
||||
|
||||
var position = this.position;
|
||||
|
||||
var generated = {
|
||||
line: position.line,
|
||||
column: position.column
|
||||
};
|
||||
|
||||
var original = loc[type];
|
||||
|
||||
if (generated.line === original.line && generated.column === original.column) return; // nothing to map
|
||||
|
||||
map.addMapping({
|
||||
source: this.opts.sourceFileName,
|
||||
generated: generated,
|
||||
original: original
|
||||
});
|
||||
};
|
||||
58
lib/6to5/generation/whitespace.js
Normal file
58
lib/6to5/generation/whitespace.js
Normal file
@@ -0,0 +1,58 @@
|
||||
module.exports = Whitespace;
|
||||
|
||||
var _ = require("lodash");
|
||||
|
||||
function Whitespace(tokens, comments) {
|
||||
this.tokens = _.sortBy(tokens.concat(comments), "start");
|
||||
this.used = [];
|
||||
}
|
||||
|
||||
Whitespace.prototype.getNewlinesBefore = function (node) {
|
||||
var startToken;
|
||||
var endToken;
|
||||
var tokens = this.tokens;
|
||||
|
||||
_.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;
|
||||
}
|
||||
});
|
||||
|
||||
return this.getNewlinesBetween(startToken, endToken);
|
||||
};
|
||||
|
||||
Whitespace.prototype.getNewlinesAfter = function (node) {
|
||||
var startToken;
|
||||
var endToken;
|
||||
var tokens = this.tokens;
|
||||
|
||||
_.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;
|
||||
}
|
||||
});
|
||||
|
||||
return this.getNewlinesBetween(startToken, endToken);
|
||||
};
|
||||
|
||||
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);
|
||||
lines++;
|
||||
}
|
||||
}
|
||||
|
||||
return lines;
|
||||
};
|
||||
@@ -1,8 +1,8 @@
|
||||
var transform = require("./transform");
|
||||
var transform = require("./transformation/transform");
|
||||
var fs = require("fs");
|
||||
var _ = require("lodash");
|
||||
|
||||
exports.util = require("./util");
|
||||
exports.runtime = require("./runtime");
|
||||
|
||||
exports.register = function (opts) {
|
||||
var register = require("./register");
|
||||
|
||||
28
lib/6to5/patch.js
Normal file
28
lib/6to5/patch.js
Normal file
@@ -0,0 +1,28 @@
|
||||
var t = require("./types");
|
||||
var _ = require("lodash");
|
||||
|
||||
var types = require("ast-types");
|
||||
var def = types.Type.def;
|
||||
|
||||
// Program wrapper
|
||||
def("File")
|
||||
.bases("Node")
|
||||
.build("program")
|
||||
.field("program", def("Program"));
|
||||
|
||||
// Non-standard Acorn type
|
||||
def("ParenthesizedExpression")
|
||||
.bases("Expression")
|
||||
.build("expression")
|
||||
.field("expression", def("Expression"));
|
||||
|
||||
// Same as ImportNamespaceSpecifier but `id` is `name`
|
||||
def("ImportBatchSpecifier")
|
||||
.bases("Specifier")
|
||||
.build("name")
|
||||
.field("name", def("Identifier"));
|
||||
|
||||
types.finalize();
|
||||
|
||||
var estraverse = require("estraverse");
|
||||
_.extend(estraverse.VisitorKeys, t.VISITOR_KEYS);
|
||||
@@ -1,3 +1,6 @@
|
||||
require("es6-symbol/implement");
|
||||
if (typeof Symbol === "undefined") {
|
||||
require("es6-symbol/implement");
|
||||
}
|
||||
|
||||
require("es6-shim");
|
||||
require("regenerator/runtime");
|
||||
require("regenerator-6to5/runtime");
|
||||
|
||||
@@ -6,7 +6,7 @@ var _ = require("lodash");
|
||||
|
||||
sourceMapSupport.install({
|
||||
retrieveSourceMap: function (source) {
|
||||
var map = maps[source];
|
||||
var map = maps && maps[source];
|
||||
if (map) {
|
||||
return {
|
||||
url: null,
|
||||
@@ -20,17 +20,56 @@ 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("arrowFunctions", "var foo = x => x * x;");
|
||||
blacklistTest("classes", "class Foo {}");
|
||||
blacklistTest("computedPropertyNames", "var foo = { [foo]: bar };");
|
||||
//blacklistTest("constants", "const foo = 0;");
|
||||
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() {}");
|
||||
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 ignoreRegex = /node_modules/;
|
||||
var onlyRegex;
|
||||
var whitelist = [];
|
||||
var exts = {};
|
||||
var maps = {};
|
||||
var old = require.extensions[".js"];
|
||||
|
||||
var loader = function (m, filename) {
|
||||
if (ignoreRegex && ignoreRegex.test(filename)) {
|
||||
if ((ignoreRegex && ignoreRegex.test(filename)) || (onlyRegex && !onlyRegex.test(filename))) {
|
||||
return old.apply(this, arguments);
|
||||
}
|
||||
|
||||
var result = to5.transformFileSync(filename, {
|
||||
whitelist: whitelist,
|
||||
blacklist: blacklist,
|
||||
sourceMap: true
|
||||
});
|
||||
|
||||
@@ -55,12 +94,16 @@ var hookExtensions = function (_exts) {
|
||||
hookExtensions([".es6", ".js"]);
|
||||
|
||||
module.exports = function (opts) {
|
||||
// normalise options
|
||||
opts = opts || {};
|
||||
if (_.isRegExp(opts)) opts = { ignoreRegex: opts };
|
||||
if (_.isRegExp(opts)) opts = { ignore: opts };
|
||||
if (opts.ignoreRegex != null) opts.ignore = opts.ignoreRegex;
|
||||
|
||||
if (opts.ignoreRegex != null) {
|
||||
ignoreRegex = opts.ignoreRegex;
|
||||
}
|
||||
if (opts.only != null) onlyRegex = opts.only;
|
||||
if (opts.ignore != null) ignoreRegex = opts.ignore;
|
||||
|
||||
if (opts.extensions) hookExtensions(opts.extensions);
|
||||
|
||||
if (opts.blacklist) blacklist = opts.blacklist;
|
||||
if (opts.whitelist) whitelist = opts.whitelist;
|
||||
};
|
||||
|
||||
40
lib/6to5/runtime.js
Normal file
40
lib/6to5/runtime.js
Normal file
@@ -0,0 +1,40 @@
|
||||
var generator = require("./generation/generator");
|
||||
var util = require("./util");
|
||||
var File = require("./file");
|
||||
var t = require("./types");
|
||||
var _ = require("lodash");
|
||||
|
||||
module.exports = function (namespace) {
|
||||
namespace = t.identifier(namespace || "to5Runtime");
|
||||
|
||||
var body = [];
|
||||
var container = t.functionExpression(null, [], t.blockStatement(body));
|
||||
var tree = t.program([t.expressionStatement(t.callExpression(container, []))]);
|
||||
|
||||
body.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(t.identifier("self"), t.conditionalExpression(
|
||||
t.binaryExpression("===",
|
||||
t.unaryExpression("typeof", t.identifier("global"), true),
|
||||
t.literal("undefined")
|
||||
),
|
||||
t.identifier("window"),
|
||||
t.identifier("global"))
|
||||
)
|
||||
]));
|
||||
|
||||
body.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(
|
||||
namespace,
|
||||
t.assignmentExpression("=", t.memberExpression(t.identifier("self"), namespace), t.objectExpression([]))
|
||||
)
|
||||
]));
|
||||
|
||||
_.each(File.declarations, function (name) {
|
||||
var key = t.identifier(t.toIdentifier(name));
|
||||
body.push(t.expressionStatement(
|
||||
t.assignmentExpression("=", t.memberExpression(namespace, key), util.template(name))
|
||||
));
|
||||
});
|
||||
|
||||
return generator(tree).code;
|
||||
};
|
||||
4
lib/6to5/templates/class-props.js
Normal file
4
lib/6to5/templates/class-props.js
Normal file
@@ -0,0 +1,4 @@
|
||||
(function (child, staticProps, instanceProps) {
|
||||
if (staticProps) Object.defineProperties(child, staticProps);
|
||||
if (instanceProps) Object.defineProperties(child.prototype, instanceProps);
|
||||
})
|
||||
@@ -1,8 +1,8 @@
|
||||
module.exports = AMDFormatter;
|
||||
|
||||
var CommonJSFormatter = require("./common");
|
||||
var util = require("../util");
|
||||
var b = require("acorn-ast-types").builders;
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
function AMDFormatter(file) {
|
||||
@@ -18,21 +18,21 @@ AMDFormatter.prototype.transform = function (ast) {
|
||||
|
||||
// build an array of module names
|
||||
|
||||
var names = [b.literal("exports")];
|
||||
var names = [t.literal("exports")];
|
||||
_.each(this.ids, function (id, name) {
|
||||
names.push(b.literal(name));
|
||||
names.push(t.literal(name));
|
||||
});
|
||||
names = b.arrayExpression(names);
|
||||
names = t.arrayExpression(names);
|
||||
|
||||
// build up define container
|
||||
|
||||
var params = _.values(this.ids);
|
||||
params.unshift(b.identifier("exports"));
|
||||
params.unshift(t.identifier("exports"));
|
||||
|
||||
var container = b.functionExpression(null, params, b.blockStatement(body));
|
||||
var call = b.callExpression(b.identifier("define"), [names, container]);
|
||||
var container = t.functionExpression(null, params, t.blockStatement(body));
|
||||
var call = t.callExpression(t.identifier("define"), [names, container]);
|
||||
|
||||
program.body = [b.expressionStatement(call)];
|
||||
program.body = [t.expressionStatement(call)];
|
||||
};
|
||||
|
||||
AMDFormatter.prototype._push = function (node) {
|
||||
@@ -42,7 +42,7 @@ AMDFormatter.prototype._push = function (node) {
|
||||
if (ids[id]) {
|
||||
return ids[id];
|
||||
} else {
|
||||
return this.ids[id] = b.identifier(this.file.generateUid(id));
|
||||
return this.ids[id] = t.identifier(this.file.generateUid(id));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -51,26 +51,26 @@ AMDFormatter.prototype.import = function (node) {
|
||||
};
|
||||
|
||||
AMDFormatter.prototype.importSpecifier = function (specifier, node, nodes) {
|
||||
var key = util.getSpecifierName(specifier);
|
||||
var key = t.getSpecifierName(specifier);
|
||||
var id = specifier.id;
|
||||
|
||||
// import foo from "foo";
|
||||
if (specifier.default) {
|
||||
id = b.identifier("default");
|
||||
id = t.identifier("default");
|
||||
}
|
||||
|
||||
var ref;
|
||||
|
||||
if (specifier.type === "ImportBatchSpecifier") {
|
||||
if (t.isImportBatchSpecifier(specifier)) {
|
||||
// import * as bar from "foo";
|
||||
ref = this._push(node);
|
||||
} else {
|
||||
// import foo from "foo";
|
||||
ref = b.memberExpression(this._push(node), id, false);
|
||||
ref = t.memberExpression(this._push(node), id, false);
|
||||
}
|
||||
|
||||
nodes.push(b.variableDeclaration("var", [
|
||||
b.variableDeclarator(key, ref)
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(key, ref)
|
||||
]));
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
module.exports = CommonJSFormatter;
|
||||
|
||||
var util = require("../util");
|
||||
var b = require("acorn-ast-types").builders;
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
|
||||
function CommonJSFormatter(file) {
|
||||
this.file = file;
|
||||
@@ -10,16 +10,18 @@ function CommonJSFormatter(file) {
|
||||
CommonJSFormatter.prototype.import = function (node, nodes) {
|
||||
// import "foo";
|
||||
nodes.push(util.template("require", {
|
||||
//inherits: node,
|
||||
|
||||
MODULE_NAME: node.source.raw
|
||||
}, true));
|
||||
};
|
||||
|
||||
CommonJSFormatter.prototype.importSpecifier = function (specifier, node, nodes) {
|
||||
var variableName = util.getSpecifierName(specifier);
|
||||
var variableName = t.getSpecifierName(specifier);
|
||||
|
||||
// import foo from "foo";
|
||||
if (specifier.default) {
|
||||
specifier.id = b.identifier("default");
|
||||
specifier.id = t.identifier("default");
|
||||
}
|
||||
|
||||
var templateName = "require-assign";
|
||||
@@ -28,6 +30,8 @@ CommonJSFormatter.prototype.importSpecifier = function (specifier, node, nodes)
|
||||
if (specifier.type !== "ImportBatchSpecifier") templateName += "-key";
|
||||
|
||||
nodes.push(util.template(templateName, {
|
||||
//inherits: node.specifiers.length === 1 && node,
|
||||
|
||||
VARIABLE_NAME: variableName,
|
||||
MODULE_NAME: node.source.raw,
|
||||
KEY: specifier.id
|
||||
@@ -38,44 +42,73 @@ CommonJSFormatter.prototype.export = function (node, nodes) {
|
||||
var declar = node.declaration;
|
||||
|
||||
if (node.default) {
|
||||
util.ensureExpressionType(declar);
|
||||
var ref = declar;
|
||||
|
||||
if (t.isClass(ref) || t.isFunction(ref)) {
|
||||
if (ref.id) {
|
||||
nodes.push(t.toStatement(ref));
|
||||
ref = ref.id;
|
||||
}
|
||||
}
|
||||
|
||||
nodes.push(util.template("exports-default", {
|
||||
VALUE: declar
|
||||
//inherits: node,
|
||||
|
||||
VALUE: ref
|
||||
}, true));
|
||||
} else {
|
||||
var id = declar.id;
|
||||
if (declar.type === "VariableDeclaration") {
|
||||
id = declar.declarations[0].id;
|
||||
var assign;
|
||||
|
||||
if (t.isVariableDeclaration(declar)) {
|
||||
var decl = declar.declarations[0];
|
||||
|
||||
if (decl.init) {
|
||||
decl.init = util.template("exports-assign", {
|
||||
//inherits: node,
|
||||
|
||||
VALUE: decl.init,
|
||||
KEY: decl.id
|
||||
});
|
||||
}
|
||||
|
||||
nodes.push(declar);
|
||||
} else {
|
||||
assign = util.template("exports-assign", {
|
||||
//inherits: node,
|
||||
|
||||
VALUE: declar.id,
|
||||
KEY: declar.id
|
||||
}, true);
|
||||
|
||||
nodes.push(t.toStatement(declar));
|
||||
nodes.push(assign);
|
||||
|
||||
if (t.isFunctionDeclaration(declar)) {
|
||||
assign._blockHoist = true;
|
||||
}
|
||||
}
|
||||
|
||||
var assign = util.template("exports-assign", {
|
||||
VALUE: id,
|
||||
KEY: id
|
||||
}, true);
|
||||
|
||||
nodes.push(declar);
|
||||
|
||||
if (declar.type === "FunctionDeclaration") {
|
||||
assign._blockHoist = true;
|
||||
}
|
||||
|
||||
nodes.push(assign);
|
||||
}
|
||||
};
|
||||
|
||||
CommonJSFormatter.prototype._exportSpecifier = function (getRef, specifier, node, nodes) {
|
||||
var variableName = util.getSpecifierName(specifier);
|
||||
var variableName = t.getSpecifierName(specifier);
|
||||
|
||||
var inherits = false;
|
||||
if (node.specifiers.length === 1) inherits = node;
|
||||
|
||||
if (node.source) {
|
||||
if (specifier.type === "ExportBatchSpecifier") {
|
||||
if (t.isExportBatchSpecifier(specifier)) {
|
||||
// export * from "foo";
|
||||
nodes.push(util.template("exports-wildcard", {
|
||||
//inherits: inherits,
|
||||
|
||||
OBJECT: getRef()
|
||||
}, true));
|
||||
} else {
|
||||
// export { foo } from "test";
|
||||
nodes.push(util.template("exports-assign-key", {
|
||||
//inherits: inherits,
|
||||
|
||||
VARIABLE_NAME: variableName.name,
|
||||
OBJECT: getRef(),
|
||||
KEY: specifier.id
|
||||
@@ -84,6 +117,8 @@ CommonJSFormatter.prototype._exportSpecifier = function (getRef, specifier, node
|
||||
} else {
|
||||
// export { foo };
|
||||
nodes.push(util.template("exports-assign", {
|
||||
//inherits: inherits,
|
||||
|
||||
VALUE: specifier.id,
|
||||
KEY: variableName
|
||||
}, true));
|
||||
@@ -92,6 +127,6 @@ CommonJSFormatter.prototype._exportSpecifier = function (getRef, specifier, node
|
||||
|
||||
CommonJSFormatter.prototype.exportSpecifier = function (specifier, node, nodes) {
|
||||
return this._exportSpecifier(function () {
|
||||
return b.callExpression(b.identifier("require"), [node.source]);
|
||||
return t.callExpression(t.identifier("require"), [node.source]);
|
||||
}, specifier, node, nodes);
|
||||
};
|
||||
24
lib/6to5/transformation/modules/ignore.js
Normal file
24
lib/6to5/transformation/modules/ignore.js
Normal file
@@ -0,0 +1,24 @@
|
||||
module.exports = IgnoreFormatter;
|
||||
|
||||
var t = require("../../types");
|
||||
|
||||
function IgnoreFormatter() {
|
||||
|
||||
}
|
||||
|
||||
IgnoreFormatter.prototype.import = function () {
|
||||
|
||||
};
|
||||
|
||||
IgnoreFormatter.prototype.importSpecifier = function () {
|
||||
|
||||
};
|
||||
|
||||
IgnoreFormatter.prototype.export = function (node, nodes) {
|
||||
var declar = t.toStatement(node.declaration, true);
|
||||
if (declar) nodes.push(t.inherits(declar, node));
|
||||
};
|
||||
|
||||
IgnoreFormatter.prototype.exportSpecifier = function () {
|
||||
|
||||
};
|
||||
@@ -1,8 +1,8 @@
|
||||
module.exports = UMDFormatter;
|
||||
|
||||
var AMDFormatter = require("./amd");
|
||||
var util = require("../util");
|
||||
var b = require("acorn-ast-types").builders;
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
function UMDFormatter(file) {
|
||||
@@ -20,28 +20,28 @@ UMDFormatter.prototype.transform = function (ast) {
|
||||
|
||||
var names = [];
|
||||
_.each(this.ids, function (id, name) {
|
||||
names.push(b.literal(name));
|
||||
names.push(t.literal(name));
|
||||
});
|
||||
|
||||
// factory
|
||||
|
||||
var ids = _.values(this.ids);
|
||||
var args = [b.identifier("exports")].concat(ids);
|
||||
var args = [t.identifier("exports")].concat(ids);
|
||||
|
||||
var factory = b.functionExpression(null, args, b.blockStatement(body));
|
||||
var factory = t.functionExpression(null, args, t.blockStatement(body));
|
||||
|
||||
// runner
|
||||
|
||||
var runner = util.template("umd-runner-body", {
|
||||
AMD_ARGUMENTS: b.arrayExpression([b.literal("exports")].concat(names)),
|
||||
AMD_ARGUMENTS: t.arrayExpression([t.literal("exports")].concat(names)),
|
||||
|
||||
COMMON_ARGUMENTS: names.map(function (name) {
|
||||
return b.callExpression(b.identifier("require"), [name]);
|
||||
return t.callExpression(t.identifier("require"), [name]);
|
||||
})
|
||||
});
|
||||
|
||||
//
|
||||
|
||||
var call = b.callExpression(runner, [factory]);
|
||||
program.body = [b.expressionStatement(call)];
|
||||
var call = t.callExpression(runner, [factory]);
|
||||
program.body = [t.expressionStatement(call)];
|
||||
};
|
||||
@@ -1,10 +1,7 @@
|
||||
module.exports = transform;
|
||||
|
||||
var Transformer = require("./transformer");
|
||||
var sourceMap = require("source-map");
|
||||
var recast = require("acorn-recast");
|
||||
var File = require("./file");
|
||||
var util = require("./util");
|
||||
var File = require("../file");
|
||||
var _ = require("lodash");
|
||||
|
||||
function transform(code, opts) {
|
||||
@@ -15,63 +12,9 @@ function transform(code, opts) {
|
||||
return file.parse(code);
|
||||
}
|
||||
|
||||
transform.test = function (task, assert) {
|
||||
var actual = task.actual;
|
||||
var expect = task.expect;
|
||||
var opts = task.options;
|
||||
var exec = task.exec;
|
||||
|
||||
var getOpts = function (filename) {
|
||||
return _.merge({ filename: filename }, opts);
|
||||
};
|
||||
|
||||
var execCode = exec.code.trim();
|
||||
var result;
|
||||
|
||||
if (execCode) {
|
||||
result = transform(execCode, getOpts(exec.filename));
|
||||
execCode = result.code;
|
||||
|
||||
require("./polyfill");
|
||||
var fn = new Function("assert", execCode);
|
||||
fn(assert);
|
||||
} else {
|
||||
var actualCode = actual.code.trim();
|
||||
var expectCode = expect.code.trim();
|
||||
|
||||
var printOpts = { tabWidth: 2 };
|
||||
|
||||
result = transform(actualCode, getOpts(actual.filename));
|
||||
actualCode = recast.prettyPrint(result.ast, printOpts).code;
|
||||
|
||||
var expectAst = util.parse(expect, expectCode);
|
||||
var expectResult = recast.prettyPrint(expectAst, printOpts);
|
||||
expectCode = expectResult.code;
|
||||
|
||||
assert.equal(actualCode, expectCode);
|
||||
}
|
||||
|
||||
if (task.sourceMap) {
|
||||
assert.deepEqual(task.sourceMap, result.map);
|
||||
}
|
||||
|
||||
if (task.sourceMappings) {
|
||||
var consumer = new sourceMap.SourceMapConsumer(result.map);
|
||||
|
||||
_.each(task.sourceMappings, function (mapping, i) {
|
||||
var generated = mapping.generated;
|
||||
var original = mapping.original;
|
||||
|
||||
var pos = consumer.originalPositionFor(generated);
|
||||
var msg = "source mapping " + i + " - generated: " + generated.line + ":" + generated.column;
|
||||
assert.equal(pos.line + ":" + pos.column, original.line + ":" + original.column, msg);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
transform._ensureTransformerNames = function (type, keys) {
|
||||
_.each(keys, function (key) {
|
||||
if (key[0] === "_" || !_.has(transform.transformers, key)) {
|
||||
if (!_.has(transform.transformers, key)) {
|
||||
throw new ReferenceError("unknown transformer " + key + " specified in " + type);
|
||||
}
|
||||
});
|
||||
@@ -79,22 +22,26 @@ transform._ensureTransformerNames = function (type, keys) {
|
||||
|
||||
transform.transformers = {
|
||||
modules: require("./transformers/modules"),
|
||||
computedPropertyNames: require("./transformers/computed-property-names"),
|
||||
propertyNameShorthand: require("./transformers/property-name-shorthand"),
|
||||
constants: require("./transformers/constants"),
|
||||
arrayComprehension: require("./transformers/array-comprehension"),
|
||||
arrowFunctions: require("./transformers/arrow-functions"),
|
||||
classes: require("./transformers/classes"),
|
||||
|
||||
_propertyLiterals: require("./transformers/_property-literals"),
|
||||
computedPropertyNames: require("./transformers/computed-property-names"),
|
||||
|
||||
spread: require("./transformers/spread"),
|
||||
templateLiterals: require("./transformers/template-literals"),
|
||||
propertyMethodAssignment: require("./transformers/property-method-assignment"),
|
||||
defaultParameters: require("./transformers/default-parameters"),
|
||||
letScoping: require("./transformers/let-scoping"),
|
||||
restParameters: require("./transformers/rest-parameters"),
|
||||
destructuring: require("./transformers/destructuring"),
|
||||
letScoping: require("./transformers/let-scoping"),
|
||||
forOf: require("./transformers/for-of"),
|
||||
unicodeRegex: require("./transformers/unicode-regex"),
|
||||
generators: require("./transformers/generators"),
|
||||
numericLiterals: require("./transformers/numeric-literals"),
|
||||
|
||||
react: require("./transformers/react"),
|
||||
jsx: require("./transformers/jsx"),
|
||||
@@ -102,13 +49,15 @@ transform.transformers = {
|
||||
_aliasFunctions: require("./transformers/_alias-functions"),
|
||||
_blockHoist: require("./transformers/_block-hoist"),
|
||||
_declarations: require("./transformers/_declarations"),
|
||||
_moduleFormatter: require("./transformers/_module-formatter"),
|
||||
|
||||
useStrict: require("./transformers/use-strict")
|
||||
useStrict: require("./transformers/use-strict"),
|
||||
|
||||
_moduleFormatter: require("./transformers/_module-formatter")
|
||||
};
|
||||
|
||||
transform.moduleFormatters = {
|
||||
common: require("./modules/common"),
|
||||
ignore: require("./modules/ignore"),
|
||||
amd: require("./modules/amd"),
|
||||
umd: require("./modules/umd")
|
||||
};
|
||||
@@ -1,6 +1,7 @@
|
||||
module.exports = Transformer;
|
||||
|
||||
var traverse = require("./traverse");
|
||||
var traverse = require("../traverse");
|
||||
var t = require("../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
function Transformer(key, transformer) {
|
||||
@@ -27,14 +28,18 @@ Transformer.prototype.transform = function (file) {
|
||||
var transformer = this.transformer;
|
||||
var ast = file.ast;
|
||||
|
||||
if (transformer.ast && transformer.ast.enter) {
|
||||
transformer.ast.enter(ast, file);
|
||||
}
|
||||
var astRun = function (key) {
|
||||
if (transformer.ast && transformer.ast[key]) {
|
||||
transformer.ast[key](ast, file);
|
||||
}
|
||||
};
|
||||
|
||||
astRun("enter");
|
||||
|
||||
var build = function (exit) {
|
||||
return function (node, parent) {
|
||||
return function (node, parent, scope) {
|
||||
// add any node type aliases that exist
|
||||
var types = [node.type].concat(traverse.aliases[node.type] || []);
|
||||
var types = [node.type].concat(t.ALIAS_KEYS[node.type] || []);
|
||||
|
||||
var fns = transformer.all;
|
||||
|
||||
@@ -49,7 +54,7 @@ Transformer.prototype.transform = function (file) {
|
||||
if (exit) fn = fns.exit;
|
||||
if (!fn) return;
|
||||
|
||||
return fn(node, parent, file);
|
||||
return fn(node, parent, file, scope);
|
||||
};
|
||||
};
|
||||
|
||||
@@ -58,19 +63,20 @@ Transformer.prototype.transform = function (file) {
|
||||
exit: build(true)
|
||||
});
|
||||
|
||||
if (transformer.ast && transformer.ast.exit) {
|
||||
transformer.ast.exit(ast, file);
|
||||
}
|
||||
astRun("exit");
|
||||
};
|
||||
|
||||
Transformer.prototype.canRun = function (file) {
|
||||
var opts = file.opts;
|
||||
var key = this.key;
|
||||
|
||||
var blacklist = opts.blacklist;
|
||||
if (blacklist.length && _.contains(blacklist, this.key)) return false;
|
||||
if (blacklist.length && _.contains(blacklist, key)) return false;
|
||||
|
||||
var whitelist = opts.whitelist;
|
||||
if (whitelist.length && !_.contains(whitelist, this.key)) return false;
|
||||
if (key[0] !== "_") {
|
||||
var whitelist = opts.whitelist;
|
||||
if (whitelist.length && !_.contains(whitelist, key)) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
@@ -1,25 +1,24 @@
|
||||
var traverse = require("../traverse");
|
||||
var util = require("../util");
|
||||
var b = require("acorn-ast-types").builders;
|
||||
var traverse = require("../../traverse");
|
||||
var t = require("../../types");
|
||||
|
||||
var go = function (getBody, node, file) {
|
||||
var go = function (getBody, node, file, scope) {
|
||||
var argumentsId;
|
||||
var thisId;
|
||||
|
||||
var getArgumentsId = function () {
|
||||
return argumentsId = argumentsId || b.identifier(file.generateUid("arguments"));
|
||||
return argumentsId = argumentsId || t.identifier(file.generateUid("arguments", scope));
|
||||
};
|
||||
|
||||
var getThisId = function () {
|
||||
return thisId = thisId || b.identifier(file.generateUid("this"));
|
||||
return thisId = thisId || t.identifier(file.generateUid("this", scope));
|
||||
};
|
||||
|
||||
// traverse the function and find all alias functions so we can alias
|
||||
// arguments and this if neccesary
|
||||
// arguments and this if necessary
|
||||
traverse(node, function (node) {
|
||||
var _aliasFunction = node._aliasFunction;
|
||||
if (!_aliasFunction) {
|
||||
if (traverse.isFunction(node)) {
|
||||
if (t.isFunction(node)) {
|
||||
// stop traversal of this node as it'll be hit again by this transformer
|
||||
return false;
|
||||
} else {
|
||||
@@ -30,22 +29,24 @@ var go = function (getBody, node, file) {
|
||||
// traverse all child nodes of this function and find arguments and this
|
||||
traverse(node, function (node, parent) {
|
||||
if (_aliasFunction === "arrows") {
|
||||
if (traverse.isFunction(node) && node._aliasFunction !== "arrows") {
|
||||
if (t.isFunction(node) && node._aliasFunction !== "arrows") {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (node._ignoreAliasFunctions) return;
|
||||
|
||||
var getId;
|
||||
|
||||
if (node.type === "Identifier" && node.name === "arguments") {
|
||||
if (t.isIdentifier(node) && node.name === "arguments") {
|
||||
getId = getArgumentsId;
|
||||
} else if (node.type === "ThisExpression") {
|
||||
} else if (t.isThisExpression(node)) {
|
||||
getId = getThisId;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if (util.isReferenced(node, parent)) return getId();
|
||||
if (t.isReferenced(node, parent)) return getId();
|
||||
});
|
||||
|
||||
return false;
|
||||
@@ -55,30 +56,30 @@ var go = function (getBody, node, file) {
|
||||
|
||||
var pushDeclaration = function (id, init) {
|
||||
body = body || getBody();
|
||||
body.unshift(b.variableDeclaration("var", [
|
||||
b.variableDeclarator(id, init)
|
||||
body.unshift(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(id, init)
|
||||
]));
|
||||
};
|
||||
|
||||
if (argumentsId) {
|
||||
pushDeclaration(argumentsId, b.identifier("arguments"));
|
||||
pushDeclaration(argumentsId, t.identifier("arguments"));
|
||||
}
|
||||
|
||||
if (thisId) {
|
||||
pushDeclaration(thisId, b.identifier("this"));
|
||||
pushDeclaration(thisId, t.identifier("this"));
|
||||
}
|
||||
};
|
||||
|
||||
exports.Program = function (node, parent, file) {
|
||||
exports.Program = function (node, parent, file, scope) {
|
||||
go(function () {
|
||||
return node.body;
|
||||
}, node, file);
|
||||
}, node, file, scope);
|
||||
};
|
||||
|
||||
exports.FunctionDeclaration =
|
||||
exports.FunctionExpression = function (node, parent, file) {
|
||||
exports.FunctionExpression = function (node, parent, file, scope) {
|
||||
go(function () {
|
||||
util.ensureBlock(node);
|
||||
t.ensureBlock(node);
|
||||
return node.body.body;
|
||||
}, node, file);
|
||||
}, node, file, scope);
|
||||
};
|
||||
@@ -1,12 +1,12 @@
|
||||
var b = require("acorn-ast-types").builders;
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
module.exports = function (ast, file) {
|
||||
var body = ast.program.body;
|
||||
|
||||
_.each(file.declarations, function (declar) {
|
||||
body.unshift(b.variableDeclaration("var", [
|
||||
b.variableDeclarator(declar.uid, declar.node)
|
||||
body.unshift(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(declar.uid, declar.node)
|
||||
]));
|
||||
});
|
||||
};
|
||||
14
lib/6to5/transformation/transformers/_property-literals.js
Normal file
14
lib/6to5/transformation/transformers/_property-literals.js
Normal file
@@ -0,0 +1,14 @@
|
||||
var esutils = require("esutils");
|
||||
var t = require("../../types");
|
||||
|
||||
exports.Property = function (node) {
|
||||
// ignore key literals that are valid identifiers
|
||||
var key = node.key;
|
||||
if (t.isLiteral(key) && esutils.keyword.isIdentifierName(key.value)) {
|
||||
key.type = "Identifier";
|
||||
key.name = key.value;
|
||||
delete key.value;
|
||||
|
||||
node.computed = false;
|
||||
}
|
||||
};
|
||||
@@ -1,11 +1,11 @@
|
||||
var util = require("../util");
|
||||
var b = require("acorn-ast-types").builders;
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
|
||||
var single = function (node) {
|
||||
var singleArrayExpression = function (node) {
|
||||
var block = node.blocks[0];
|
||||
|
||||
var templateName = "array-comprehension-map";
|
||||
if (node.filter) templateName = "array-comprehension-filter";
|
||||
var templateName = "array-expression-comprehension-map";
|
||||
if (node.filter) templateName = "array-expression-comprehension-filter";
|
||||
|
||||
var result = util.template(templateName, {
|
||||
STATEMENT: node.body,
|
||||
@@ -25,7 +25,7 @@ var multiple = function (node, file) {
|
||||
});
|
||||
container._aliasFunction = true;
|
||||
|
||||
var block = container.callee.body;
|
||||
var block = container.callee.expression.body;
|
||||
var body = block.body;
|
||||
|
||||
var returnStatement = body.pop();
|
||||
@@ -45,19 +45,15 @@ var multiple = function (node, file) {
|
||||
|
||||
// add a filter as this is our final stop
|
||||
if (node.filter) {
|
||||
child = b.ifStatement(node.filter, b.blockStatement([child]));
|
||||
child = t.ifStatement(node.filter, t.blockStatement([child]));
|
||||
}
|
||||
}
|
||||
|
||||
var container2 = util.template("array-comprehension-for-each", {
|
||||
ARRAY: self.right,
|
||||
KEY: self.left
|
||||
}, true);
|
||||
|
||||
// set function body
|
||||
container2.expression.arguments[0].body.body = [child];
|
||||
|
||||
return container2;
|
||||
return t.forOfStatement(
|
||||
t.variableDeclaration("var", [t.variableDeclarator(self.left)]),
|
||||
self.right,
|
||||
t.blockStatement([child])
|
||||
);
|
||||
};
|
||||
|
||||
body.push(build());
|
||||
@@ -67,8 +63,8 @@ var multiple = function (node, file) {
|
||||
};
|
||||
|
||||
exports.ComprehensionExpression = function (node, parent, file) {
|
||||
if (node.blocks.length === 1) {
|
||||
return single(node);
|
||||
if (node.blocks.length === 1 && t.isArrayExpression(node.blocks[0].right)) {
|
||||
return singleArrayExpression(node);
|
||||
} else {
|
||||
return multiple(node, file);
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
var util = require("../util");
|
||||
var t = require("../../types");
|
||||
|
||||
exports.ArrowFunctionExpression = function (node) {
|
||||
util.ensureBlock(node);
|
||||
t.ensureBlock(node);
|
||||
|
||||
node._aliasFunction = "arrows";
|
||||
node.expression = false;
|
||||
209
lib/6to5/transformation/transformers/classes.js
Normal file
209
lib/6to5/transformation/transformers/classes.js
Normal file
@@ -0,0 +1,209 @@
|
||||
var traverse = require("../../traverse");
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
exports.ClassDeclaration = function (node, parent, file, scope) {
|
||||
return t.variableDeclaration("var", [
|
||||
t.variableDeclarator(node.id, buildClass(node, file, scope))
|
||||
]);
|
||||
};
|
||||
|
||||
exports.ClassExpression = function (node, parent, file, scope) {
|
||||
return buildClass(node, file, scope);
|
||||
};
|
||||
|
||||
var getMemberExpressionObject = function (node) {
|
||||
while (t.isMemberExpression(node)) {
|
||||
node = node.object;
|
||||
}
|
||||
return node;
|
||||
};
|
||||
|
||||
var buildClass = function (node, file, scope) {
|
||||
var superName = node.superClass;
|
||||
var className = node.id || t.identifier(file.generateUid("class", scope));
|
||||
|
||||
var superClassArgument = node.superClass;
|
||||
var superClassCallee = node.superClass;
|
||||
|
||||
if (superName) {
|
||||
if (t.isMemberExpression(superName)) {
|
||||
superClassArgument = superClassCallee = getMemberExpressionObject(superName);
|
||||
} else if (!t.isIdentifier(superName)) {
|
||||
superClassArgument = superName;
|
||||
superClassCallee = superName = t.identifier(file.generateUid("ref", scope));
|
||||
}
|
||||
}
|
||||
|
||||
var container = util.template("class", {
|
||||
CLASS_NAME: className
|
||||
});
|
||||
|
||||
var block = container.callee.expression.body;
|
||||
var body = block.body;
|
||||
var constructor = body[0].declarations[0].init;
|
||||
|
||||
if (node.id) constructor.id = className;
|
||||
|
||||
var returnStatement = body.pop();
|
||||
|
||||
if (superName) {
|
||||
body.push(t.expressionStatement(t.callExpression(file.addDeclaration("extends"), [className, superName])));
|
||||
|
||||
container.arguments.push(superClassArgument);
|
||||
container.callee.expression.params.push(superClassCallee);
|
||||
}
|
||||
|
||||
buildClassBody({
|
||||
file: file,
|
||||
body: body,
|
||||
node: node,
|
||||
className: className,
|
||||
superName: superName,
|
||||
constructor: constructor,
|
||||
});
|
||||
|
||||
if (body.length === 1) {
|
||||
// only a constructor so no need for a closure container
|
||||
return constructor;
|
||||
} else {
|
||||
body.push(returnStatement);
|
||||
return container;
|
||||
}
|
||||
};
|
||||
|
||||
var buildClassBody = function (opts) {
|
||||
var file = opts.file;
|
||||
var body = opts.body;
|
||||
var node = opts.node;
|
||||
var constructor = opts.constructor;
|
||||
var className = opts.className;
|
||||
var superName = opts.superName;
|
||||
|
||||
var instanceMutatorMap = {};
|
||||
var staticMutatorMap = {};
|
||||
var hasConstructor = false;
|
||||
|
||||
var classBody = node.body.body;
|
||||
|
||||
_.each(classBody, function (node) {
|
||||
var methodName = node.key;
|
||||
var method = node.value;
|
||||
|
||||
replaceInstanceSuperReferences(superName, node);
|
||||
|
||||
if (node.key.name === "constructor") {
|
||||
if (node.kind === "") {
|
||||
hasConstructor = true;
|
||||
addConstructor(constructor, method);
|
||||
} else {
|
||||
throw file.errorWithNode(node, "illegal kind for constructor method");
|
||||
}
|
||||
} else {
|
||||
var mutatorMap = instanceMutatorMap;
|
||||
if (node.static) mutatorMap = staticMutatorMap;
|
||||
|
||||
var kind = node.kind;
|
||||
|
||||
if (kind === "") {
|
||||
kind = "value";
|
||||
util.pushMutatorMap(mutatorMap, methodName, "writable", t.identifier("true"));
|
||||
}
|
||||
|
||||
util.pushMutatorMap(mutatorMap, methodName, kind, node);
|
||||
}
|
||||
});
|
||||
|
||||
if (!hasConstructor && superName) {
|
||||
constructor.body.body.push(util.template("class-super-constructor-call", {
|
||||
SUPER_NAME: superName
|
||||
}, true));
|
||||
}
|
||||
|
||||
var instanceProps;
|
||||
var staticProps;
|
||||
|
||||
if (!_.isEmpty(instanceMutatorMap)) {
|
||||
var protoId = util.template("prototype-identifier", {
|
||||
CLASS_NAME: className
|
||||
});
|
||||
|
||||
instanceProps = util.buildDefineProperties(instanceMutatorMap, protoId);
|
||||
}
|
||||
|
||||
if (!_.isEmpty(staticMutatorMap)) {
|
||||
staticProps = util.buildDefineProperties(staticMutatorMap, className);
|
||||
}
|
||||
|
||||
if (instanceProps || staticProps) {
|
||||
staticProps = staticProps || t.literal(null);
|
||||
|
||||
var args = [className, staticProps];
|
||||
if (instanceProps) args.push(instanceProps);
|
||||
|
||||
body.push(t.expressionStatement(
|
||||
t.callExpression(file.addDeclaration("class-props"), args)
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
var superIdentifier = function (superName, methodNode, node, parent) {
|
||||
var methodName = methodNode.key;
|
||||
|
||||
if (parent.property === node) {
|
||||
return;
|
||||
} else if (t.isCallExpression(parent, { callee: node })) {
|
||||
// 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 {
|
||||
node = superName;
|
||||
|
||||
// foo() { super(); }
|
||||
if (!methodNode.static) {
|
||||
node = t.memberExpression(node, t.identifier("prototype"));
|
||||
}
|
||||
|
||||
node = t.memberExpression(node, methodName, methodNode.computed);
|
||||
return t.memberExpression(node, 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;
|
||||
}
|
||||
};
|
||||
|
||||
var replaceInstanceSuperReferences = function (superName, methodNode) {
|
||||
var method = methodNode.value;
|
||||
|
||||
superName = superName || t.identifier("Function");
|
||||
|
||||
traverse(method, function (node, parent) {
|
||||
if (t.isIdentifier(node, { name: "super" })) {
|
||||
return superIdentifier(superName, methodNode, node, parent);
|
||||
} else if (t.isCallExpression(node)) {
|
||||
var callee = node.callee;
|
||||
if (!t.isMemberExpression(callee)) return;
|
||||
if (callee.object.name !== "super") return;
|
||||
|
||||
// super.test(); -> ClassName.prototype.MethodName.call(this);
|
||||
callee.property.name = callee.property.name + ".call";
|
||||
node.arguments.unshift(t.thisExpression());
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var addConstructor = function (construct, method) {
|
||||
construct.defaults = method.defaults;
|
||||
construct.params = method.params;
|
||||
construct.body = method.body;
|
||||
construct.rest = method.rest;
|
||||
|
||||
t.inherits(construct, method);
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
var util = require("../util");
|
||||
var b = require("acorn-ast-types").builders;
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
exports.ObjectExpression = function (node, parent, file) {
|
||||
@@ -26,17 +26,17 @@ exports.ObjectExpression = function (node, parent, file) {
|
||||
OBJECT: node
|
||||
});
|
||||
|
||||
var containerCallee = container.callee;
|
||||
var containerCallee = container.callee.expression;
|
||||
var containerBody = containerCallee.body.body;
|
||||
|
||||
containerCallee._aliasFunction = "arrows";
|
||||
|
||||
_.each(computed, function (prop) {
|
||||
containerBody.unshift(
|
||||
b.expressionStatement(
|
||||
b.assignmentExpression(
|
||||
t.expressionStatement(
|
||||
t.assignmentExpression(
|
||||
"=",
|
||||
b.memberExpression(objId, prop.key, true),
|
||||
t.memberExpression(objId, prop.key, true),
|
||||
prop.value
|
||||
)
|
||||
)
|
||||
45
lib/6to5/transformation/transformers/constants.js
Normal file
45
lib/6to5/transformation/transformers/constants.js
Normal file
@@ -0,0 +1,45 @@
|
||||
var traverse = require("../../traverse");
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
exports.Program =
|
||||
exports.BlockStatement =
|
||||
exports.ForInStatement =
|
||||
exports.ForOfStatement =
|
||||
exports.ForStatement = function (node, parent, file) {
|
||||
var constants = [];
|
||||
|
||||
var check = function (node, names) {
|
||||
_.each(names, function (name) {
|
||||
if (constants.indexOf(name) >= 0) {
|
||||
throw file.errorWithNode(node, name + " is read-only");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
_.each(node.body, function (child) {
|
||||
if (child && t.isVariableDeclaration(child, { kind: "const" })) {
|
||||
_.each(child.declarations, function (declar) {
|
||||
_.each(t.getIds(declar), function (name) {
|
||||
check(declar, [name]);
|
||||
constants.push(name);
|
||||
});
|
||||
|
||||
declar._ignoreConstant = true;
|
||||
});
|
||||
|
||||
child._ignoreConstant = true;
|
||||
child.kind = "let";
|
||||
}
|
||||
});
|
||||
|
||||
if (!constants.length) return;
|
||||
|
||||
traverse(node, function (child) {
|
||||
if (child._ignoreConstant) return;
|
||||
|
||||
if (t.isVariableDeclarator(child) || t.isDeclaration(child) || t.isAssignmentExpression(child)) {
|
||||
check(child, t.getIds(child));
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -1,9 +1,10 @@
|
||||
var util = require("../util");
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
exports.Function = function (node) {
|
||||
if (!node.defaults.length) return;
|
||||
util.ensureBlock(node);
|
||||
t.ensureBlock(node);
|
||||
|
||||
_.each(node.defaults, function (def, i) {
|
||||
if (!def) return;
|
||||
209
lib/6to5/transformation/transformers/destructuring.js
Normal file
209
lib/6to5/transformation/transformers/destructuring.js
Normal file
@@ -0,0 +1,209 @@
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
var buildVariableAssign = function (kind, id, init) {
|
||||
if (kind === false) {
|
||||
return t.expressionStatement(t.assignmentExpression("=", id, init));
|
||||
} else {
|
||||
return t.variableDeclaration(kind, [
|
||||
t.variableDeclarator(id, init)
|
||||
]);
|
||||
}
|
||||
};
|
||||
|
||||
var get = function (node) {
|
||||
if (t.isParenthesizedExpression(node)) {
|
||||
return node.expression;
|
||||
} else {
|
||||
return node;
|
||||
}
|
||||
};
|
||||
|
||||
var push = function (kind, nodes, elem, parentId) {
|
||||
elem = get(elem);
|
||||
|
||||
if (t.isObjectPattern(elem)) {
|
||||
pushObjectPattern(kind, nodes, elem, parentId);
|
||||
} else if (t.isArrayPattern(elem)) {
|
||||
pushArrayPattern(kind, nodes, elem, parentId);
|
||||
} else if (t.isMemberExpression(elem)) {
|
||||
nodes.push(buildVariableAssign(false, elem, parentId));
|
||||
} else {
|
||||
nodes.push(buildVariableAssign(kind, elem, parentId));
|
||||
}
|
||||
};
|
||||
|
||||
var pushObjectPattern = function (kind, nodes, pattern, parentId) {
|
||||
_.each(pattern.properties, function (prop) {
|
||||
var pattern2 = get(prop.value);
|
||||
var patternId2 = t.memberExpression(parentId, prop.key);
|
||||
|
||||
if (t.isPattern(pattern2)) {
|
||||
push(kind, nodes, pattern2, patternId2);
|
||||
} else {
|
||||
nodes.push(buildVariableAssign(kind, pattern2, patternId2));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var pushArrayPattern = function (kind, nodes, pattern, parentId) {
|
||||
_.each(pattern.elements, function (elem, i) {
|
||||
if (!elem) return;
|
||||
|
||||
var newPatternId;
|
||||
|
||||
if (t.isSpreadElement(elem)) {
|
||||
newPatternId = t.callExpression(t.memberExpression(parentId, t.identifier("slice")), [t.literal(i)]);
|
||||
elem = elem.argument;
|
||||
} else {
|
||||
newPatternId = t.memberExpression(parentId, t.literal(i), true);
|
||||
}
|
||||
|
||||
push(kind, nodes, elem, newPatternId);
|
||||
});
|
||||
};
|
||||
|
||||
var pushPattern = function (opts) {
|
||||
var kind = opts.kind;
|
||||
var nodes = opts.nodes;
|
||||
var pattern = opts.pattern;
|
||||
var parentId = opts.id;
|
||||
var file = opts.file;
|
||||
var scope = opts.scope;
|
||||
|
||||
if (!t.isMemberExpression(parentId) && !t.isIdentifier(parentId)) {
|
||||
var key = t.identifier(file.generateUid("ref", scope));
|
||||
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(key, parentId)
|
||||
]));
|
||||
|
||||
parentId = key;
|
||||
}
|
||||
|
||||
push(kind, nodes, pattern, parentId);
|
||||
};
|
||||
|
||||
exports.ForInStatement =
|
||||
exports.ForOfStatement = function (node, parent, file, scope) {
|
||||
var declar = node.left;
|
||||
if (!t.isVariableDeclaration(declar)) return;
|
||||
|
||||
var pattern = get(declar.declarations[0].id);
|
||||
if (!t.isPattern(pattern)) return;
|
||||
|
||||
var key = t.identifier(file.generateUid("ref", scope));
|
||||
node.left = t.variableDeclaration(declar.kind, [
|
||||
t.variableDeclarator(key, null)
|
||||
]);
|
||||
|
||||
var nodes = [];
|
||||
|
||||
push(declar.kind, nodes, pattern, key);
|
||||
|
||||
t.ensureBlock(node);
|
||||
|
||||
var block = node.body;
|
||||
block.body = nodes.concat(block.body);
|
||||
};
|
||||
|
||||
exports.Function = function (node, parent, file, scope) {
|
||||
var nodes = [];
|
||||
|
||||
var hasDestructuring = false;
|
||||
|
||||
node.params = node.params.map(function (pattern) {
|
||||
if (!t.isPattern(get(pattern))) return pattern;
|
||||
|
||||
hasDestructuring = true;
|
||||
var parentId = t.identifier(file.generateUid("ref", scope));
|
||||
|
||||
pushPattern({
|
||||
kind: "var",
|
||||
nodes: nodes,
|
||||
pattern: pattern,
|
||||
id: parentId,
|
||||
file: file,
|
||||
scope: scope
|
||||
});
|
||||
|
||||
return parentId;
|
||||
});
|
||||
|
||||
if (!hasDestructuring) return;
|
||||
|
||||
t.ensureBlock(node);
|
||||
|
||||
var block = node.body;
|
||||
block.body = nodes.concat(block.body);
|
||||
};
|
||||
|
||||
exports.ExpressionStatement = function (node, parent, file, scope) {
|
||||
var expr = node.expression;
|
||||
if (expr.type !== "AssignmentExpression") return;
|
||||
|
||||
var left = get(expr.left);
|
||||
if (!t.isPattern(left)) return;
|
||||
|
||||
var nodes = [];
|
||||
|
||||
var ref = t.identifier(file.generateUid("ref", scope));
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(ref, expr.right)
|
||||
]));
|
||||
|
||||
push(false, nodes, left, ref);
|
||||
|
||||
return nodes;
|
||||
};
|
||||
|
||||
exports.VariableDeclaration = function (node, parent, file, scope) {
|
||||
if (t.isForInStatement(parent) || t.isForOfStatement(parent)) return;
|
||||
|
||||
var nodes = [];
|
||||
|
||||
var hasPattern = false;
|
||||
_.each(node.declarations, function (declar) {
|
||||
if (t.isPattern(get(declar.id))) {
|
||||
hasPattern = true;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if (!hasPattern) return;
|
||||
|
||||
_.each(node.declarations, function (declar) {
|
||||
var patternId = declar.init;
|
||||
var pattern = get(declar.id);
|
||||
if (t.isPattern(pattern) && patternId) {
|
||||
pushPattern({
|
||||
kind: node.kind,
|
||||
nodes: nodes,
|
||||
pattern: pattern,
|
||||
id: patternId,
|
||||
file: file,
|
||||
scope: scope
|
||||
});
|
||||
} else {
|
||||
nodes.push(buildVariableAssign(node.kind, declar.id, declar.init));
|
||||
}
|
||||
});
|
||||
|
||||
if (!t.isProgram(parent) && !t.isBlockStatement(parent)) {
|
||||
var declar;
|
||||
|
||||
_.each(nodes, function (node) {
|
||||
declar = declar || t.variableDeclaration(node.kind, []);
|
||||
|
||||
if (!t.isVariableDeclaration(node) && declar.kind !== node.kind) {
|
||||
throw file.errorWithNode(node, "Cannot use this node within the current parent");
|
||||
}
|
||||
|
||||
declar.declarations = declar.declarations.concat(node.declarations);
|
||||
});
|
||||
|
||||
return declar;
|
||||
}
|
||||
|
||||
return nodes;
|
||||
};
|
||||
|
||||
34
lib/6to5/transformation/transformers/for-of.js
Normal file
34
lib/6to5/transformation/transformers/for-of.js
Normal file
@@ -0,0 +1,34 @@
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
|
||||
exports.ForOfStatement = function (node, parent, file, scope) {
|
||||
var left = node.left;
|
||||
var declar;
|
||||
|
||||
var stepKey = t.identifier(file.generateUid("step", scope));
|
||||
var stepValueId = t.memberExpression(stepKey, t.identifier("value"));
|
||||
|
||||
if (t.isIdentifier(left)) {
|
||||
declar = t.expressionStatement(t.assignmentExpression("=", left, stepValueId));
|
||||
} else if (t.isVariableDeclaration(left)) {
|
||||
declar = t.variableDeclaration(left.kind, [
|
||||
t.variableDeclarator(left.declarations[0].id, stepValueId)
|
||||
]);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
var node2 = util.template("for-of", {
|
||||
ITERATOR_KEY: file.generateUid("iterator", scope),
|
||||
STEP_KEY: stepKey,
|
||||
OBJECT: node.right
|
||||
});
|
||||
|
||||
t.ensureBlock(node);
|
||||
|
||||
var block = node2.body;
|
||||
block.body.push(declar);
|
||||
block.body = block.body.concat(node.body.body);
|
||||
|
||||
return node2;
|
||||
};
|
||||
3
lib/6to5/transformation/transformers/generators.js
Normal file
3
lib/6to5/transformation/transformers/generators.js
Normal file
@@ -0,0 +1,3 @@
|
||||
var regenerator = require("regenerator-6to5");
|
||||
|
||||
module.exports = regenerator.transform;
|
||||
@@ -2,26 +2,23 @@
|
||||
// https://github.com/RReverser/jsx-transpiler
|
||||
|
||||
var esutils = require("esutils");
|
||||
var b = require("acorn-ast-types").builders;
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
var JSX_ANNOTATION_REGEX = /^\*\s*@jsx\s+([^\s]+)/;
|
||||
var KNOWN_TAGS = require("./known-tags");
|
||||
|
||||
exports.Program = function (node, parent, file) {
|
||||
var jsx = "React.DOM";
|
||||
|
||||
// looking for namespace annotation
|
||||
_.each(node.comments, function (comment) {
|
||||
if (!comment.possiblyLeading) return;
|
||||
|
||||
_.each(node.leadingComments, function (comment) {
|
||||
var matches = JSX_ANNOTATION_REGEX.exec(comment.value);
|
||||
if (matches) jsx = matches[1];
|
||||
});
|
||||
|
||||
// prebuilding AST node
|
||||
file.jsx = jsx.split(".").map(b.identifier).reduce(function (object, property) {
|
||||
return b.memberExpression(object, property, false);
|
||||
file.jsx = jsx.split(".").map(t.identifier).reduce(function (object, property) {
|
||||
return t.memberExpression(object, property);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -29,7 +26,7 @@ exports.XJSIdentifier = function (node) {
|
||||
if (esutils.keyword.isIdentifierName(node.name)) {
|
||||
node.type = "Identifier";
|
||||
} else {
|
||||
return b.literal(node.name);
|
||||
return t.literal(node.name);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -39,26 +36,19 @@ exports.XJSNamespacedName = function () {
|
||||
|
||||
exports.XJSMemberExpression = {
|
||||
exit: function (node) {
|
||||
node.computed = node.property.type === "Literal";
|
||||
node.computed = t.isLiteral(node.property);
|
||||
node.type = "MemberExpression";
|
||||
}
|
||||
};
|
||||
|
||||
exports.XJSEmptyExpression = function (node) {
|
||||
node.value = null;
|
||||
node.type = "Literal";
|
||||
};
|
||||
|
||||
exports.XJSExpressionContainer = function (node) {
|
||||
return node.expression;
|
||||
};
|
||||
|
||||
exports.XJSAttribute = {
|
||||
exit: function (node) {
|
||||
var value = node.value || b.literal(true);
|
||||
var propNode = b.property("init", node.name, value);
|
||||
propNode.loc = node.loc;
|
||||
return propNode;
|
||||
var value = node.value || t.literal(true);
|
||||
return t.property("init", node.name, value);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -66,18 +56,22 @@ exports.XJSOpeningElement = {
|
||||
exit: function (node, parent, file) {
|
||||
var tagExpr = node.name;
|
||||
|
||||
if (_.contains(KNOWN_TAGS, tagExpr.name)) {
|
||||
tagExpr = b.memberExpression(file.jsx, tagExpr, false);
|
||||
if (t.isIdentifier(tagExpr)) {
|
||||
var tagName = tagExpr.name;
|
||||
|
||||
if (/[a-z]/.exec(tagName[0]) || _.contains(tagName, "-")) {
|
||||
tagExpr = t.memberExpression(file.jsx, tagExpr);
|
||||
}
|
||||
}
|
||||
|
||||
var props = node.attributes;
|
||||
if (props.length) {
|
||||
props = b.objectExpression(props);
|
||||
props = t.objectExpression(props);
|
||||
} else {
|
||||
props = b.literal(null);
|
||||
props = t.literal(null);
|
||||
}
|
||||
|
||||
return b.callExpression(tagExpr, [props]);
|
||||
return t.callExpression(tagExpr, [props]);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -87,11 +81,9 @@ exports.XJSElement = {
|
||||
var children = node.children;
|
||||
|
||||
_.each(children, function (child) {
|
||||
delete child.raw;
|
||||
callExpr.arguments.push(child);
|
||||
});
|
||||
|
||||
callExpr.loc = node.loc;
|
||||
return callExpr;
|
||||
return t.inherits(callExpr, node);
|
||||
}
|
||||
};
|
||||
325
lib/6to5/transformation/transformers/let-scoping.js
Normal file
325
lib/6to5/transformation/transformers/let-scoping.js
Normal file
@@ -0,0 +1,325 @@
|
||||
var traverse = require("../../traverse");
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
var isLet = function (node) {
|
||||
if (!t.isVariableDeclaration(node)) return false;
|
||||
if (node._let) return true;
|
||||
if (node.kind !== "let") return false;
|
||||
|
||||
node._let = true;
|
||||
node.kind = "var";
|
||||
return true;
|
||||
};
|
||||
|
||||
var isVar = function (node) {
|
||||
return t.isVariableDeclaration(node, { kind: "var" }) && !isLet(node);
|
||||
};
|
||||
|
||||
exports.VariableDeclaration = function (node) {
|
||||
isLet(node);
|
||||
};
|
||||
|
||||
exports.For = function (node, parent, file, scope) {
|
||||
var init = node.left || node.init;
|
||||
if (isLet(init)) {
|
||||
t.ensureBlock(node);
|
||||
node.body._letDeclars = [init];
|
||||
}
|
||||
|
||||
if (t.isLabeledStatement(parent)) {
|
||||
// set label so `run` has access to it
|
||||
node.label = parent.label;
|
||||
}
|
||||
|
||||
run(node, node.body, parent, file, scope);
|
||||
|
||||
if (node.label && !t.isLabeledStatement(parent)) {
|
||||
// we've been given a label so let's wrap ourselves
|
||||
return t.labeledStatement(node.label, node);
|
||||
}
|
||||
};
|
||||
|
||||
exports.BlockStatement = function (block, parent, file, scope) {
|
||||
if (!t.isFor(parent)) {
|
||||
run(false, block, parent, file, scope);
|
||||
}
|
||||
};
|
||||
|
||||
var noClosure = function (letDeclars, block, replacements) {
|
||||
standardiseLets(letDeclars);
|
||||
|
||||
if (_.isEmpty(replacements)) return;
|
||||
|
||||
traverse(block, function (node, parent) {
|
||||
if (!t.isIdentifier(node)) return;
|
||||
if (!t.isReferenced(node, parent)) return;
|
||||
node.name = replacements[node.name] || node.name;
|
||||
});
|
||||
};
|
||||
|
||||
var standardiseLets = function (declars) {
|
||||
_.each(declars, function (declar) {
|
||||
delete declar._let;
|
||||
});
|
||||
};
|
||||
|
||||
var getInfo = function (block, file, scope) {
|
||||
var opts = {
|
||||
// array of `Identifier` names of let variables that appear lexically out of
|
||||
// this scope but should be accessible - eg. `ForOfStatement`.left
|
||||
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: {},
|
||||
|
||||
// array of `Identifier` names of let variables that are accessible within
|
||||
// the current block
|
||||
keys: []
|
||||
};
|
||||
|
||||
_.each(opts.declarators, function (declar) {
|
||||
opts.declarators.push(declar);
|
||||
|
||||
var keys = t.getIds(declar);
|
||||
opts.outsideKeys = opts.outsideKeys.concat(keys);
|
||||
opts.keys = opts.keys.concat(keys);
|
||||
});
|
||||
|
||||
_.each(block.body, function (declar) {
|
||||
if (!isLet(declar)) return;
|
||||
|
||||
_.each(t.getIds(declar, true), 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.keys.push(key);
|
||||
});
|
||||
});
|
||||
|
||||
return opts;
|
||||
};
|
||||
|
||||
var checkFor = function (forParent, block) {
|
||||
var has = {
|
||||
hasContinue: false,
|
||||
hasReturn: false,
|
||||
hasBreak: false,
|
||||
};
|
||||
|
||||
if (forParent) {
|
||||
traverse(block, function (node) {
|
||||
var replace;
|
||||
|
||||
if (t.isFunction(node) || t.isFor(node)) {
|
||||
return false;
|
||||
} else if (t.isBreakStatement(node) && !node.label) {
|
||||
has.hasBreak = true;
|
||||
replace = t.returnStatement(t.literal("break"));
|
||||
} else if (t.isContinueStatement(node) && !node.label) {
|
||||
has.hasContinue = true;
|
||||
replace = t.returnStatement(t.literal("continue"));
|
||||
} else if (t.isReturnStatement(node)) {
|
||||
has.hasReturn = true;
|
||||
replace = t.returnStatement(t.objectExpression([
|
||||
t.property("init", t.identifier("v"), node.argument)
|
||||
]));
|
||||
}
|
||||
|
||||
if (replace) return t.inherits(replace, node);
|
||||
});
|
||||
}
|
||||
|
||||
return has;
|
||||
};
|
||||
|
||||
var hoistVarDeclarations = function (block, pushDeclar) {
|
||||
traverse(block, function (node) {
|
||||
if (t.isForStatement(node)) {
|
||||
if (isVar(node.init)) {
|
||||
node.init = t.sequenceExpression(pushDeclar(node.init));
|
||||
}
|
||||
} else if (t.isFor(node)) {
|
||||
if (isVar(node.left)) {
|
||||
node.left = node.left.declarations[0].id;
|
||||
}
|
||||
} else if (isVar(node)) {
|
||||
return pushDeclar(node).map(t.expressionStatement);
|
||||
} else if (t.isFunction(node)) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var getParams = function (info, letReferences) {
|
||||
var params = _.cloneDeep(letReferences);
|
||||
_.each(params, function (param) {
|
||||
param.name = info.duplicates[param.name] || param.name;
|
||||
});
|
||||
return params;
|
||||
};
|
||||
|
||||
var getLetReferences = function (block, info, letReferences) {
|
||||
var closurify = false;
|
||||
|
||||
// traverse through this block, stopping on functions and checking if they
|
||||
// contain any outside let references
|
||||
traverse(block, function (node, parent, scope) {
|
||||
if (t.isFunction(node)) {
|
||||
traverse(node, 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)) return;
|
||||
|
||||
closurify = true;
|
||||
|
||||
// this key doesn't appear just outside our scope
|
||||
if (!_.contains(info.outsideKeys, node.name)) return;
|
||||
|
||||
// push this badboy
|
||||
letReferences[node.name] = node;
|
||||
});
|
||||
|
||||
return false;
|
||||
} else if (t.isFor(node)) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
return closurify;
|
||||
};
|
||||
|
||||
var buildPushDeclar = function (body) {
|
||||
return function (node) {
|
||||
body.push(t.variableDeclaration(node.kind, node.declarations.map(function (declar) {
|
||||
return t.variableDeclarator(declar.id);
|
||||
})));
|
||||
|
||||
var replace = [];
|
||||
|
||||
_.each(node.declarations, function (declar) {
|
||||
if (!declar.init) return;
|
||||
|
||||
var expr = t.assignmentExpression("=", declar.id, declar.init);
|
||||
replace.push(t.inherits(expr, declar));
|
||||
});
|
||||
|
||||
return replace;
|
||||
};
|
||||
};
|
||||
|
||||
var run = function (forParent, block, parent, file, scope) {
|
||||
if (block._letDone) return;
|
||||
block._letDone = true;
|
||||
|
||||
var info = getInfo(block, file, scope);
|
||||
var declarators = info.declarators;
|
||||
var letKeys = info.keys;
|
||||
|
||||
// this is a block within a `Function` so we can safely leave it be
|
||||
if (t.isFunction(parent)) return;
|
||||
|
||||
// this block has no let references so let's clean up
|
||||
if (!letKeys.length) return noClosure(declarators, block, info.duplicates);
|
||||
|
||||
// outside let references that we need to wrap
|
||||
var letReferences = {};
|
||||
|
||||
// returns whether or not there are any outside let references within any
|
||||
// functions
|
||||
var closurify = getLetReferences(block, info, letReferences);
|
||||
|
||||
letReferences = _.values(letReferences);
|
||||
|
||||
// no need for a closure so let's clean up
|
||||
if (!closurify) return noClosure(declarators, block, info.duplicates);
|
||||
|
||||
// if we're inside of a for loop then we search to see if there are any
|
||||
// `break`s, `continue`s, `return`s etc
|
||||
var has = checkFor(forParent, block);
|
||||
|
||||
var body = [];
|
||||
|
||||
// hoist a `VariableDeclaration` and add `AssignmentExpression`s in it's place
|
||||
var pushDeclar = buildPushDeclar(body);
|
||||
|
||||
// hoist var references to retain scope
|
||||
hoistVarDeclarations(block, pushDeclar);
|
||||
|
||||
// set let references to plain var references
|
||||
standardiseLets(declarators);
|
||||
|
||||
// build the closure that we're going to wrap the block with
|
||||
var fn = t.functionExpression(null, letReferences, t.blockStatement(block.body));
|
||||
fn._aliasFunction = true;
|
||||
|
||||
// replace the current block body with the one we've built
|
||||
block.body = body;
|
||||
|
||||
// change duplicate let references to their uid if they have one
|
||||
var params = getParams(info, letReferences);
|
||||
|
||||
var call = t.callExpression(fn, params);
|
||||
var ret = t.identifier(file.generateUid("ret", scope));
|
||||
|
||||
if (has.hasReturn || has.hasBreak || has.hasContinue) {
|
||||
body.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(ret, call)
|
||||
]));
|
||||
|
||||
var retCheck;
|
||||
|
||||
if (has.hasReturn) {
|
||||
// typeof ret === "object"
|
||||
retCheck = t.ifStatement(
|
||||
t.binaryExpression("===", t.unaryExpression("typeof", ret, true), t.literal("object")),
|
||||
t.returnStatement(t.memberExpression(ret, t.identifier("v")))
|
||||
);
|
||||
|
||||
// there's no `break` or `continue` so we can just push in the `if`
|
||||
if (!has.hasBreak && !has.hasContinue) {
|
||||
body.push(retCheck);
|
||||
}
|
||||
}
|
||||
|
||||
if (has.hasBreak || has.hasContinue) {
|
||||
// ensure that the parent has a label as we're building a switch and we
|
||||
// need to be able to access it
|
||||
var label = forParent.label = forParent.label || t.identifier(file.generateUid("loop", scope));
|
||||
|
||||
var cases = [];
|
||||
|
||||
if (has.hasBreak) {
|
||||
cases.push(t.switchCase(t.literal("break"), [t.breakStatement(label)]));
|
||||
}
|
||||
|
||||
if (has.hasContinue) {
|
||||
cases.push(t.switchCase(t.literal("continue"), [t.continueStatement(label)]));
|
||||
}
|
||||
|
||||
if (has.hasReturn) {
|
||||
cases.push(t.switchCase(null, [retCheck]));
|
||||
}
|
||||
|
||||
body.push(t.switchStatement(ret, cases));
|
||||
}
|
||||
} else {
|
||||
body.push(t.expressionStatement(call));
|
||||
}
|
||||
};
|
||||
6
lib/6to5/transformation/transformers/numeric-literals.js
Normal file
6
lib/6to5/transformation/transformers/numeric-literals.js
Normal file
@@ -0,0 +1,6 @@
|
||||
var _ = require("lodash");
|
||||
|
||||
exports.Literal = function (node) {
|
||||
// TODO: remove this when the new code generator is released
|
||||
if (_.isNumber(node.value)) delete node.raw;
|
||||
};
|
||||
@@ -1,4 +1,4 @@
|
||||
var util = require("../util");
|
||||
var util = require("../../util");
|
||||
var _ = require("lodash");
|
||||
|
||||
exports.Property = function (node) {
|
||||
@@ -10,7 +10,7 @@ exports.ObjectExpression = function (node, parent, file) {
|
||||
|
||||
node.properties = node.properties.filter(function (prop) {
|
||||
if (prop.kind === "get" || prop.kind === "set") {
|
||||
util.pushMutatorMap(mutatorMap, prop.key.name, prop.kind, prop.value);
|
||||
util.pushMutatorMap(mutatorMap, prop.key, prop.kind, prop.value);
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
@@ -24,6 +24,9 @@ exports.ObjectExpression = function (node, parent, file) {
|
||||
return util.template("object-define-properties-closure", {
|
||||
KEY: objId,
|
||||
OBJECT: node,
|
||||
CONTENT: util.buildDefineProperties(mutatorMap, objId).expression
|
||||
CONTENT: util.template("object-define-properties", {
|
||||
OBJECT: objId,
|
||||
PROPS: util.buildDefineProperties(mutatorMap)
|
||||
})
|
||||
});
|
||||
};
|
||||
@@ -1,19 +1,19 @@
|
||||
var b = require("acorn-ast-types").builders;
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
var addDisplayName = function (id, call) {
|
||||
if (!call || call.type !== "CallExpression") return;
|
||||
if (!call || !t.isCallExpression(call)) return;
|
||||
|
||||
var callee = call.callee;
|
||||
if (callee.type !== "MemberExpression") return;
|
||||
if (!t.isMemberExpression(callee)) return;
|
||||
|
||||
// not React
|
||||
var obj = callee.object;
|
||||
if (obj.type !== "Identifier" || obj.name !== "React") return;
|
||||
if (!t.isIdentifier(obj, { name: "React" })) return;
|
||||
|
||||
// not createClass
|
||||
var prop = callee.property;
|
||||
if (prop.type !== "Identifier" || prop.name !== "createClass") return;
|
||||
if (!t.isIdentifier(prop, { name: "createClass" })) return;
|
||||
|
||||
// no arguments
|
||||
var args = call.arguments;
|
||||
@@ -21,19 +21,19 @@ var addDisplayName = function (id, call) {
|
||||
|
||||
// not an object
|
||||
var first = args[0];
|
||||
if (first.type !== "ObjectExpression") return;
|
||||
if (!t.isObjectExpression(first)) return;
|
||||
|
||||
var props = first.properties;
|
||||
var safe = true;
|
||||
|
||||
_.each(props, function (prop) {
|
||||
if (prop.key.name === "displayName") {
|
||||
if (t.isIdentifier(prop.key, { name: "displayName" })) {
|
||||
return safe = false;
|
||||
}
|
||||
});
|
||||
|
||||
if (safe) {
|
||||
props.unshift(b.property("init", b.identifier("displayName"), b.literal(id)));
|
||||
props.unshift(t.property("init", t.identifier("displayName"), t.literal(id)));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -42,22 +42,22 @@ exports.Property =
|
||||
exports.VariableDeclarator = function (node) {
|
||||
var left, right;
|
||||
|
||||
if (node.type === "AssignmentExpression") {
|
||||
if (t.isAssignmentExpression(node)) {
|
||||
left = node.left;
|
||||
right = node.right;
|
||||
} else if (node.type === "Property") {
|
||||
} else if (t.isProperty(node)) {
|
||||
left = node.key;
|
||||
right = node.value;
|
||||
} else if (node.type === "VariableDeclarator") {
|
||||
} else if (t.isVariableDeclarator(node)) {
|
||||
left = node.id;
|
||||
right = node.init;
|
||||
}
|
||||
|
||||
if (left && left.type === "MemberExpression") {
|
||||
if (t.isMemberExpression(left)) {
|
||||
left = left.property;
|
||||
}
|
||||
|
||||
if (left && left.type === "Identifier") {
|
||||
if (t.isIdentifier(left)) {
|
||||
addDisplayName(left.name, right);
|
||||
}
|
||||
};
|
||||
24
lib/6to5/transformation/transformers/rest-parameters.js
Normal file
24
lib/6to5/transformation/transformers/rest-parameters.js
Normal file
@@ -0,0 +1,24 @@
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
|
||||
exports.Function = function (node, parent, file) {
|
||||
if (!node.rest) return;
|
||||
|
||||
var rest = node.rest;
|
||||
delete node.rest;
|
||||
|
||||
var templateName = "arguments-slice-assign";
|
||||
if (node.params.length) templateName += "-arg";
|
||||
|
||||
t.ensureBlock(node);
|
||||
|
||||
var template = util.template(templateName, {
|
||||
SLICE_KEY: file.addDeclaration("slice"),
|
||||
VARIABLE_NAME: rest,
|
||||
SLICE_ARG: t.literal(node.params.length)
|
||||
});
|
||||
|
||||
template.declarations[0].init.arguments[0]._ignoreAliasFunctions = true;
|
||||
|
||||
node.body.body.unshift(template);
|
||||
};
|
||||
@@ -1,10 +1,10 @@
|
||||
var util = require("../util");
|
||||
var b = require("acorn-ast-types").builders;
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
var getSpreadLiteral = function (spread, file) {
|
||||
var literal = spread.argument;
|
||||
if (literal.type !== "ArrayExpression") {
|
||||
if (!t.isArrayExpression(literal)) {
|
||||
literal = util.template("call", {
|
||||
OBJECT: file.addDeclaration("slice"),
|
||||
CONTEXT: literal
|
||||
@@ -16,7 +16,7 @@ var getSpreadLiteral = function (spread, file) {
|
||||
var hasSpread = function (nodes) {
|
||||
var has = false;
|
||||
_.each(nodes, function (node) {
|
||||
if (node.type === "SpreadElement") {
|
||||
if (t.isSpreadElement(node)) {
|
||||
has = true;
|
||||
return false;
|
||||
}
|
||||
@@ -31,12 +31,12 @@ var build = function (props, file) {
|
||||
|
||||
var push = function () {
|
||||
if (!_props.length) return;
|
||||
nodes.push(b.arrayExpression(_props));
|
||||
nodes.push(t.arrayExpression(_props));
|
||||
_props = [];
|
||||
};
|
||||
|
||||
_.each(props, function (prop) {
|
||||
if (prop.type === "SpreadElement") {
|
||||
if (t.isSpreadElement(prop)) {
|
||||
push();
|
||||
nodes.push(getSpreadLiteral(prop, file));
|
||||
} else {
|
||||
@@ -58,14 +58,14 @@ exports.ArrayExpression = function (node, parent, file) {
|
||||
|
||||
if (!nodes.length) return first;
|
||||
|
||||
return b.callExpression(b.memberExpression(first, b.identifier("concat"), false), nodes);
|
||||
return t.callExpression(t.memberExpression(first, t.identifier("concat")), nodes);
|
||||
};
|
||||
|
||||
exports.CallExpression = function (node, parent, file) {
|
||||
var args = node.arguments;
|
||||
if (!hasSpread(args)) return;
|
||||
|
||||
var contextLiteral = b.literal(null);
|
||||
var contextLiteral = t.literal(null);
|
||||
|
||||
node.arguments = [];
|
||||
|
||||
@@ -73,25 +73,25 @@ exports.CallExpression = function (node, parent, file) {
|
||||
var first = nodes.shift();
|
||||
|
||||
if (nodes.length) {
|
||||
node.arguments.push(b.callExpression(b.memberExpression(first, b.identifier("concat"), false), nodes));
|
||||
node.arguments.push(t.callExpression(t.memberExpression(first, t.identifier("concat")), nodes));
|
||||
} else {
|
||||
node.arguments.push(first);
|
||||
}
|
||||
|
||||
var callee = node.callee;
|
||||
|
||||
if (callee.type === "MemberExpression") {
|
||||
if (t.isMemberExpression(callee)) {
|
||||
contextLiteral = callee.object;
|
||||
|
||||
if (callee.computed) {
|
||||
callee.object = b.memberExpression(callee.object, callee.property, true);
|
||||
callee.property = b.identifier("apply");
|
||||
callee.object = t.memberExpression(callee.object, callee.property, true);
|
||||
callee.property = t.identifier("apply");
|
||||
callee.computed = false;
|
||||
} else {
|
||||
callee.property = b.memberExpression(callee.property, b.identifier("apply"), false);
|
||||
callee.property = t.memberExpression(callee.property, t.identifier("apply"));
|
||||
}
|
||||
} else {
|
||||
node.callee = b.memberExpression(node.callee, b.identifier("apply"), false);
|
||||
node.callee = t.memberExpression(node.callee, t.identifier("apply"));
|
||||
}
|
||||
|
||||
node.arguments.unshift(contextLiteral);
|
||||
@@ -1,8 +1,8 @@
|
||||
var b = require("acorn-ast-types").builders;
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
var buildBinaryExpression = function (left, right) {
|
||||
return b.binaryExpression("+", left, right);
|
||||
return t.binaryExpression("+", left, right);
|
||||
};
|
||||
|
||||
exports.TaggedTemplateExpression = function (node) {
|
||||
@@ -10,31 +10,34 @@ exports.TaggedTemplateExpression = function (node) {
|
||||
var quasi = node.quasi;
|
||||
|
||||
var strings = quasi.quasis.map(function (elem) {
|
||||
return b.literal(elem.value.raw);
|
||||
return t.literal(elem.value.raw);
|
||||
});
|
||||
args.push(b.arrayExpression(strings));
|
||||
args.push(t.arrayExpression(strings));
|
||||
|
||||
_.each(quasi.expressions, function (expr) {
|
||||
args.push(expr);
|
||||
});
|
||||
|
||||
return b.callExpression(node.tag, args);
|
||||
return t.callExpression(node.tag, args);
|
||||
};
|
||||
|
||||
exports.TemplateLiteral = function (node) {
|
||||
var nodes = [];
|
||||
|
||||
_.each(node.quasis, function (elem) {
|
||||
nodes.push(b.literal(elem.value.raw));
|
||||
nodes.push(t.literal(elem.value.raw));
|
||||
|
||||
var expr = node.expressions.shift();
|
||||
if (expr) nodes.push(expr);
|
||||
if (expr) {
|
||||
if (t.isBinary(expr)) expr = t.parenthesizedExpression(expr);
|
||||
nodes.push(expr);
|
||||
}
|
||||
});
|
||||
|
||||
if (nodes.length > 1) {
|
||||
// remove redundant '' at the end of the expression
|
||||
var last = _.last(nodes);
|
||||
if (last.type === "Literal" && last.value === "") nodes.pop();
|
||||
if (t.isLiteral(last, { value: "" })) nodes.pop();
|
||||
|
||||
var root = buildBinaryExpression(nodes.shift(), nodes.shift());
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
var rewritePattern = require("regexpu/rewrite-pattern");
|
||||
var b = require("acorn-ast-types").builders;
|
||||
var _ = require("lodash");
|
||||
|
||||
exports.Literal = function (node) {
|
||||
@@ -10,6 +9,6 @@ exports.Literal = function (node) {
|
||||
if (!_.contains(regex.flags, "u")) return;
|
||||
_.pull(flags, "u");
|
||||
|
||||
var pattern = rewritePattern(regex.pattern, regex.flags);
|
||||
return b.literal(new RegExp(pattern, flags.join("")));
|
||||
regex.pattern = rewritePattern(regex.pattern, regex.flags);
|
||||
regex.flags = flags.join("");
|
||||
};
|
||||
12
lib/6to5/transformation/transformers/use-strict.js
Normal file
12
lib/6to5/transformation/transformers/use-strict.js
Normal file
@@ -0,0 +1,12 @@
|
||||
var t = require("../../types");
|
||||
|
||||
module.exports = function (ast) {
|
||||
var body = ast.program.body;
|
||||
var first = body[0];
|
||||
|
||||
var noStrict = !first || !t.isExpressionStatement(first) || !t.isLiteral(first.expression) || first.expression.value !== "use strict";
|
||||
|
||||
if (noStrict) {
|
||||
body.unshift(t.expressionStatement(t.literal("use strict")));
|
||||
}
|
||||
};
|
||||
@@ -1,173 +0,0 @@
|
||||
var traverse = require("../traverse");
|
||||
var util = require("../util");
|
||||
var b = require("acorn-ast-types").builders;
|
||||
var _ = require("lodash");
|
||||
|
||||
exports.ClassDeclaration = function (node, parent, file) {
|
||||
return b.variableDeclaration("var", [
|
||||
b.variableDeclarator(node.id, buildClass(node, file))
|
||||
]);
|
||||
};
|
||||
|
||||
exports.ClassExpression = function (node, parent, file) {
|
||||
return buildClass(node, file);
|
||||
};
|
||||
|
||||
var getMemberExpressionObject = function (node) {
|
||||
while (node.type === "MemberExpression") {
|
||||
node = node.object;
|
||||
}
|
||||
return node;
|
||||
};
|
||||
|
||||
var buildClass = function (node, file) {
|
||||
var superName = node.superClass;
|
||||
var className = node.id || b.identifier(file.generateUid("class"));
|
||||
|
||||
var superClassArgument = node.superClass;
|
||||
var superClassCallee = node.superClass;
|
||||
|
||||
if (superName) {
|
||||
if (superName.type === "MemberExpression") {
|
||||
superClassArgument = superClassCallee = getMemberExpressionObject(superName);
|
||||
} else if (superName.type !== "Identifier") {
|
||||
superClassArgument = superName;
|
||||
superClassCallee = superName = b.identifier(file.generateUid("ref"));
|
||||
}
|
||||
}
|
||||
|
||||
var container = util.template("class", {
|
||||
CLASS_NAME: className
|
||||
});
|
||||
|
||||
var block = container.callee.body;
|
||||
var body = block.body;
|
||||
|
||||
if (node.id) {
|
||||
body[0].declarations[0].init.id = className;
|
||||
}
|
||||
|
||||
var returnStatement = body.pop();
|
||||
|
||||
if (superName) {
|
||||
body.push(b.expressionStatement(b.callExpression(file.addDeclaration("extends"), [className, superName])));
|
||||
|
||||
container.arguments.push(superClassArgument);
|
||||
container.callee.params.push(superClassCallee);
|
||||
}
|
||||
|
||||
buildClassBody(body, className, superName, node);
|
||||
|
||||
body.push(returnStatement);
|
||||
|
||||
return container;
|
||||
};
|
||||
|
||||
var buildClassBody = function (body, className, superName, node) {
|
||||
var instanceMutatorMap = {};
|
||||
var staticMutatorMap = {};
|
||||
var hasConstructor = false;
|
||||
|
||||
var construct = body[0].declarations[0].init;
|
||||
var classBody = node.body.body;
|
||||
|
||||
_.each(classBody, function (node) {
|
||||
var methodName = node.key.name;
|
||||
var method = node.value;
|
||||
|
||||
replaceInstanceSuperReferences(superName, method, node, methodName);
|
||||
|
||||
if (methodName === "constructor") {
|
||||
if (node.kind === "") {
|
||||
hasConstructor = true;
|
||||
addConstructor(construct, method);
|
||||
} else {
|
||||
throw util.errorWithNode(node, "unknown kind for constructor method");
|
||||
}
|
||||
} else {
|
||||
var mutatorMap = instanceMutatorMap;
|
||||
if (node.static) mutatorMap = staticMutatorMap;
|
||||
|
||||
var kind = node.kind;
|
||||
|
||||
if (kind === "") {
|
||||
kind = "value";
|
||||
util.pushMutatorMap(mutatorMap, methodName, "writable", b.identifier("true"));
|
||||
}
|
||||
|
||||
util.pushMutatorMap(mutatorMap, methodName, kind, node);
|
||||
}
|
||||
});
|
||||
|
||||
if (!hasConstructor && superName) {
|
||||
construct.body.body.push(util.template("class-super-constructor-call", {
|
||||
SUPER_NAME: superName
|
||||
}, true));
|
||||
}
|
||||
|
||||
if (!_.isEmpty(instanceMutatorMap)) {
|
||||
var protoId = util.template("prototype-identifier", {
|
||||
CLASS_NAME: className
|
||||
});
|
||||
|
||||
body.push(util.buildDefineProperties(instanceMutatorMap, protoId));
|
||||
}
|
||||
|
||||
if (!_.isEmpty(staticMutatorMap)) {
|
||||
body.push(util.buildDefineProperties(staticMutatorMap, className));
|
||||
}
|
||||
};
|
||||
|
||||
var superIdentifier = function (superName, methodNode, methodName, node, parent) {
|
||||
if (parent.property === node) {
|
||||
return;
|
||||
} else if (parent.type === "CallExpression" && parent.callee === node) {
|
||||
// super(); -> ClassName.prototype.MethodName.call(this);
|
||||
parent.arguments.unshift(b.thisExpression());
|
||||
|
||||
if (methodName === "constructor") {
|
||||
// constructor() { super(); }
|
||||
return b.memberExpression(superName, b.identifier("call"), false);
|
||||
} else {
|
||||
node = superName;
|
||||
|
||||
// foo() { super(); }
|
||||
if (!methodNode.static) {
|
||||
node = b.memberExpression(node, b.identifier("prototype"), false);
|
||||
}
|
||||
|
||||
node = b.memberExpression(node, b.identifier(methodName), false);
|
||||
return b.memberExpression(node, b.identifier("call"), false);
|
||||
}
|
||||
} else if (parent.type === "MemberExpression" && !methodNode.static) {
|
||||
// super.test -> ClassName.prototype.test
|
||||
return b.memberExpression(superName, b.identifier("prototype"), false);
|
||||
} else {
|
||||
return superName;
|
||||
}
|
||||
};
|
||||
|
||||
var replaceInstanceSuperReferences = function (superName, method, methodNode, methodName) {
|
||||
superName = superName || b.identifier("Function");
|
||||
|
||||
traverse(method, function (node, parent) {
|
||||
if (node.type === "Identifier" && node.name === "super") {
|
||||
return superIdentifier(superName, methodNode, methodName, node, parent);
|
||||
} else if (node.type === "CallExpression") {
|
||||
var callee = node.callee;
|
||||
if (callee.type !== "MemberExpression") return;
|
||||
if (callee.object.name !== "super") return;
|
||||
|
||||
// super.test(); -> ClassName.prototype.MethodName.call(this);
|
||||
callee.property.name = callee.property.name + ".call";
|
||||
node.arguments.unshift(b.thisExpression());
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var addConstructor = function (construct, method) {
|
||||
construct.defaults = method.defaults;
|
||||
construct.params = method.params;
|
||||
construct.body = method.body;
|
||||
construct.rest = method.rest;
|
||||
};
|
||||
@@ -1,45 +0,0 @@
|
||||
var traverse = require("../traverse");
|
||||
var util = require("../util");
|
||||
var _ = require("lodash");
|
||||
|
||||
exports.Program =
|
||||
exports.BlockStatement =
|
||||
exports.ForInStatement =
|
||||
exports.ForOfStatement =
|
||||
exports.ForStatement = function (node) {
|
||||
var constants = [];
|
||||
|
||||
var check = function (node, name) {
|
||||
if (constants.indexOf(name) >= 0) {
|
||||
throw util.errorWithNode(node, name + " is read-only");
|
||||
}
|
||||
};
|
||||
|
||||
_.each(node.body, function (child) {
|
||||
if (child && child.type === "VariableDeclaration" && child.kind === "const") {
|
||||
_.each(child.declarations, function (declar) {
|
||||
_.each(util.getIds(declar.id), function (name) {
|
||||
check(declar, name);
|
||||
constants.push(name);
|
||||
});
|
||||
|
||||
declar._ignoreConstant = true;
|
||||
});
|
||||
child.kind = "let";
|
||||
}
|
||||
});
|
||||
|
||||
if (!constants.length) return;
|
||||
|
||||
traverse(node, function (child) {
|
||||
if (child._ignoreConstant) return;
|
||||
|
||||
if (child.type === "VariableDeclarator" ||
|
||||
child.type === "FunctionDeclaration" ||
|
||||
child.type === "ClassDeclaration") {
|
||||
check(child, child.id.name);
|
||||
} else if (child.type === "AssignmentExpression") {
|
||||
check(child, child.left.name);
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -1,153 +0,0 @@
|
||||
var traverse = require("../traverse");
|
||||
var util = require("../util");
|
||||
var b = require("acorn-ast-types").builders;
|
||||
var _ = require("lodash");
|
||||
|
||||
var buildVariableAssign = function (kind, id, init) {
|
||||
if (kind === false) {
|
||||
return b.expressionStatement(b.assignmentExpression("=", id, init));
|
||||
} else {
|
||||
return b.variableDeclaration(kind, [
|
||||
b.variableDeclarator(id, init)
|
||||
]);
|
||||
}
|
||||
};
|
||||
|
||||
var push = function (kind, nodes, pattern, parentId) {
|
||||
if (pattern.type === "ObjectPattern") {
|
||||
pushObjectPattern(kind, nodes, pattern, parentId);
|
||||
} else if (pattern.type === "ArrayPattern") {
|
||||
pushArrayPattern(kind, nodes, pattern, parentId);
|
||||
}
|
||||
};
|
||||
|
||||
var pushObjectPattern = function (kind, nodes, pattern, parentId) {
|
||||
_.each(pattern.properties, function (prop) {
|
||||
var pattern2 = prop.value;
|
||||
var patternId2 = b.memberExpression(parentId, prop.key, false);
|
||||
|
||||
if (traverse.isPattern(pattern2)) {
|
||||
push(kind, nodes, pattern2, patternId2);
|
||||
} else {
|
||||
nodes.push(buildVariableAssign(kind, pattern2, patternId2));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var pushArrayPattern = function (kind, nodes, pattern, parentId) {
|
||||
_.each(pattern.elements, function (elem, i) {
|
||||
if (!elem) return;
|
||||
|
||||
var newPatternId = b.memberExpression(parentId, b.literal(i), true);
|
||||
|
||||
if (elem.type === "Identifier") {
|
||||
nodes.push(buildVariableAssign(kind, elem, newPatternId));
|
||||
} else {
|
||||
push(kind, nodes, elem, newPatternId);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var pushPattern = function (kind, nodes, pattern, parentId, file) {
|
||||
if (parentId.type !== "MemberExpression" && parentId.type !== "Identifier") {
|
||||
var key = b.identifier(file.generateUid("ref"));
|
||||
|
||||
nodes.push(b.variableDeclaration("var", [
|
||||
b.variableDeclarator(key, parentId)
|
||||
]));
|
||||
|
||||
parentId = key;
|
||||
}
|
||||
|
||||
push(kind, nodes, pattern, parentId);
|
||||
};
|
||||
|
||||
exports.ForInStatement =
|
||||
exports.ForOfStatement = function (node, parent, file) {
|
||||
var declar = node.left;
|
||||
if (declar.type !== "VariableDeclaration") return;
|
||||
|
||||
var pattern = declar.declarations[0].id;
|
||||
if (!traverse.isPattern(pattern)) return;
|
||||
|
||||
var key = b.identifier(file.generateUid("ref"));
|
||||
node.left = b.variableDeclaration(declar.kind, [
|
||||
b.variableDeclarator(key, null)
|
||||
]);
|
||||
|
||||
var nodes = [];
|
||||
|
||||
push(declar.kind, nodes, pattern, key);
|
||||
|
||||
util.ensureBlock(node);
|
||||
|
||||
var block = node.body;
|
||||
block.body = nodes.concat(block.body);
|
||||
};
|
||||
|
||||
exports.Function = function (node, parent, file) {
|
||||
var nodes = [];
|
||||
|
||||
var hasDestructuring = false;
|
||||
|
||||
node.params = node.params.map(function (pattern) {
|
||||
if (!traverse.isPattern(pattern)) return pattern;
|
||||
|
||||
hasDestructuring = true;
|
||||
var parentId = b.identifier(file.generateUid("ref"));
|
||||
pushPattern("var", nodes, pattern, parentId, file);
|
||||
return parentId;
|
||||
});
|
||||
|
||||
if (!hasDestructuring) return;
|
||||
|
||||
util.ensureBlock(node);
|
||||
|
||||
var block = node.body;
|
||||
block.body = nodes.concat(block.body);
|
||||
};
|
||||
|
||||
exports.ExpressionStatement = function (node, parent, file) {
|
||||
var expr = node.expression;
|
||||
if (expr.type !== "AssignmentExpression") return;
|
||||
|
||||
if (!traverse.isPattern(expr.left)) return;
|
||||
|
||||
var nodes = [];
|
||||
|
||||
var ref = b.identifier(file.generateUid("ref"));
|
||||
nodes.push(b.variableDeclaration("var", [
|
||||
b.variableDeclarator(ref, expr.right)
|
||||
]));
|
||||
|
||||
push(false, nodes, expr.left, ref);
|
||||
|
||||
return nodes;
|
||||
};
|
||||
|
||||
exports.VariableDeclaration = function (node, parent, file) {
|
||||
if (parent.type === "ForInStatement") return;
|
||||
|
||||
var nodes = [];
|
||||
|
||||
var hasPattern = false;
|
||||
_.each(node.declarations, function (declar) {
|
||||
if (traverse.isPattern(declar.id)) {
|
||||
hasPattern = true;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if (!hasPattern) return;
|
||||
|
||||
_.each(node.declarations, function (declar) {
|
||||
var patternId = declar.init;
|
||||
var pattern = declar.id;
|
||||
if (traverse.isPattern(pattern) && patternId) {
|
||||
pushPattern(node.kind, nodes, pattern, patternId, file);
|
||||
} else {
|
||||
nodes.push(buildVariableAssign(node.kind, declar.id, declar.init));
|
||||
}
|
||||
});
|
||||
|
||||
return nodes;
|
||||
};
|
||||
@@ -1,34 +0,0 @@
|
||||
var util = require("../util");
|
||||
var b = require("acorn-ast-types").builders;
|
||||
|
||||
exports.ForOfStatement = function (node, parent, file) {
|
||||
var left = node.left;
|
||||
var declar;
|
||||
|
||||
var stepKey = b.identifier(file.generateUid("step"));
|
||||
var stepValueId = b.memberExpression(stepKey, b.identifier("value"), false);
|
||||
|
||||
if (left.type === "Identifier") {
|
||||
declar = b.expressionStatement(b.assignmentExpression("=", left, stepValueId));
|
||||
} else if (left.type === "VariableDeclaration") {
|
||||
declar = b.variableDeclaration(left.kind, [
|
||||
b.variableDeclarator(left.declarations[0].id, stepValueId)
|
||||
]);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
var node2 = util.template("for-of", {
|
||||
ITERATOR_KEY: file.generateUid("iterator"),
|
||||
STEP_KEY: stepKey,
|
||||
OBJECT: node.right
|
||||
});
|
||||
|
||||
util.ensureBlock(node);
|
||||
|
||||
var block = node2.body;
|
||||
block.body.push(declar);
|
||||
block.body = block.body.concat(node.body.body);
|
||||
|
||||
return node2;
|
||||
};
|
||||
@@ -1,3 +0,0 @@
|
||||
var regenerator = require("regenerator");
|
||||
|
||||
module.exports = regenerator.transform;
|
||||
@@ -1,132 +0,0 @@
|
||||
[
|
||||
"a",
|
||||
"abbr",
|
||||
"address",
|
||||
"applet",
|
||||
"area",
|
||||
"article",
|
||||
"aside",
|
||||
"audio",
|
||||
"b",
|
||||
"base",
|
||||
"bdi",
|
||||
"bdo",
|
||||
"big",
|
||||
"blockquote",
|
||||
"body",
|
||||
"br",
|
||||
"button",
|
||||
"canvas",
|
||||
"caption",
|
||||
"circle",
|
||||
"cite",
|
||||
"code",
|
||||
"col",
|
||||
"colgroup",
|
||||
"command",
|
||||
"data",
|
||||
"datalist",
|
||||
"dd",
|
||||
"defs",
|
||||
"del",
|
||||
"details",
|
||||
"dfn",
|
||||
"dialog",
|
||||
"div",
|
||||
"dl",
|
||||
"dt",
|
||||
"ellipse",
|
||||
"em",
|
||||
"embed",
|
||||
"fieldset",
|
||||
"figcaption",
|
||||
"figure",
|
||||
"footer",
|
||||
"form",
|
||||
"g",
|
||||
"h1",
|
||||
"h2",
|
||||
"h3",
|
||||
"h4",
|
||||
"h5",
|
||||
"h6",
|
||||
"head",
|
||||
"header",
|
||||
"hgroup",
|
||||
"hr",
|
||||
"html",
|
||||
"i",
|
||||
"iframe",
|
||||
"img",
|
||||
"input",
|
||||
"ins",
|
||||
"kbd",
|
||||
"keygen",
|
||||
"label",
|
||||
"legend",
|
||||
"li",
|
||||
"line",
|
||||
"linearGradient",
|
||||
"link",
|
||||
"main",
|
||||
"map",
|
||||
"mark",
|
||||
"marquee",
|
||||
"menu",
|
||||
"menuitem",
|
||||
"meta",
|
||||
"meter",
|
||||
"nav",
|
||||
"noscript",
|
||||
"object",
|
||||
"ol",
|
||||
"optgroup",
|
||||
"option",
|
||||
"output",
|
||||
"p",
|
||||
"param",
|
||||
"path",
|
||||
"polygon",
|
||||
"polyline",
|
||||
"pre",
|
||||
"progress",
|
||||
"q",
|
||||
"radialGradient",
|
||||
"rect",
|
||||
"rp",
|
||||
"rt",
|
||||
"ruby",
|
||||
"s",
|
||||
"samp",
|
||||
"script",
|
||||
"section",
|
||||
"select",
|
||||
"small",
|
||||
"source",
|
||||
"span",
|
||||
"stop",
|
||||
"strong",
|
||||
"style",
|
||||
"sub",
|
||||
"summary",
|
||||
"sup",
|
||||
"svg",
|
||||
"table",
|
||||
"tbody",
|
||||
"td",
|
||||
"text",
|
||||
"textarea",
|
||||
"tfoot",
|
||||
"th",
|
||||
"thead",
|
||||
"time",
|
||||
"title",
|
||||
"tr",
|
||||
"track",
|
||||
"tspan",
|
||||
"u",
|
||||
"ul",
|
||||
"var",
|
||||
"video",
|
||||
"wbr"
|
||||
]
|
||||
@@ -1,58 +0,0 @@
|
||||
var traverse = require("../traverse");
|
||||
var util = require("../util");
|
||||
var b = require("acorn-ast-types").builders;
|
||||
var _ = require("lodash");
|
||||
|
||||
exports.VariableDeclaration = function (node, parent, file) {
|
||||
if (node.kind !== "let") return;
|
||||
node.kind = "var";
|
||||
|
||||
var ids = {};
|
||||
|
||||
_.each(node.declarations, function (declar) {
|
||||
_.each(util.getIds(declar.id), function (id) {
|
||||
ids[id] = b.identifier(file.generateUid(id));
|
||||
});
|
||||
});
|
||||
|
||||
var replaceId = function (node, parent) {
|
||||
// not an identifier so we have no use for this node
|
||||
if (node.type !== "Identifier") return;
|
||||
|
||||
// not a let reference
|
||||
var id = ids[node.name];
|
||||
if (!id) return;
|
||||
|
||||
if (util.isReferenced(node, parent)) return id;
|
||||
};
|
||||
|
||||
var isProgram = parent.type === "Program";
|
||||
|
||||
var replace = function (node, parent) {
|
||||
if (!isProgram && _.contains(traverse.FUNCTION_TYPES, node.type)) {
|
||||
var letReferences = [];
|
||||
|
||||
traverse(node, function (node, parent) {
|
||||
var id = replaceId(node, parent);
|
||||
if (id && !_.contains(letReferences, id)) letReferences.push(id);
|
||||
return id;
|
||||
});
|
||||
|
||||
if (letReferences.length) {
|
||||
if (node.type === "FunctionDeclaration") {
|
||||
throw new Error("`FunctionDeclaration`s that use `let` and `constant` references aren't allowed outside of the root scope");
|
||||
} else {
|
||||
return b.callExpression(b.functionExpression(null, letReferences, b.blockStatement([
|
||||
b.returnStatement(node)
|
||||
])), letReferences);
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return replaceId(node, parent);
|
||||
};
|
||||
|
||||
traverse(parent, replace);
|
||||
};
|
||||
@@ -1,19 +0,0 @@
|
||||
var util = require("../util");
|
||||
var b = require("acorn-ast-types").builders;
|
||||
|
||||
exports.Function = function (node, parent, file) {
|
||||
if (!node.rest) return;
|
||||
|
||||
var rest = node.rest;
|
||||
delete node.rest;
|
||||
|
||||
var templateName = "arguments-slice-assign";
|
||||
if (node.params.length) templateName += "-arg";
|
||||
|
||||
util.ensureBlock(node);
|
||||
node.body.body.unshift(util.template(templateName, {
|
||||
SLICE_KEY: file.addDeclaration("slice"),
|
||||
VARIABLE_NAME: rest,
|
||||
SLICE_ARG: b.literal(node.params.length)
|
||||
}));
|
||||
};
|
||||
@@ -1,15 +0,0 @@
|
||||
var b = require("acorn-ast-types").builders;
|
||||
|
||||
module.exports = function (ast, file) {
|
||||
var body = ast.program.body;
|
||||
var first = body[0];
|
||||
|
||||
var noStrict = !first || first.type !== "ExpressionStatement" || first.expression.type !== "Literal" || first.expression.value !== "use strict";
|
||||
|
||||
if (noStrict) {
|
||||
if (file.opts._noStrict) return;
|
||||
body.unshift(b.expressionStatement(b.literal("use strict")));
|
||||
} else {
|
||||
if (file.opts._noStrict) body.shift();
|
||||
}
|
||||
};
|
||||
@@ -1,24 +1,30 @@
|
||||
var VISITOR_KEYS = require("./visitor-keys");
|
||||
var _ = require("lodash");
|
||||
module.exports = traverse;
|
||||
|
||||
var traverse = module.exports = function (parent, callbacks, blacklistTypes) {
|
||||
var Scope = require("./scope");
|
||||
var t = require("../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
function traverse(parent, callbacks, opts) {
|
||||
// falsy node
|
||||
if (!parent) return;
|
||||
|
||||
// array of nodes
|
||||
if (_.isArray(parent)) {
|
||||
_.each(parent, function (node) {
|
||||
traverse(node, callbacks, blacklistTypes);
|
||||
traverse(node, callbacks, opts);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// unknown node type to traverse
|
||||
var keys = VISITOR_KEYS[parent.type];
|
||||
var keys = t.VISITOR_KEYS[parent.type];
|
||||
if (!keys) return;
|
||||
|
||||
opts = opts || {};
|
||||
if (_.isArray(opts)) opts = { blacklist: opts };
|
||||
|
||||
// blacklist these node types from being traversed
|
||||
blacklistTypes = blacklistTypes || [];
|
||||
var blacklistTypes = opts.blacklist || [];
|
||||
|
||||
// normalise callbacks
|
||||
if (_.isFunction(callbacks)) callbacks = { enter: callbacks };
|
||||
@@ -38,12 +44,17 @@ var traverse = module.exports = function (parent, callbacks, blacklistTypes) {
|
||||
|
||||
// replace node
|
||||
var maybeReplace = function (result) {
|
||||
if (result != null) obj[key] = result;
|
||||
if (result === false) return;
|
||||
if (result != null) node = obj[key] = result;
|
||||
};
|
||||
|
||||
//
|
||||
var opts2 = _.clone(opts);
|
||||
if (t.isScope(node)) opts2.scope = new Scope(opts.scope, node);
|
||||
|
||||
// enter
|
||||
if (callbacks.enter) {
|
||||
result = callbacks.enter(node, parent, obj, key);
|
||||
result = callbacks.enter(node, parent, opts2.scope);
|
||||
|
||||
// stop iteration
|
||||
if (result === false) return;
|
||||
@@ -52,11 +63,11 @@ var traverse = module.exports = function (parent, callbacks, blacklistTypes) {
|
||||
}
|
||||
|
||||
// traverse node
|
||||
traverse(node, callbacks, blacklistTypes);
|
||||
traverse(node, callbacks, opts2);
|
||||
|
||||
// exit
|
||||
if (callbacks.exit) {
|
||||
maybeReplace(callbacks.exit(node, parent, obj, key));
|
||||
maybeReplace(callbacks.exit(node, parent, opts2.scope));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -65,39 +76,39 @@ var traverse = module.exports = function (parent, callbacks, blacklistTypes) {
|
||||
handle(nodes, i);
|
||||
});
|
||||
|
||||
// remove deleted nodes
|
||||
parent[key] = _.flatten(parent[key]).filter(function (node) {
|
||||
return node !== traverse.Delete;
|
||||
});
|
||||
parent[key] = _.flatten(parent[key]);
|
||||
} else {
|
||||
handle(parent, key);
|
||||
|
||||
if (parent[key] === traverse.Delete) {
|
||||
throw new Error("trying to delete property " + key + " from " +
|
||||
parent.type + " but can't because it's required");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
traverse.removeProperties = function (tree) {
|
||||
var clear = function (node) {
|
||||
delete node.extendedRange;
|
||||
delete node._scopeIds;
|
||||
delete node._parent;
|
||||
delete node.tokens;
|
||||
delete node.range;
|
||||
delete node.start;
|
||||
delete node.end;
|
||||
delete node.loc;
|
||||
delete node.raw;
|
||||
|
||||
clearComments(node.trailingComments);
|
||||
clearComments(node.leadingComments);
|
||||
};
|
||||
|
||||
var clearComments = function (comments) {
|
||||
_.each(comments, clear);
|
||||
};
|
||||
|
||||
clear(tree);
|
||||
traverse(tree, clear);
|
||||
|
||||
return tree;
|
||||
};
|
||||
|
||||
traverse.FUNCTION_TYPES = ["ArrowFunctionExpression", "FunctionDeclaration", "FunctionExpression"];
|
||||
|
||||
traverse.aliases = {
|
||||
ArrowFunctionExpression: ["Function"],
|
||||
FunctionDeclaration: ["Function"],
|
||||
FunctionExpression: ["Function"]
|
||||
};
|
||||
|
||||
traverse.isFunction = function (node) {
|
||||
return _.contains(traverse.FUNCTION_TYPES, node.type);
|
||||
};
|
||||
|
||||
traverse.isPattern = function (node) {
|
||||
return node.type === "ArrayPattern" || node.type === "ObjectPattern";
|
||||
};
|
||||
|
||||
traverse.Delete = {};
|
||||
|
||||
traverse.hasType = function (tree, type, blacklistTypes) {
|
||||
blacklistTypes = [].concat(blacklistTypes || []);
|
||||
|
||||
@@ -105,7 +116,7 @@ traverse.hasType = function (tree, type, blacklistTypes) {
|
||||
|
||||
if (_.isArray(tree)) {
|
||||
// array of nodes, find the first
|
||||
return !!_.find(tree, function (node) {
|
||||
return tree.some(function (node) {
|
||||
return traverse.hasType(node, type, blacklistTypes);
|
||||
});
|
||||
} else {
|
||||
@@ -120,7 +131,7 @@ traverse.hasType = function (tree, type, blacklistTypes) {
|
||||
has = true;
|
||||
return false;
|
||||
}
|
||||
}, blacklistTypes);
|
||||
}, { blacklist: blacklistTypes });
|
||||
}
|
||||
|
||||
return has;
|
||||
|
||||
79
lib/6to5/traverse/scope.js
Normal file
79
lib/6to5/traverse/scope.js
Normal file
@@ -0,0 +1,79 @@
|
||||
module.exports = Scope;
|
||||
|
||||
var traverse = require("./index");
|
||||
var t = require("../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
function Scope(parent, block) {
|
||||
this.parent = parent;
|
||||
this.block = block;
|
||||
this.ids = this.getIds();
|
||||
|
||||
this.getIds();
|
||||
}
|
||||
|
||||
Scope.prototype.getIds = function () {
|
||||
var block = this.block;
|
||||
if (block._scopeIds) return block._scopeIds;
|
||||
|
||||
var self = this;
|
||||
var ids = block._scopeIds = {};
|
||||
|
||||
if (t.isBlockStatement(block)) {
|
||||
_.each(block.body, function (node) {
|
||||
if (t.isVariableDeclaration(node) && node.kind !== "var") {
|
||||
self.add(node, ids);
|
||||
}
|
||||
});
|
||||
} else if (t.isProgram(block) || t.isFunction(block)) {
|
||||
traverse(block, function (node, parent) {
|
||||
if (parent !== block && t.isVariableDeclaration(node) && node.kind !== "var") {
|
||||
return;
|
||||
}
|
||||
|
||||
if (t.isDeclaration(node)) {
|
||||
self.add(node, ids);
|
||||
} else if (t.isFunction(node)) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
} else if (t.isCatchClause(block)) {
|
||||
self.add(block.param, ids);
|
||||
}
|
||||
|
||||
if (t.isFunction(block)) {
|
||||
_.each(block.params, function (param) {
|
||||
self.add(param, ids);
|
||||
});
|
||||
}
|
||||
|
||||
return ids;
|
||||
};
|
||||
|
||||
Scope.prototype.add = function (node, ids) {
|
||||
_.merge(ids || this.ids, t.getIds(node, true));
|
||||
};
|
||||
|
||||
Scope.prototype.get = function (id) {
|
||||
return id && (this.getOwn(id) || this.parentGet(id));
|
||||
};
|
||||
|
||||
Scope.prototype.getOwn = function (id) {
|
||||
return _.has(this.ids, id) && this.ids[id];
|
||||
};
|
||||
|
||||
Scope.prototype.parentGet = function (id) {
|
||||
return this.parent && this.parent.get(id);
|
||||
};
|
||||
|
||||
Scope.prototype.has = function (id) {
|
||||
return id && (this.hasOwn(id) || this.parentHas(id));
|
||||
};
|
||||
|
||||
Scope.prototype.hasOwn = function (id) {
|
||||
return !!this.getOwn(id);
|
||||
};
|
||||
|
||||
Scope.prototype.parentHas = function (id) {
|
||||
return this.parent && this.parent.has(id);
|
||||
};
|
||||
@@ -1,86 +0,0 @@
|
||||
{
|
||||
"ArrayExpression": ["elements"],
|
||||
"ArrayPattern": ["elements"],
|
||||
"ArrowFunctionExpression": ["params", "defaults", "rest", "body"],
|
||||
"AssignmentExpression": ["left", "right"],
|
||||
"AwaitExpression": ["argument"],
|
||||
"BinaryExpression": ["left", "right"],
|
||||
"BlockStatement": ["body"],
|
||||
"BreakStatement": ["label"],
|
||||
"CallExpression": ["callee", "arguments"],
|
||||
"CatchClause": ["param", "body"],
|
||||
"ClassBody": ["body"],
|
||||
"ClassDeclaration": ["id", "body", "superClass"],
|
||||
"ClassExpression": ["id", "body", "superClass"],
|
||||
"ClassProperty": ["key", "value"],
|
||||
"ComprehensionBlock": ["left", "right", "body"],
|
||||
"ComprehensionExpression": ["filter", "blocks", "body"],
|
||||
"ConditionalExpression": ["test", "consequent", "alternate"],
|
||||
"ContinueStatement": ["label"],
|
||||
"DebuggerStatement": [],
|
||||
"DoWhileStatement": ["body", "test"],
|
||||
"EmptyStatement": [],
|
||||
"ExportDeclaration": ["declaration", "specifiers", "source"],
|
||||
"ExportBatchSpecifier": [],
|
||||
"ExportSpecifier": ["id", "name"],
|
||||
"ExpressionStatement": ["expression"],
|
||||
"File": ["program"],
|
||||
"ForInStatement": ["left", "right", "body"],
|
||||
"ForOfStatement": ["left", "right", "body"],
|
||||
"ForStatement": ["init", "test", "update", "body"],
|
||||
"FunctionDeclaration": ["id", "params", "defaults", "rest", "body"],
|
||||
"FunctionExpression": ["id", "params", "defaults", "rest", "body"],
|
||||
"Identifier": [],
|
||||
"IfStatement": ["test", "consequent", "alternate"],
|
||||
"ImportDeclaration": ["specifiers", "source"],
|
||||
"ImportDefaultSpecifier": ["id"],
|
||||
"ImportNamespaceSpecifier": ["id"],
|
||||
"ImportSpecifier": ["id", "name"],
|
||||
"LabeledStatement": ["label", "body"],
|
||||
"Literal": [],
|
||||
"LogicalExpression": ["left", "right"],
|
||||
"MemberExpression": ["object", "property"],
|
||||
"MethodDefinition": ["key", "value"],
|
||||
"ModuleSpecifier": [],
|
||||
"NewExpression": ["callee", "arguments"],
|
||||
"ObjectExpression": ["properties"],
|
||||
"ObjectPattern": ["properties"],
|
||||
"ObjectTypeAnnotation": ["properties"],
|
||||
"OptionalParameter": ["id"],
|
||||
"ParametricTypeAnnotation": ["params"],
|
||||
"ParametricallyTypedIdentifier": [],
|
||||
"Program": ["body"],
|
||||
"Property": ["key", "value"],
|
||||
"ReturnStatement": ["argument"],
|
||||
"SequenceExpression": ["expressions"],
|
||||
"SpreadElement": ["argument"],
|
||||
"SpreadProperty": ["argument"],
|
||||
"SwitchCase": ["test", "consequent"],
|
||||
"SwitchStatement": ["discriminant", "cases"],
|
||||
"TaggedTemplateExpression": ["tag", "quasi"],
|
||||
"TemplateElement": [],
|
||||
"TemplateLiteral": ["quasis", "expressions"],
|
||||
"ThisExpression": [],
|
||||
"ThrowStatement": ["argument"],
|
||||
"TryStatement": ["block", "handlers", "handler", "guardedHandlers", "finalizer"],
|
||||
"TypeAnnotatedIdentifier": ["id", "annotation"],
|
||||
"TypeAnnotation": ["id", "params", "returnType", "parametricType"],
|
||||
"UnaryExpression": ["argument"],
|
||||
"UpdateExpression": ["argument"],
|
||||
"VariableDeclaration": ["declarations"],
|
||||
"VariableDeclarator": ["id", "init"],
|
||||
"VoidTypeAnnotation": [],
|
||||
"WhileStatement": ["test", "body"],
|
||||
"WithStatement": ["object", "body"],
|
||||
"XJSIdentifier": [],
|
||||
"XJSNamespacedName": ["namespace", "name"],
|
||||
"XJSMemberExpression": ["object", "property"],
|
||||
"XJSEmptyExpression": [],
|
||||
"XJSExpressionContainer": ["expression"],
|
||||
"XJSElement": ["openingElement", "closingElement", "children"],
|
||||
"XJSClosingElement": ["name"],
|
||||
"XJSOpeningElement": ["name", "attributes"],
|
||||
"XJSAttribute": ["name", "value"],
|
||||
"XJSText": [],
|
||||
"YieldExpression": ["argument"]
|
||||
}
|
||||
46
lib/6to5/types/alias-keys.json
Normal file
46
lib/6to5/types/alias-keys.json
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"ExpressionStatement": ["Statement"],
|
||||
"BreakStatement": ["Statement"],
|
||||
"ContinueStatement": ["Statement"],
|
||||
"DebuggerStatement": ["Statement"],
|
||||
"DoWhileStatement": ["Statement"],
|
||||
"IfStatement": ["Statement"],
|
||||
"ReturnStatement": ["Statement"],
|
||||
"SwitchStatement": ["Statement"],
|
||||
"ThrowStatement": ["Statement"],
|
||||
"TryStatement": ["Statement"],
|
||||
"WhileStatement": ["Statement"],
|
||||
"WithStatement": ["Statement"],
|
||||
"EmptyStatement": ["Statement"],
|
||||
"LabeledStatement": ["Statement"],
|
||||
"VariableDeclaration": ["Statement", "Declaration"],
|
||||
"ExportDeclaration": ["Statement", "Declaration"],
|
||||
"ImportDeclaration": ["Statement", "Declaration"],
|
||||
|
||||
"ArrowFunctionExpression": ["Scope", "Function"],
|
||||
"FunctionDeclaration": ["Statement", "Declaration", "Scope", "Function"],
|
||||
"FunctionExpression": ["Scope", "Function"],
|
||||
|
||||
"BlockStatement": ["Statement", "Scope"],
|
||||
"Program": ["Scope"],
|
||||
"CatchClause": ["Scope"],
|
||||
|
||||
"LogicalExpression": ["Binary"],
|
||||
"BinaryExpression": ["Binary"],
|
||||
|
||||
"UnaryExpression": ["UnaryLike"],
|
||||
"SpreadProperty": ["UnaryLike"],
|
||||
"SpreadElement": ["UnaryLike"],
|
||||
|
||||
"ClassDeclaration": ["Statement", "Declaration", "Class"],
|
||||
"ClassExpression": ["Class"],
|
||||
|
||||
"ForOfStatement": ["Statement", "For"],
|
||||
"ForInStatement": ["Statement", "For"],
|
||||
"ForStatement": ["Statement", "For"],
|
||||
|
||||
"ObjectPattern": ["Pattern"],
|
||||
"ArrayPattern": ["Pattern"],
|
||||
|
||||
"Property": ["UserWhitespacable"]
|
||||
}
|
||||
24
lib/6to5/types/builder-keys.json
Normal file
24
lib/6to5/types/builder-keys.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"ArrayExpression": ["elements"],
|
||||
"AssignmentExpression": ["operator", "left", "right"],
|
||||
"BinaryExpression": ["operator", "left", "right"],
|
||||
"BlockStatement": ["body"],
|
||||
"CallExpression": ["callee", "arguments"],
|
||||
"ConditionalExpression": ["test", "consequent", "alternate"],
|
||||
"ExpressionStatement": ["expression"],
|
||||
"File": ["program", "comments", "tokens"],
|
||||
"FunctionExpression": ["id", "params", "body"],
|
||||
"Identifier": ["name"],
|
||||
"IfStatement": ["test", "consequent", "alternate"],
|
||||
"Literal": ["value"],
|
||||
"MemberExpression": ["object", "property", "computed"],
|
||||
"ObjectExpression": ["properties"],
|
||||
"ParenthesizedExpression": ["expression"],
|
||||
"Program": ["body"],
|
||||
"Property": ["kind", "key", "value", "computed"],
|
||||
"ReturnStatement": ["argument"],
|
||||
"SequenceExpression": ["expressions"],
|
||||
"UnaryExpression": ["operator", "argument", "prefix"],
|
||||
"VariableDeclaration": ["kind", "declarations"],
|
||||
"VariableDeclarator": ["id", "init"]
|
||||
}
|
||||
205
lib/6to5/types/index.js
Normal file
205
lib/6to5/types/index.js
Normal file
@@ -0,0 +1,205 @@
|
||||
var _ = require("lodash");
|
||||
|
||||
var t = exports;
|
||||
|
||||
//
|
||||
|
||||
t.VISITOR_KEYS = require("./visitor-keys");
|
||||
|
||||
_.each(t.VISITOR_KEYS, function (keys, type) {
|
||||
t["is" + type] = function (node, opts) {
|
||||
return node && node.type === type && t.shallowEqual(node, opts);
|
||||
};
|
||||
});
|
||||
|
||||
//
|
||||
|
||||
t.BUILDER_KEYS = _.defaults(require("./builder-keys"), t.VISITOR_KEYS);
|
||||
|
||||
_.each(t.BUILDER_KEYS, function (keys, type) {
|
||||
t[type[0].toLowerCase() + type.slice(1)] = function () {
|
||||
var args = arguments;
|
||||
var node = { type: type };
|
||||
_.each(keys, function (key, i) {
|
||||
node[key] = args[i];
|
||||
});
|
||||
return node;
|
||||
};
|
||||
});
|
||||
|
||||
//
|
||||
|
||||
t.ALIAS_KEYS = require("./alias-keys");
|
||||
|
||||
var _aliases = {};
|
||||
|
||||
_.each(t.ALIAS_KEYS, function (aliases, type) {
|
||||
_.each(aliases, function (alias) {
|
||||
var types = _aliases[alias] = _aliases[alias] || [];
|
||||
types.push(type);
|
||||
});
|
||||
});
|
||||
|
||||
_.each(_aliases, function (types, type) {
|
||||
t[type.toUpperCase() + "_TYPES"] = types;
|
||||
|
||||
t["is" + type] = function (node, opts) {
|
||||
return node && _.contains(types, node.type) && t.shallowEqual(node, opts);
|
||||
};
|
||||
});
|
||||
|
||||
//
|
||||
|
||||
t.shallowEqual = function (actual, expected) {
|
||||
var same = true;
|
||||
|
||||
if (expected) {
|
||||
_.each(expected, function (val, key) {
|
||||
if (actual[key] !== val) {
|
||||
return same = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return same;
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
t.isReferenced = function (node, parent) {
|
||||
// we're a property key so we aren't referenced
|
||||
if (t.isProperty(parent) && parent.key === node) return false;
|
||||
|
||||
var isMemberExpression = t.isMemberExpression(parent);
|
||||
|
||||
// we're in a member expression and we're the computed property so we're referenced
|
||||
var isComputedProperty = isMemberExpression && parent.property === node && parent.computed;
|
||||
|
||||
// we're in a member expression and we're the object so we're referenced
|
||||
var isObject = isMemberExpression && parent.object === node;
|
||||
|
||||
// we are referenced
|
||||
if (!isMemberExpression || isComputedProperty || isObject) return true;
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
t.toIdentifier = function (name) {
|
||||
if (t.isIdentifier(name)) return name.name;
|
||||
|
||||
// replace all non-valid identifiers with dashes
|
||||
name = name.replace(/[^a-zA-Z0-9]/g, "-");
|
||||
|
||||
// remove all dashes and numbers from start of name
|
||||
name = name.replace(/^[-0-9]+/, "");
|
||||
|
||||
// camel case
|
||||
name = name.replace(/[-_\s]+(.)?/g, function (match, c) {
|
||||
return c ? c.toUpperCase() : "";
|
||||
});
|
||||
|
||||
return name;
|
||||
};
|
||||
|
||||
t.ensureBlock = function (node) {
|
||||
node.body = t.toBlock(node.body, node);
|
||||
};
|
||||
|
||||
t.toStatement = function (node, ignore) {
|
||||
var mustHaveId = false;
|
||||
var newType;
|
||||
|
||||
if (t.isClass(node)) {
|
||||
mustHaveId = true;
|
||||
newType = "ClassDeclaration";
|
||||
} else if (t.isFunction(node)) {
|
||||
mustHaveId = true;
|
||||
newType = "FunctionDeclaration";
|
||||
} else if (t.isStatement(node)) {
|
||||
newType = node.type;
|
||||
}
|
||||
|
||||
if (mustHaveId && !node.id) {
|
||||
newType = false;
|
||||
}
|
||||
|
||||
if (!newType) {
|
||||
if (ignore) {
|
||||
return false;
|
||||
} else {
|
||||
throw new Error("cannot turn " + node.type + " to a statement");
|
||||
}
|
||||
}
|
||||
|
||||
node.type = newType;
|
||||
|
||||
return node;
|
||||
};
|
||||
|
||||
t.toBlock = function (node, parent) {
|
||||
if (t.isBlockStatement(node)) {
|
||||
return node;
|
||||
}
|
||||
|
||||
if (!_.isArray(node)) {
|
||||
if (!t.isStatement(node)) {
|
||||
if (t.isFunction(parent)) {
|
||||
node = t.returnStatement(node);
|
||||
} else {
|
||||
node = t.expressionStatement(node);
|
||||
}
|
||||
}
|
||||
|
||||
node = [node];
|
||||
}
|
||||
|
||||
return t.blockStatement(node);
|
||||
};
|
||||
|
||||
t.getIds = function (node, map) {
|
||||
var search = [node];
|
||||
var ids = {};
|
||||
|
||||
while (search.length) {
|
||||
var id = search.shift();
|
||||
|
||||
if (t.isIdentifier(id)) {
|
||||
ids[id.name] = id;
|
||||
} else if (t.isArrayPattern(id)) {
|
||||
_.each(id.elements, function (elem) {
|
||||
search.push(elem);
|
||||
});
|
||||
} else if (t.isAssignmentExpression(id)) {
|
||||
search.push(id.left);
|
||||
} else if (t.isObjectPattern(id)) {
|
||||
_.each(id.properties, function (prop) {
|
||||
search.push(prop.value);
|
||||
});
|
||||
} else if (t.isVariableDeclaration(id)) {
|
||||
search = search.concat(id.declarations);
|
||||
} else if (t.isImportSpecifier(id) || t.isExportSpecifier(id) || t.isVariableDeclarator(id) || t.isFunctionDeclaration(id) || t.isClassDeclaration(id)) {
|
||||
search.push(id.id);
|
||||
} else if (t.isSpreadElement(id)) {
|
||||
search.push(id.argument);
|
||||
} else if (t.isExportDeclaration(id) || t.isImportDeclaration(id)) {
|
||||
search = search.concat(id.specifiers);
|
||||
} else if (t.isMemberExpression(id)) {
|
||||
search.push(id.object);
|
||||
}
|
||||
}
|
||||
|
||||
if (!map) ids = _.keys(ids);
|
||||
return ids;
|
||||
};
|
||||
|
||||
t.inherits = function (child, parent) {
|
||||
child.loc = parent.loc;
|
||||
child.end = parent.end;
|
||||
child.range = parent.range;
|
||||
child.start = parent.start;
|
||||
return child;
|
||||
};
|
||||
|
||||
t.getSpecifierName = function (specifier) {
|
||||
return specifier.name || specifier.id;
|
||||
};
|
||||
75
lib/6to5/types/visitor-keys.json
Normal file
75
lib/6to5/types/visitor-keys.json
Normal file
@@ -0,0 +1,75 @@
|
||||
{
|
||||
"ArrayExpression": ["elements"],
|
||||
"ArrayPattern": ["elements"],
|
||||
"ArrowFunctionExpression": ["params", "defaults", "rest", "body"],
|
||||
"AssignmentExpression": ["left", "right"],
|
||||
"BinaryExpression": ["left", "right"],
|
||||
"BlockStatement": ["body"],
|
||||
"BreakStatement": ["label"],
|
||||
"CallExpression": ["callee", "arguments"],
|
||||
"CatchClause": ["param", "body"],
|
||||
"ClassBody": ["body"],
|
||||
"ClassDeclaration": ["id", "body", "superClass"],
|
||||
"ClassExpression": ["id", "body", "superClass"],
|
||||
"ComprehensionBlock": ["left", "right", "body"],
|
||||
"ComprehensionExpression": ["filter", "blocks", "body"],
|
||||
"ConditionalExpression": ["test", "consequent", "alternate"],
|
||||
"ContinueStatement": ["label"],
|
||||
"DebuggerStatement": [],
|
||||
"DoWhileStatement": ["body", "test"],
|
||||
"EmptyStatement": [],
|
||||
"ExportBatchSpecifier": [],
|
||||
"ExportDeclaration": ["declaration", "specifiers", "source"],
|
||||
"ExportSpecifier": ["id", "name"],
|
||||
"ExpressionStatement": ["expression"],
|
||||
"File": ["program"],
|
||||
"ForInStatement": ["left", "right", "body"],
|
||||
"ForOfStatement": ["left", "right", "body"],
|
||||
"ForStatement": ["init", "test", "update", "body"],
|
||||
"FunctionDeclaration": ["id", "params", "defaults", "rest", "body"],
|
||||
"FunctionExpression": ["id", "params", "defaults", "rest", "body"],
|
||||
"Identifier": [],
|
||||
"IfStatement": ["test", "consequent", "alternate"],
|
||||
"ImportBatchSpecifier": ["id"],
|
||||
"ImportDeclaration": ["specifiers", "source"],
|
||||
"ImportSpecifier": ["id", "name"],
|
||||
"LabeledStatement": ["label", "body"],
|
||||
"Literal": [],
|
||||
"LogicalExpression": ["left", "right"],
|
||||
"MemberExpression": ["object", "property"],
|
||||
"MethodDefinition": ["key", "value"],
|
||||
"NewExpression": ["callee", "arguments"],
|
||||
"ObjectExpression": ["properties"],
|
||||
"ObjectPattern": ["properties"],
|
||||
"ParenthesizedExpression": ["expression"],
|
||||
"Program": ["body"],
|
||||
"Property": ["key", "value"],
|
||||
"ReturnStatement": ["argument"],
|
||||
"SequenceExpression": ["expressions"],
|
||||
"SpreadElement": ["argument"],
|
||||
"SwitchCase": ["test", "consequent"],
|
||||
"SwitchStatement": ["discriminant", "cases"],
|
||||
"TaggedTemplateExpression": ["tag", "quasi"],
|
||||
"TemplateElement": [],
|
||||
"TemplateLiteral": ["quasis", "expressions"],
|
||||
"ThisExpression": [],
|
||||
"ThrowStatement": ["argument"],
|
||||
"TryStatement": ["block", "handlers", "handler", "guardedHandlers", "finalizer"],
|
||||
"UnaryExpression": ["argument"],
|
||||
"UpdateExpression": ["argument"],
|
||||
"VariableDeclaration": ["declarations"],
|
||||
"VariableDeclarator": ["id", "init"],
|
||||
"WhileStatement": ["test", "body"],
|
||||
"WithStatement": ["object", "body"],
|
||||
"XJSAttribute": ["name", "value"],
|
||||
"XJSClosingElement": ["name"],
|
||||
"XJSElement": ["openingElement", "closingElement", "children"],
|
||||
"XJSEmptyExpression": [],
|
||||
"XJSExpressionContainer": ["expression"],
|
||||
"XJSIdentifier": [],
|
||||
"XJSMemberExpression": ["object", "property"],
|
||||
"XJSNamespacedName": ["namespace", "name"],
|
||||
"XJSOpeningElement": ["name", "attributes"],
|
||||
"XJSSpreadAttribute": [],
|
||||
"YieldExpression": ["argument"]
|
||||
}
|
||||
275
lib/6to5/util.js
275
lib/6to5/util.js
@@ -1,28 +1,16 @@
|
||||
var traverse = require("./traverse");
|
||||
var astTypes = require("acorn-ast-types");
|
||||
var recast = require("acorn-recast");
|
||||
var path = require("path");
|
||||
var util = require("util");
|
||||
var fs = require("fs");
|
||||
var _ = require("lodash");
|
||||
require("./patch");
|
||||
|
||||
var n = astTypes.namedTypes;
|
||||
var b = astTypes.builders;
|
||||
var estraverse = require("estraverse");
|
||||
var traverse = require("./traverse");
|
||||
var acorn = require("acorn-6to5");
|
||||
var path = require("path");
|
||||
var util = require("util");
|
||||
var fs = require("fs");
|
||||
var t = require("./types");
|
||||
var _ = require("lodash");
|
||||
|
||||
exports.inherits = util.inherits;
|
||||
|
||||
exports.ensureBlock = function (node) {
|
||||
var block = node.body;
|
||||
if (block.type === "BlockStatement") return;
|
||||
|
||||
if (!_.isArray(block)) {
|
||||
if (!n.Statement.check(block)) block = b.returnStatement(block);
|
||||
block = [block];
|
||||
}
|
||||
|
||||
node.body = b.blockStatement(block);
|
||||
};
|
||||
|
||||
exports.resolve = function (loc) {
|
||||
try {
|
||||
return require.resolve(loc);
|
||||
@@ -35,34 +23,20 @@ exports.list = function (val) {
|
||||
return val ? val.split(",") : [];
|
||||
};
|
||||
|
||||
exports.getSpecifierName = function (specifier) {
|
||||
return specifier.name || specifier.id;
|
||||
};
|
||||
|
||||
exports.ensureExpressionType = function (node) {
|
||||
node.type = {
|
||||
FunctionDeclaration: "FunctionExpression",
|
||||
ClassDeclaration: "ClassExpression"
|
||||
}[node.type] || node.type;
|
||||
return node;
|
||||
};
|
||||
|
||||
exports.getUid = function (parent, file) {
|
||||
var node;
|
||||
|
||||
if (parent.type === "AssignmentExpression") {
|
||||
if (t.isAssignmentExpression(parent)) {
|
||||
node = parent.left;
|
||||
} else if (parent.type === "VariableDeclarator") {
|
||||
} else if (t.isVariableDeclarator(parent)) {
|
||||
node = parent.id;
|
||||
}
|
||||
|
||||
var id = "ref";
|
||||
|
||||
if (node && node.type === "Identifier") {
|
||||
id = node.name;
|
||||
}
|
||||
if (t.isIdentifier(node)) id = node.name;
|
||||
|
||||
return b.identifier(file.generateUid(id));
|
||||
return t.identifier(file.generateUid(id));
|
||||
};
|
||||
|
||||
exports.isAbsolute = function (loc) {
|
||||
@@ -72,54 +46,6 @@ exports.isAbsolute = function (loc) {
|
||||
return false;
|
||||
};
|
||||
|
||||
exports.removeProperties = function (tree) {
|
||||
var clear = function (node) {
|
||||
delete node.tokens;
|
||||
delete node.range;
|
||||
delete node.loc;
|
||||
};
|
||||
|
||||
clear(tree);
|
||||
traverse(tree, clear);
|
||||
|
||||
return tree;
|
||||
};
|
||||
|
||||
exports.getIds = function (node) {
|
||||
var search = [node];
|
||||
var ids = [];
|
||||
|
||||
while (search.length) {
|
||||
var id = search.shift();
|
||||
|
||||
if (id.type === "Identifier") {
|
||||
ids.push(id.name);
|
||||
} else if (id.type === "ArrayPattern") {
|
||||
_.each(id.elements, function (elem) {
|
||||
search.push(elem);
|
||||
});
|
||||
} else if (id.type === "ObjectPattern") {
|
||||
_.each(id.properties, function (prop) {
|
||||
search.push(prop.value);
|
||||
});
|
||||
} else {
|
||||
throw new Error("unknown node " + id.type);
|
||||
}
|
||||
}
|
||||
|
||||
return ids;
|
||||
};
|
||||
|
||||
exports.errorWithNode = function (node, msg) {
|
||||
var line = node.loc.start.line;
|
||||
var col = node.loc.start.column;
|
||||
|
||||
var err = new SyntaxError("Line " + line + ": " + msg);
|
||||
err.lineNumber = line;
|
||||
err.column = col;
|
||||
return err;
|
||||
};
|
||||
|
||||
exports.canCompile = function (filename) {
|
||||
var ext = path.extname(filename);
|
||||
return _.contains([".js", ".es6"], ext);
|
||||
@@ -132,42 +58,53 @@ exports.sourceMapToComment = function (map) {
|
||||
};
|
||||
|
||||
exports.pushMutatorMap = function (mutatorMap, key, kind, method) {
|
||||
var alias;
|
||||
|
||||
if (t.isIdentifier(key)) {
|
||||
alias = key.name;
|
||||
if (method.computed) alias = "computed:" + alias;
|
||||
} else if (t.isLiteral(key)) {
|
||||
alias = String(key.value);
|
||||
} else {
|
||||
alias = JSON.stringify(traverse.removeProperties(_.cloneDeep(key)));
|
||||
}
|
||||
|
||||
var map;
|
||||
if (_.has(mutatorMap, key)) {
|
||||
map = mutatorMap[key];
|
||||
if (_.has(mutatorMap, alias)) {
|
||||
map = mutatorMap[alias];
|
||||
} else {
|
||||
map = {};
|
||||
}
|
||||
mutatorMap[key] = map;
|
||||
mutatorMap[alias] = map;
|
||||
|
||||
if (map[kind]) {
|
||||
throw new Error("a " + kind + " already exists for this property");
|
||||
} else {
|
||||
map[kind] = method;
|
||||
map._key = key;
|
||||
if (method.computed) {
|
||||
map._computed = true;
|
||||
}
|
||||
|
||||
map[kind] = method;
|
||||
};
|
||||
|
||||
exports.buildDefineProperties = function (mutatorMap, keyNode) {
|
||||
var objExpr = b.objectExpression([]);
|
||||
exports.buildDefineProperties = function (mutatorMap) {
|
||||
var objExpr = t.objectExpression([]);
|
||||
|
||||
_.each(mutatorMap, function (map, key) {
|
||||
var mapNode = b.objectExpression([]);
|
||||
_.each(mutatorMap, function (map) {
|
||||
var mapNode = t.objectExpression([]);
|
||||
|
||||
var propNode = b.property("init", b.identifier(key), mapNode);
|
||||
var propNode = t.property("init", map._key, mapNode, map._computed);
|
||||
|
||||
_.each(map, function (node, key) {
|
||||
if (key[0] === "_") return;
|
||||
|
||||
node = _.clone(node);
|
||||
if (node.type === "MethodDefinition") node = node.value;
|
||||
mapNode.properties.push(b.property("init", b.identifier(key), node));
|
||||
if (t.isMethodDefinition(node)) node = node.value;
|
||||
mapNode.properties.push(t.property("init", t.identifier(key), node));
|
||||
});
|
||||
|
||||
objExpr.properties.push(propNode);
|
||||
});
|
||||
|
||||
return exports.template("object-define-properties", {
|
||||
OBJECT: keyNode,
|
||||
PROPS: objExpr
|
||||
}, true);
|
||||
return objExpr;
|
||||
};
|
||||
|
||||
exports.template = function (name, nodes, keepExpression) {
|
||||
@@ -176,54 +113,54 @@ exports.template = function (name, nodes, keepExpression) {
|
||||
|
||||
template = _.cloneDeep(template);
|
||||
|
||||
if (!_.isEmpty(nodes)) {
|
||||
traverse(template, function (node) {
|
||||
if (node.type === "Identifier" && _.has(nodes, node.name)) {
|
||||
var newNode = nodes[node.name];
|
||||
if (_.isString(newNode)) {
|
||||
node.name = newNode;
|
||||
} else {
|
||||
return newNode;
|
||||
var inherits = false;
|
||||
if (nodes) {
|
||||
inherits = nodes.inherits;
|
||||
delete nodes.inherits;
|
||||
|
||||
if (!_.isEmpty(nodes)) {
|
||||
traverse(template, function (node) {
|
||||
if (t.isIdentifier(node) && _.has(nodes, node.name)) {
|
||||
var newNode = nodes[node.name];
|
||||
if (_.isString(newNode)) {
|
||||
node.name = newNode;
|
||||
} else {
|
||||
return newNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var node = template.body[0];
|
||||
|
||||
if (!keepExpression && node.type === "ExpressionStatement") {
|
||||
return node.expression;
|
||||
} else {
|
||||
return node;
|
||||
if (!keepExpression && t.isExpressionStatement(node)) {
|
||||
node = node.expression;
|
||||
|
||||
if (t.isParenthesizedExpression(node)) node = node.expression;
|
||||
}
|
||||
};
|
||||
|
||||
exports.isReferenced = function (node, parent) {
|
||||
// we're a property key
|
||||
if (parent.type === "Property" && parent.key === node) return false;
|
||||
if (inherits) {
|
||||
node = t.inherits(node, inherits);
|
||||
}
|
||||
|
||||
var isMemberExpression = parent.type === "MemberExpression";
|
||||
|
||||
// we're in a member expression and we're the computed property so we're referenced
|
||||
var isComputedProperty = isMemberExpression && parent.property === node && parent.computed;
|
||||
|
||||
// we're in a member expression and we're the object so we're referenced
|
||||
var isObject = isMemberExpression && parent.object === node;
|
||||
|
||||
// we are referenced
|
||||
if (!isMemberExpression || isComputedProperty || isObject) return true;
|
||||
|
||||
return false;
|
||||
return node;
|
||||
};
|
||||
|
||||
exports.codeFrame = function (lines, lineNumber, colNumber) {
|
||||
colNumber = Math.max(colNumber, 0);
|
||||
|
||||
lines = lines.split("\n");
|
||||
|
||||
var start = Math.max(lineNumber - 3, 0);
|
||||
var end = Math.min(lines.length, lineNumber + 3);
|
||||
var width = (end + "").length;
|
||||
|
||||
if (!lineNumber && !colNumber) {
|
||||
start = 0;
|
||||
end = lines.length;
|
||||
}
|
||||
|
||||
return "\n" + lines.slice(start, end).map(function (line, i) {
|
||||
var curr = i + start + 1;
|
||||
|
||||
@@ -251,14 +188,26 @@ exports.repeat = function (width, cha) {
|
||||
|
||||
exports.parse = function (opts, code, callback) {
|
||||
try {
|
||||
var recastOpts = {};
|
||||
var comments = [];
|
||||
var tokens = [];
|
||||
|
||||
if (opts.sourceMap) {
|
||||
recastOpts.sourceFileName = opts.sourceFileName;
|
||||
recastOpts.sourceRoot = opts.sourceRoot;
|
||||
}
|
||||
var ast = acorn.parse(code, {
|
||||
preserveParens: true,
|
||||
ecmaVersion: Infinity,
|
||||
strictMode: true,
|
||||
onComment: comments,
|
||||
locations: true,
|
||||
onToken: tokens,
|
||||
ranges: true
|
||||
});
|
||||
|
||||
var ast = recast.parse(code, recastOpts);
|
||||
estraverse.attachComments(ast, comments, tokens);
|
||||
|
||||
ast = t.file(ast, comments, tokens);
|
||||
|
||||
traverse(ast, function (node, parent) {
|
||||
node._parent = parent;
|
||||
});
|
||||
|
||||
if (callback) {
|
||||
return callback(ast);
|
||||
@@ -268,12 +217,16 @@ exports.parse = function (opts, code, callback) {
|
||||
} catch (err) {
|
||||
if (!err._6to5) {
|
||||
err._6to5 = true;
|
||||
err.message = opts.filename + ": " + err.message;
|
||||
var message = opts.filename + ": " + err.message;
|
||||
|
||||
if (err.loc) {
|
||||
var frame = exports.codeFrame(code, err.loc.line, err.loc.column);
|
||||
err.message = err.message + frame;
|
||||
var loc = err.loc;
|
||||
if (loc) {
|
||||
var frame = exports.codeFrame(code, loc.line, loc.column);
|
||||
message += frame;
|
||||
}
|
||||
|
||||
if (err.stack) err.stack = err.stack.replace(err.message, message);
|
||||
err.message = message;
|
||||
}
|
||||
|
||||
throw err;
|
||||
@@ -282,21 +235,17 @@ exports.parse = function (opts, code, callback) {
|
||||
|
||||
exports.parseNoProperties = function (loc, code) {
|
||||
var ast = exports.parse({ filename: loc }, code).program;
|
||||
return exports.removeProperties(ast);
|
||||
return traverse.removeProperties(ast);
|
||||
};
|
||||
|
||||
try {
|
||||
exports.templates = require("../../templates.json");
|
||||
} catch (err) {
|
||||
if (err.code !== "MODULE_NOT_FOUND") throw err;
|
||||
|
||||
exports.templates = {};
|
||||
var loadTemplates = function () {
|
||||
var templates = {};
|
||||
|
||||
var templatesLoc = __dirname + "/templates";
|
||||
if (!fs.existsSync(templatesLoc)) {
|
||||
throw new Error("no templates directory - this is most likely the result" +
|
||||
" of a broken `npm publish`. Please report to " +
|
||||
"https://github.com/sebmck/6to5/issues");
|
||||
throw new Error("no templates directory - this is most likely the " +
|
||||
"result of a broken `npm publish`. Please report to " +
|
||||
"https://githut.com/6to5/6to5/issues");
|
||||
}
|
||||
|
||||
_.each(fs.readdirSync(templatesLoc), function (name) {
|
||||
@@ -306,6 +255,20 @@ try {
|
||||
var loc = templatesLoc + "/" + name;
|
||||
var code = fs.readFileSync(loc, "utf8");
|
||||
|
||||
exports.templates[key] = exports.parseNoProperties(loc, code);
|
||||
templates[key] = exports.parseNoProperties(loc, code);
|
||||
});
|
||||
|
||||
return templates;
|
||||
};
|
||||
|
||||
try {
|
||||
exports.templates = require("../../templates.json");
|
||||
} catch (err) {
|
||||
if (err.code !== "MODULE_NOT_FOUND") throw err;
|
||||
|
||||
Object.defineProperty(exports, "templates", {
|
||||
get: function () {
|
||||
return exports.templates = loadTemplates();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
24
package.json
24
package.json
@@ -1,21 +1,22 @@
|
||||
{
|
||||
"name": "6to5",
|
||||
"description": "Turn ES6 code into readable vanilla ES5 with source maps",
|
||||
"version": "1.10.1",
|
||||
"version": "1.11.1",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||
"homepage": "https://github.com/sebmck/6to5",
|
||||
"homepage": "https://github.com/6to5/6to5",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebmck/6to5.git"
|
||||
"url": "https://github.com/6to5/6to5.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/sebmck/6to5/issues"
|
||||
"url": "https://github.com/6to5/6to5/issues"
|
||||
},
|
||||
"preferGlobal": true,
|
||||
"main": "lib/6to5/index.js",
|
||||
"bin": {
|
||||
"6to5": "./bin/6to5/index.js",
|
||||
"6to5-node": "./bin/6to5-node"
|
||||
"6to5-node": "./bin/6to5-node",
|
||||
"6to5-runtime": "./bin/6to5-runtime"
|
||||
},
|
||||
"keywords": [
|
||||
"harmony",
|
||||
@@ -34,6 +35,7 @@
|
||||
"test": "make test"
|
||||
},
|
||||
"dependencies": {
|
||||
"ast-types": "~0.6.0",
|
||||
"commander": "2.4.0",
|
||||
"fs-readdir-recursive": "0.0.2",
|
||||
"lodash": "2.4.1",
|
||||
@@ -41,15 +43,13 @@
|
||||
"es6-shim": "0.18.0",
|
||||
"es6-symbol": "0.1.1",
|
||||
"regexpu": "0.3.0",
|
||||
"recast": "0.8.0",
|
||||
"source-map": "0.1.40",
|
||||
"regenerator": "0.6.7",
|
||||
"regenerator-6to5": "https://github.com/6to5/regenerator-6to5/archive/b7bc53e1a655879974aad53a8ceb93a70efaa08d.tar.gz",
|
||||
"chokidar": "0.10.0",
|
||||
"source-map-support": "0.2.7",
|
||||
"esutils": "1.1.4",
|
||||
"acorn-jsx": "https://github.com/sebmck/acorn-jsx/archive/master.tar.gz",
|
||||
"acorn-recast": "0.8.0-3",
|
||||
"acorn-ast-types": "0.5.3-1"
|
||||
"acorn-6to5": "https://github.com/6to5/acorn-6to5/archive/f5110383517eef0bea78c2da2a1fb01fbed74e4e.tar.gz",
|
||||
"estraverse": "^1.7.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"istanbul": "0.3.2",
|
||||
@@ -57,8 +57,8 @@
|
||||
"mocha": "1.21.5",
|
||||
"uglify-js": "2.4.15",
|
||||
"browserify": "6.1.0",
|
||||
"proclaim": "2.0.0",
|
||||
"rimraf": "2.2.8",
|
||||
"jshint": "2.5.6"
|
||||
"jshint": "2.5.6",
|
||||
"chai": "^1.9.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
require("./lib/6to5/polyfill");
|
||||
7
test/_browser.js
Normal file
7
test/_browser.js
Normal file
@@ -0,0 +1,7 @@
|
||||
if (process.browser) {
|
||||
require("../lib/6to5/browser");
|
||||
require("./generation");
|
||||
require("./transformation");
|
||||
require("./traverse");
|
||||
require("./util");
|
||||
}
|
||||
@@ -1,56 +1,32 @@
|
||||
var fs = require("fs");
|
||||
var _ = require("lodash");
|
||||
|
||||
var fixturesDir = __dirname + "/fixtures/transformation";
|
||||
|
||||
var humanise = function (val) {
|
||||
return val.replace(/-/g, " ");
|
||||
};
|
||||
|
||||
var readFile = function (filename) {
|
||||
if (fs.existsSync(filename)) {
|
||||
return fs.readFileSync(filename, "utf8");
|
||||
return fs.readFileSync(filename, "utf8").trim();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
||||
exports.run = function (suites, transform, assert) {
|
||||
_.each(suites, function (testSuite) {
|
||||
suite("transformation/" + testSuite.title, function () {
|
||||
_.each(testSuite.tests, function (task) {
|
||||
test(task.title, function () {
|
||||
var run = function () {
|
||||
transform.test(task, assert);
|
||||
};
|
||||
exports.get = function (entryName) {
|
||||
if (exports.cache[entryName]) return exports.cache[entryName];
|
||||
|
||||
var throwMsg = task.options.throws;
|
||||
if (throwMsg) {
|
||||
// internal api doesn't have this option but it's best not to pollute
|
||||
// the options object with useless options
|
||||
delete task.options.throws;
|
||||
|
||||
assert.throws(run, new RegExp(throwMsg));
|
||||
} else {
|
||||
run();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
exports.getTests = function () {
|
||||
var suites = [];
|
||||
var entryLoc = __dirname + "/fixtures/" + entryName;
|
||||
|
||||
_.each(fs.readdirSync(fixturesDir), function (suiteName) {
|
||||
_.each(fs.readdirSync(entryLoc), function (suiteName) {
|
||||
if (suiteName[0] === ".") return;
|
||||
|
||||
var suite = {
|
||||
options: {},
|
||||
tests: [],
|
||||
title: humanise(suiteName),
|
||||
filename: fixturesDir + "/" + suiteName
|
||||
filename: entryLoc + "/" + suiteName
|
||||
};
|
||||
suites.push(suite);
|
||||
|
||||
@@ -87,10 +63,12 @@ exports.getTests = function () {
|
||||
filename: execLocAlias,
|
||||
},
|
||||
actual: {
|
||||
loc: actualLoc,
|
||||
code: readFile(actualLoc),
|
||||
filename: actualLocAlias,
|
||||
},
|
||||
expect: {
|
||||
loc: expectLoc,
|
||||
code: readFile(expectLoc),
|
||||
filename: expectLocAlias
|
||||
}
|
||||
@@ -112,5 +90,15 @@ exports.getTests = function () {
|
||||
});
|
||||
});
|
||||
|
||||
return suites;
|
||||
return exports.cache[entryName] = suites;
|
||||
};
|
||||
|
||||
try {
|
||||
exports.cache = require("../tests.json");
|
||||
} catch (err) {
|
||||
if (err.code !== "MODULE_NOT_FOUND") throw err;
|
||||
|
||||
var cache = exports.cache = {};
|
||||
cache.transformation = exports.get("transformation");
|
||||
cache.generation = exports.get("generation");
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ var rimraf = require("rimraf");
|
||||
var mkdirp = require("mkdirp");
|
||||
var child = require("child_process");
|
||||
var path = require("path");
|
||||
var chai = require("chai");
|
||||
var fs = require("fs");
|
||||
var _ = require("lodash");
|
||||
|
||||
@@ -42,7 +43,7 @@ var assertTest = function (stdout, stderr, opts) {
|
||||
if (opts.stderrContains) {
|
||||
assert.ok(_.contains(stderr, expectStderr), "stderr " + JSON.stringify(stderr) + " didn't contain " + JSON.stringify(expectStderr));
|
||||
} else {
|
||||
assert.equal(stderr, expectStderr, "stderr didn't match");
|
||||
chai.expect(stderr).to.equal(expectStderr, "stderr didn't match");
|
||||
}
|
||||
} else if (stderr) {
|
||||
throw new Error("stderr: " + JSON.stringify(stderr));
|
||||
@@ -55,7 +56,7 @@ var assertTest = function (stdout, stderr, opts) {
|
||||
if (opts.stdoutContains) {
|
||||
assert.ok(_.contains(stdout, expectStdout), "stdout " + JSON.stringify(stdout) + " didn't contain " + JSON.stringify(expectStdout));
|
||||
} else {
|
||||
assert.equal(stdout, expectStdout, "stdout didn't match");
|
||||
chai.expect(stdout).to.equal(expectStdout, "stdout didn't match");
|
||||
}
|
||||
} else if (stdout) {
|
||||
throw new Error("stdout: " + JSON.stringify(stdout));
|
||||
@@ -63,7 +64,7 @@ var assertTest = function (stdout, stderr, opts) {
|
||||
|
||||
_.each(opts.outFiles, function (expect, filename) {
|
||||
var actual = readFile(filename);
|
||||
assert.equal(actual, expect, "out-file " + filename);
|
||||
chai.expect(actual).to.equal(expect, "out-file " + filename);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -6,10 +6,8 @@
|
||||
</head>
|
||||
<body>
|
||||
<div id="mocha"></div>
|
||||
<script src="../node_modules/proclaim/lib/proclaim.js"></script>
|
||||
<script src="../node_modules/lodash/lodash.js"></script>
|
||||
<script src="../node_modules/mocha/mocha.js"></script>
|
||||
<script src="../dist/6to5.js"></script>
|
||||
<script>mocha.setup("tdd");</script>
|
||||
<script src="../dist/6to5-test.js"></script>
|
||||
<script>
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
arr.map(x => x * MULTIPLIER);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
let MULTIPLER = 5;
|
||||
arr.map(function(x) {
|
||||
arr.map(function (x) {
|
||||
return x * MULTIPLIER;
|
||||
});
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
"use strict";
|
||||
|
||||
var Test = function() {
|
||||
var Test = function Test() {};
|
||||
return Test;
|
||||
}();
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3JjL2Jhci9iYXIuanMiLCJzb3VyY2VzIjpbInNyYy9iYXIvYmFyLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0lBQU0sQ0FBQyxDQUFDLENBQUM7TUFBSCxDQUFDLENBQUMsQ0FBQyxhQUFILENBQUMsQ0FBQyxDQUFDO1NBQUgsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJjbGFzcyBUZXN0IHtcblxufSJdfQ==
|
||||
var Test = function Test() {};
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNyYy9iYXIvYmFyLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0lBQU0sSUFBSSxZQUFKLElBQUkiLCJmaWxlIjoic3JjL2Jhci9iYXIuanMiLCJzb3VyY2VzQ29udGVudCI6WyJjbGFzcyBUZXN0IHtcblxufSJdfQ==
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"use strict";
|
||||
arr.map(function(x) {
|
||||
|
||||
arr.map(function (x) {
|
||||
return x * MULTIPLIER;
|
||||
});
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3JjL2Zvby5qcyIsInNvdXJjZXMiOlsic3JjL2Zvby5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFDO1NBQUssRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0NBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImFyci5tYXAoeCA9PiB4ICogTVVMVElQTElFUik7Il19
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNyYy9mb28uanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxHQUFHLENBQUMsR0FBRyxDQUFDLFVBQUEsQ0FBQztTQUFJLENBQUMsR0FBRyxVQUFVO0NBQUEsQ0FBQyxDQUFDIiwiZmlsZSI6InNyYy9mb28uanMiLCJzb3VyY2VzQ29udGVudCI6WyJhcnIubWFwKHggPT4geCAqIE1VTFRJUExJRVIpOyJdfQ==
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
var Test = function() {
|
||||
var Test = function Test() {};
|
||||
return Test;
|
||||
}();
|
||||
var Test = function Test() {};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user