Compare commits
511 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
86a49e2b1d | ||
|
|
5cd8822888 | ||
|
|
420492388b | ||
|
|
d5be4bb5b9 | ||
|
|
d6dc29ec6a | ||
|
|
f3e77c7a0d | ||
|
|
b08012cf12 | ||
|
|
ef275da1c2 | ||
|
|
cc6eb50f28 | ||
|
|
a260b6859f | ||
|
|
eb182ccbe0 | ||
|
|
fe1e99c799 | ||
|
|
deeb75a5d1 | ||
|
|
961d482269 | ||
|
|
1c8f0dcab4 | ||
|
|
5dc39439ed | ||
|
|
58e029a064 | ||
|
|
01ea72790d | ||
|
|
118ac2e62d | ||
|
|
3207a387a7 | ||
|
|
90a5b96480 | ||
|
|
74cf5ac552 | ||
|
|
dce1a3548c | ||
|
|
d67ba39d1c | ||
|
|
894c3fe481 | ||
|
|
27cce1446c | ||
|
|
7e64bcd85a | ||
|
|
4a851130ee | ||
|
|
6a9b14563e | ||
|
|
4f11c6a4be | ||
|
|
d7a669e96b | ||
|
|
4b6a5f4ea9 | ||
|
|
9c60c633d2 | ||
|
|
3b428e45a3 | ||
|
|
d961e2d291 | ||
|
|
2d884c282a | ||
|
|
350a3b664f | ||
|
|
9e4ec19487 | ||
|
|
d613975feb | ||
|
|
77e9387c5f | ||
|
|
ac00de44a7 | ||
|
|
8e03a2b720 | ||
|
|
4e660f7b3e | ||
|
|
63618f876c | ||
|
|
155f3407bc | ||
|
|
bf62042fe6 | ||
|
|
2a226b3a2b | ||
|
|
f996d6bfa6 | ||
|
|
89b1c387a0 | ||
|
|
dfea7368e1 | ||
|
|
06867dd52b | ||
|
|
3f72a4b200 | ||
|
|
ee286ed482 | ||
|
|
8604c0c2cd | ||
|
|
b2476b3603 | ||
|
|
c2ebe7f26d | ||
|
|
4809747304 | ||
|
|
e572d25640 | ||
|
|
07e3d9a8df | ||
|
|
7763c74563 | ||
|
|
e45dc0fbaf | ||
|
|
8539182452 | ||
|
|
18380d2aee | ||
|
|
19b1032474 | ||
|
|
f7761982cd | ||
|
|
950d3d2280 | ||
|
|
12d7b33f62 | ||
|
|
f9c7d0d095 | ||
|
|
efaa0608af | ||
|
|
b522bfe822 | ||
|
|
9efb02f60f | ||
|
|
9805c0387f | ||
|
|
81019ec76d | ||
|
|
b0d0adda9b | ||
|
|
d335535f04 | ||
|
|
f738c95c8d | ||
|
|
7fec1c98e5 | ||
|
|
33ae022e4d | ||
|
|
eac9e9b372 | ||
|
|
eb6b38d3a8 | ||
|
|
8111ab28d7 | ||
|
|
ed25845152 | ||
|
|
457638e904 | ||
|
|
2e5255dbf5 | ||
|
|
86095d9dac | ||
|
|
02dd785d02 | ||
|
|
205fab2ed8 | ||
|
|
d01b26951b | ||
|
|
fc15c91b2a | ||
|
|
421b01865f | ||
|
|
af7510adec | ||
|
|
ec7c40fbf6 | ||
|
|
4a36a9fb31 | ||
|
|
4d25b0d96a | ||
|
|
babc9c90b4 | ||
|
|
288293ca11 | ||
|
|
a262e99abd | ||
|
|
b518394a3f | ||
|
|
337c51df5c | ||
|
|
0509fb148f | ||
|
|
bb5f1120b7 | ||
|
|
38d46012a7 | ||
|
|
cdb8e3aefa | ||
|
|
4a84cd785a | ||
|
|
f47d17345c | ||
|
|
8746ca8d31 | ||
|
|
76e954bc36 | ||
|
|
64903d0dcf | ||
|
|
1fd0b1f741 | ||
|
|
cda2bfce38 | ||
|
|
0e4bb5ee3f | ||
|
|
e9793b1f16 | ||
|
|
224db29c05 | ||
|
|
bd1bd38556 | ||
|
|
1f39114126 | ||
|
|
4c0b8599f1 | ||
|
|
848909620c | ||
|
|
c40215497d | ||
|
|
6450f5263e | ||
|
|
74c59c94ce | ||
|
|
3f38a83600 | ||
|
|
1945f849c3 | ||
|
|
5b0b7ba226 | ||
|
|
42de6bc716 | ||
|
|
fb66f347b9 | ||
|
|
5e28bd4e68 | ||
|
|
9869566963 | ||
|
|
4a27b10e8a | ||
|
|
c3b5ed5b3d | ||
|
|
afa4871a08 | ||
|
|
70c739250b | ||
|
|
722e706a8c | ||
|
|
f3973c8397 | ||
|
|
47c3792d34 | ||
|
|
456accb4b3 | ||
|
|
72771ed439 | ||
|
|
7cb7ea4248 | ||
|
|
301df15921 | ||
|
|
15535406bd | ||
|
|
63f53e3773 | ||
|
|
03a979a6bd | ||
|
|
910622e66e | ||
|
|
c5a8702021 | ||
|
|
336c65fe2c | ||
|
|
092d98fb27 | ||
|
|
e55ce575cd | ||
|
|
d63ae5fce8 | ||
|
|
541309c4bb | ||
|
|
2d289150d1 | ||
|
|
b9f6169ed4 | ||
|
|
ce372281cd | ||
|
|
0044100e3d | ||
|
|
81edc4c6ab | ||
|
|
3b1a9a0adb | ||
|
|
8ab90aacd3 | ||
|
|
a1a46882fd | ||
|
|
12b4e6db40 | ||
|
|
7f06bb79c0 | ||
|
|
34218afdae | ||
|
|
b94118db5e | ||
|
|
54819b94e9 | ||
|
|
50ca6b1018 | ||
|
|
2d195c4843 | ||
|
|
2f0d0c94ef | ||
|
|
5e3ea5b6e7 | ||
|
|
95128f98bc | ||
|
|
c4d1d58167 | ||
|
|
7da1d9fadd | ||
|
|
6ab57fd367 | ||
|
|
d4edce6559 | ||
|
|
9c8cb33a09 | ||
|
|
a2fb70bae3 | ||
|
|
273a81fe1f | ||
|
|
72a0ac5e02 | ||
|
|
c5ace10536 | ||
|
|
b833614b87 | ||
|
|
ae067a08b7 | ||
|
|
f56337541f | ||
|
|
1fe8447a1a | ||
|
|
13bbfa041d | ||
|
|
c43bbb9bf6 | ||
|
|
1bca59a921 | ||
|
|
f80fdf7359 | ||
|
|
aefd69d31e | ||
|
|
e328031b19 | ||
|
|
571b6a4cd7 | ||
|
|
41cf942391 | ||
|
|
98f28b8e89 | ||
|
|
8f88afc037 | ||
|
|
6359675a4f | ||
|
|
a265c3f25c | ||
|
|
29eb99ee93 | ||
|
|
0c5c1ff989 | ||
|
|
499951123a | ||
|
|
c0fd4c1f9e | ||
|
|
579e6fecee | ||
|
|
bb3665a3b6 | ||
|
|
e6de688234 | ||
|
|
4c233e88ff | ||
|
|
ae2ba0b5a3 | ||
|
|
e34d950793 | ||
|
|
e4083fbbd7 | ||
|
|
59ed7977ef | ||
|
|
dc441e9a8f | ||
|
|
2e21795f57 | ||
|
|
5c988f7fc8 | ||
|
|
493826973e | ||
|
|
1acc71aa4e | ||
|
|
bbab5f72ec | ||
|
|
58ff9e387a | ||
|
|
5a0d099984 | ||
|
|
05c95e04f7 | ||
|
|
88430b4be2 | ||
|
|
19adcfae4d | ||
|
|
7c4fe984ce | ||
|
|
4476e8311c | ||
|
|
2a3142273d | ||
|
|
bbcb889a49 | ||
|
|
c87f85815b | ||
|
|
48d0df17d0 | ||
|
|
01b243347f | ||
|
|
45a5cbf72f | ||
|
|
05efae1c58 | ||
|
|
c08fff4b44 | ||
|
|
13e910ea83 | ||
|
|
b308602098 | ||
|
|
560a044d8f | ||
|
|
619fbe4c3b | ||
|
|
1d83ad6cce | ||
|
|
5353ccd773 | ||
|
|
a8e23d2eb9 | ||
|
|
95d830fde0 | ||
|
|
c8a5d7d970 | ||
|
|
43481eb2cc | ||
|
|
b8bb665691 | ||
|
|
e6846b2730 | ||
|
|
31c1286a3c | ||
|
|
489f9e92b5 | ||
|
|
073809efac | ||
|
|
c9b8e2f3ce | ||
|
|
c6cb871355 | ||
|
|
1b0e5b3ed1 | ||
|
|
0f70c76312 | ||
|
|
e8c672bf4f | ||
|
|
7083ac61ff | ||
|
|
d256809120 | ||
|
|
26a19f82d2 | ||
|
|
128d3b5c91 | ||
|
|
c1a080d0ca | ||
|
|
0b1ce6c9a4 | ||
|
|
a6f04055c0 | ||
|
|
c3219e8b88 | ||
|
|
a35c863341 | ||
|
|
6f862a4c45 | ||
|
|
cf38210fd2 | ||
|
|
5c9d564339 | ||
|
|
031a61515b | ||
|
|
d3884fd53b | ||
|
|
c6eef3080e | ||
|
|
25be0a974d | ||
|
|
7ccd135e83 | ||
|
|
4fc1bbeb60 | ||
|
|
32a4d7172b | ||
|
|
aa25903c05 | ||
|
|
23ec1a455e | ||
|
|
e6ac2d049b | ||
|
|
084ae31816 | ||
|
|
8e530afd78 | ||
|
|
6c66a82b37 | ||
|
|
737abca3a9 | ||
|
|
9db43ca7a9 | ||
|
|
25b0683316 | ||
|
|
a096f6b1c5 | ||
|
|
e41ab2ab0c | ||
|
|
6a6764fa7b | ||
|
|
a2358d6863 | ||
|
|
612ef79d35 | ||
|
|
2dfa6ddf36 | ||
|
|
2910d4f82c | ||
|
|
4b6c954f5e | ||
|
|
b7e23e3410 | ||
|
|
a19f10e124 | ||
|
|
8e1f134635 | ||
|
|
aa151016f5 | ||
|
|
ce3c6289a2 | ||
|
|
0364519869 | ||
|
|
58cda35831 | ||
|
|
ebaa06f4a2 | ||
|
|
4b0f624fb3 | ||
|
|
aa0f3ac5d0 | ||
|
|
725906a7dc | ||
|
|
13d5c94b8b | ||
|
|
85308a1e8c | ||
|
|
83bcaba1a5 | ||
|
|
185648cb2c | ||
|
|
be355fc1c6 | ||
|
|
7795e11d58 | ||
|
|
8f74e8068c | ||
|
|
4f08a77230 | ||
|
|
4ac33d62af | ||
|
|
2710a914e8 | ||
|
|
8934e7f9da | ||
|
|
b4f18e05fa | ||
|
|
c07540a2c4 | ||
|
|
c409f63bbe | ||
|
|
d3c30b669f | ||
|
|
d10856d16c | ||
|
|
fb08a519c8 | ||
|
|
6a8ecf2507 | ||
|
|
100317e0c8 | ||
|
|
a32f744341 | ||
|
|
c4feff3cb7 | ||
|
|
498297ce6b | ||
|
|
2412c1d502 | ||
|
|
d92e1a4fb8 | ||
|
|
1d0d050413 | ||
|
|
a607ac0077 | ||
|
|
41f5e7c077 | ||
|
|
99604362ed | ||
|
|
2c8e374eaf | ||
|
|
238c68f829 | ||
|
|
09b334ad21 | ||
|
|
d647ede94b | ||
|
|
6386b60b9a | ||
|
|
25749a9933 | ||
|
|
fd4c0dae95 | ||
|
|
80d362c534 | ||
|
|
59820b9a84 | ||
|
|
f6ff366edf | ||
|
|
c7cac7aaba | ||
|
|
0647d374a3 | ||
|
|
25c2816a85 | ||
|
|
b57a80ecae | ||
|
|
574d47a571 | ||
|
|
7c5d2b19b7 | ||
|
|
c7669f44c1 | ||
|
|
0ed5c5f480 | ||
|
|
94c34e0132 | ||
|
|
92c4bbd003 | ||
|
|
ec8e840841 | ||
|
|
1c3c64c12c | ||
|
|
cae80d6e9b | ||
|
|
aaf29ddd82 | ||
|
|
fb485567b9 | ||
|
|
050bcec617 | ||
|
|
6231015557 | ||
|
|
822eb47ee7 | ||
|
|
91161ae9a1 | ||
|
|
4c1b4b6490 | ||
|
|
e792256087 | ||
|
|
19ad22f6e8 | ||
|
|
01818a50fa | ||
|
|
3247851019 | ||
|
|
939c00d33c | ||
|
|
8b096ac705 | ||
|
|
30c4a0cf06 | ||
|
|
e08d400b36 | ||
|
|
7e080aa9d2 | ||
|
|
c0e5059634 | ||
|
|
f8f5684faa | ||
|
|
2c3e9fbc07 | ||
|
|
b9d066d953 | ||
|
|
94e15b0750 | ||
|
|
3256c1d120 | ||
|
|
eba9f0ffbd | ||
|
|
52c3c143f9 | ||
|
|
b0f797205b | ||
|
|
dd52c6a687 | ||
|
|
3cf773b528 | ||
|
|
98424f80af | ||
|
|
708879ff1b | ||
|
|
70042bb0a8 | ||
|
|
0f7711a202 | ||
|
|
27f039488e | ||
|
|
e3ce82e12f | ||
|
|
4934ea56a0 | ||
|
|
ce03457b19 | ||
|
|
1298c67949 | ||
|
|
668274edcb | ||
|
|
0694a7dd06 | ||
|
|
20d19735fc | ||
|
|
b5b6bf4ad5 | ||
|
|
844c10cac0 | ||
|
|
43583e4e9d | ||
|
|
f5b921cda9 | ||
|
|
763892aa79 | ||
|
|
3e6eae4d1a | ||
|
|
7c090c8580 | ||
|
|
a5f6c1c389 | ||
|
|
c159f2d982 | ||
|
|
9205f10244 | ||
|
|
4cd7bcad59 | ||
|
|
7e9660efd3 | ||
|
|
2d66ce5224 | ||
|
|
1257b2cf40 | ||
|
|
f21d935de5 | ||
|
|
2e20364793 | ||
|
|
e47e8a187a | ||
|
|
26924d5944 | ||
|
|
5eb1850a55 | ||
|
|
333e287226 | ||
|
|
80a77bd6a2 | ||
|
|
c9286a1de1 | ||
|
|
52f614dcdf | ||
|
|
600367ae25 | ||
|
|
b761cba135 | ||
|
|
947d3e262d | ||
|
|
4061bea528 | ||
|
|
de195e5bfc | ||
|
|
3bcef86973 | ||
|
|
fa670ac71e | ||
|
|
572261f9ce | ||
|
|
8a320d53a5 | ||
|
|
0650eedeb6 | ||
|
|
2282d066a2 | ||
|
|
f4d7cc55c1 | ||
|
|
eaaa279aa5 | ||
|
|
0595e06e29 | ||
|
|
9b27a170ae | ||
|
|
1db232da9e | ||
|
|
4cc844f410 | ||
|
|
024ae670cb | ||
|
|
429edda9c0 | ||
|
|
05b13b9ea3 | ||
|
|
b7320ce400 | ||
|
|
0c37b7b973 | ||
|
|
bb36dbd8d9 | ||
|
|
2dd8c40618 | ||
|
|
33128b0ccf | ||
|
|
cf25424295 | ||
|
|
7492074794 | ||
|
|
c4a491123e | ||
|
|
55ad88fe4e | ||
|
|
7170dbced8 | ||
|
|
b0971412a2 | ||
|
|
a6b374a681 | ||
|
|
2d0355b3b9 | ||
|
|
7fade101be | ||
|
|
0918da8569 | ||
|
|
917db622c4 | ||
|
|
f7ee6fbd20 | ||
|
|
5899e9a0be | ||
|
|
d41cb11545 | ||
|
|
3ad909a4ae | ||
|
|
4bafdf733c | ||
|
|
b825998c63 | ||
|
|
6b02ca47c3 | ||
|
|
ea1b85bffa | ||
|
|
3cffe47eea | ||
|
|
e5d5a9fb27 | ||
|
|
ca97fa63a9 | ||
|
|
f4cc27bc0e | ||
|
|
8cea575e2e | ||
|
|
c91baee4d5 | ||
|
|
8055ce29f7 | ||
|
|
4596ae48b8 | ||
|
|
6c268cdf21 | ||
|
|
fce977f1d7 | ||
|
|
a298075949 | ||
|
|
66599c3779 | ||
|
|
60340244b1 | ||
|
|
eb72ea3e5a | ||
|
|
ede6237b6f | ||
|
|
e91e10aae6 | ||
|
|
9c3cca0d25 | ||
|
|
8eee5367f3 | ||
|
|
40d55a3d44 | ||
|
|
75330304dc | ||
|
|
776c508418 | ||
|
|
e804741632 | ||
|
|
3d3cb4be4f | ||
|
|
64f4209119 | ||
|
|
2ede226ef9 | ||
|
|
f5cf641c0a | ||
|
|
1abd3419f6 | ||
|
|
75699db716 | ||
|
|
7c3572f08c | ||
|
|
9dacde6d07 | ||
|
|
8c3aab9a26 | ||
|
|
ba4550c953 | ||
|
|
d0ac65a934 | ||
|
|
a4c70bb029 | ||
|
|
795cf0c0b1 | ||
|
|
e64b90e322 | ||
|
|
d69b0973e1 | ||
|
|
6296f49653 | ||
|
|
9f2b739046 | ||
|
|
da1d5e5577 | ||
|
|
7333b4e392 | ||
|
|
b0442d0784 | ||
|
|
295e69f8f8 | ||
|
|
cfe844fa39 | ||
|
|
0f4ea2d2a6 | ||
|
|
4b85b05839 | ||
|
|
2539d08dce | ||
|
|
c26fd7a819 | ||
|
|
2053610429 | ||
|
|
cd4f83b299 | ||
|
|
ec29ba19a9 | ||
|
|
9dc03e0978 | ||
|
|
bc4258eca9 | ||
|
|
b0e58f9770 | ||
|
|
a1e2641c91 | ||
|
|
9108422f99 | ||
|
|
9e8f4b25ca | ||
|
|
1cecd24823 | ||
|
|
97f6e1469b | ||
|
|
ec46eaf224 | ||
|
|
a102692103 | ||
|
|
0376ec8ff0 | ||
|
|
5932a07610 |
3
.babelrc
3
.babelrc
@@ -2,5 +2,6 @@
|
||||
"stage": 0,
|
||||
"loose": ["all"],
|
||||
"blacklist": ["es6.tailCall"],
|
||||
"optional": ["optimisation.flow.forOf"]
|
||||
"optional": ["optimisation.flow.forOf"],
|
||||
"plugins": ["./tools/build-plugins/protect"]
|
||||
}
|
||||
|
||||
@@ -17,7 +17,9 @@
|
||||
"no-fallthrough": 0,
|
||||
"new-cap": 0,
|
||||
"no-loop-func": 0,
|
||||
"no-unreachable": 0
|
||||
"no-unreachable": 0,
|
||||
"no-labels": 0,
|
||||
"no-process-exit": 0
|
||||
},
|
||||
"env": {
|
||||
"node": true
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -15,3 +15,4 @@ test/core/tmp
|
||||
/packages/babel-runtime/helpers/*.js
|
||||
/packages/babel-runtime/regenerator/*.js
|
||||
/lib
|
||||
_babel.github.io
|
||||
|
||||
@@ -13,3 +13,4 @@
|
||||
/vendor
|
||||
/packages
|
||||
/src
|
||||
_babel.github.io
|
||||
|
||||
40
.travis.yml
40
.travis.yml
@@ -1,19 +1,35 @@
|
||||
#sudo: false
|
||||
language: node_js
|
||||
cache:
|
||||
directories:
|
||||
- node_modules
|
||||
- node_modules
|
||||
node_js:
|
||||
- "0.12"
|
||||
- "iojs"
|
||||
- "0.10"
|
||||
- "0.12"
|
||||
- iojs
|
||||
|
||||
before_script: "npm install -g codeclimate-test-reporter"
|
||||
script: "make test-travis"
|
||||
before_script: ./tools/setup-git.sh
|
||||
script: make test-travis
|
||||
after_success: ./tools/merge-development-with-master.sh
|
||||
|
||||
notifications:
|
||||
webhooks:
|
||||
urls:
|
||||
- https://webhooks.gitter.im/e/acf1870e9d223c65e8d5
|
||||
on_success: always
|
||||
on_failure: always
|
||||
on_start: false
|
||||
slack: babeljs:5Wy4QX13KVkGy9CnU0rmvgeK
|
||||
|
||||
before_deploy:
|
||||
- make prepublish
|
||||
|
||||
deploy:
|
||||
provider: npm
|
||||
email: sebmck@gmail.com
|
||||
skip_cleanup: true
|
||||
api_key:
|
||||
secure: Q/pZStwherdYPCqCa0aUuiEktLcx6ccBxieyH8j9IXdDgty0ydmnajZfUnlZuCjN13XI9esM44nSJFTWZvntTryDQAQm37c63VXhAEnw/qrAINI06yt0gLBTT69/fKvIAkH8l48nmW32ZS2dse3rHRPZF1CwyQLC/pdMip8I4sM=
|
||||
on:
|
||||
branch: master
|
||||
tags: true
|
||||
repo: babel/babel
|
||||
|
||||
after_deploy:
|
||||
- make publish-cli
|
||||
- make publish-runtime
|
||||
- make build-website
|
||||
- make comment-issues
|
||||
|
||||
170
CHANGELOG.md
170
CHANGELOG.md
@@ -9,10 +9,178 @@
|
||||
> - [Internal]
|
||||
> - [Polish]
|
||||
|
||||
_Note: Gaps between patch versions are faulty/broken releases._
|
||||
_Note: Gaps between patch versions are faulty, broken or test releases._
|
||||
|
||||
See [CHANGELOG - 6to5](CHANGELOG-6to5.md) for the pre-4.0.0 version changelog.
|
||||
|
||||
## 5.6.19
|
||||
|
||||
* Removed do expressions.
|
||||
|
||||
## 5.6.17
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix `CodeGenerator.findCommonStringDelimiter` causing a stack overflow.
|
||||
|
||||
## 5.6.16
|
||||
|
||||
* **Internal**
|
||||
* Fix `recast` version to avoid pulling in a newer version.
|
||||
* **New Feature**
|
||||
* Add support for functions in `util.shouldIgnore`.
|
||||
* **Polish**
|
||||
* Strip flow directives in flow transformer.
|
||||
* Add a check for out of bounds default parameters, drastically improving performance and removes engine deoptimisations.
|
||||
* Various performance optimisations by [@samccone](https://github.com/samccone) 💅✨
|
||||
* Delay `this` assignment when referencing this inside an arrow function pre-bare super in derived class constructors.
|
||||
* Split up class body pushing if the constructor is in the wrong order.
|
||||
* **Bug Fix**
|
||||
* Fix hoisting of `ForInStatement` `init` variables in `system` module formatter.
|
||||
* `PathHoister`: Don't hoist to the same function as their original paths function parent.
|
||||
* `PathHoister`: Push each violation paths ancestry to the breakOnScopePaths collection to avoid constant hoisting to nested paths.fix tail call recursion on functions with less arguments than parameters.
|
||||
* Disallow `super.*` before `super()` in derived class constructors.
|
||||
* Properly regenerate scope for replaced nodes. Thanks [@loganfsmyth](https://github.com/loganfsmyth)!
|
||||
* Move up template literal simplification logic to avoid breaking on single elements.
|
||||
|
||||
## 5.6.13-5.6.15
|
||||
|
||||
* Setting up automatic Travis releases.
|
||||
|
||||
## 5.6.12
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix finding parent for top-level shadowed functions.
|
||||
|
||||
## 5.6.11
|
||||
|
||||
** **Internal**
|
||||
* Merge `es6.parameters.rest` and `es6.parameters.default` transformers. See commit [c0fd4c1f9e0b18231f585c4fa793e4cb0e01aed1](https://github.com/babel/babel/commit/c0fd4c1f9e0b18231f585c4fa793e4cb0e01aed1) for more info.
|
||||
|
||||
## 5.6.10
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix faulty internal require check.
|
||||
* **Polish**
|
||||
* Add support for trailing commas in arrow function parameter lists.
|
||||
|
||||
## 5.6.8
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix binary expressions colliding with unary expression operators in compact mode.
|
||||
* Fix node properties being set to `null` when using computed properties.
|
||||
|
||||
## 5.6.7
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix hoisting of `ForXStatement` `left` `var`s when inserting a block scoping IIFE.
|
||||
* **Polish**
|
||||
* Combine all leading computed property initialisers into the root object in loose mode.
|
||||
* **Internal**
|
||||
* Deprecate returning of replacement strings from visitor methods.
|
||||
|
||||
## 5.6.6
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix weird parser bug where `void` type annotations were being parsed as keywords causing the tokeniser to lose track of context.
|
||||
|
||||
## 5.6.5
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix nested functions causing rest parameter optimisation to not properly detect when it should deopt on a reference.
|
||||
* **Internal**
|
||||
* Update Regenerator `0.8.31`.
|
||||
|
||||
## 5.6.4
|
||||
|
||||
* **Internal**
|
||||
* Add `ParenthesizedExpression` node type.
|
||||
|
||||
## 5.6.3
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix rest parameter array allocation loop being incorrectly aliased.
|
||||
|
||||
## 5.6.2
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix method key literals not turning into computed member expression in loose mode.
|
||||
* Elect rest parameters in spread element position as candidates instead of replacing them in place.
|
||||
|
||||
## 5.6.0
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix istanbul interop for register hook when registering for non-existence extension.
|
||||
* Fix super class constructor call differing for no constructor in derived classes.
|
||||
* Disable module import receiver when in loose mode.
|
||||
* Fix duplicate filenames when using `babel` CLI when passing multiple matching patterns.
|
||||
* Register labels as bindings to fix undeclared variable checks.
|
||||
* **Polish**
|
||||
* Remove unnecessary string binary expressions when transforming template literals.
|
||||
* Support module live bindings in arbitary positions not in Program statement position.
|
||||
* Throw error when attemping to replace a `Program` root node with another node not of type `Program`.
|
||||
* Optimise rest parameters in spread element position and allocate rest array at the earliest common ancestor of all references.
|
||||
* Generate original number representation when value was not changed.
|
||||
* Check for invalid binding identifiers when generating inferred method names.
|
||||
* Don't terminate CLI when watching files fail compilation on init.
|
||||
* **New Feature**
|
||||
* Add new plugin API.
|
||||
* **Internal**
|
||||
* Split react displayName addition into a plugin.
|
||||
* Add check for `JSXMemberExpression` to `t.isReferenced`.
|
||||
* Move `validation.undeclaredVariableCheck` transformer up.
|
||||
* Start great core-to-plugin exodus.
|
||||
* Add `BindingIdentifier` virtual type.
|
||||
* Hidden class optimisations.
|
||||
* Array allocation optimisations.
|
||||
* Update `regenerator`.
|
||||
* Update `js-tokens`.
|
||||
* Sync with upstream Acorn.
|
||||
|
||||
## 5.5.8
|
||||
|
||||
* **Internal**
|
||||
* Remove extremely unprofessional and harsh error message for those hotlinking to `resolve-rc`.
|
||||
|
||||
## 5.5.7
|
||||
|
||||
* **Bug Fix**
|
||||
* Push newline after decorators when doing code gen.
|
||||
* Rewriting error handling to normalise options before merging them.
|
||||
* Remove duplicate keys in `alias-keys.json` causing errors in strict mode.
|
||||
* Fix `$ babel --help` not showing optional transformers as such.
|
||||
* **New Feature**
|
||||
* Add `auxiliaryCommentBefore` and `auxiliaryCommentAfter` options.
|
||||
|
||||
## 5.5.6
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix `let` binding collision in loop head not properly replacing `AssignmentExpression`s.
|
||||
|
||||
## 5.5.5
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix `file.opts` not being set before `file.log.deprecate` was called causing a `ReferenceError` as it was checking for a property on it.
|
||||
|
||||
## 5.5.4
|
||||
|
||||
* **Bug Fix**
|
||||
* Add back missing `shouldIgnore` check.
|
||||
* Log message on deprecated options rather than throw an error.
|
||||
* Fix name of `auxiliaryComment` option when attempting Istanbul interop in `babel/register`.
|
||||
|
||||
## 5.5.3
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix weird state bug when traversing overa `node` `ClassProperty` instead of `path` in the `es6.classes` transformer.
|
||||
|
||||
## 5.5.2
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix `NodePath#isPure` on `Property` nodes.
|
||||
* Use cwd instead of entry file directory when working out relative directory for `babel/register`.
|
||||
* **Internal**
|
||||
* Add scary warning for those few who choose to use the WIP experimental transformers.
|
||||
|
||||
## 5.5.1
|
||||
|
||||
* **Bug Fix**
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
<strong><a href="#dependencies">Dependencies</a></strong>
|
||||
|
|
||||
<strong><a href="#code-standards">Code Standards</a></strong>
|
||||
|
|
||||
<strong><a href="#internals">Internals</a></strong>
|
||||
</p>
|
||||
|
||||
----
|
||||
@@ -22,11 +24,10 @@ Contributions are always welcome, no matter how large or small. Before
|
||||
contributing, please read the
|
||||
[code of conduct](https://github.com/babel/babel/blob/master/CODE_OF_CONDUCT.md).
|
||||
|
||||
|
||||
## Developing
|
||||
|
||||
>Note: Babel moves fast. Only the latest release is guaranteed to build correctly.
|
||||
>Older releases are not officially supported. If you attempt to build them, do that at your own risk.
|
||||
> Note: Babel moves fast. Only the latest release is guaranteed to build correctly.
|
||||
> Older releases are not officially supported. If you attempt to build them, do that at your own risk.
|
||||
|
||||
#### Setup
|
||||
|
||||
@@ -112,8 +113,6 @@ your [`$PATH`](http://unix.stackexchange.com/questions/26047/how-to-correctly-ad
|
||||
|
||||
+ [js-tokens](http://ghub.io/js-tokens) This is used to get tokens for syntax error highlighting.
|
||||
|
||||
+ [leven](http://ghub.io/leven) A levenstein algorithm to determine how close a word is to another. This is used to offer suggestions when using the utility.undeclaredVariableCheck transformer.
|
||||
|
||||
+ [line-numbers](http://ghub.io/line-numbers) Used to produce the code frames in syntax errors.
|
||||
|
||||
+ [lodash](http://ghub.io/lodash) Used for various utilities.
|
||||
@@ -144,8 +143,11 @@ your [`$PATH`](http://unix.stackexchange.com/questions/26047/how-to-correctly-ad
|
||||
|
||||
+ [trim-right](http://ghub.io/trim-right) Trims the rightside whitespace.
|
||||
|
||||
+ [user-home](http://ghub.io/user-home) Gets the users home directory. This is used to resolve the babel-node/babel/register cache.
|
||||
+ [path-exists](https://www.npmjs.com/package/path-exists) Checks if a path exists. (replaces the deprecated `fs.exists` methods)
|
||||
|
||||
+ [home-or-tmp](https://github.com/sindresorhus/home-or-tmp) Gets the user home directory with fallback to the system temporary directory. This is used to resolve the babel-node/babel/register cache.
|
||||
|
||||
+ [resolve](https://www.npmjs.com/package/resolve) Implements the [`require.resolve()` algorithm](http://nodejs.org/docs/v0.12.0/api/all.html#all_require_resolve) such that we can `require.resolve()` on behalf of a file asynchronously and synchronously.
|
||||
|
||||
#### Code Standards
|
||||
|
||||
@@ -173,3 +175,6 @@ your [`$PATH`](http://unix.stackexchange.com/questions/26047/how-to-correctly-ad
|
||||
* **Declaration**
|
||||
* No unused variables
|
||||
* No pollution of global variables and prototypes
|
||||
|
||||
#### Internals
|
||||
Please see [`/doc`](/doc) for internals documentation relevant to developing babel.
|
||||
|
||||
56
Makefile
56
Makefile
@@ -5,16 +5,17 @@ UGLIFY_CMD = node_modules/uglify-js/bin/uglifyjs
|
||||
#UGLIFY_CMD = node_modules/uglify-js/bin/uglifyjs --mangle sort
|
||||
MOCHA_CMD = node_modules/mocha/bin/_mocha
|
||||
BABEL_CMD = node_modules/babel/bin/babel
|
||||
BROWSERIFY_IGNORE = -i esprima-fb
|
||||
|
||||
export NODE_ENV = test
|
||||
|
||||
.PHONY: clean test test-cov test-clean test-travis test-simple test-all test-browser test-parser publish build bootstrap publish-core publish-runtime build-core watch-core build-core-test clean-core
|
||||
.PHONY: clean test test-cov test-clean test-travis test-simple test-all test-browser test-parser publish build bootstrap publish-core publish-runtime build-website build-core watch-core build-core-test clean-core prepublish
|
||||
|
||||
build-core: clean-core
|
||||
node $(BABEL_CMD) src --out-dir lib --copy-files
|
||||
|
||||
build-core-test: clean-core
|
||||
node $(BABEL_CMD) src --out-dir lib --copy-files --auxiliary-comment "istanbul ignore next"
|
||||
node $(BABEL_CMD) src --out-dir lib --copy-files --auxiliary-comment-before "istanbul ignore next"
|
||||
|
||||
watch-core: clean-core
|
||||
node $(BABEL_CMD) src --out-dir lib --watch --copy-files
|
||||
@@ -23,7 +24,7 @@ clean-core:
|
||||
rm -rf lib
|
||||
|
||||
lint:
|
||||
eslint src/babel
|
||||
eslint src/babel packages/babel-cli/bin
|
||||
|
||||
build:
|
||||
mkdir -p dist
|
||||
@@ -34,8 +35,10 @@ build:
|
||||
node $(BROWSERIFY_CMD) -e lib/babel/polyfill.js >dist/polyfill.js
|
||||
node $(UGLIFY_CMD) dist/polyfill.js >dist/polyfill.min.js
|
||||
|
||||
node $(BROWSERIFY_CMD) lib/babel/api/browser.js -s babel >dist/babel.js
|
||||
node $(UGLIFY_CMD) dist/babel.js >dist/babel.min.js
|
||||
node $(BROWSERIFY_CMD) lib/babel/api/browser.js -s babel $(BROWSERIFY_IGNORE) >dist/browser.js
|
||||
node $(UGLIFY_CMD) dist/browser.js >dist/browser.min.js
|
||||
|
||||
node $(BROWSERIFY_CMD) lib/babel/api/node.js --node $(BROWSERIFY_IGNORE) >dist/node.js
|
||||
|
||||
node packages/babel-cli/bin/babel-external-helpers >dist/external-helpers.js
|
||||
node $(UGLIFY_CMD) dist/external-helpers.js >dist/external-helpers.min.js
|
||||
@@ -78,34 +81,20 @@ test-browser:
|
||||
|
||||
publish: lint
|
||||
git pull --rebase
|
||||
|
||||
make test
|
||||
|
||||
read -p "Version: " version; \
|
||||
npm version $$version --message "v%s"
|
||||
|
||||
make build
|
||||
|
||||
cp dist/babel.js browser.js
|
||||
cp dist/babel.min.js browser.min.js
|
||||
|
||||
cp dist/polyfill.js browser-polyfill.js
|
||||
cp dist/polyfill.min.js browser-polyfill.min.js
|
||||
|
||||
cp dist/external-helpers.js external-helpers.js
|
||||
cp dist/external-helpers.min.js external-helpers.min.js
|
||||
|
||||
node tools/cache-templates
|
||||
test -f templates.json
|
||||
|
||||
npm publish
|
||||
|
||||
git push --follow-tags
|
||||
|
||||
make publish-cli
|
||||
make publish-runtime
|
||||
|
||||
rm -rf templates.json browser.js browser.min.js browser-polyfill.js browser-polyfill.min.js external-helpers.js external-helpers.min.js
|
||||
prepublish: build
|
||||
cp dist/browser.js browser.js
|
||||
cp dist/browser.min.js browser.min.js
|
||||
cp dist/polyfill.js browser-polyfill.js
|
||||
cp dist/polyfill.min.js browser-polyfill.min.js
|
||||
cp dist/external-helpers.js external-helpers.js
|
||||
cp dist/external-helpers.min.js external-helpers.min.js
|
||||
node tools/cache-templates
|
||||
test -f templates.json
|
||||
|
||||
publish-runtime:
|
||||
cd packages; \
|
||||
@@ -114,10 +103,13 @@ publish-runtime:
|
||||
npm publish
|
||||
|
||||
publish-cli:
|
||||
cd packages; \
|
||||
node build-cli.js; \
|
||||
cd babel-cli; \
|
||||
npm publish
|
||||
@./tools/publish-cli.sh
|
||||
|
||||
build-website:
|
||||
@./tools/build-website.sh
|
||||
|
||||
comment-issues:
|
||||
@./tools/comment-issues.sh
|
||||
|
||||
bootstrap:
|
||||
npm list --global --depth 1 babel >/dev/null 2>&1 && npm uninstall -g babel || true
|
||||
|
||||
17
README.md
17
README.md
@@ -1,19 +1,28 @@
|
||||
<p align="center">
|
||||
<a href="https://babeljs.io/">
|
||||
<img alt="babel" src="https://raw.githubusercontent.com/babel/logo/master/logo.png" width="546">
|
||||
<img alt="babel" src="https://raw.githubusercontent.com/babel/logo/master/babel.png" width="546">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<strong>Babel</strong> is a compiler for writing next generation JavaScript.
|
||||
The compiler for writing next generation JavaScript.
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
For questions and support please visit the <a href="https://gitter.im/babel/babel">gitter room</a> or <a href="http://stackoverflow.com/questions/tagged/babeljs">StackOverflow</a>. The Babel issue tracker is <strong>exclusively</strong> for bug reports and feature requests.
|
||||
<a href="https://travis-ci.org/babel/babel"><img alt="Build Status" src="https://img.shields.io/travis/babel/babel.svg?style=flat"></a>
|
||||
<a href="http://badge.fury.io/js/babel-core"><img alt="npm version" src="https://badge.fury.io/js/babel-core.svg"></a>
|
||||
<a href="https://npmjs.org/package/babel-core"><img alt="Downloads" src="http://img.shields.io/npm/dm/babel-core.svg"></a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
Issues without instructions to reproduce <strong>will be immediately closed<strong>.
|
||||
<a href="http://issuestats.com/github/babel/babel"><img alt="Issue Stats" src="http://issuestats.com/github/babel/babel/badge/pr?style=flat"></a>
|
||||
<a href="http://issuestats.com/github/babel/babel"><img alt="Issue Stats" src="http://issuestats.com/github/babel/babel/badge/issue?style=flat"></a>
|
||||
</p>
|
||||
|
||||
----
|
||||
|
||||
<p align="center">
|
||||
For questions and support please visit the <a href="https://babel-slack.herokuapp.com">Slack community</a> or <a href="http://stackoverflow.com/questions/tagged/babeljs">StackOverflow</a>. The Babel issue tracker is <strong>exclusively</strong> for bug reports and feature requests.
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
|
||||
4
doc/index.md
Normal file
4
doc/index.md
Normal file
@@ -0,0 +1,4 @@
|
||||
This is a collection of documentation about babel internals, for use in development of babel.
|
||||
|
||||
# [Properties of nodes](/doc/node-props.md)
|
||||
These are properties babel stores in AST node objects for internal use, as opposed to properties that are part of the AST spec (ESTree at the time of this writing).
|
||||
11
doc/node-props.md
Normal file
11
doc/node-props.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# Properties of nodes
|
||||
These are properties babel stores in AST node objects for internal use, as opposed to properties that are part of the AST spec ([ESTree](https://github.com/estree/estree) at the time of this writing).
|
||||
|
||||
## `_blockHoist`
|
||||
`node._blockHoist != null` triggers the [block-hoist transformer](/src/babel/transformation/transformers/internal/block-hoist.js). Value should be `true` or an integer in the range `0..3`. `true` is equivalent to `2`. The value indicates whether the node should be hoisted and to what degree. See the source code for more detailed information.
|
||||
|
||||
## `_paths`
|
||||
Stores a representation of a node's position in the tree and relationship to other nodes.
|
||||
|
||||
## `shadow`
|
||||
A truthy value on a function node triggers the [shadow-functions transformer](/src/babel/transformation/transformers/internal/shadow-functions.js), which transforms the node so that it references (or inherits) `arguments` and the `this` context from the parent scope. It is invoked for arrow functions, for example.
|
||||
43
package.json
43
package.json
@@ -1,27 +1,26 @@
|
||||
{
|
||||
"name": "babel-core",
|
||||
"description": "A compiler for writing next generation JavaScript",
|
||||
"version": "5.5.1",
|
||||
"version": "5.6.19",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||
"homepage": "https://babeljs.io/",
|
||||
"license": "MIT",
|
||||
"repository": "babel/babel",
|
||||
"main": "lib/babel/api/node.js",
|
||||
"browser": {
|
||||
"./lib/babel/api/register/node.js": "./lib/babel/api/register/browser.js"
|
||||
},
|
||||
"keywords": [
|
||||
"harmony",
|
||||
"6to5",
|
||||
"babel",
|
||||
"classes",
|
||||
"modules",
|
||||
"let",
|
||||
"const",
|
||||
"var",
|
||||
"es6",
|
||||
"harmony",
|
||||
"let",
|
||||
"modules",
|
||||
"transpile",
|
||||
"transpiler",
|
||||
"6to5",
|
||||
"babel"
|
||||
"var"
|
||||
],
|
||||
"scripts": {
|
||||
"bench": "make bench",
|
||||
@@ -29,29 +28,41 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"acorn-jsx": "^1.0.0",
|
||||
"ast-types": "~0.7.0",
|
||||
"bluebird": "^2.9.25",
|
||||
"babel-plugin-constant-folding": "^1.0.1",
|
||||
"babel-plugin-dead-code-elimination": "^1.0.2",
|
||||
"babel-plugin-eval": "^1.0.1",
|
||||
"babel-plugin-inline-environment-variables": "^1.0.1",
|
||||
"babel-plugin-jscript": "^1.0.1",
|
||||
"babel-plugin-member-expression-literals": "^1.0.1",
|
||||
"babel-plugin-property-literals": "^1.0.1",
|
||||
"babel-plugin-proto-to-assign": "^1.0.3",
|
||||
"babel-plugin-react-constant-elements": "^1.0.3",
|
||||
"babel-plugin-react-display-name": "^1.0.3",
|
||||
"babel-plugin-remove-console": "^1.0.1",
|
||||
"babel-plugin-remove-debugger": "^1.0.1",
|
||||
"babel-plugin-runtime": "^1.0.7",
|
||||
"babel-plugin-undeclared-variables-check": "^1.0.2",
|
||||
"babel-plugin-undefined-to-void": "^1.1.6",
|
||||
"chalk": "^1.0.0",
|
||||
"convert-source-map": "^1.1.0",
|
||||
"core-js": "^0.9.0",
|
||||
"debug": "^2.1.1",
|
||||
"detect-indent": "^3.0.0",
|
||||
"esquery": "^0.4.0",
|
||||
"estraverse": "^4.0.0",
|
||||
"esutils": "^2.0.0",
|
||||
"fs-readdir-recursive": "^0.1.0",
|
||||
"globals": "^6.4.0",
|
||||
"home-or-tmp": "^1.0.0",
|
||||
"is-integer": "^1.0.4",
|
||||
"js-tokens": "1.0.0",
|
||||
"leven": "^1.0.1",
|
||||
"js-tokens": "1.0.1",
|
||||
"line-numbers": "0.2.0",
|
||||
"lodash": "^3.6.0",
|
||||
"minimatch": "^2.0.3",
|
||||
"output-file-sync": "^1.1.0",
|
||||
"path-exists": "^1.0.0",
|
||||
"path-is-absolute": "^1.0.0",
|
||||
"private": "^0.1.6",
|
||||
"regenerator": "^0.8.28",
|
||||
"regenerator": "0.8.34",
|
||||
"regexpu": "^1.1.2",
|
||||
"repeating": "^1.1.2",
|
||||
"resolve": "^1.1.6",
|
||||
@@ -64,11 +75,11 @@
|
||||
"trim-right": "^1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel": "5.3.1",
|
||||
"babel": "5.6.10",
|
||||
"babel-eslint": "^3.1.19",
|
||||
"browserify": "^9.0.8",
|
||||
"chai": "^2.2.0",
|
||||
"eslint": "^0.21.2",
|
||||
"babel-eslint": "^3.1.9",
|
||||
"esvalid": "^1.1.0",
|
||||
"istanbul": "^0.3.5",
|
||||
"matcha": "^0.6.0",
|
||||
|
||||
@@ -18,9 +18,9 @@ program.option("-p, --print [code]", "Evaluate script and print result");
|
||||
program.option("-i, --ignore [regex]", "Ignore all files that match this regex when using the require hook");
|
||||
program.option("-x, --extensions [extensions]", "List of extensions to hook into [.es6,.js,.es,.jsx]");
|
||||
program.option("-r, --stage [stage]", "Enable support for specific ECMAScript stages");
|
||||
program.option("-w, --whitelist [whitelist]", "Whitelist of transformers to ONLY use", util.list);
|
||||
program.option("-b, --blacklist [blacklist]", "Blacklist of transformers to NOT use", util.list);
|
||||
program.option("-o, --optional [optional]", "List of optional transformers to enable", util.list);
|
||||
program.option("-w, --whitelist [whitelist]", "Whitelist of transformers separated by comma to ONLY use", util.list);
|
||||
program.option("-b, --blacklist [blacklist]", "Blacklist of transformers separated by comma to NOT use", util.list);
|
||||
program.option("-o, --optional [optional]", "List of optional transformers separated by comma to enable", util.list);
|
||||
|
||||
var pkg = require("../package.json");
|
||||
program.version(pkg.version);
|
||||
@@ -41,6 +41,7 @@ babel.register({
|
||||
//
|
||||
|
||||
var _eval = function (code, filename) {
|
||||
code = code.trim();
|
||||
if (!code) return undefined;
|
||||
|
||||
code = babel.transform(code, {
|
||||
|
||||
141
packages/babel-cli/bin/babel-plugin/index.js
Executable file
141
packages/babel-cli/bin/babel-plugin/index.js
Executable file
@@ -0,0 +1,141 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
var pathExists = require("path-exists");
|
||||
var readline = require("readline");
|
||||
var child = require("child_process");
|
||||
var path = require("path");
|
||||
var fs = require("fs");
|
||||
|
||||
function spawn(cmd, args, callback) {
|
||||
console.log(">", cmd, args);
|
||||
|
||||
var spawn = child.spawn(cmd, args, { stdio: "inherit" });
|
||||
|
||||
spawn.on("exit", function (code) {
|
||||
if (code === 0) {
|
||||
if (callback) callback();
|
||||
} else {
|
||||
console.log("Killing...");
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function spawnMultiple(cmds) {
|
||||
function next() {
|
||||
var cmd = cmds.shift();
|
||||
if (cmd) {
|
||||
spawn(cmd.command, cmd.args, next);
|
||||
} else {
|
||||
process.exit();
|
||||
}
|
||||
}
|
||||
|
||||
next();
|
||||
}
|
||||
|
||||
function template(name, data) {
|
||||
var source = fs.readFileSync(path.join(__dirname, "templates", name), "utf8");
|
||||
source = source.replace(/[A-Z_]+/g, function (key) {
|
||||
return data[key] === undefined ? key : data[key];
|
||||
});
|
||||
return source;
|
||||
}
|
||||
|
||||
function write(filename, content) {
|
||||
console.log(filename);
|
||||
fs.writeFileSync(filename, content);
|
||||
}
|
||||
|
||||
var rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout
|
||||
});
|
||||
|
||||
var BABEL_PLUGIN_PREFIX = "babel-plugin-";
|
||||
|
||||
var cmds = {
|
||||
init: function () {
|
||||
var name = path.basename(process.cwd());
|
||||
|
||||
if (name.indexOf(BABEL_PLUGIN_PREFIX) === 0) {
|
||||
name = name.slice(BABEL_PLUGIN_PREFIX.length);
|
||||
}
|
||||
|
||||
rl.question("Description (optional): ", function (description) {
|
||||
rl.question("GitHub Repository (eg. sebmck/babel-plugin-foobar) (optional): ", function (repo) {
|
||||
rl.close();
|
||||
|
||||
var templateData = {
|
||||
DESCRIPTION: description,
|
||||
FULL_NAME: BABEL_PLUGIN_PREFIX + name,
|
||||
NAME: name
|
||||
};
|
||||
|
||||
write("package.json", JSON.stringify({
|
||||
name: templateData.FULL_NAME,
|
||||
version: "1.0.0",
|
||||
description: templateData.DESCRIPTION,
|
||||
repository: repo || undefined,
|
||||
license: "MIT",
|
||||
main: "lib/index.js",
|
||||
|
||||
devDependencies: {
|
||||
babel: "^5.6.0"
|
||||
},
|
||||
|
||||
scripts: {
|
||||
build: "babel-plugin build",
|
||||
push: "babel-plugin publish",
|
||||
test: "babel-plugin test"
|
||||
},
|
||||
|
||||
keywords: ["babel-plugin"]
|
||||
}, null, " ") + "\n");
|
||||
|
||||
write(".npmignore", "node_modules\n*.log\nsrc\n");
|
||||
|
||||
write(".gitignore", "node_modules\n*.log\nlib\n");
|
||||
|
||||
write("README.md", template("README.md", templateData));
|
||||
|
||||
if (!pathExists.sync("src")) {
|
||||
fs.mkdirSync("src");
|
||||
write("src/index.js", template("index.js", templateData));
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
build: function () {
|
||||
spawn("babel", ["src", "--out-dir", "lib", "--copy-files"]);
|
||||
},
|
||||
|
||||
publish: function () {
|
||||
var pkg = require(process.cwd() + "/package.json");
|
||||
console.log("Current verison:", pkg.version);
|
||||
|
||||
rl.question("New version (enter nothing for patch): ", function (newVersion) {
|
||||
rl.close();
|
||||
|
||||
newVersion = newVersion || "patch";
|
||||
|
||||
spawnMultiple([
|
||||
{ command: "git", args: ["pull"] },
|
||||
{ command: "git", args: ["push"] },
|
||||
{ command: "babel-plugin", args: ["build"] },
|
||||
{ command: "npm", args: ["version", newVersion] },
|
||||
{ command: "npm", args: ["publish"] },
|
||||
{ command: "git", args: ["push", "--follow-tags"] }
|
||||
]);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
var cmd = cmds[process.argv[2]];
|
||||
if (cmd) {
|
||||
cmd();
|
||||
} else {
|
||||
console.error("Unknown command:", cmd);
|
||||
process.exit(1);
|
||||
}
|
||||
35
packages/babel-cli/bin/babel-plugin/templates/README.md
Normal file
35
packages/babel-cli/bin/babel-plugin/templates/README.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# FULL_NAME
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
$ npm install FULL_NAME
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Via `.babelrc` (Recommended)
|
||||
|
||||
**.babelrc**
|
||||
|
||||
```json
|
||||
{
|
||||
"plugins": ["NAME"]
|
||||
}
|
||||
```
|
||||
|
||||
### Via CLI
|
||||
|
||||
```sh
|
||||
$ babel --plugins NAME script.js
|
||||
```
|
||||
|
||||
### Via Node API
|
||||
|
||||
```javascript
|
||||
require("babel-core").transform("code", {
|
||||
plugins: ["NAME"]
|
||||
});
|
||||
```
|
||||
7
packages/babel-cli/bin/babel-plugin/templates/index.js
Normal file
7
packages/babel-cli/bin/babel-plugin/templates/index.js
Normal file
@@ -0,0 +1,7 @@
|
||||
export default function ({ Plugin, types: t }) {
|
||||
return new Plugin("NAME", {
|
||||
visitor: {
|
||||
// your visitor methods go here
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
var outputFileSync = require("output-file-sync");
|
||||
var pathExists = require("path-exists");
|
||||
var chokidar = require("chokidar");
|
||||
var slash = require("slash");
|
||||
var path = require("path");
|
||||
@@ -6,7 +7,7 @@ var util = require("./util");
|
||||
var fs = require("fs");
|
||||
var _ = require("lodash");
|
||||
|
||||
module.exports = function (commander, filenames, opts) {
|
||||
module.exports = function (commander, filenames) {
|
||||
var write = function (src, relative) {
|
||||
// remove extension and then append back on .js
|
||||
relative = relative.replace(/\.(\w*?)$/, "") + ".js";
|
||||
@@ -27,7 +28,7 @@ module.exports = function (commander, filenames, opts) {
|
||||
|
||||
outputFileSync(dest, data.code);
|
||||
|
||||
console.log(src + " -> " + dest);
|
||||
util.log(src + " -> " + dest);
|
||||
};
|
||||
|
||||
var handleFile = function (src, filename) {
|
||||
@@ -41,7 +42,7 @@ module.exports = function (commander, filenames, opts) {
|
||||
};
|
||||
|
||||
var handle = function (filename) {
|
||||
if (!fs.existsSync(filename)) return;
|
||||
if (!pathExists.sync(filename)) return;
|
||||
|
||||
var stat = fs.statSync(filename);
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
var convertSourceMap = require("convert-source-map");
|
||||
var pathExists = require("path-exists");
|
||||
var sourceMap = require("source-map");
|
||||
var chokidar = require("chokidar");
|
||||
var slash = require("slash");
|
||||
@@ -100,7 +101,7 @@ module.exports = function (commander, filenames, opts) {
|
||||
results = [];
|
||||
|
||||
_.each(filenames, function (filename) {
|
||||
if (!fs.existsSync(filename)) return;
|
||||
if (!pathExists.sync(filename)) return;
|
||||
|
||||
var stat = fs.statSync(filename);
|
||||
if (stat.isDirectory()) {
|
||||
@@ -134,7 +135,7 @@ module.exports = function (commander, filenames, opts) {
|
||||
ignoreInitial: true
|
||||
}).on("all", function (type, filename) {
|
||||
if (type === "add" || type === "change") {
|
||||
console.log(type, filename);
|
||||
util.log(type + " " + filename);
|
||||
try {
|
||||
walk();
|
||||
} catch (err) {
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
require("babel-core");
|
||||
|
||||
var moduleFormatters = require("babel-core/lib/babel/transformation/modules");
|
||||
var pathExists = require("path-exists");
|
||||
var commander = require("commander");
|
||||
var transform = require("babel-core").transform;
|
||||
var kebabCase = require("lodash/string/kebabCase");
|
||||
var options = require("babel-core").options;
|
||||
var util = require("babel-core").util;
|
||||
var uniq = require("lodash/array/uniq");
|
||||
var each = require("lodash/collection/each");
|
||||
var keys = require("lodash/object/keys");
|
||||
var fs = require("fs");
|
||||
var glob = require("glob");
|
||||
|
||||
each(options, function (option, key) {
|
||||
@@ -35,13 +38,14 @@ each(options, function (option, key) {
|
||||
if (option.description) desc.push(option.description);
|
||||
|
||||
commander.option(arg, desc.join(" "));
|
||||
})
|
||||
});
|
||||
|
||||
commander.option("-x, --extensions [extensions]", "List of extensions to compile when a directory has been input [.es6,.js,.es,.jsx]");
|
||||
commander.option("-w, --watch", "Recompile files on changes");
|
||||
commander.option("-o, --out-file [out]", "Compile all input files into a single file");
|
||||
commander.option("-d, --out-dir [out]", "Compile an input directory of modules into an output directory");
|
||||
commander.option("-D, --copy-files", "When compiling a directory copy over non-compilable files");
|
||||
commander.option("-q, --quiet", "Don't log anything");
|
||||
|
||||
commander.on("--help", function () {
|
||||
var outKeys = function (title, obj) {
|
||||
@@ -51,7 +55,7 @@ commander.on("--help", function () {
|
||||
each(keys(obj).sort(), function (key) {
|
||||
if (key[0] === "_") return;
|
||||
|
||||
if (obj[key].optional) key = "[" + key + "]";
|
||||
if (obj[key].metadata && obj[key].metadata.optional) key = "[" + key + "]";
|
||||
|
||||
console.log(" - " + key);
|
||||
});
|
||||
@@ -64,7 +68,7 @@ commander.on("--help", function () {
|
||||
});
|
||||
|
||||
var pkg = require("../../package.json");
|
||||
commander.version(pkg.version);
|
||||
commander.version(pkg.version + " (babel-core " + require("babel-core").version + ")");
|
||||
commander.usage("[options] <files ...>");
|
||||
commander.parse(process.argv);
|
||||
|
||||
@@ -84,8 +88,10 @@ var filenames = commander.args.reduce(function (globbed, input) {
|
||||
return globbed.concat(files);
|
||||
}, []);
|
||||
|
||||
filenames = uniq(filenames);
|
||||
|
||||
each(filenames, function (filename) {
|
||||
if (!fs.existsSync(filename)) {
|
||||
if (!pathExists.sync(filename)) {
|
||||
errors.push(filename + " doesn't exist");
|
||||
}
|
||||
});
|
||||
@@ -118,11 +124,16 @@ if (errors.length) {
|
||||
var opts = exports.opts = {};
|
||||
|
||||
each(options, function (opt, key) {
|
||||
opts[key] = commander[key];
|
||||
if (commander[key] !== undefined) {
|
||||
opts[key] = commander[key];
|
||||
}
|
||||
});
|
||||
|
||||
opts.ignore = util.arrayify(opts.ignore, util.regexify);
|
||||
opts.only = util.arrayify(opts.only, util.regexify);
|
||||
|
||||
if (opts.only) {
|
||||
opts.only = util.arrayify(opts.only, util.regexify);
|
||||
}
|
||||
|
||||
var fn;
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
var readdir = require("fs-readdir-recursive");
|
||||
var index = require("./index");
|
||||
var babel = require("babel-core");
|
||||
var util = require("babel-core").util;
|
||||
var path = require("path");
|
||||
var fs = require("fs");
|
||||
var _ = require("lodash");
|
||||
var commander = require("commander");
|
||||
var readdir = require("fs-readdir-recursive");
|
||||
var index = require("./index");
|
||||
var babel = require("babel-core");
|
||||
var util = require("babel-core").util;
|
||||
var path = require("path");
|
||||
var fs = require("fs");
|
||||
var _ = require("lodash");
|
||||
|
||||
exports.readdirFilter = function (filename) {
|
||||
return readdir(filename).filter(function (filename) {
|
||||
@@ -24,6 +25,10 @@ exports.addSourceMappingUrl = function (code, loc) {
|
||||
return code + "\n//# sourceMappingURL=" + path.basename(loc);
|
||||
};
|
||||
|
||||
exports.log = function (msg) {
|
||||
if (!commander.quiet) console.log(msg);
|
||||
};
|
||||
|
||||
exports.transform = function (filename, code, opts) {
|
||||
opts = _.defaults(opts || {}, index.opts);
|
||||
opts.filename = filename;
|
||||
@@ -37,6 +42,15 @@ exports.transform = function (filename, code, opts) {
|
||||
};
|
||||
|
||||
exports.compile = function (filename, opts) {
|
||||
var code = fs.readFileSync(filename, "utf8");
|
||||
return exports.transform(filename, code, opts);
|
||||
try {
|
||||
var code = fs.readFileSync(filename, "utf8");
|
||||
return exports.transform(filename, code, opts);
|
||||
} catch (err) {
|
||||
if (commander.watch) {
|
||||
console.error(err.stack);
|
||||
return { ignored: true };
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
{
|
||||
"name": "babel",
|
||||
"description": "Turn ES6 code into readable vanilla ES5 with source maps",
|
||||
"version": "5.5.0",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||
"homepage": "https://babeljs.io/",
|
||||
"license": "MIT",
|
||||
"repository": "babel/babel",
|
||||
"preferGlobal": true,
|
||||
"dependencies": {
|
||||
"babel-core": "^5.5.0",
|
||||
"chokidar": "^1.0.0",
|
||||
"commander": "^2.6.0",
|
||||
"convert-source-map": "^1.1.0",
|
||||
@@ -16,6 +14,7 @@
|
||||
"glob": "^5.0.5",
|
||||
"lodash": "^3.2.0",
|
||||
"output-file-sync": "^1.1.0",
|
||||
"path-exists": "^1.0.0",
|
||||
"path-is-absolute": "^1.0.0",
|
||||
"source-map": "^0.4.0",
|
||||
"slash": "^1.0.0"
|
||||
@@ -23,6 +22,7 @@
|
||||
"bin": {
|
||||
"babel": "./bin/babel/index.js",
|
||||
"babel-node": "./bin/babel-node",
|
||||
"babel-external-helpers": "./bin/babel-external-helpers"
|
||||
"babel-external-helpers": "./bin/babel-external-helpers",
|
||||
"babel-plugin": "./bin/babel-plugin/index.js"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
{
|
||||
"name": "babel-runtime",
|
||||
"description": "babel selfContained runtime",
|
||||
"version": "5.5.0",
|
||||
"license": "MIT",
|
||||
"repository": "babel/babel",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||
"dependencies": {
|
||||
"core-js": "^0.9.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,9 +73,8 @@ each(File.helpers, function (helperName) {
|
||||
writeFile("regenerator/index.js", readFile("regenerator/runtime-module", true));
|
||||
writeFile("regenerator/runtime.js", selfContainify(readFile("regenerator/runtime")));
|
||||
|
||||
//
|
||||
|
||||
var coreDefinitions = require("../lib/babel/transformation/transformers/other/runtime/definitions");
|
||||
var coreDefinitions = require("babel-plugin-runtime/lib/definitions");
|
||||
|
||||
var paths = ["is-iterable", "get-iterator"];
|
||||
|
||||
@@ -93,6 +92,5 @@ each(paths, function (path) {
|
||||
writeFile("core-js/" + path + ".js", defaultify('require("core-js/library/fn/' + path + '")'));
|
||||
});
|
||||
|
||||
//
|
||||
|
||||
updatePackage();
|
||||
|
||||
27
src/README.md
Normal file
27
src/README.md
Normal file
@@ -0,0 +1,27 @@
|
||||
## Welcome to the Babel Codebase
|
||||
|
||||
Babel is broken down into three parts:
|
||||
|
||||
- Parsing
|
||||
- [Transformation](babel/transformation/)
|
||||
- [Generation](babel/generation/)
|
||||
|
||||
**Parsing** is the process of turning a piece of code into an [ESTree spec](https://github.com/estree/estree) compatible AST (Abstract
|
||||
Syntax Tree) which is a tree-like object of nodes that _describes_ the code.
|
||||
This makes it easier to transform the code over direct string manpulation.
|
||||
|
||||
**Transformation** is the process of taking an AST and manipulating it into
|
||||
a new one. For example, Babel might take an ES2015 ArrowFunction and transform
|
||||
it into a normal Function which will work in ES5 environments.
|
||||
|
||||
**Generation** is the process of turning an AST back into code. After Babel is
|
||||
done transforming the AST, the generation takes over to return normal code.
|
||||
|
||||
---
|
||||
|
||||
Babel's parsing step is done by [Acorn](https://github.com/marijnh/acorn). However, because Babel is implementing
|
||||
future standards it maintains a [fork of Acorn](acorn/) in order to do it's job. You can
|
||||
see that fork in the "acorn" folder.
|
||||
|
||||
The transformation and generation steps are both handled inside of the Babel
|
||||
codebase itself, which is in the "babel" folder here.
|
||||
@@ -15,6 +15,15 @@ pp.expectRelational = function (op) {
|
||||
}
|
||||
}
|
||||
|
||||
pp.flow_parseTypeInitialiser = function (tok) {
|
||||
var oldInType = this.inType
|
||||
this.inType = true
|
||||
this.expect(tok || tt.colon)
|
||||
var type = this.flow_parseType()
|
||||
this.inType = oldInType
|
||||
return type;
|
||||
}
|
||||
|
||||
pp.flow_parseDeclareClass = function (node) {
|
||||
this.next()
|
||||
this.flow_parseInterfaceish(node, true)
|
||||
@@ -40,9 +49,7 @@ pp.flow_parseDeclareFunction = function (node) {
|
||||
typeNode.params = tmp.params
|
||||
typeNode.rest = tmp.rest
|
||||
this.expect(tt.parenR)
|
||||
|
||||
this.expect(tt.colon)
|
||||
typeNode.returnType = this.flow_parseType()
|
||||
typeNode.returnType = this.flow_parseTypeInitialiser()
|
||||
|
||||
typeContainer.typeAnnotation = this.finishNode(typeNode, "FunctionTypeAnnotation")
|
||||
id.typeAnnotation = this.finishNode(typeContainer, "TypeAnnotation")
|
||||
@@ -153,15 +160,7 @@ pp.flow_parseTypeAlias = function (node) {
|
||||
node.typeParameters = null
|
||||
}
|
||||
|
||||
var oldInType = this.inType;
|
||||
this.inType = true;
|
||||
|
||||
this.expect(tt.eq)
|
||||
|
||||
node.right = this.flow_parseType()
|
||||
|
||||
this.inType = oldInType;
|
||||
|
||||
node.right = this.flow_parseTypeInitialiser(tt.eq)
|
||||
this.semicolon()
|
||||
|
||||
return this.finishNode(node, "TypeAlias")
|
||||
@@ -214,11 +213,9 @@ pp.flow_parseObjectTypeIndexer = function (node, isStatic) {
|
||||
|
||||
this.expect(tt.bracketL)
|
||||
node.id = this.flow_parseObjectPropertyKey()
|
||||
this.expect(tt.colon)
|
||||
node.key = this.flow_parseType()
|
||||
node.key = this.flow_parseTypeInitialiser()
|
||||
this.expect(tt.bracketR)
|
||||
this.expect(tt.colon)
|
||||
node.value = this.flow_parseType()
|
||||
node.value = this.flow_parseTypeInitialiser()
|
||||
|
||||
this.flow_objectTypeSemicolon()
|
||||
return this.finishNode(node, "ObjectTypeIndexer")
|
||||
@@ -245,8 +242,7 @@ pp.flow_parseObjectTypeMethodish = function (node) {
|
||||
node.rest = this.flow_parseFunctionTypeParam()
|
||||
}
|
||||
this.expect(tt.parenR)
|
||||
this.expect(tt.colon)
|
||||
node.returnType = this.flow_parseType()
|
||||
node.returnType = this.flow_parseTypeInitialiser()
|
||||
|
||||
return this.finishNode(node, "FunctionTypeAnnotation")
|
||||
}
|
||||
@@ -265,7 +261,7 @@ pp.flow_parseObjectTypeCallProperty = function (node, isStatic) {
|
||||
var valueNode = this.startNode()
|
||||
node.static = isStatic
|
||||
node.value = this.flow_parseObjectTypeMethodish(valueNode)
|
||||
this.flow_objectTypeSemicolon()
|
||||
this.flow_objectTypeSemicolon()
|
||||
return this.finishNode(node, "ObjectTypeCallProperty")
|
||||
}
|
||||
|
||||
@@ -310,9 +306,8 @@ pp.flow_parseObjectType = function (allowStatic) {
|
||||
if (this.eat(tt.question)) {
|
||||
optional = true
|
||||
}
|
||||
this.expect(tt.colon)
|
||||
node.key = propertyKey
|
||||
node.value = this.flow_parseType()
|
||||
node.value = this.flow_parseTypeInitialiser()
|
||||
node.optional = optional
|
||||
node.static = isStatic
|
||||
this.flow_objectTypeSemicolon()
|
||||
@@ -352,12 +347,6 @@ pp.flow_parseGenericType = function (start, id) {
|
||||
return this.finishNode(node, "GenericTypeAnnotation")
|
||||
}
|
||||
|
||||
pp.flow_parseVoidType = function () {
|
||||
var node = this.startNode()
|
||||
this.expect(tt._void)
|
||||
return this.finishNode(node, "VoidTypeAnnotation")
|
||||
}
|
||||
|
||||
pp.flow_parseTypeofType = function () {
|
||||
var node = this.startNode()
|
||||
this.expect(tt._typeof)
|
||||
@@ -386,9 +375,8 @@ pp.flow_parseFunctionTypeParam = function () {
|
||||
if (this.eat(tt.question)) {
|
||||
optional = true
|
||||
}
|
||||
this.expect(tt.colon)
|
||||
node.optional = optional
|
||||
node.typeAnnotation = this.flow_parseType()
|
||||
node.typeAnnotation = this.flow_parseTypeInitialiser()
|
||||
return this.finishNode(node, "FunctionTypeParam")
|
||||
}
|
||||
|
||||
@@ -411,6 +399,9 @@ pp.flow_identToTypeAnnotation = function (start, node, id) {
|
||||
case "any":
|
||||
return this.finishNode(node, "AnyTypeAnnotation")
|
||||
|
||||
case "void":
|
||||
return this.finishNode(node, "VoidTypeAnnotation")
|
||||
|
||||
case "bool":
|
||||
case "boolean":
|
||||
return this.finishNode(node, "BooleanTypeAnnotation")
|
||||
@@ -524,14 +515,8 @@ pp.flow_parsePrimaryType = function () {
|
||||
return this.finishNode(node, "StringLiteralTypeAnnotation")
|
||||
|
||||
default:
|
||||
if (this.type.keyword) {
|
||||
switch (this.type.keyword) {
|
||||
case "void":
|
||||
return this.flow_parseVoidType()
|
||||
|
||||
case "typeof":
|
||||
return this.flow_parseTypeofType()
|
||||
}
|
||||
if (this.type.keyword === "typeof") {
|
||||
return this.flow_parseTypeofType()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -588,13 +573,7 @@ pp.flow_parseType = function () {
|
||||
|
||||
pp.flow_parseTypeAnnotation = function () {
|
||||
var node = this.startNode()
|
||||
|
||||
var oldInType = this.inType
|
||||
this.inType = true
|
||||
this.expect(tt.colon)
|
||||
node.typeAnnotation = this.flow_parseType()
|
||||
this.inType = oldInType
|
||||
|
||||
node.typeAnnotation = this.flow_parseTypeInitialiser()
|
||||
return this.finishNode(node, "TypeAnnotation")
|
||||
}
|
||||
|
||||
@@ -694,6 +673,18 @@ acorn.plugins.flow = function (instance) {
|
||||
}
|
||||
})
|
||||
|
||||
// don't consider `void` to be a keyword as then it'll use the void token type
|
||||
// and set startExpr
|
||||
instance.extend("isKeyword", function (inner) {
|
||||
return function(name) {
|
||||
if (this.inType && name === "void") {
|
||||
return false
|
||||
} else {
|
||||
return inner.call(this, name)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
instance.extend("readToken", function (inner) {
|
||||
return function(code) {
|
||||
if (this.inType && (code === 62 || code === 60)) {
|
||||
@@ -800,16 +791,15 @@ acorn.plugins.flow = function (instance) {
|
||||
|
||||
instance.extend("parseImportSpecifiers", function (inner) {
|
||||
return function (node) {
|
||||
node.isType = false
|
||||
if (this.isContextual("type")) {
|
||||
var start = this.markPosition()
|
||||
var typeId = this.parseIdent()
|
||||
if ((this.type === tt.name && this.value !== "from") || this.type === tt.braceL || this.type === tt.star) {
|
||||
node.isType = true
|
||||
} else {
|
||||
node.specifiers.push(this.parseImportSpecifierDefault(typeId, start))
|
||||
if (this.isContextual("from")) return
|
||||
this.eat(tt.comma)
|
||||
node.importKind = "value"
|
||||
var kind =
|
||||
(this.type === tt._typeof ? "typeof" :
|
||||
(this.isContextual("type") ? "type" : null))
|
||||
if (kind) {
|
||||
var lh = this.lookahead()
|
||||
if ((lh.type === tt.name && lh.value !== "from") || lh.type === tt.braceL || lh.type === tt.star) {
|
||||
this.next()
|
||||
node.importKind = kind
|
||||
}
|
||||
}
|
||||
inner.call(this, node)
|
||||
|
||||
@@ -29,14 +29,23 @@ const pp = Parser.prototype
|
||||
// strict mode, init properties are also not allowed to be repeated.
|
||||
|
||||
pp.checkPropClash = function(prop, propHash) {
|
||||
if (this.options.ecmaVersion >= 6) return
|
||||
if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand))
|
||||
return
|
||||
let key = prop.key, name
|
||||
switch (key.type) {
|
||||
case "Identifier": name = key.name; break
|
||||
case "Literal": name = String(key.value); break
|
||||
default: return
|
||||
}
|
||||
let kind = prop.kind || "init", other
|
||||
let kind = prop.kind
|
||||
if (this.options.ecmaVersion >= 6) {
|
||||
if (name === "__proto__" && kind === "init") {
|
||||
if (propHash.proto) this.raise(key.start, "Redefinition of __proto__ property");
|
||||
propHash.proto = true
|
||||
}
|
||||
return
|
||||
}
|
||||
let other
|
||||
if (has(propHash, name)) {
|
||||
other = propHash[name]
|
||||
let isGetSet = kind !== "init"
|
||||
@@ -260,8 +269,10 @@ pp.parseNoCallExpr = function() {
|
||||
pp.parseExprAtom = function(refShorthandDefaultPos) {
|
||||
let node, canBeArrow = this.potentialArrowAt == this.start
|
||||
switch (this.type) {
|
||||
case tt._this:
|
||||
case tt._super:
|
||||
if (!this.inFunction)
|
||||
this.raise(this.start, "'super' outside of function or class")
|
||||
case tt._this:
|
||||
let type = this.type === tt._this ? "ThisExpression" : "Super"
|
||||
node = this.startNode()
|
||||
this.next()
|
||||
@@ -270,20 +281,6 @@ pp.parseExprAtom = function(refShorthandDefaultPos) {
|
||||
case tt._yield:
|
||||
if (this.inGenerator) this.unexpected()
|
||||
|
||||
case tt._do:
|
||||
if (this.options.features["es7.doExpressions"]) {
|
||||
let node = this.startNode()
|
||||
this.next()
|
||||
var oldInFunction = this.inFunction
|
||||
var oldLabels = this.labels
|
||||
this.labels = []
|
||||
this.inFunction = false
|
||||
node.body = this.parseBlock()
|
||||
this.inFunction = oldInFunction
|
||||
this.labels = oldLabels
|
||||
return this.finishNode(node, "DoExpression")
|
||||
}
|
||||
|
||||
case tt.name:
|
||||
let start = this.markPosition()
|
||||
node = this.startNode()
|
||||
@@ -292,7 +289,7 @@ pp.parseExprAtom = function(refShorthandDefaultPos) {
|
||||
//
|
||||
if (this.options.features["es7.asyncFunctions"]) {
|
||||
// async functions!
|
||||
if (id.name === "async") {
|
||||
if (id.name === "async" && !this.canInsertSemicolon()) {
|
||||
// arrow functions
|
||||
if (this.type === tt.parenL) {
|
||||
let expr = this.parseParenAndDistinguishExpression(start, true, true)
|
||||
@@ -421,9 +418,18 @@ pp.parseParenAndDistinguishExpression = function(start, isAsync, canBeArrow) {
|
||||
}
|
||||
|
||||
let innerStart = this.markPosition(), exprList = [], first = true
|
||||
let refShorthandDefaultPos = {start: 0}, spreadStart, innerParenStart
|
||||
let refShorthandDefaultPos = {start: 0}, spreadStart, innerParenStart, optionalCommaStart
|
||||
while (this.type !== tt.parenR) {
|
||||
first ? first = false : this.expect(tt.comma)
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
this.expect(tt.comma)
|
||||
if (this.type === tt.parenR && this.options.features["es7.trailingFunctionCommas"]) {
|
||||
optionalCommaStart = this.start
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (this.type === tt.ellipsis) {
|
||||
let spreadNodeStart = this.markPosition()
|
||||
spreadStart = this.start
|
||||
@@ -451,6 +457,7 @@ pp.parseParenAndDistinguishExpression = function(start, isAsync, canBeArrow) {
|
||||
this.unexpected(this.lastTokStart)
|
||||
}
|
||||
}
|
||||
if (optionalCommaStart) this.unexpected(optionalCommaStart)
|
||||
if (spreadStart) this.unexpected(spreadStart)
|
||||
if (refShorthandDefaultPos.start) this.unexpected(refShorthandDefaultPos.start)
|
||||
|
||||
@@ -609,6 +616,14 @@ pp.parseObjPropValue = function (prop, start, isGenerator, isAsync, isPattern, r
|
||||
prop.kind = prop.key.name
|
||||
this.parsePropertyName(prop)
|
||||
prop.value = this.parseMethod(false)
|
||||
let paramCount = prop.kind === "get" ? 0 : 1
|
||||
if (prop.value.params.length !== paramCount) {
|
||||
let start = prop.value.start
|
||||
if (prop.kind === "get")
|
||||
this.raise(start, "getter should have no params");
|
||||
else
|
||||
this.raise(start, "setter should have exactly one param")
|
||||
}
|
||||
} else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") {
|
||||
prop.kind = "init"
|
||||
if (isPattern) {
|
||||
@@ -634,12 +649,12 @@ pp.parsePropertyName = function(prop) {
|
||||
prop.computed = true
|
||||
prop.key = this.parseMaybeAssign()
|
||||
this.expect(tt.bracketR)
|
||||
return
|
||||
return prop.key
|
||||
} else {
|
||||
prop.computed = false
|
||||
}
|
||||
}
|
||||
prop.key = (this.type === tt.num || this.type === tt.string) ? this.parseExprAtom() : this.parseIdent(true)
|
||||
return prop.key = (this.type === tt.num || this.type === tt.string) ? this.parseExprAtom() : this.parseIdent(true)
|
||||
}
|
||||
|
||||
// Initialize empty function node.
|
||||
|
||||
@@ -9,6 +9,7 @@ var STATE_KEYS = [
|
||||
"lastTokEnd",
|
||||
"lineStart",
|
||||
"startLoc",
|
||||
"curLine",
|
||||
"endLoc",
|
||||
"start",
|
||||
"pos",
|
||||
@@ -18,7 +19,11 @@ var STATE_KEYS = [
|
||||
"exprAllowed",
|
||||
"potentialArrowAt",
|
||||
"currLine",
|
||||
"input"
|
||||
"input",
|
||||
"inType",
|
||||
"inFunction",
|
||||
"inGenerator",
|
||||
"labels"
|
||||
];
|
||||
|
||||
pp.getState = function () {
|
||||
@@ -28,6 +33,7 @@ pp.getState = function () {
|
||||
state[key] = this[key]
|
||||
}
|
||||
state.context = this.context.slice()
|
||||
state.labels = this.labels.slice()
|
||||
return state
|
||||
};
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ pp.toAssignable = function(node, isBinding) {
|
||||
case "AssignmentExpression":
|
||||
if (node.operator === "=") {
|
||||
node.type = "AssignmentPattern"
|
||||
delete node.operator
|
||||
} else {
|
||||
this.raise(node.left.end, "Only '=' operator can be used for specifying default value.")
|
||||
}
|
||||
@@ -171,7 +172,7 @@ pp.checkLVal = function(expr, isBinding, checkClashes) {
|
||||
break
|
||||
|
||||
case "ObjectPattern":
|
||||
for (let i = 0; i < expr.properties.length; i++) {
|
||||
for (let i = 0; i < expr.properties.length; i++) {
|
||||
var prop = expr.properties[i];
|
||||
if (prop.type === "Property") prop = prop.value;
|
||||
this.checkLVal(prop, isBinding, checkClashes)
|
||||
@@ -194,6 +195,10 @@ pp.checkLVal = function(expr, isBinding, checkClashes) {
|
||||
this.checkLVal(expr.argument, isBinding, checkClashes)
|
||||
break
|
||||
|
||||
case "ParenthesizedExpression":
|
||||
this.checkLVal(expr.expression, isBinding, checkClashes)
|
||||
break
|
||||
|
||||
default:
|
||||
this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " rvalue")
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {has, isArray} from "./util"
|
||||
import {has} from "./util"
|
||||
import {SourceLocation} from "./location"
|
||||
|
||||
// A second optional argument can be given to further configure
|
||||
@@ -94,11 +94,11 @@ export function getOptions(opts) {
|
||||
for (let opt in defaultOptions)
|
||||
options[opt] = opts && has(opts, opt) ? opts[opt] : defaultOptions[opt]
|
||||
|
||||
if (isArray(options.onToken)) {
|
||||
if (Array.isArray(options.onToken)) {
|
||||
let tokens = options.onToken
|
||||
options.onToken = (token) => tokens.push(token)
|
||||
}
|
||||
if (isArray(options.onComment))
|
||||
if (Array.isArray(options.onComment))
|
||||
options.onComment = pushComment(options, options.onComment)
|
||||
|
||||
return options
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import {reservedWords, keywords} from "./identifier"
|
||||
import {types as tt, lineBreak} from "./tokentype"
|
||||
import {types as tt} from "./tokentype"
|
||||
import {lineBreak} from "./whitespace"
|
||||
|
||||
export function Parser(options, input, startPos) {
|
||||
this.options = options
|
||||
this.loadPlugins(this.options.plugins)
|
||||
this.sourceFile = this.options.sourceFile || null
|
||||
this.isKeyword = keywords[this.options.ecmaVersion >= 6 ? 6 : 5]
|
||||
this.isReservedWord = reservedWords[this.options.ecmaVersion]
|
||||
this.input = input
|
||||
this.loadPlugins(this.options.plugins)
|
||||
|
||||
// Set up token state
|
||||
|
||||
|
||||
@@ -83,10 +83,13 @@ pp.parseStatement = function(declaration, topLevel) {
|
||||
return starttype === tt._import ? this.parseImport(node) : this.parseExport(node)
|
||||
|
||||
case tt.name:
|
||||
if (this.options.features["es7.asyncFunctions"] && this.value === "async" && this.lookahead().type === tt._function) {
|
||||
this.next();
|
||||
this.expect(tt._function);
|
||||
return this.parseFunction(node, true, false, true);
|
||||
if (this.options.features["es7.asyncFunctions"] && this.value === "async") {
|
||||
var lookahead = this.lookahead();
|
||||
if (lookahead.type === tt._function && !this.canInsertSemicolon.call(lookahead)) {
|
||||
this.next();
|
||||
this.expect(tt._function);
|
||||
return this.parseFunction(node, true, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
// If the statement does not start with a statement keyword or a
|
||||
@@ -344,7 +347,14 @@ pp.parseLabeledStatement = function(node, maybeName, expr) {
|
||||
for (let i = 0; i < this.labels.length; ++i)
|
||||
if (this.labels[i].name === maybeName) this.raise(expr.start, "Label '" + maybeName + "' is already declared")
|
||||
let kind = this.type.isLoop ? "loop" : this.type === tt._switch ? "switch" : null
|
||||
this.labels.push({name: maybeName, kind: kind})
|
||||
for (let i = this.labels.length - 1; i >= 0; i--) {
|
||||
let label = this.labels[i]
|
||||
if (label.statementStart == node.start) {
|
||||
label.statementStart = this.start;
|
||||
label.kind = kind;
|
||||
} else break;
|
||||
}
|
||||
this.labels.push({name: maybeName, kind: kind, statementStart: this.start})
|
||||
node.body = this.parseStatement(true)
|
||||
this.labels.pop()
|
||||
node.label = expr
|
||||
@@ -463,6 +473,7 @@ pp.parseClass = function(node, isStatement) {
|
||||
this.parseClassId(node, isStatement)
|
||||
this.parseClassSuper(node)
|
||||
var classBody = this.startNode()
|
||||
let hadConstructor = false
|
||||
classBody.body = []
|
||||
this.expect(tt.braceL)
|
||||
let decorators = []
|
||||
@@ -477,16 +488,14 @@ pp.parseClass = function(node, isStatement) {
|
||||
method.decorators = decorators
|
||||
decorators = []
|
||||
}
|
||||
let isMaybeStatic = this.type === tt.name && this.value === "static"
|
||||
var isGenerator = this.eat(tt.star), isAsync = false
|
||||
this.parsePropertyName(method)
|
||||
if (this.type !== tt.parenL && !method.computed && method.key.type === "Identifier" &&
|
||||
method.key.name === "static") {
|
||||
method.static = isMaybeStatic && this.type !== tt.parenL
|
||||
if (method.static) {
|
||||
if (isGenerator) this.unexpected()
|
||||
method['static'] = true
|
||||
isGenerator = this.eat(tt.star)
|
||||
this.parsePropertyName(method)
|
||||
} else {
|
||||
method['static'] = false
|
||||
}
|
||||
if (!isGenerator && method.key.type === "Identifier" && !method.computed && this.isClassProperty()) {
|
||||
classBody.body.push(this.parseClassProperty(method))
|
||||
@@ -497,23 +506,39 @@ pp.parseClass = function(node, isStatement) {
|
||||
isAsync = true
|
||||
this.parsePropertyName(method)
|
||||
}
|
||||
let isGetSet = false
|
||||
method.kind = "method"
|
||||
if (!method.computed && !isGenerator && !isAsync) {
|
||||
if (method.key.type === "Identifier") {
|
||||
if (this.type !== tt.parenL && (method.key.name === "get" || method.key.name === "set")) {
|
||||
method.kind = method.key.name
|
||||
this.parsePropertyName(method)
|
||||
} else if (!method['static'] && method.key.name === "constructor") {
|
||||
method.kind = "constructor"
|
||||
}
|
||||
} else if (!method['static'] && method.key.type === "Literal" && method.key.value === "constructor") {
|
||||
if (!method.computed) {
|
||||
let {key} = method
|
||||
if (!isAsync && !isGenerator && key.type === "Identifier" && this.type !== tt.parenL && (key.name === "get" || key.name === "set")) {
|
||||
isGetSet = true
|
||||
method.kind = key.name
|
||||
key = this.parsePropertyName(method)
|
||||
}
|
||||
if (!method.static && (key.type === "Identifier" && key.name === "constructor" ||
|
||||
key.type === "Literal" && key.value === "constructor")) {
|
||||
if (hadConstructor) this.raise(key.start, "Duplicate constructor in the same class")
|
||||
if (isGetSet) this.raise(key.start, "Constructor can't have get/set modifier")
|
||||
if (isGenerator) this.raise(key.start, "Constructor can't be a generator")
|
||||
if (isAsync) this.raise(key.start, "Constructor can't be an async function")
|
||||
method.kind = "constructor"
|
||||
hadConstructor = true
|
||||
}
|
||||
}
|
||||
if (method.kind === "constructor" && method.decorators) {
|
||||
this.raise(method.start, "You can't attach decorators to a class constructor")
|
||||
}
|
||||
this.parseClassMethod(classBody, method, isGenerator, isAsync)
|
||||
if (isGetSet) {
|
||||
let paramCount = method.kind === "get" ? 0 : 1
|
||||
if (method.value.params.length !== paramCount) {
|
||||
let start = method.value.start
|
||||
if (method.kind === "get")
|
||||
this.raise(start, "getter should have no params");
|
||||
else
|
||||
this.raise(start, "setter should have exactly one param")
|
||||
}
|
||||
}
|
||||
}
|
||||
if (decorators.length) {
|
||||
this.raise(this.start, "You have trailing decorators with no method");
|
||||
|
||||
@@ -25,6 +25,9 @@ export class Token {
|
||||
|
||||
const pp = Parser.prototype
|
||||
|
||||
// Are we running under Rhino?
|
||||
const isRhino = typeof Packages == "object" && Object.prototype.toString.call(Packages) == "[object JavaPackage]"
|
||||
|
||||
// Move to the next token
|
||||
|
||||
pp.next = function() {
|
||||
@@ -430,23 +433,30 @@ pp.readRegexp = function() {
|
||||
// negatives in unlikely scenarios. For example, `[\u{61}-b]` is a
|
||||
// perfectly valid pattern that is equivalent to `[a-b]`, but it would
|
||||
// be replaced by `[x-b]` which throws an error.
|
||||
tmp = tmp.replace(/\\u([a-fA-F0-9]{4})|\\u\{([0-9a-fA-F]+)\}|[\uD800-\uDBFF][\uDC00-\uDFFF]/g, "x")
|
||||
tmp = tmp.replace(/\\u\{([0-9a-fA-F]+)\}/g, (match, code, offset) => {
|
||||
code = Number("0x" + code)
|
||||
if (code > 0x10FFFF) this.raise(start + offset + 3, "Code point out of bounds")
|
||||
return "x"
|
||||
});
|
||||
tmp = tmp.replace(/\\u([a-fA-F0-9]{4})|[\uD800-\uDBFF][\uDC00-\uDFFF]/g, "x")
|
||||
}
|
||||
}
|
||||
// Detect invalid regular expressions.
|
||||
try {
|
||||
new RegExp(tmp)
|
||||
} catch (e) {
|
||||
if (e instanceof SyntaxError) this.raise(start, "Error parsing regular expression: " + e.message)
|
||||
this.raise(e)
|
||||
}
|
||||
// Get a regular expression object for this pattern-flag pair, or `null` in
|
||||
// case the current environment doesn't support the flags it uses.
|
||||
let value
|
||||
try {
|
||||
value = new RegExp(content, mods)
|
||||
} catch (err) {
|
||||
value = null
|
||||
let value = null
|
||||
// Rhino's regular expression parser is flaky and throws uncatchable exceptions,
|
||||
// so don't do detection if we are running under Rhino
|
||||
if (!isRhino) {
|
||||
try {
|
||||
new RegExp(tmp)
|
||||
} catch (e) {
|
||||
if (e instanceof SyntaxError) this.raise(start, "Error parsing regular expression: " + e.message)
|
||||
this.raise(e)
|
||||
}
|
||||
// Get a regular expression object for this pattern-flag pair, or `null` in
|
||||
// case the current environment doesn't support the flags it uses.
|
||||
try {
|
||||
value = new RegExp(content, mods)
|
||||
} catch (err) {}
|
||||
}
|
||||
return this.finishToken(tt.regexp, {pattern: content, flags: mods, value: value})
|
||||
}
|
||||
@@ -514,10 +524,10 @@ pp.readCodePoint = function() {
|
||||
|
||||
if (ch === 123) {
|
||||
if (this.options.ecmaVersion < 6) this.unexpected()
|
||||
++this.pos
|
||||
let codePos = ++this.pos
|
||||
code = this.readHexChar(this.input.indexOf('}', this.pos) - this.pos)
|
||||
++this.pos
|
||||
if (code > 0x10FFFF) this.unexpected()
|
||||
if (code > 0x10FFFF) this.raise(codePos, "Code point out of bounds")
|
||||
} else {
|
||||
code = this.readHexChar(4)
|
||||
}
|
||||
@@ -539,7 +549,7 @@ pp.readString = function(quote) {
|
||||
if (ch === quote) break
|
||||
if (ch === 92) { // '\'
|
||||
out += this.input.slice(chunkStart, this.pos)
|
||||
out += this.readEscapedChar()
|
||||
out += this.readEscapedChar(false)
|
||||
chunkStart = this.pos
|
||||
} else {
|
||||
if (isNewLine(ch)) this.raise(this.start, "Unterminated string constant")
|
||||
@@ -572,7 +582,7 @@ pp.readTmplToken = function() {
|
||||
}
|
||||
if (ch === 92) { // '\'
|
||||
out += this.input.slice(chunkStart, this.pos)
|
||||
out += this.readEscapedChar()
|
||||
out += this.readEscapedChar(true)
|
||||
chunkStart = this.pos
|
||||
} else if (isNewLine(ch)) {
|
||||
out += this.input.slice(chunkStart, this.pos)
|
||||
@@ -600,42 +610,46 @@ pp.readTmplToken = function() {
|
||||
|
||||
// Used to read escaped characters
|
||||
|
||||
pp.readEscapedChar = function() {
|
||||
pp.readEscapedChar = function(inTemplate) {
|
||||
let ch = this.input.charCodeAt(++this.pos)
|
||||
let octal = /^[0-7]+/.exec(this.input.slice(this.pos, this.pos + 3))
|
||||
if (octal) octal = octal[0]
|
||||
while (octal && parseInt(octal, 8) > 255) octal = octal.slice(0, -1)
|
||||
if (octal === "0") octal = null
|
||||
++this.pos
|
||||
if (octal) {
|
||||
if (this.strict) this.raise(this.pos - 2, "Octal literal in strict mode")
|
||||
this.pos += octal.length - 1
|
||||
return String.fromCharCode(parseInt(octal, 8))
|
||||
} else {
|
||||
switch (ch) {
|
||||
case 110: return "\n"; // 'n' -> '\n'
|
||||
case 114: return "\r"; // 'r' -> '\r'
|
||||
case 120: return String.fromCharCode(this.readHexChar(2)); // 'x'
|
||||
case 117: return codePointToString(this.readCodePoint()); // 'u'
|
||||
case 116: return "\t"; // 't' -> '\t'
|
||||
case 98: return "\b"; // 'b' -> '\b'
|
||||
case 118: return "\u000b"; // 'v' -> '\u000b'
|
||||
case 102: return "\f"; // 'f' -> '\f'
|
||||
case 48: return "\0"; // 0 -> '\0'
|
||||
case 13: if (this.input.charCodeAt(this.pos) === 10) ++this.pos; // '\r\n'
|
||||
case 10: // ' \n'
|
||||
if (this.options.locations) { this.lineStart = this.pos; ++this.curLine }
|
||||
return ""
|
||||
default: return String.fromCharCode(ch)
|
||||
switch (ch) {
|
||||
case 110: return "\n"; // 'n' -> '\n'
|
||||
case 114: return "\r"; // 'r' -> '\r'
|
||||
case 120: return String.fromCharCode(this.readHexChar(2)); // 'x'
|
||||
case 117: return codePointToString(this.readCodePoint()); // 'u'
|
||||
case 116: return "\t"; // 't' -> '\t'
|
||||
case 98: return "\b"; // 'b' -> '\b'
|
||||
case 118: return "\u000b"; // 'v' -> '\u000b'
|
||||
case 102: return "\f"; // 'f' -> '\f'
|
||||
case 13: if (this.input.charCodeAt(this.pos) === 10) ++this.pos; // '\r\n'
|
||||
case 10: // ' \n'
|
||||
if (this.options.locations) { this.lineStart = this.pos; ++this.curLine }
|
||||
return ""
|
||||
default:
|
||||
if (ch >= 48 && ch <= 55) {
|
||||
let octalStr = this.input.substr(this.pos - 1, 3).match(/^[0-7]+/)[0]
|
||||
let octal = parseInt(octalStr, 8)
|
||||
if (octal > 255) {
|
||||
octalStr = octalStr.slice(0, -1)
|
||||
octal = parseInt(octalStr, 8)
|
||||
}
|
||||
if (octal > 0 && (this.strict || inTemplate)) {
|
||||
this.raise(this.pos - 2, "Octal literal in strict mode")
|
||||
}
|
||||
this.pos += octalStr.length - 1
|
||||
return String.fromCharCode(octal)
|
||||
}
|
||||
return String.fromCharCode(ch)
|
||||
}
|
||||
}
|
||||
|
||||
// Used to read character escape sequences ('\x', '\u', '\U').
|
||||
|
||||
pp.readHexChar = function(len) {
|
||||
let codePos = this.pos
|
||||
let n = this.readInt(16, len)
|
||||
if (n === null) this.raise(this.start, "Bad character escape sequence")
|
||||
if (n === null) this.raise(codePos, "Bad character escape sequence")
|
||||
return n
|
||||
}
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@ kw("case", beforeExpr)
|
||||
kw("catch")
|
||||
kw("continue")
|
||||
kw("debugger")
|
||||
kw("default")
|
||||
kw("default", beforeExpr)
|
||||
kw("do", {isLoop: true})
|
||||
kw("else", beforeExpr)
|
||||
kw("finally")
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
export function isArray(obj) {
|
||||
return Object.prototype.toString.call(obj) === "[object Array]"
|
||||
}
|
||||
|
||||
// Checks if an object has a property.
|
||||
|
||||
export function has(obj, propName) {
|
||||
|
||||
4
src/babel/README.md
Normal file
4
src/babel/README.md
Normal file
@@ -0,0 +1,4 @@
|
||||
## Diving into Babel
|
||||
|
||||
If you look around in the various directories in here you'll find some details
|
||||
about the organization of the Babel codebase.
|
||||
18
src/babel/api/README.md
Normal file
18
src/babel/api/README.md
Normal file
@@ -0,0 +1,18 @@
|
||||
## API
|
||||
|
||||
In this directory you'll find all the public interfaces to using Babel for both
|
||||
node and the browser.
|
||||
|
||||
### Node
|
||||
|
||||
There are two ways people use Babel within Node, they either are manipulating
|
||||
strings of code with `babel.transform` or `babel.parse`, they also might be
|
||||
running their code through Babel before execution via `register` or `polyfill`.
|
||||
|
||||
### Browser
|
||||
|
||||
Usage of Babel in the browser is extremely uncommon and in most cases
|
||||
considered A Bad Idea™. However it works by loading `<script>`'s with XHR,
|
||||
transforming them and then executing them. These `<script>`'s need to have a
|
||||
`type` of "text/ecmascript-6", "text/babel", or "module" ("text/6to5" exists as
|
||||
well for legacy reasons).
|
||||
@@ -3,16 +3,32 @@
|
||||
require("./node");
|
||||
var transform = module.exports = require("../transformation");
|
||||
|
||||
/**
|
||||
* Add `options` and `version` to `babel` global.
|
||||
*/
|
||||
|
||||
transform.options = require("../transformation/file/options");
|
||||
transform.version = require("../../../package").version;
|
||||
|
||||
/**
|
||||
* Add `transform` api to `babel` global.
|
||||
*/
|
||||
|
||||
transform.transform = transform;
|
||||
|
||||
/**
|
||||
* Tranform and execute script, adding in inline sourcemaps.
|
||||
*/
|
||||
|
||||
transform.run = function (code, opts = {}) {
|
||||
opts.sourceMaps = "inline";
|
||||
return new Function(transform(code, opts).code)();
|
||||
};
|
||||
|
||||
/**
|
||||
* Load scripts via xhr, and `transform` when complete (optional).
|
||||
*/
|
||||
|
||||
transform.load = function (url, callback, opts = {}, hold) {
|
||||
opts.filename = opts.filename || url;
|
||||
|
||||
@@ -20,6 +36,10 @@ transform.load = function (url, callback, opts = {}, hold) {
|
||||
xhr.open("GET", url, true);
|
||||
if ("overrideMimeType" in xhr) xhr.overrideMimeType("text/plain");
|
||||
|
||||
/**
|
||||
* When successfully loaded, transform (optional), and call `callback`.
|
||||
*/
|
||||
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState !== 4) return;
|
||||
|
||||
@@ -36,11 +56,22 @@ transform.load = function (url, callback, opts = {}, hold) {
|
||||
xhr.send(null);
|
||||
};
|
||||
|
||||
/**
|
||||
* Load and transform all scripts of `types`.
|
||||
*
|
||||
* @example
|
||||
* <script type="module"></script>
|
||||
*/
|
||||
|
||||
var runScripts = function () {
|
||||
var scripts = [];
|
||||
var types = ["text/ecmascript-6", "text/6to5", "text/babel", "module"];
|
||||
var index = 0;
|
||||
|
||||
/**
|
||||
* Transform and execute script. Ensures correct load order.
|
||||
*/
|
||||
|
||||
var exec = function () {
|
||||
var param = scripts[index];
|
||||
if (param instanceof Array) {
|
||||
@@ -50,6 +81,10 @@ var runScripts = function () {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Load, transform, and execute all scripts.
|
||||
*/
|
||||
|
||||
var run = function (script, i) {
|
||||
var opts = {};
|
||||
|
||||
@@ -64,7 +99,9 @@ var runScripts = function () {
|
||||
}
|
||||
};
|
||||
|
||||
var _scripts = global.document .getElementsByTagName("script");
|
||||
// Collect scripts with Babel `types`.
|
||||
|
||||
var _scripts = global.document.getElementsByTagName("script");
|
||||
|
||||
for (var i = 0; i < _scripts.length; ++i) {
|
||||
var _script = _scripts[i];
|
||||
@@ -78,6 +115,10 @@ var runScripts = function () {
|
||||
exec();
|
||||
};
|
||||
|
||||
/**
|
||||
* Register load event to transform and execute scripts.
|
||||
*/
|
||||
|
||||
if (global.addEventListener) {
|
||||
global.addEventListener("DOMContentLoaded", runScripts, false);
|
||||
} else if (global.attachEvent) {
|
||||
|
||||
@@ -8,9 +8,10 @@ export { util, acorn, transform };
|
||||
export { pipeline } from "../transformation";
|
||||
export { canCompile } from "../util";
|
||||
|
||||
export { default as options } from "../transformation/file/options";
|
||||
export { default as options } from "../transformation/file/options/config";
|
||||
export { default as Plugin } from "../transformation/plugin";
|
||||
export { default as Transformer } from "../transformation/transformer";
|
||||
export { default as TransformerPipeline } from "../transformation/transformer-pipeline";
|
||||
export { default as Pipeline } from "../transformation/pipeline";
|
||||
export { default as traverse } from "../traversal";
|
||||
export { default as buildExternalHelpers } from "../tools/build-external-helpers";
|
||||
export { version } from "../../../package";
|
||||
@@ -18,16 +19,28 @@ export { version } from "../../../package";
|
||||
import * as t from "../types";
|
||||
export { t as types };
|
||||
|
||||
/**
|
||||
* Register Babel and polyfill globally.
|
||||
*/
|
||||
|
||||
export function register(opts?: Object) {
|
||||
var callback = require("./register/node-polyfill");
|
||||
if (opts != null) callback(opts);
|
||||
return callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register polyfill globally.
|
||||
*/
|
||||
|
||||
export function polyfill() {
|
||||
require("../polyfill");
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously transform `filename` with optional `opts`, calls `callback` when complete.
|
||||
*/
|
||||
|
||||
export function transformFile(filename: string, opts?: Object, callback: Function) {
|
||||
if (isFunction(opts)) {
|
||||
callback = opts;
|
||||
@@ -51,11 +64,19 @@ export function transformFile(filename: string, opts?: Object, callback: Functio
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronous form of `transformFile`.
|
||||
*/
|
||||
|
||||
export function transformFileSync(filename: string, opts?: Object = {}) {
|
||||
opts.filename = filename;
|
||||
return transform(fs.readFileSync(filename, "utf8"), opts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse script with Babel's parser.
|
||||
*/
|
||||
|
||||
export function parse(code, opts = {}) {
|
||||
opts.allowHashBang = true;
|
||||
opts.sourceType = "module";
|
||||
|
||||
@@ -1,21 +1,30 @@
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
import homeOrTmp from "home-or-tmp";
|
||||
import pathExists from "path-exists";
|
||||
|
||||
const FILENAME = process.env.BABEL_CACHE_PATH || path.join(homeOrTmp, ".babel.json");
|
||||
var data = {};
|
||||
|
||||
/**
|
||||
* Write stringified cache to disk.
|
||||
*/
|
||||
|
||||
export function save() {
|
||||
fs.writeFileSync(FILENAME, JSON.stringify(data, null, " "));
|
||||
}
|
||||
|
||||
/**
|
||||
* Load cache from disk and parse.
|
||||
*/
|
||||
|
||||
export function load() {
|
||||
if (process.env.BABEL_DISABLE_CACHE) return;
|
||||
|
||||
process.on("exit", save);
|
||||
process.nextTick(save);
|
||||
|
||||
if (!fs.existsSync(FILENAME)) return;
|
||||
if (!pathExists.sync(FILENAME)) return;
|
||||
|
||||
try {
|
||||
data = JSON.parse(fs.readFileSync(FILENAME));
|
||||
@@ -24,6 +33,10 @@ export function load() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve data from cache.
|
||||
*/
|
||||
|
||||
export function get() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import sourceMapSupport from "source-map-support";
|
||||
import * as registerCache from "./cache";
|
||||
import resolveRc from "../../tools/resolve-rc";
|
||||
import OptionManager from "../../transformation/file/options/option-manager";
|
||||
import extend from "lodash/object/extend";
|
||||
import * as babel from "../node";
|
||||
import each from "lodash/collection/each";
|
||||
@@ -8,6 +8,10 @@ import * as util from "../../util";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
|
||||
/**
|
||||
* Install sourcemaps into node.
|
||||
*/
|
||||
|
||||
sourceMapSupport.install({
|
||||
handleUncaughtExceptions: false,
|
||||
retrieveSourceMap(source) {
|
||||
@@ -23,12 +27,16 @@ sourceMapSupport.install({
|
||||
}
|
||||
});
|
||||
|
||||
//
|
||||
/**
|
||||
* Load and setup cache.
|
||||
*/
|
||||
|
||||
registerCache.load();
|
||||
var cache = registerCache.get();
|
||||
|
||||
//
|
||||
/**
|
||||
* Store options.
|
||||
*/
|
||||
|
||||
var transformOpts = {};
|
||||
|
||||
@@ -38,24 +46,34 @@ var only;
|
||||
var oldHandlers = {};
|
||||
var maps = {};
|
||||
|
||||
var cwd = require.main ? require.main.filename : process.cwd();
|
||||
var cwd = process.cwd();
|
||||
|
||||
/**
|
||||
* Get path from `filename` relative to the current working directory.
|
||||
*/
|
||||
|
||||
var getRelativePath = function (filename){
|
||||
return path.relative(cwd, filename);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get last modified time for a `filename`.
|
||||
*/
|
||||
|
||||
var mtime = function (filename) {
|
||||
return +fs.statSync(filename).mtime;
|
||||
};
|
||||
|
||||
/**
|
||||
* Compile a `filename` with optional `opts`.
|
||||
*/
|
||||
|
||||
var compile = function (filename, opts = {}) {
|
||||
var result;
|
||||
|
||||
opts = extend(opts, transformOpts);
|
||||
|
||||
// this will be done when the file is transformed anyway but we need all
|
||||
// the options so we can generate the cache key
|
||||
resolveRc(filename, opts);
|
||||
var optsManager = new OptionManager;
|
||||
optsManager.mergeOptions(transformOpts);
|
||||
opts = optsManager.init(opts);
|
||||
|
||||
var cacheKey = `${filename}:${JSON.stringify(opts)}:${babel.version}`;
|
||||
|
||||
@@ -86,14 +104,22 @@ var compile = function (filename, opts = {}) {
|
||||
return result.code;
|
||||
};
|
||||
|
||||
/**
|
||||
* Test if a `filename` should be ignored by Babel.
|
||||
*/
|
||||
|
||||
var shouldIgnore = function (filename) {
|
||||
if (!ignore && !only) {
|
||||
return getRelativePath(filename).split(path.sep).indexOf("node_modules") >= 0;
|
||||
} else {
|
||||
return util.shouldIgnore(filename, ignore || [], only || []);
|
||||
return util.shouldIgnore(filename, ignore || [], only);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Monkey patch istanbul if it is running so that it works properly.
|
||||
*/
|
||||
|
||||
var istanbulMonkey = {};
|
||||
|
||||
if (process.env.running_under_istanbul) {
|
||||
@@ -105,7 +131,7 @@ if (process.env.running_under_istanbul) {
|
||||
if (istanbulMonkey[filename]) {
|
||||
delete istanbulMonkey[filename];
|
||||
var code = compile(filename, {
|
||||
attachAuxiliaryComment: "istanbul ignore next"
|
||||
auxiliaryCommentBefore: "istanbul ignore next"
|
||||
});
|
||||
istanbulMonkey[filename] = true;
|
||||
return code;
|
||||
@@ -115,17 +141,29 @@ if (process.env.running_under_istanbul) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Replacement for the loader for istanbul.
|
||||
*/
|
||||
|
||||
var istanbulLoader = function (m, filename, old) {
|
||||
istanbulMonkey[filename] = true;
|
||||
old(m, filename);
|
||||
};
|
||||
|
||||
/**
|
||||
* Default loader.
|
||||
*/
|
||||
|
||||
var normalLoader = function (m, filename) {
|
||||
m._compile(compile(filename), filename);
|
||||
};
|
||||
|
||||
/**
|
||||
* Register a loader for an extension.
|
||||
*/
|
||||
|
||||
var registerExtension = function (ext) {
|
||||
var old = oldHandlers[ext] || oldHandlers[".js"];
|
||||
var old = oldHandlers[ext] || oldHandlers[".js"] || require.extensions[".js"];
|
||||
|
||||
var loader = normalLoader;
|
||||
if (process.env.running_under_istanbul) loader = istanbulLoader;
|
||||
@@ -139,6 +177,10 @@ var registerExtension = function (ext) {
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Register loader for given extensions.
|
||||
*/
|
||||
|
||||
var hookExtensions = function (_exts) {
|
||||
each(oldHandlers, function (old, ext) {
|
||||
if (old === undefined) {
|
||||
@@ -156,8 +198,16 @@ var hookExtensions = function (_exts) {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Register loader for default extensions.
|
||||
*/
|
||||
|
||||
hookExtensions(util.canCompile.EXTENSIONS);
|
||||
|
||||
/**
|
||||
* Update options at runtime.
|
||||
*/
|
||||
|
||||
export default function (opts = {}) {
|
||||
if (opts.only != null) only = util.arrayify(opts.only, util.regexify);
|
||||
if (opts.ignore != null) ignore = util.arrayify(opts.ignore, util.regexify);
|
||||
|
||||
16
src/babel/generation/README.md
Normal file
16
src/babel/generation/README.md
Normal file
@@ -0,0 +1,16 @@
|
||||
## Generation
|
||||
|
||||
Here is Babel's code generator, here you'll find all of the code to turn an AST
|
||||
back into a string of code.
|
||||
|
||||
[TBD: To Be Documented:]
|
||||
|
||||
- Code Generator
|
||||
- Buffer
|
||||
- Source Maps
|
||||
- Position
|
||||
- Printer
|
||||
- Code Style
|
||||
- Whitespace
|
||||
- Parenthesis
|
||||
- Generators
|
||||
@@ -4,6 +4,10 @@ import isBoolean from "lodash/lang/isBoolean";
|
||||
import includes from "lodash/collection/includes";
|
||||
import isNumber from "lodash/lang/isNumber";
|
||||
|
||||
/**
|
||||
* Buffer for collecting generated output.
|
||||
*/
|
||||
|
||||
export default class Buffer {
|
||||
constructor(position, format) {
|
||||
this.position = position;
|
||||
@@ -12,10 +16,18 @@ export default class Buffer {
|
||||
this.buf = "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current trimmed buffer.
|
||||
*/
|
||||
|
||||
get() {
|
||||
return trimRight(this.buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current indent.
|
||||
*/
|
||||
|
||||
getIndent() {
|
||||
if (this.format.compact || this.format.concise) {
|
||||
return "";
|
||||
@@ -24,43 +36,80 @@ export default class Buffer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current indent size.
|
||||
*/
|
||||
|
||||
indentSize() {
|
||||
return this.getIndent().length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment indent size.
|
||||
*/
|
||||
|
||||
indent() {
|
||||
this._indent++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrement indent size.
|
||||
*/
|
||||
|
||||
dedent() {
|
||||
this._indent--;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a semicolon to the buffer.
|
||||
*/
|
||||
|
||||
semicolon() {
|
||||
this.push(";");
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure last character is a semicolon.
|
||||
*/
|
||||
|
||||
ensureSemicolon() {
|
||||
if (!this.isLast(";")) this.semicolon();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a right brace to the buffer.
|
||||
*/
|
||||
|
||||
rightBrace() {
|
||||
this.newline(true);
|
||||
this.push("}");
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a keyword to the buffer.
|
||||
*/
|
||||
|
||||
keyword(name) {
|
||||
this.push(name);
|
||||
this.space();
|
||||
}
|
||||
|
||||
space() {
|
||||
if (this.format.compact) return;
|
||||
if (this.buf && !this.isLast(" ") && !this.isLast("\n")) {
|
||||
/**
|
||||
* Add a space to the buffer unless it is compact (override with force).
|
||||
*/
|
||||
|
||||
space(force?) {
|
||||
if (!force && this.format.compact) return;
|
||||
|
||||
if (force || this.buf && !this.isLast(" ") && !this.isLast("\n")) {
|
||||
this.push(" ");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the last character.
|
||||
*/
|
||||
|
||||
removeLast(cha) {
|
||||
if (this.format.compact) return;
|
||||
if (!this.isLast(cha)) return;
|
||||
@@ -69,6 +118,11 @@ export default class Buffer {
|
||||
this.position.unshift(cha);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a newline (or many newlines), maintaining formatting.
|
||||
* Strips multiple newlines if removeLast is true.
|
||||
*/
|
||||
|
||||
newline(i, removeLast) {
|
||||
if (this.format.compact || this.format.retainLines) return;
|
||||
|
||||
@@ -99,6 +153,10 @@ export default class Buffer {
|
||||
this._newline(removeLast);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a newline unless there is already two previous newlines.
|
||||
*/
|
||||
|
||||
_newline(removeLast) {
|
||||
// never allow more than two lines
|
||||
if (this.endsWith("\n\n")) return;
|
||||
@@ -135,6 +193,10 @@ export default class Buffer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Push a string to the buffer, maintaining indentation and newlines.
|
||||
*/
|
||||
|
||||
push(str, noIndent) {
|
||||
if (!this.format.compact && this._indent && !noIndent && str !== "\n") {
|
||||
// we have an indent level and we aren't pushing a newline
|
||||
@@ -150,15 +212,31 @@ export default class Buffer {
|
||||
this._push(str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Push a string to the buffer.
|
||||
*/
|
||||
|
||||
_push(str) {
|
||||
this.position.push(str);
|
||||
this.buf += str;
|
||||
}
|
||||
|
||||
endsWith(str) {
|
||||
return this.buf.slice(-str.length) === str;
|
||||
/**
|
||||
* Test if the buffer ends with a string.
|
||||
*/
|
||||
|
||||
endsWith(str, buf = this.buf) {
|
||||
if (str.length === 1) {
|
||||
return buf[buf.length - 1] === str;
|
||||
} else {
|
||||
return buf.slice(-str.length) === str;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if a character is last in the buffer.
|
||||
*/
|
||||
|
||||
isLast(cha) {
|
||||
if (this.format.compact) return false;
|
||||
|
||||
|
||||
10
src/babel/generation/generators/README.md
Normal file
10
src/babel/generation/generators/README.md
Normal file
@@ -0,0 +1,10 @@
|
||||
## Generators
|
||||
|
||||
Code generation in Babel is broken down into generators by node type, they all
|
||||
live in this directory.
|
||||
|
||||
[TBD: To Be Documented:]
|
||||
|
||||
- How generators work
|
||||
- How to print a node
|
||||
- How generators related to one another
|
||||
@@ -1,11 +1,23 @@
|
||||
/**
|
||||
* Print File.program
|
||||
*/
|
||||
|
||||
export function File(node, print) {
|
||||
print.plain(node.program);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print all nodes in a Program.body.
|
||||
*/
|
||||
|
||||
export function Program(node, print) {
|
||||
print.sequence(node.body);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print BlockStatement, collapses empty blocks, prints body.
|
||||
*/
|
||||
|
||||
export function BlockStatement(node, print) {
|
||||
if (node.body.length === 0) {
|
||||
this.push("{}");
|
||||
@@ -17,3 +29,14 @@ export function BlockStatement(node, print) {
|
||||
this.rightBrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* What is my purpose?
|
||||
* Why am I here?
|
||||
* Why are any of us here?
|
||||
* Does any of this really matter?
|
||||
*/
|
||||
|
||||
export function Noop() {
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
/**
|
||||
* Print ClassDeclaration, prints decorators, typeParameters, extends, implements, and body.
|
||||
*/
|
||||
|
||||
export function ClassDeclaration(node, print) {
|
||||
print.list(node.decorators);
|
||||
print.list(node.decorators, { separator: "" });
|
||||
this.push("class");
|
||||
|
||||
if (node.id) {
|
||||
@@ -24,8 +28,16 @@ export function ClassDeclaration(node, print) {
|
||||
print.plain(node.body);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias ClassDeclaration printer as ClassExpression.
|
||||
*/
|
||||
|
||||
export { ClassDeclaration as ClassExpression };
|
||||
|
||||
/**
|
||||
* Print ClassBody, collapses empty blocks, prints body.
|
||||
*/
|
||||
|
||||
export function ClassBody(node, print) {
|
||||
if (node.body.length === 0) {
|
||||
this.push("{}");
|
||||
@@ -41,9 +53,13 @@ export function ClassBody(node, print) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print ClassProperty, prints decorators, static, key, typeAnnotation, and value.
|
||||
* Also: semicolons, deal with it.
|
||||
*/
|
||||
|
||||
export function ClassProperty(node, print) {
|
||||
print.list(node.decorators);
|
||||
print.list(node.decorators, { separator: "" });
|
||||
|
||||
if (node.static) this.push("static ");
|
||||
print.plain(node.key);
|
||||
@@ -57,8 +73,12 @@ export function ClassProperty(node, print) {
|
||||
this.semicolon();
|
||||
}
|
||||
|
||||
/**
|
||||
* Print MethodDefinition, prints decorations, static, and method.
|
||||
*/
|
||||
|
||||
export function MethodDefinition(node, print) {
|
||||
print.list(node.decorators);
|
||||
print.list(node.decorators, { separator: "" });
|
||||
|
||||
if (node.static) {
|
||||
this.push("static ");
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* Prints ComprehensionBlock, prints left and right.
|
||||
*/
|
||||
|
||||
export function ComprehensionBlock(node, print) {
|
||||
this.keyword("for");
|
||||
this.push("(");
|
||||
@@ -7,6 +11,10 @@ export function ComprehensionBlock(node, print) {
|
||||
this.push(")");
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints ComprehensionExpression, prints blocks, filter, and body. Handles generators.
|
||||
*/
|
||||
|
||||
export function ComprehensionExpression(node, print) {
|
||||
this.push(node.generator ? "(" : "[");
|
||||
|
||||
|
||||
@@ -1,30 +1,41 @@
|
||||
import isInteger from "is-integer";
|
||||
import isNumber from "lodash/lang/isNumber";
|
||||
import * as t from "../../types";
|
||||
|
||||
/**
|
||||
* Prints UnaryExpression, prints operator and argument.
|
||||
*/
|
||||
|
||||
export function UnaryExpression(node, print) {
|
||||
var hasSpace = /[a-z]$/.test(node.operator);
|
||||
var needsSpace = /[a-z]$/.test(node.operator);
|
||||
var arg = node.argument;
|
||||
|
||||
if (t.isUpdateExpression(arg) || t.isUnaryExpression(arg)) {
|
||||
hasSpace = true;
|
||||
needsSpace = true;
|
||||
}
|
||||
|
||||
if (t.isUnaryExpression(arg) && arg.operator === "!") {
|
||||
hasSpace = false;
|
||||
needsSpace = false;
|
||||
}
|
||||
|
||||
this.push(node.operator);
|
||||
if (hasSpace) this.push(" ");
|
||||
if (needsSpace) this.push(" ");
|
||||
print.plain(node.argument);
|
||||
}
|
||||
|
||||
export function DoExpression(node, print) {
|
||||
this.push("do");
|
||||
this.space();
|
||||
print.plain(node.body);
|
||||
/**
|
||||
* Prints ParenthesizedExpression, prints expression.
|
||||
*/
|
||||
|
||||
export function ParenthesizedExpression(node, print) {
|
||||
this.push("(");
|
||||
print.plain(node.expression);
|
||||
this.push(")");
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints UpdateExpression, prints operator and argument.
|
||||
*/
|
||||
|
||||
export function UpdateExpression(node, print) {
|
||||
if (node.prefix) {
|
||||
this.push(node.operator);
|
||||
@@ -35,6 +46,10 @@ export function UpdateExpression(node, print) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints ConditionalExpression, prints test, consequent, and alternate.
|
||||
*/
|
||||
|
||||
export function ConditionalExpression(node, print) {
|
||||
print.plain(node.test);
|
||||
this.space();
|
||||
@@ -47,6 +62,10 @@ export function ConditionalExpression(node, print) {
|
||||
print.plain(node.alternate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints NewExpression, prints callee and arguments.
|
||||
*/
|
||||
|
||||
export function NewExpression(node, print) {
|
||||
this.push("new ");
|
||||
print.plain(node.callee);
|
||||
@@ -55,41 +74,59 @@ export function NewExpression(node, print) {
|
||||
this.push(")");
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints SequenceExpression.expressions.
|
||||
*/
|
||||
|
||||
export function SequenceExpression(node, print) {
|
||||
print.list(node.expressions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints ThisExpression.
|
||||
*/
|
||||
|
||||
export function ThisExpression() {
|
||||
this.push("this");
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints Super.
|
||||
*/
|
||||
|
||||
export function Super() {
|
||||
this.push("super");
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints Decorator, prints expression.
|
||||
*/
|
||||
|
||||
export function Decorator(node, print) {
|
||||
this.push("@");
|
||||
print.plain(node.expression);
|
||||
this.newline();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints CallExpression, prints callee and arguments.
|
||||
*/
|
||||
|
||||
export function CallExpression(node, print) {
|
||||
print.plain(node.callee);
|
||||
|
||||
this.push("(");
|
||||
|
||||
var separator = ",";
|
||||
|
||||
var isPrettyCall = node._prettyCall && !this.format.retainLines;
|
||||
var isPrettyCall = node._prettyCall && !this.format.retainLines && !this.format.compact;
|
||||
|
||||
var separator;
|
||||
if (isPrettyCall) {
|
||||
separator += "\n";
|
||||
separator = ",\n";
|
||||
this.newline();
|
||||
this.indent();
|
||||
} else {
|
||||
separator += " ";
|
||||
}
|
||||
|
||||
print.list(node.arguments, { separator: separator });
|
||||
print.list(node.arguments, { separator });
|
||||
|
||||
if (isPrettyCall) {
|
||||
this.newline();
|
||||
@@ -99,6 +136,11 @@ export function CallExpression(node, print) {
|
||||
this.push(")");
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds yield or await expression printer.
|
||||
* Prints delegate, all, and argument.
|
||||
*/
|
||||
|
||||
var buildYieldAwait = function (keyword) {
|
||||
return function (node, print) {
|
||||
this.push(keyword);
|
||||
@@ -114,40 +156,90 @@ var buildYieldAwait = function (keyword) {
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Create YieldExpression and AwaitExpression printers.
|
||||
*/
|
||||
|
||||
export var YieldExpression = buildYieldAwait("yield");
|
||||
export var AwaitExpression = buildYieldAwait("await");
|
||||
|
||||
/**
|
||||
* Prints EmptyStatement.
|
||||
*/
|
||||
|
||||
export function EmptyStatement() {
|
||||
this.semicolon();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints ExpressionStatement, prints expression.
|
||||
*/
|
||||
|
||||
export function ExpressionStatement(node, print) {
|
||||
print.plain(node.expression);
|
||||
this.semicolon();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints AssignmentPattern, prints left and right.
|
||||
*/
|
||||
|
||||
export function AssignmentPattern(node, print) {
|
||||
print.plain(node.left);
|
||||
this.push(" = ");
|
||||
print.plain(node.right);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints AssignmentExpression, prints left, operator, and right.
|
||||
*/
|
||||
|
||||
export function AssignmentExpression(node, print) {
|
||||
// todo: add cases where the spaces can be dropped when in compact mode
|
||||
print.plain(node.left);
|
||||
this.push(" ");
|
||||
|
||||
var spaces = node.operator === "in" || node.operator === "instanceof";
|
||||
spaces = true; // todo: https://github.com/babel/babel/issues/1835
|
||||
this.space(spaces);
|
||||
|
||||
this.push(node.operator);
|
||||
this.push(" ");
|
||||
|
||||
if (!spaces) {
|
||||
// space is mandatory to avoid outputting <!--
|
||||
// http://javascript.spec.whatwg.org/#comment-syntax
|
||||
spaces = node.operator === "<" &&
|
||||
t.isUnaryExpression(node.right, { prefix: true, operator: "!" }) &&
|
||||
t.isUnaryExpression(node.right.argument, { prefix: true, operator: "--" });
|
||||
}
|
||||
|
||||
this.space(spaces);
|
||||
|
||||
print.plain(node.right);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints BindExpression, prints object and callee.
|
||||
*/
|
||||
|
||||
export function BindExpression(node, print) {
|
||||
print.plain(node.object);
|
||||
this.push("::");
|
||||
print.plain(node.callee);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias ClassDeclaration printer as ClassExpression,
|
||||
* and AssignmentExpression printer as LogicalExpression.
|
||||
*/
|
||||
|
||||
export {
|
||||
AssignmentExpression as BinaryExpression,
|
||||
AssignmentExpression as LogicalExpression,
|
||||
AssignmentExpression as AssignmentPattern
|
||||
AssignmentExpression as LogicalExpression
|
||||
};
|
||||
|
||||
var SCIENTIFIC_NOTATION = /e/i;
|
||||
/**
|
||||
* Print MemberExpression, prints object, property, and value. Handles computed.
|
||||
*/
|
||||
|
||||
export function MemberExpression(node, print) {
|
||||
var obj = node.object;
|
||||
@@ -167,16 +259,15 @@ export function MemberExpression(node, print) {
|
||||
print.plain(node.property);
|
||||
this.push("]");
|
||||
} else {
|
||||
// 5..toFixed(2);
|
||||
if (t.isLiteral(obj) && isInteger(obj.value) && !SCIENTIFIC_NOTATION.test(obj.value.toString())) {
|
||||
this.push(".");
|
||||
}
|
||||
|
||||
this.push(".");
|
||||
print.plain(node.property);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print MetaProperty, prints meta and property.
|
||||
*/
|
||||
|
||||
export function MetaProperty(node, print) {
|
||||
print.plain(node.meta);
|
||||
this.push(".");
|
||||
|
||||
@@ -1,24 +1,44 @@
|
||||
import * as t from "../../types";
|
||||
|
||||
/**
|
||||
* Prints AnyTypeAnnotation.
|
||||
*/
|
||||
|
||||
export function AnyTypeAnnotation() {
|
||||
this.push("any");
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints ArrayTypeAnnotation, prints elementType.
|
||||
*/
|
||||
|
||||
export function ArrayTypeAnnotation(node, print) {
|
||||
print.plain(node.elementType);
|
||||
this.push("[");
|
||||
this.push("]");
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints BooleanTypeAnnotation.
|
||||
*/
|
||||
|
||||
export function BooleanTypeAnnotation(node) {
|
||||
this.push("bool");
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints DeclareClass, prints node.
|
||||
*/
|
||||
|
||||
export function DeclareClass(node, print) {
|
||||
this.push("declare class ");
|
||||
this._interfaceish(node, print);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints DeclareFunction, prints id and id.typeAnnotation.
|
||||
*/
|
||||
|
||||
export function DeclareFunction(node, print) {
|
||||
this.push("declare function ");
|
||||
print.plain(node.id);
|
||||
@@ -26,6 +46,10 @@ export function DeclareFunction(node, print) {
|
||||
this.semicolon();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints DeclareModule, prints id and body.
|
||||
*/
|
||||
|
||||
export function DeclareModule(node, print) {
|
||||
this.push("declare module ");
|
||||
print.plain(node.id);
|
||||
@@ -33,6 +57,10 @@ export function DeclareModule(node, print) {
|
||||
print.plain(node.body);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints DeclareVariable, prints id and id.typeAnnotation.
|
||||
*/
|
||||
|
||||
export function DeclareVariable(node, print) {
|
||||
this.push("declare var ");
|
||||
print.plain(node.id);
|
||||
@@ -40,6 +68,10 @@ export function DeclareVariable(node, print) {
|
||||
this.semicolon();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints FunctionTypeAnnotation, prints typeParameters, params, and rest.
|
||||
*/
|
||||
|
||||
export function FunctionTypeAnnotation(node, print, parent) {
|
||||
print.plain(node.typeParameters);
|
||||
this.push("(");
|
||||
@@ -68,6 +100,10 @@ export function FunctionTypeAnnotation(node, print, parent) {
|
||||
print.plain(node.returnType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints FunctionTypeParam, prints name and typeAnnotation, handles optional.
|
||||
*/
|
||||
|
||||
export function FunctionTypeParam(node, print) {
|
||||
print.plain(node.name);
|
||||
if (node.optional) this.push("?");
|
||||
@@ -76,13 +112,26 @@ export function FunctionTypeParam(node, print) {
|
||||
print.plain(node.typeAnnotation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints InterfaceExtends, prints id and typeParameters.
|
||||
*/
|
||||
|
||||
export function InterfaceExtends(node, print) {
|
||||
print.plain(node.id);
|
||||
print.plain(node.typeParameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias InterfaceExtends printer as ClassImplements,
|
||||
* and InterfaceExtends printer as GenericTypeAnnotation.
|
||||
*/
|
||||
|
||||
export { InterfaceExtends as ClassImplements, InterfaceExtends as GenericTypeAnnotation };
|
||||
|
||||
/**
|
||||
* Prints interface-like node, prints id, typeParameters, extends, and body.
|
||||
*/
|
||||
|
||||
export function _interfaceish(node, print) {
|
||||
print.plain(node.id);
|
||||
print.plain(node.typeParameters);
|
||||
@@ -94,47 +143,87 @@ export function _interfaceish(node, print) {
|
||||
print.plain(node.body);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints InterfaceDeclaration, prints node.
|
||||
*/
|
||||
|
||||
export function InterfaceDeclaration(node, print) {
|
||||
this.push("interface ");
|
||||
this._interfaceish(node, print);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints IntersectionTypeAnnotation, prints types.
|
||||
*/
|
||||
|
||||
export function IntersectionTypeAnnotation(node, print) {
|
||||
print.join(node.types, { separator: " & " });
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints MixedTypeAnnotation.
|
||||
*/
|
||||
|
||||
export function MixedTypeAnnotation() {
|
||||
this.push("mixed");
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints NullableTypeAnnotation, prints typeAnnotation.
|
||||
*/
|
||||
|
||||
export function NullableTypeAnnotation(node, print) {
|
||||
this.push("?");
|
||||
print.plain(node.typeAnnotation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints NumberTypeAnnotation.
|
||||
*/
|
||||
|
||||
export function NumberTypeAnnotation() {
|
||||
this.push("number");
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints StringLiteralTypeAnnotation, prints value.
|
||||
*/
|
||||
|
||||
export function StringLiteralTypeAnnotation(node) {
|
||||
this._stringLiteral(node.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints StringTypeAnnotation.
|
||||
*/
|
||||
|
||||
export function StringTypeAnnotation() {
|
||||
this.push("string");
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints TupleTypeAnnotation, prints types.
|
||||
*/
|
||||
|
||||
export function TupleTypeAnnotation(node, print) {
|
||||
this.push("[");
|
||||
print.join(node.types, { separator: ", " });
|
||||
this.push("]");
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints TypeofTypeAnnotation, prints argument.
|
||||
*/
|
||||
|
||||
export function TypeofTypeAnnotation(node, print) {
|
||||
this.push("typeof ");
|
||||
print.plain(node.argument);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints TypeAlias, prints id, typeParameters, and right.
|
||||
*/
|
||||
|
||||
export function TypeAlias(node, print) {
|
||||
this.push("type ");
|
||||
print.plain(node.id);
|
||||
@@ -146,6 +235,10 @@ export function TypeAlias(node, print) {
|
||||
this.semicolon();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints TypeAnnotation, prints typeAnnotation, handles optional.
|
||||
*/
|
||||
|
||||
export function TypeAnnotation(node, print) {
|
||||
this.push(":");
|
||||
this.space();
|
||||
@@ -153,14 +246,26 @@ export function TypeAnnotation(node, print) {
|
||||
print.plain(node.typeAnnotation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints TypeParameterInstantiation, prints params.
|
||||
*/
|
||||
|
||||
export function TypeParameterInstantiation(node, print) {
|
||||
this.push("<");
|
||||
print.join(node.params, { separator: ", " });
|
||||
this.push(">");
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias TypeParameterInstantiation printer as TypeParameterDeclaration
|
||||
*/
|
||||
|
||||
export { TypeParameterInstantiation as TypeParameterDeclaration };
|
||||
|
||||
/**
|
||||
* Prints ObjectTypeAnnotation, prints properties, callProperties, and indexers.
|
||||
*/
|
||||
|
||||
export function ObjectTypeAnnotation(node, print) {
|
||||
this.push("{");
|
||||
var props = node.properties.concat(node.callProperties, node.indexers);
|
||||
@@ -185,11 +290,19 @@ export function ObjectTypeAnnotation(node, print) {
|
||||
this.push("}");
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints ObjectTypeCallProperty, prints value, handles static.
|
||||
*/
|
||||
|
||||
export function ObjectTypeCallProperty(node, print) {
|
||||
if (node.static) this.push("static ");
|
||||
print.plain(node.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints ObjectTypeIndexer, prints id, key, and value, handles static.
|
||||
*/
|
||||
|
||||
export function ObjectTypeIndexer(node, print) {
|
||||
if (node.static) this.push("static ");
|
||||
this.push("[");
|
||||
@@ -203,6 +316,10 @@ export function ObjectTypeIndexer(node, print) {
|
||||
print.plain(node.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints ObjectTypeProperty, prints static, key, and value.
|
||||
*/
|
||||
|
||||
export function ObjectTypeProperty(node, print) {
|
||||
if (node.static) this.push("static ");
|
||||
print.plain(node.key);
|
||||
@@ -214,16 +331,28 @@ export function ObjectTypeProperty(node, print) {
|
||||
print.plain(node.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints QualifiedTypeIdentifier, prints qualification and id.
|
||||
*/
|
||||
|
||||
export function QualifiedTypeIdentifier(node, print) {
|
||||
print.plain(node.qualification);
|
||||
this.push(".");
|
||||
print.plain(node.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints UnionTypeAnnotation, prints types.
|
||||
*/
|
||||
|
||||
export function UnionTypeAnnotation(node, print) {
|
||||
print.join(node.types, { separator: " | " });
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints TypeCastExpression, prints expression and typeAnnotation.
|
||||
*/
|
||||
|
||||
export function TypeCastExpression(node, print) {
|
||||
this.push("(");
|
||||
print.plain(node.expression);
|
||||
@@ -231,6 +360,10 @@ export function TypeCastExpression(node, print) {
|
||||
this.push(")");
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints VoidTypeAnnotation.
|
||||
*/
|
||||
|
||||
export function VoidTypeAnnotation(node) {
|
||||
this.push("void");
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import * as t from "../../types";
|
||||
|
||||
/**
|
||||
* Prints JSXAttribute, prints name and value.
|
||||
*/
|
||||
|
||||
export function JSXAttribute(node, print) {
|
||||
print.plain(node.name);
|
||||
if (node.value) {
|
||||
@@ -8,34 +12,58 @@ export function JSXAttribute(node, print) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints JSXIdentifier, prints name.
|
||||
*/
|
||||
|
||||
export function JSXIdentifier(node) {
|
||||
this.push(node.name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints JSXNamespacedName, prints namespace and name.
|
||||
*/
|
||||
|
||||
export function JSXNamespacedName(node, print) {
|
||||
print.plain(node.namespace);
|
||||
this.push(":");
|
||||
print.plain(node.name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints JSXMemberExpression, prints object and property.
|
||||
*/
|
||||
|
||||
export function JSXMemberExpression(node, print) {
|
||||
print.plain(node.object);
|
||||
this.push(".");
|
||||
print.plain(node.property);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints JSXSpreadAttribute, prints argument.
|
||||
*/
|
||||
|
||||
export function JSXSpreadAttribute(node, print) {
|
||||
this.push("{...");
|
||||
print.plain(node.argument);
|
||||
this.push("}");
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints JSXExpressionContainer, prints expression.
|
||||
*/
|
||||
|
||||
export function JSXExpressionContainer(node, print) {
|
||||
this.push("{");
|
||||
print.plain(node.expression);
|
||||
this.push("}");
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints JSXElement, prints openingElement, children, and closingElement.
|
||||
*/
|
||||
|
||||
export function JSXElement(node, print) {
|
||||
var open = node.openingElement;
|
||||
print.plain(open);
|
||||
@@ -54,6 +82,10 @@ export function JSXElement(node, print) {
|
||||
print.plain(node.closingElement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints JSXOpeningElement, prints name and attributes, handles selfClosing.
|
||||
*/
|
||||
|
||||
export function JSXOpeningElement(node, print) {
|
||||
this.push("<");
|
||||
print.plain(node.name);
|
||||
@@ -64,10 +96,18 @@ export function JSXOpeningElement(node, print) {
|
||||
this.push(node.selfClosing ? " />" : ">");
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints JSXClosingElement, prints name.
|
||||
*/
|
||||
|
||||
export function JSXClosingElement(node, print) {
|
||||
this.push("</");
|
||||
print.plain(node.name);
|
||||
this.push(">");
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints JSXEmptyExpression.
|
||||
*/
|
||||
|
||||
export function JSXEmptyExpression() {}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import * as t from "../../types";
|
||||
|
||||
/**
|
||||
* Prints nodes with params, prints typeParameters, params, and returnType, handles optional params.
|
||||
*/
|
||||
|
||||
export function _params(node, print) {
|
||||
print.plain(node.typeParameters);
|
||||
this.push("(");
|
||||
@@ -16,6 +20,10 @@ export function _params(node, print) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints method-like nodes, prints key, value, and body, handles async, generator, computed, and get or set.
|
||||
*/
|
||||
|
||||
export function _method(node, print) {
|
||||
var value = node.value;
|
||||
var kind = node.kind;
|
||||
@@ -42,10 +50,14 @@ export function _method(node, print) {
|
||||
}
|
||||
|
||||
this._params(value, print);
|
||||
this.push(" ");
|
||||
this.space();
|
||||
print.plain(value.body);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints FunctionExpression, prints id and body, handles async and generator.
|
||||
*/
|
||||
|
||||
export function FunctionExpression(node, print) {
|
||||
if (node.async) this.push("async ");
|
||||
this.push("function");
|
||||
@@ -63,8 +75,17 @@ export function FunctionExpression(node, print) {
|
||||
print.plain(node.body);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias FunctionExpression printer as FunctionDeclaration.
|
||||
*/
|
||||
|
||||
export { FunctionExpression as FunctionDeclaration };
|
||||
|
||||
/**
|
||||
* Prints ArrowFunctionExpression, prints params and body, handles async.
|
||||
* Leaves out parentheses when single param.
|
||||
*/
|
||||
|
||||
export function ArrowFunctionExpression(node, print) {
|
||||
if (node.async) this.push("async ");
|
||||
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import * as t from "../../types";
|
||||
|
||||
/**
|
||||
* Prints ImportSpecifier, prints imported and local.
|
||||
*/
|
||||
|
||||
export function ImportSpecifier(node, print) {
|
||||
print.plain(node.imported);
|
||||
if (node.local && node.local.name !== node.imported.name) {
|
||||
@@ -8,14 +12,26 @@ export function ImportSpecifier(node, print) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints ImportDefaultSpecifier, prints local.
|
||||
*/
|
||||
|
||||
export function ImportDefaultSpecifier(node, print) {
|
||||
print.plain(node.local);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints ExportDefaultSpecifier, prints exported.
|
||||
*/
|
||||
|
||||
export function ExportDefaultSpecifier(node, print) {
|
||||
print.plain(node.exported);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints ExportSpecifier, prints local and exported.
|
||||
*/
|
||||
|
||||
export function ExportSpecifier(node, print) {
|
||||
print.plain(node.local);
|
||||
if (node.exported && node.local.name !== node.exported.name) {
|
||||
@@ -24,11 +40,19 @@ export function ExportSpecifier(node, print) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints ExportNamespaceSpecifier, prints exported.
|
||||
*/
|
||||
|
||||
export function ExportNamespaceSpecifier(node, print) {
|
||||
this.push("* as ");
|
||||
print.plain(node.exported);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints ExportAllDeclaration, prints exported and source.
|
||||
*/
|
||||
|
||||
export function ExportAllDeclaration(node, print) {
|
||||
this.push("export *");
|
||||
if (node.exported) {
|
||||
@@ -40,16 +64,28 @@ export function ExportAllDeclaration(node, print) {
|
||||
this.semicolon();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints ExportNamedDeclaration, delegates to ExportDeclaration.
|
||||
*/
|
||||
|
||||
export function ExportNamedDeclaration(node, print) {
|
||||
this.push("export ");
|
||||
ExportDeclaration.call(this, node, print);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints ExportDefaultDeclaration, delegates to ExportDeclaration.
|
||||
*/
|
||||
|
||||
export function ExportDefaultDeclaration(node, print) {
|
||||
this.push("export default ");
|
||||
ExportDeclaration.call(this, node, print);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints ExportDeclaration, prints specifiers, declration, and source.
|
||||
*/
|
||||
|
||||
function ExportDeclaration(node, print) {
|
||||
var specifiers = node.specifiers;
|
||||
|
||||
@@ -87,11 +123,15 @@ function ExportDeclaration(node, print) {
|
||||
this.ensureSemicolon();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints ImportDeclaration, prints specifiers and source, handles isType.
|
||||
*/
|
||||
|
||||
export function ImportDeclaration(node, print) {
|
||||
this.push("import ");
|
||||
|
||||
if (node.isType) {
|
||||
this.push("type ");
|
||||
if (node.importKind === "type" || node.importKind === "typeof") {
|
||||
this.push(node.importKind + " ");
|
||||
}
|
||||
|
||||
var specfiers = node.specifiers;
|
||||
@@ -119,6 +159,10 @@ export function ImportDeclaration(node, print) {
|
||||
this.semicolon();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints ImportNamespaceSpecifier, prints local.
|
||||
*/
|
||||
|
||||
export function ImportNamespaceSpecifier(node, print) {
|
||||
this.push("* as ");
|
||||
print.plain(node.local);
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import repeating from "repeating";
|
||||
import * as t from "../../types";
|
||||
|
||||
/**
|
||||
* Prints WithStatement, prints object and body.
|
||||
*/
|
||||
|
||||
export function WithStatement(node, print) {
|
||||
this.keyword("with");
|
||||
this.push("(");
|
||||
@@ -9,6 +13,10 @@ export function WithStatement(node, print) {
|
||||
print.block(node.body);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints IfStatement, prints test, consequent, and alternate.
|
||||
*/
|
||||
|
||||
export function IfStatement(node, print) {
|
||||
this.keyword("if");
|
||||
this.push("(");
|
||||
@@ -25,6 +33,10 @@ export function IfStatement(node, print) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints ForStatement, prints init, test, update, and body.
|
||||
*/
|
||||
|
||||
export function ForStatement(node, print) {
|
||||
this.keyword("for");
|
||||
this.push("(");
|
||||
@@ -33,13 +45,13 @@ export function ForStatement(node, print) {
|
||||
this.push(";");
|
||||
|
||||
if (node.test) {
|
||||
this.push(" ");
|
||||
this.space();
|
||||
print.plain(node.test);
|
||||
}
|
||||
this.push(";");
|
||||
|
||||
if (node.update) {
|
||||
this.push(" ");
|
||||
this.space();
|
||||
print.plain(node.update);
|
||||
}
|
||||
|
||||
@@ -47,6 +59,10 @@ export function ForStatement(node, print) {
|
||||
print.block(node.body);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints WhileStatement, prints test and body.
|
||||
*/
|
||||
|
||||
export function WhileStatement(node, print) {
|
||||
this.keyword("while");
|
||||
this.push("(");
|
||||
@@ -55,6 +71,11 @@ export function WhileStatement(node, print) {
|
||||
print.block(node.body);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds ForIn or ForOf statement printers.
|
||||
* Prints left, right, and body.
|
||||
*/
|
||||
|
||||
var buildForXStatement = function (op) {
|
||||
return function (node, print) {
|
||||
this.keyword("for");
|
||||
@@ -67,9 +88,17 @@ var buildForXStatement = function (op) {
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Create ForInStatement and ForOfStatement printers.
|
||||
*/
|
||||
|
||||
export var ForInStatement = buildForXStatement("in");
|
||||
export var ForOfStatement = buildForXStatement("of");
|
||||
|
||||
/**
|
||||
* Prints DoWhileStatement, prints body and test.
|
||||
*/
|
||||
|
||||
export function DoWhileStatement(node, print) {
|
||||
this.push("do ");
|
||||
print.plain(node.body);
|
||||
@@ -80,6 +109,11 @@ export function DoWhileStatement(node, print) {
|
||||
this.push(");");
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds continue, return, or break statement printers.
|
||||
* Prints label (or key).
|
||||
*/
|
||||
|
||||
var buildLabelStatement = function (prefix, key) {
|
||||
return function (node, print) {
|
||||
this.push(prefix);
|
||||
@@ -94,16 +128,28 @@ var buildLabelStatement = function (prefix, key) {
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Create ContinueStatement, ReturnStatement, and BreakStatement printers.
|
||||
*/
|
||||
|
||||
export var ContinueStatement = buildLabelStatement("continue");
|
||||
export var ReturnStatement = buildLabelStatement("return", "argument");
|
||||
export var BreakStatement = buildLabelStatement("break");
|
||||
|
||||
/**
|
||||
* Prints LabeledStatement, prints label and body.
|
||||
*/
|
||||
|
||||
export function LabeledStatement(node, print) {
|
||||
print.plain(node.label);
|
||||
this.push(": ");
|
||||
print.plain(node.body);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints TryStatement, prints block, handlers, and finalizer.
|
||||
*/
|
||||
|
||||
export function TryStatement(node, print) {
|
||||
this.keyword("try");
|
||||
print.plain(node.block);
|
||||
@@ -125,6 +171,10 @@ export function TryStatement(node, print) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints CatchClause, prints param and body.
|
||||
*/
|
||||
|
||||
export function CatchClause(node, print) {
|
||||
this.keyword("catch");
|
||||
this.push("(");
|
||||
@@ -133,12 +183,20 @@ export function CatchClause(node, print) {
|
||||
print.plain(node.body);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints ThrowStatement, prints argument.
|
||||
*/
|
||||
|
||||
export function ThrowStatement(node, print) {
|
||||
this.push("throw ");
|
||||
print.plain(node.argument);
|
||||
this.semicolon();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints SwitchStatement, prints discriminant and cases.
|
||||
*/
|
||||
|
||||
export function SwitchStatement(node, print) {
|
||||
this.keyword("switch");
|
||||
this.push("(");
|
||||
@@ -157,6 +215,10 @@ export function SwitchStatement(node, print) {
|
||||
this.push("}");
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints SwitchCase, prints test and consequent.
|
||||
*/
|
||||
|
||||
export function SwitchCase(node, print) {
|
||||
if (node.test) {
|
||||
this.push("case ");
|
||||
@@ -172,10 +234,18 @@ export function SwitchCase(node, print) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints DebuggerStatement.
|
||||
*/
|
||||
|
||||
export function DebuggerStatement() {
|
||||
this.push("debugger;");
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints VariableDeclaration, prints declarations, handles kind and format.
|
||||
*/
|
||||
|
||||
export function VariableDeclaration(node, print, parent) {
|
||||
this.push(node.kind + " ");
|
||||
|
||||
@@ -190,22 +260,39 @@ export function VariableDeclaration(node, print, parent) {
|
||||
}
|
||||
}
|
||||
|
||||
var sep = ",";
|
||||
//
|
||||
// use a pretty separator when we aren't in compact mode, have initializers and don't have retainLines on
|
||||
// this will format declarations like:
|
||||
//
|
||||
// var foo = "bar", bar = "foo";
|
||||
//
|
||||
// into
|
||||
//
|
||||
// var foo = "bar",
|
||||
// bar = "foo";
|
||||
//
|
||||
|
||||
var sep;
|
||||
if (!this.format.compact && !this.format.concise && hasInits && !this.format.retainLines) {
|
||||
sep += `\n${repeating(" ", node.kind.length + 1)}`;
|
||||
} else {
|
||||
sep += " ";
|
||||
sep = `,\n${repeating(" ", node.kind.length + 1)}`;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
print.list(node.declarations, { separator: sep });
|
||||
|
||||
if (t.isFor(parent)) {
|
||||
// don't give semicolons to these nodes since they'll be inserted in the parent generator
|
||||
if (parent.left === node || parent.init === node) return;
|
||||
}
|
||||
|
||||
this.semicolon();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints VariableDeclarator, handles id, id.typeAnnotation, and init.
|
||||
*/
|
||||
|
||||
export function VariableDeclarator(node, print) {
|
||||
print.plain(node.id);
|
||||
print.plain(node.id.typeAnnotation);
|
||||
|
||||
@@ -1,12 +1,24 @@
|
||||
/**
|
||||
* Prints TaggedTemplateExpression, prints tag and quasi.
|
||||
*/
|
||||
|
||||
export function TaggedTemplateExpression(node, print) {
|
||||
print.plain(node.tag);
|
||||
print.plain(node.quasi);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints TemplateElement, prints value.
|
||||
*/
|
||||
|
||||
export function TemplateElement(node) {
|
||||
this._push(node.value.raw);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints TemplateLiteral, prints quasis, and expressions.
|
||||
*/
|
||||
|
||||
export function TemplateLiteral(node, print) {
|
||||
this.push("`");
|
||||
|
||||
|
||||
@@ -1,18 +1,36 @@
|
||||
/* eslint quotes: 0 */
|
||||
|
||||
import isInteger from "is-integer";
|
||||
import * as t from "../../types";
|
||||
|
||||
/**
|
||||
* Prints Identifier, prints name.
|
||||
*/
|
||||
|
||||
export function Identifier(node) {
|
||||
this.push(node.name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints RestElement, prints argument.
|
||||
*/
|
||||
|
||||
export function RestElement(node, print) {
|
||||
this.push("...");
|
||||
print.plain(node.argument);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias RestElement printer as SpreadElement,
|
||||
* and RestElement printer as SpreadProperty.
|
||||
*/
|
||||
|
||||
export { RestElement as SpreadElement, RestElement as SpreadProperty };
|
||||
|
||||
/**
|
||||
* Prints ObjectExpression, prints properties.
|
||||
*/
|
||||
|
||||
export function ObjectExpression(node, print) {
|
||||
var props = node.properties;
|
||||
|
||||
@@ -29,9 +47,19 @@ export function ObjectExpression(node, print) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias ObjectExpression printer as ObjectPattern.
|
||||
*/
|
||||
|
||||
export { ObjectExpression as ObjectPattern };
|
||||
|
||||
/**
|
||||
* Prints Property, prints decorators, key, and value, handles kind, computed, and shorthand.
|
||||
*/
|
||||
|
||||
export function Property(node, print) {
|
||||
print.list(node.decorators, { separator: "" });
|
||||
|
||||
if (node.method || node.kind === "get" || node.kind === "set") {
|
||||
this._method(node, print);
|
||||
} else {
|
||||
@@ -63,6 +91,10 @@ export function Property(node, print) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints ArrayExpression, prints elements.
|
||||
*/
|
||||
|
||||
export function ArrayExpression(node, print) {
|
||||
var elems = node.elements;
|
||||
var len = elems.length;
|
||||
@@ -79,7 +111,7 @@ export function ArrayExpression(node, print) {
|
||||
// both (all) of the holes.
|
||||
this.push(",");
|
||||
} else {
|
||||
if (i > 0) this.push(" ");
|
||||
if (i > 0) this.space();
|
||||
print.plain(elem);
|
||||
if (i < len - 1) this.push(",");
|
||||
}
|
||||
@@ -88,16 +120,43 @@ export function ArrayExpression(node, print) {
|
||||
this.push("]");
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias ArrayExpression printer as ArrayPattern.
|
||||
*/
|
||||
|
||||
export { ArrayExpression as ArrayPattern };
|
||||
|
||||
export function Literal(node) {
|
||||
/**
|
||||
* RegExp for testing scientific notation in literals.
|
||||
*/
|
||||
|
||||
const SCIENTIFIC_NOTATION = /e/i;
|
||||
|
||||
/**
|
||||
* Prints Literal, prints value, regex, raw, handles val type.
|
||||
*/
|
||||
|
||||
export function Literal(node, print, parent) {
|
||||
var val = node.value;
|
||||
var type = typeof val;
|
||||
|
||||
if (type === "string") {
|
||||
this._stringLiteral(val);
|
||||
} else if (type === "number") {
|
||||
this.push(val + "");
|
||||
// check to see if this is the same number as the raw one in the original source as asm.js uses
|
||||
// numbers in the form 5.0 for type hinting
|
||||
var raw = node.raw;
|
||||
if (val === +raw && raw[raw.length - 1] !== "." && !/^0[bo]/i.test(raw)) {
|
||||
val = raw;
|
||||
}
|
||||
|
||||
val = val + "";
|
||||
|
||||
if (isInteger(+val) && t.isMemberExpression(parent, { object: node }) && !SCIENTIFIC_NOTATION.test(val)) {
|
||||
val += ".";
|
||||
}
|
||||
|
||||
this.push(val);
|
||||
} else if (type === "boolean") {
|
||||
this.push(val ? "true" : "false");
|
||||
} else if (node.regex) {
|
||||
@@ -107,6 +166,10 @@ export function Literal(node) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints string literals, handles format.
|
||||
*/
|
||||
|
||||
export function _stringLiteral(val) {
|
||||
val = JSON.stringify(val);
|
||||
|
||||
@@ -116,9 +179,16 @@ export function _stringLiteral(val) {
|
||||
});
|
||||
|
||||
if (this.format.quotes === "single") {
|
||||
// remove double quotes
|
||||
val = val.slice(1, -1);
|
||||
|
||||
// unescape double quotes
|
||||
val = val.replace(/\\"/g, '"');
|
||||
|
||||
// escape single quotes
|
||||
val = val.replace(/'/g, "\\'");
|
||||
|
||||
// add single quotes
|
||||
val = `'${val}'`;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,11 @@ import each from "lodash/collection/each";
|
||||
import n from "./node";
|
||||
import * as t from "../types";
|
||||
|
||||
/**
|
||||
* Babel's code generator, turns an ast into code, maintaining sourcemaps,
|
||||
* user preferences, and valid output.
|
||||
*/
|
||||
|
||||
class CodeGenerator {
|
||||
constructor(ast, opts, code) {
|
||||
opts = opts || {};
|
||||
@@ -27,6 +32,13 @@ class CodeGenerator {
|
||||
this.buffer = new Buffer(this.position, this.format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize generator options, setting defaults.
|
||||
*
|
||||
* - Detects code indentation.
|
||||
* - If `opts.compact = "auto"` and the code is over 100KB, `compact` will be set to `true`.
|
||||
*/
|
||||
|
||||
static normalizeOptions(code, opts, tokens) {
|
||||
var style = " ";
|
||||
if (code) {
|
||||
@@ -57,6 +69,9 @@ class CodeGenerator {
|
||||
return format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if input code uses more single or double quotes.
|
||||
*/
|
||||
static findCommonStringDelimiter(code, tokens) {
|
||||
var occurences = {
|
||||
single: 0,
|
||||
@@ -79,7 +94,6 @@ class CodeGenerator {
|
||||
checked++;
|
||||
if (checked >= 3) break;
|
||||
}
|
||||
|
||||
if (occurences.single > occurences.double) {
|
||||
return "single";
|
||||
} else {
|
||||
@@ -87,6 +101,10 @@ class CodeGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* All node generators.
|
||||
*/
|
||||
|
||||
static generators = {
|
||||
templateLiterals: require("./generators/template-literals"),
|
||||
comprehensions: require("./generators/comprehensions"),
|
||||
@@ -101,6 +119,12 @@ class CodeGenerator {
|
||||
jsx: require("./generators/jsx")
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate code and sourcemap from ast.
|
||||
*
|
||||
* Appends comments that weren't attached to any node to the end of the generated output.
|
||||
*/
|
||||
|
||||
generate() {
|
||||
var ast = this.ast;
|
||||
|
||||
@@ -120,16 +144,23 @@ class CodeGenerator {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Build NodePrinter.
|
||||
*/
|
||||
|
||||
buildPrint(parent) {
|
||||
return new NodePrinter(this, parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
catchUp(node, parent, leftParenPrinted) {
|
||||
// catch up to this nodes newline if we're behind
|
||||
if (node.loc && this.format.retainLines && this.buffer.buf) {
|
||||
var needsParens = false;
|
||||
if (!leftParenPrinted && parent &&
|
||||
this.position.line < node.loc.start.line && t.isTerminatorless(parent)) {
|
||||
if (!leftParenPrinted && parent && this.position.line < node.loc.start.line && t.isTerminatorless(parent)) {
|
||||
needsParens = true;
|
||||
this._push("(");
|
||||
}
|
||||
@@ -141,6 +172,10 @@ class CodeGenerator {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
_printNewline(leading, node, parent, opts) {
|
||||
if (!opts.statement && !n.isUserWhitespacable(node, parent)) {
|
||||
return;
|
||||
@@ -171,6 +206,10 @@ class CodeGenerator {
|
||||
this.newline(lines);
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
print(node, parent, opts = {}) {
|
||||
if (!node) return;
|
||||
|
||||
@@ -220,6 +259,10 @@ class CodeGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
printJoin(print, nodes, opts = {}) {
|
||||
if (!nodes || !nodes.length) return;
|
||||
|
||||
@@ -249,6 +292,10 @@ class CodeGenerator {
|
||||
if (opts.indent) this.dedent();
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
printAndIndentOnComments(print, node) {
|
||||
var indent = !!node.leadingComments;
|
||||
if (indent) this.indent();
|
||||
@@ -256,6 +303,10 @@ class CodeGenerator {
|
||||
if (indent) this.dedent();
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
printBlock(print, node) {
|
||||
if (t.isEmptyStatement(node)) {
|
||||
this.semicolon();
|
||||
@@ -265,6 +316,10 @@ class CodeGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
generateComment(comment) {
|
||||
var val = comment.value;
|
||||
if (comment.type === "CommentLine") {
|
||||
@@ -275,14 +330,26 @@ class CodeGenerator {
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
printTrailingComments(node, parent) {
|
||||
this._printComments(this.getComments("trailingComments", node, parent));
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
printLeadingComments(node, parent) {
|
||||
this._printComments(this.getComments("leadingComments", node, parent));
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
getComments(key, node, parent) {
|
||||
if (t.isExpressionStatement(parent)) {
|
||||
return [];
|
||||
@@ -302,10 +369,18 @@ class CodeGenerator {
|
||||
return comments;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
_getComments(key, node) {
|
||||
return (node && node[key]) || [];
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
_printComments(comments) {
|
||||
if (this.format.compact) return;
|
||||
if (!this.format.comments) return;
|
||||
@@ -344,7 +419,7 @@ class CodeGenerator {
|
||||
|
||||
//
|
||||
if (comment.type === "CommentBlock" && this.format.indent.adjustMultilineComment) {
|
||||
var offset = comment.loc.start.column;
|
||||
var offset = comment.loc && comment.loc.start.column;
|
||||
if (offset) {
|
||||
var newlineRegex = new RegExp("\\n\\s{1," + offset + "}", "g");
|
||||
val = val.replace(newlineRegex, "\n");
|
||||
@@ -373,16 +448,28 @@ class CodeGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
each(Buffer.prototype, function (fn, key) {
|
||||
CodeGenerator.prototype[key] = function () {
|
||||
return fn.apply(this.buffer, arguments);
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
each(CodeGenerator.generators, function (generator) {
|
||||
extend(CodeGenerator.prototype, generator);
|
||||
});
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
module.exports = function (ast, opts, code) {
|
||||
var gen = new CodeGenerator(ast, opts, code);
|
||||
return gen.generate();
|
||||
|
||||
@@ -4,6 +4,16 @@ import each from "lodash/collection/each";
|
||||
import some from "lodash/collection/some";
|
||||
import * as t from "../../types";
|
||||
|
||||
/**
|
||||
* Test if node matches a set of type-matcher pairs.
|
||||
* @example
|
||||
* find({
|
||||
* VariableDeclaration(node, parent) {
|
||||
* return true;
|
||||
* }
|
||||
* }, node, parent);
|
||||
*/
|
||||
|
||||
var find = function (obj, node, parent) {
|
||||
if (!obj) return;
|
||||
var result;
|
||||
@@ -22,16 +32,28 @@ var find = function (obj, node, parent) {
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Whitespace and Parenthesis related methods for nodes.
|
||||
*/
|
||||
|
||||
export default class Node {
|
||||
constructor(node, parent) {
|
||||
this.parent = parent;
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if `node` can have whitespace set by the user.
|
||||
*/
|
||||
|
||||
static isUserWhitespacable(node) {
|
||||
return t.isUserWhitespacable(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if a `node` requires whitespace.
|
||||
*/
|
||||
|
||||
static needsWhitespace(node, parent, type) {
|
||||
if (!node) return 0;
|
||||
|
||||
@@ -54,14 +76,26 @@ export default class Node {
|
||||
return (linesInfo && linesInfo[type]) || 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if a `node` requires whitespace before it.
|
||||
*/
|
||||
|
||||
static needsWhitespaceBefore(node, parent) {
|
||||
return Node.needsWhitespace(node, parent, "before");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if a `note` requires whitespace after it.
|
||||
*/
|
||||
|
||||
static needsWhitespaceAfter(node, parent) {
|
||||
return Node.needsWhitespace(node, parent, "after");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if a `node` needs parentheses around it.
|
||||
*/
|
||||
|
||||
static needsParens(node, parent) {
|
||||
if (!parent) return false;
|
||||
|
||||
@@ -77,6 +111,10 @@ export default class Node {
|
||||
return find(parens, node, parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
static needsParensNoLineTerminator(node, parent) {
|
||||
if (!parent) return false;
|
||||
|
||||
@@ -89,6 +127,10 @@ export default class Node {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all static methods from `Node` to `Node.prototype`.
|
||||
*/
|
||||
|
||||
each(Node, function (fn, key) {
|
||||
Node.prototype[key] = function () {
|
||||
// Avoid leaking arguments to prevent deoptimization
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
import each from "lodash/collection/each";
|
||||
import * as t from "../../types";
|
||||
|
||||
/**
|
||||
* Create a mapping of operators to precendence.
|
||||
*
|
||||
* @example
|
||||
* { "==": 6, "+": 9 }
|
||||
*/
|
||||
const PRECEDENCE = {};
|
||||
|
||||
each([
|
||||
@@ -21,12 +27,24 @@ each([
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Test if NullableTypeAnnotation needs parentheses.
|
||||
*/
|
||||
|
||||
export function NullableTypeAnnotation(node, parent) {
|
||||
return t.isArrayTypeAnnotation(parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias NullableTypeAnnotation test as FunctionTypeAnnotation.
|
||||
*/
|
||||
|
||||
export { NullableTypeAnnotation as FunctionTypeAnnotation };
|
||||
|
||||
/**
|
||||
* Test if UpdateExpression needs parentheses.
|
||||
*/
|
||||
|
||||
export function UpdateExpression(node, parent) {
|
||||
if (t.isMemberExpression(parent) && parent.object === node) {
|
||||
// (foo++).test()
|
||||
@@ -34,6 +52,10 @@ export function UpdateExpression(node, parent) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if ObjectExpression needs parentheses.
|
||||
*/
|
||||
|
||||
export function ObjectExpression(node, parent) {
|
||||
if (t.isExpressionStatement(parent)) {
|
||||
// ({ foo: "bar" });
|
||||
@@ -48,6 +70,10 @@ export function ObjectExpression(node, parent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if Binary needs parentheses.
|
||||
*/
|
||||
|
||||
export function Binary(node, parent) {
|
||||
if ((t.isCallExpression(parent) || t.isNewExpression(parent)) && parent.callee === node) {
|
||||
return true;
|
||||
@@ -78,6 +104,10 @@ export function Binary(node, parent) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if BinaryExpression needs parentheses.
|
||||
*/
|
||||
|
||||
export function BinaryExpression(node, parent) {
|
||||
if (node.operator === "in") {
|
||||
// var i = (1 in []);
|
||||
@@ -92,6 +122,10 @@ export function BinaryExpression(node, parent) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if SequenceExpression needs parentheses.
|
||||
*/
|
||||
|
||||
export function SequenceExpression(node, parent) {
|
||||
if (t.isForStatement(parent)) {
|
||||
// Although parentheses wouldn't hurt around sequence
|
||||
@@ -110,6 +144,10 @@ export function SequenceExpression(node, parent) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if YieldExpression needs parentheses.
|
||||
*/
|
||||
|
||||
export function YieldExpression(node, parent) {
|
||||
return t.isBinary(parent) ||
|
||||
t.isUnaryLike(parent) ||
|
||||
@@ -120,14 +158,26 @@ export function YieldExpression(node, parent) {
|
||||
t.isYieldExpression(parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if ClassExpression needs parentheses.
|
||||
*/
|
||||
|
||||
export function ClassExpression(node, parent) {
|
||||
return t.isExpressionStatement(parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if UnaryLike needs parentheses.
|
||||
*/
|
||||
|
||||
export function UnaryLike(node, parent) {
|
||||
return t.isMemberExpression(parent) && parent.object === node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if FunctionExpression needs parentheses.
|
||||
*/
|
||||
|
||||
export function FunctionExpression(node, parent) {
|
||||
// function () {};
|
||||
if (t.isExpressionStatement(parent)) {
|
||||
@@ -145,6 +195,10 @@ export function FunctionExpression(node, parent) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if ConditionalExpression needs parentheses.
|
||||
*/
|
||||
|
||||
export function ConditionalExpression(node, parent) {
|
||||
if (t.isUnaryLike(parent)) {
|
||||
return true;
|
||||
@@ -171,6 +225,10 @@ export function ConditionalExpression(node, parent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if AssignmentExpression needs parentheses.
|
||||
*/
|
||||
|
||||
export function AssignmentExpression(node) {
|
||||
if (t.isObjectPattern(node.left)) {
|
||||
return true;
|
||||
|
||||
@@ -1,31 +1,63 @@
|
||||
/**
|
||||
* Printer for nodes, needs a `generator` and a `parent`.
|
||||
*/
|
||||
|
||||
export default class NodePrinter {
|
||||
constructor(generator, parent) {
|
||||
this.generator = generator;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a plain node.
|
||||
*/
|
||||
|
||||
plain(node, opts) {
|
||||
return this.generator.print(node, this.parent, opts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a sequence of nodes as statements.
|
||||
*/
|
||||
|
||||
sequence(nodes, opts = {}) {
|
||||
opts.statement = true;
|
||||
return this.generator.printJoin(this, nodes, opts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a sequence of nodes as expressions.
|
||||
*/
|
||||
|
||||
join(nodes, opts) {
|
||||
return this.generator.printJoin(this, nodes, opts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a list of nodes, with a customizable separator (defaults to ",").
|
||||
*/
|
||||
|
||||
list(items, opts = {}) {
|
||||
if (opts.separator == null) opts.separator = ", ";
|
||||
if (opts.separator == null) {
|
||||
opts.separator = ",";
|
||||
if (!this.generator.format.compact) opts.separator += " ";
|
||||
}
|
||||
|
||||
return this.join(items, opts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a block-like node.
|
||||
*/
|
||||
|
||||
block(node) {
|
||||
return this.generator.printBlock(this, node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print node and indent comments.
|
||||
*/
|
||||
|
||||
indentOnComments(node) {
|
||||
return this.generator.printAndIndentOnComments(this, node);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,14 @@ import each from "lodash/collection/each";
|
||||
import map from "lodash/collection/map";
|
||||
import * as t from "../../types";
|
||||
|
||||
/**
|
||||
* Crawl a node to test if it contains a CallExpression, a Function, or a Helper.
|
||||
*
|
||||
* @example
|
||||
* crawl(node)
|
||||
* // { hasCall: false, hasFunction: true, hasHelper: false }
|
||||
*/
|
||||
|
||||
function crawl(node, state = {}) {
|
||||
if (t.isMemberExpression(node)) {
|
||||
crawl(node.object, state);
|
||||
@@ -22,6 +30,10 @@ function crawl(node, state = {}) {
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if a node is or has a helper.
|
||||
*/
|
||||
|
||||
function isHelper(node) {
|
||||
if (t.isMemberExpression(node)) {
|
||||
return isHelper(node.object) || isHelper(node.property);
|
||||
@@ -36,12 +48,25 @@ function isHelper(node) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
function isType(node) {
|
||||
return t.isLiteral(node) || t.isObjectExpression(node) || t.isArrayExpression(node) ||
|
||||
t.isIdentifier(node) || t.isMemberExpression(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for node types that need whitespace.
|
||||
*/
|
||||
|
||||
exports.nodes = {
|
||||
|
||||
/**
|
||||
* Test if AssignmentExpression needs whitespace.
|
||||
*/
|
||||
|
||||
AssignmentExpression(node) {
|
||||
var state = crawl(node.right);
|
||||
if ((state.hasCall && state.hasHelper) || state.hasFunction) {
|
||||
@@ -52,12 +77,20 @@ exports.nodes = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Test if SwitchCase needs whitespace.
|
||||
*/
|
||||
|
||||
SwitchCase(node, parent) {
|
||||
return {
|
||||
before: node.consequent.length || parent.cases[0] === node
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Test if LogicalExpression needs whitespace.
|
||||
*/
|
||||
|
||||
LogicalExpression(node) {
|
||||
if (t.isFunction(node.left) || t.isFunction(node.right)) {
|
||||
return {
|
||||
@@ -66,6 +99,10 @@ exports.nodes = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Test if Literal needs whitespace.
|
||||
*/
|
||||
|
||||
Literal(node) {
|
||||
if (node.value === "use strict") {
|
||||
return {
|
||||
@@ -74,6 +111,10 @@ exports.nodes = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Test if CallExpression needs whitespace.
|
||||
*/
|
||||
|
||||
CallExpression(node) {
|
||||
if (t.isFunction(node.callee) || isHelper(node)) {
|
||||
return {
|
||||
@@ -83,6 +124,10 @@ exports.nodes = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Test if VariableDeclaration needs whitespace.
|
||||
*/
|
||||
|
||||
VariableDeclaration(node) {
|
||||
for (var i = 0; i < node.declarations.length; i++) {
|
||||
var declar = node.declarations[i];
|
||||
@@ -102,6 +147,10 @@ exports.nodes = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Test if IfStatement needs whitespace.
|
||||
*/
|
||||
|
||||
IfStatement(node) {
|
||||
if (t.isBlockStatement(node.consequent)) {
|
||||
return {
|
||||
@@ -112,6 +161,10 @@ exports.nodes = {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Test if Property or SpreadProperty needs whitespace.
|
||||
*/
|
||||
|
||||
exports.nodes.Property =
|
||||
exports.nodes.SpreadProperty = function (node, parent) {
|
||||
if (parent.properties[0] === node) {
|
||||
@@ -121,20 +174,41 @@ exports.nodes.SpreadProperty = function (node, parent) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns lists from node types that need whitespace.
|
||||
*/
|
||||
|
||||
exports.list = {
|
||||
|
||||
/**
|
||||
* Return VariableDeclaration declarations init properties.
|
||||
*/
|
||||
|
||||
VariableDeclaration(node) {
|
||||
return map(node.declarations, "init");
|
||||
},
|
||||
|
||||
/**
|
||||
* Return VariableDeclaration elements.
|
||||
*/
|
||||
|
||||
ArrayExpression(node) {
|
||||
return node.elements;
|
||||
},
|
||||
|
||||
/**
|
||||
* Return VariableDeclaration properties.
|
||||
*/
|
||||
|
||||
ObjectExpression(node) {
|
||||
return node.properties;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Add whitespace tests for nodes and their aliases.
|
||||
*/
|
||||
|
||||
each({
|
||||
Function: true,
|
||||
Class: true,
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
/**
|
||||
* Track current position in code generation.
|
||||
*/
|
||||
|
||||
export default class Position {
|
||||
constructor() {
|
||||
this.line = 1;
|
||||
this.column = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Push a string to the current position, mantaining the current line and column.
|
||||
*/
|
||||
|
||||
push(str) {
|
||||
for (var i = 0; i < str.length; i++) {
|
||||
if (str[i] === "\n") {
|
||||
@@ -15,6 +23,10 @@ export default class Position {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unshift a string from the current position, mantaining the current line and column.
|
||||
*/
|
||||
|
||||
unshift(str) {
|
||||
for (var i = 0; i < str.length; i++) {
|
||||
if (str[i] === "\n") {
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import sourceMap from "source-map";
|
||||
import * as t from "../types";
|
||||
|
||||
/**
|
||||
* Build a sourcemap.
|
||||
*/
|
||||
|
||||
export default class SourceMap {
|
||||
constructor(position, opts, code) {
|
||||
this.position = position;
|
||||
@@ -18,6 +22,10 @@ export default class SourceMap {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the sourcemap.
|
||||
*/
|
||||
|
||||
get() {
|
||||
var map = this.map;
|
||||
if (map) {
|
||||
@@ -27,6 +35,10 @@ export default class SourceMap {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark a node's generated position, and add it to the sourcemap.
|
||||
*/
|
||||
|
||||
mark(node, type) {
|
||||
var loc = node.loc;
|
||||
if (!loc) return; // no location info
|
||||
|
||||
@@ -18,6 +18,10 @@ function getLookupIndex(i, base, max) {
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whitespace around tokens.
|
||||
*/
|
||||
|
||||
export default class Whitespace {
|
||||
constructor(tokens) {
|
||||
this.tokens = tokens;
|
||||
@@ -34,6 +38,10 @@ export default class Whitespace {
|
||||
this._lastFoundIndex = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count all the newlines before a node.
|
||||
*/
|
||||
|
||||
getNewlinesBefore(node) {
|
||||
var startToken;
|
||||
var endToken;
|
||||
@@ -57,6 +65,10 @@ export default class Whitespace {
|
||||
return this.getNewlinesBetween(startToken, endToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* Count all the newlines after a node.
|
||||
*/
|
||||
|
||||
getNewlinesAfter(node) {
|
||||
var startToken;
|
||||
var endToken;
|
||||
@@ -91,6 +103,10 @@ export default class Whitespace {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Count all the newlines between two tokens.
|
||||
*/
|
||||
|
||||
getNewlinesBetween(startToken, endToken) {
|
||||
if (!endToken || !endToken.loc) return 0;
|
||||
|
||||
|
||||
4
src/babel/helpers/README.md
Normal file
4
src/babel/helpers/README.md
Normal file
@@ -0,0 +1,4 @@
|
||||
## Helpers
|
||||
|
||||
Utilities for Babel, which is just another way to say "helpers", but I wrote it
|
||||
anyways, so– deal with it.
|
||||
@@ -4,6 +4,10 @@ import jsTokens from "js-tokens";
|
||||
import esutils from "esutils";
|
||||
import chalk from "chalk";
|
||||
|
||||
/**
|
||||
* Chalk styles for token types.
|
||||
*/
|
||||
|
||||
var defs = {
|
||||
string: chalk.red,
|
||||
punctuator: chalk.bold,
|
||||
@@ -17,8 +21,16 @@ var defs = {
|
||||
invalid: chalk.inverse
|
||||
};
|
||||
|
||||
/**
|
||||
* RegExp to test for newlines in terminal.
|
||||
*/
|
||||
|
||||
const NEWLINE = /\r\n|[\n\r\u2028\u2029]/;
|
||||
|
||||
/**
|
||||
* Get the type of token, specifying punctuator type.
|
||||
*/
|
||||
|
||||
function getTokenType(match) {
|
||||
var token = jsTokens.matchToToken(match);
|
||||
if (token.type === "name" && esutils.keyword.isReservedWordES6(token.value)) {
|
||||
@@ -42,6 +54,10 @@ function getTokenType(match) {
|
||||
return token.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Highlight `text`.
|
||||
*/
|
||||
|
||||
function highlight(text) {
|
||||
return text.replace(jsTokens, function (...args) {
|
||||
var type = getTokenType(args);
|
||||
@@ -54,6 +70,10 @@ function highlight(text) {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a code frame, adding line numbers, code highlighting, and pointing to a given position.
|
||||
*/
|
||||
|
||||
export default function (lines: number, lineNumber: number, colNumber: number, opts = {}): string {
|
||||
colNumber = Math.max(colNumber, 0);
|
||||
|
||||
@@ -79,9 +99,11 @@ export default function (lines: number, lineNumber: number, colNumber: number, o
|
||||
if (params.number !== lineNumber) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (colNumber) {
|
||||
params.line += `\n${params.before}${repeating(" ", params.width)}${params.after}${repeating(" ", colNumber - 1)}^`;
|
||||
}
|
||||
|
||||
params.before = params.before.replace(/^./, ">");
|
||||
}
|
||||
}).join("\n");
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
import merge from "lodash/object/merge";
|
||||
|
||||
/**
|
||||
* Merge options.
|
||||
*/
|
||||
|
||||
export default function (dest, src) {
|
||||
if (!dest || !src) return;
|
||||
|
||||
return merge(dest, src, function(a, b) {
|
||||
if (Array.isArray(a)) {
|
||||
return merge(dest, src, function (a, b) {
|
||||
if (b && Array.isArray(a)) {
|
||||
var c = a.slice(0);
|
||||
for (var v of b) {
|
||||
if (a.indexOf(v) < 0) {
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
import * as t from "../types";
|
||||
|
||||
/**
|
||||
* Normalize an AST.
|
||||
*
|
||||
* - Wrap `Program` node with a `File` node.
|
||||
*/
|
||||
|
||||
export default function (ast, comments, tokens) {
|
||||
if (ast && ast.type === "Program") {
|
||||
return t.file(ast, comments || [], tokens || []);
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* Create an object with a `null` prototype.
|
||||
*/
|
||||
|
||||
export default function () {
|
||||
return Object.create(null);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,10 @@ import normalizeAst from "./normalize-ast";
|
||||
import estraverse from "estraverse";
|
||||
import * as acorn from "../../acorn";
|
||||
|
||||
/**
|
||||
* Parse `code` with normalized options, collecting tokens and comments.
|
||||
*/
|
||||
|
||||
export default function (code, opts = {}) {
|
||||
var commentsAndTokens = [];
|
||||
var comments = [];
|
||||
@@ -21,11 +25,17 @@ export default function (code, opts = {}) {
|
||||
ranges: true
|
||||
};
|
||||
|
||||
/**
|
||||
* Collect all tokens.
|
||||
*/
|
||||
parseOpts.onToken = function (token) {
|
||||
tokens.push(token);
|
||||
commentsAndTokens.push(token);
|
||||
};
|
||||
|
||||
/**
|
||||
* Collection all comments.
|
||||
*/
|
||||
parseOpts.onComment = function (block, text, start, end, startLoc, endLoc) {
|
||||
var comment = {
|
||||
type: block ? "CommentBlock" : "CommentLine",
|
||||
|
||||
@@ -1,30 +1,37 @@
|
||||
import * as util from "util";
|
||||
|
||||
/**
|
||||
* Mapping of messages to be used in Babel.
|
||||
* Messages can include $0-style placeholders.
|
||||
*/
|
||||
|
||||
export const MESSAGES = {
|
||||
tailCallReassignmentDeopt: "Function reference has been reassigned so it's probably be dereferenced so we can't optimise this with confidence",
|
||||
tailCallReassignmentDeopt: "Function reference has been reassigned, so it will probably be dereferenced, therefore we can't optimise this with confidence",
|
||||
JSXNamespacedTags: "Namespace tags are not supported. ReactJSX is not XML.",
|
||||
classesIllegalBareSuper: "Illegal use of bare super",
|
||||
classesIllegalSuperCall: "Direct super call is illegal in non-constructor, use super.$1() instead",
|
||||
classesIllegalConstructorKind: "Illegal kind for constructor method",
|
||||
scopeDuplicateDeclaration: "Duplicate declaration $1",
|
||||
undeclaredVariable: "Reference to undeclared variable $1",
|
||||
undeclaredVariableSuggestion: "Reference to undeclared variable $1 - did you mean $2?",
|
||||
settersInvalidParamLength: "Setters must have exactly one parameter",
|
||||
settersNoRest: "Setters aren't allowed to have a rest",
|
||||
noAssignmentsInForHead: "No assignments allowed in for-in/of head",
|
||||
expectedMemberExpressionOrIdentifier: "Expected type MemeberExpression or Identifier",
|
||||
expectedMemberExpressionOrIdentifier: "Expected type MemberExpression or Identifier",
|
||||
invalidParentForThisNode: "We don't know how to handle this node within the current parent - please open an issue",
|
||||
readOnly: "$1 is read-only",
|
||||
modulesIllegalExportName: "Illegal export $1",
|
||||
unknownForHead: "Unknown node type $1 in ForStatement",
|
||||
didYouMean: "Did you mean $1?",
|
||||
codeGeneratorDeopt: "Note: The code generator has deoptimised the styling of $1 as it exceeds the max of $2.",
|
||||
missingTemplatesDirectory: "no templates directory - this is most likely the result of a broken `npm publish`. Please report to https://github.com/babel/babel/issues",
|
||||
unsupportedOutputType: "Unsupported output type $1",
|
||||
illegalMethodName: "Illegal method name $1",
|
||||
lostTrackNodePath: "We lost track of this nodes position, likely because the AST was directly manipulated",
|
||||
lostTrackNodePath: "We lost track of this node's position, likely because the AST was directly manipulated",
|
||||
|
||||
traverseNeedsParent: "Must pass a scope and parentPath unless traversing a Program/File got a $1 node",
|
||||
modulesIllegalExportName: "Illegal export $1",
|
||||
modulesDuplicateDeclarations: "Duplicate module declarations with the same source but in different scopes",
|
||||
|
||||
undeclaredVariable: "Reference to undeclared variable $1",
|
||||
undeclaredVariableType: "Referencing a type alias outside of a type annotation",
|
||||
undeclaredVariableSuggestion: "Reference to undeclared variable $1 - did you mean $2?",
|
||||
|
||||
traverseNeedsParent: "You must pass a scope and parentPath unless traversing a Program/File got a $1 node",
|
||||
traverseVerifyRootFunction: "You passed `traverse()` a function when it expected a visitor object, are you sure you didn't mean `{ enter: Function }`?",
|
||||
traverseVerifyVisitorProperty: "You passed `traverse()` a visitor object with the property $1 that has the invalid property $2",
|
||||
traverseVerifyNodeType: "You gave us a visitor for the node type $1 but it's not a valid type",
|
||||
@@ -32,24 +39,44 @@ export const MESSAGES = {
|
||||
pluginIllegalKind: "Illegal kind $1 for plugin $2",
|
||||
pluginIllegalPosition: "Illegal position $1 for plugin $2",
|
||||
pluginKeyCollision: "The plugin $1 collides with another of the same name",
|
||||
pluginNotTransformer: "The plugin $1 didn't export a Transformer instance",
|
||||
pluginNotTransformer: "The plugin $1 didn't export a Plugin instance",
|
||||
pluginUnknown: "Unknown plugin $1",
|
||||
|
||||
transformerNotFile: "Transformer $1 is resolving to a different Babel version to what is doing the actual transformation..."
|
||||
pluginNotFile: "Plugin $1 is resolving to a different Babel version than what is performing the transformation.",
|
||||
|
||||
pluginInvalidProperty: "Plugin $1 provided an invalid property of $2.",
|
||||
pluginInvalidPropertyVisitor: `Define your visitor methods inside a \`visitor\` property like so:
|
||||
|
||||
new Plugin("foobar", {
|
||||
visitor: {
|
||||
// define your visitor methods here!
|
||||
}
|
||||
});
|
||||
`
|
||||
};
|
||||
|
||||
export function get(key: String, ...args) {
|
||||
/**
|
||||
* Get a message with $0 placeholders replaced by arguments.
|
||||
*/
|
||||
|
||||
export function get(key: string, ...args): string {
|
||||
var msg = MESSAGES[key];
|
||||
if (!msg) throw new ReferenceError(`Unknown message ${JSON.stringify(key)}`);
|
||||
|
||||
// stringify args
|
||||
args = parseArgs(args);
|
||||
|
||||
// replace $0 placeholders with args
|
||||
return msg.replace(/\$(\d+)/g, function (str, i) {
|
||||
return args[--i];
|
||||
});
|
||||
}
|
||||
|
||||
export function parseArgs(args: Array<any>) {
|
||||
/**
|
||||
* Stingify arguments to be used inside messages.
|
||||
*/
|
||||
|
||||
export function parseArgs(args: Array<any>): Array<string> {
|
||||
return args.map(function (val) {
|
||||
if (val != null && val.inspect) {
|
||||
return val.inspect();
|
||||
|
||||
@@ -1,81 +1,7 @@
|
||||
import estraverse from "estraverse";
|
||||
import extend from "lodash/object/extend";
|
||||
import types from "ast-types";
|
||||
import * as t from "./types";
|
||||
|
||||
// estraverse
|
||||
|
||||
extend(estraverse.VisitorKeys, t.VISITOR_KEYS);
|
||||
|
||||
// regenerator/ast-types
|
||||
|
||||
var def = types.Type.def;
|
||||
var or = types.Type.or;
|
||||
|
||||
//def("File")
|
||||
// .bases("Node")
|
||||
// .build("program")
|
||||
// .field("program", def("Program"));
|
||||
|
||||
def("AssignmentPattern")
|
||||
.bases("Pattern")
|
||||
.build("left", "right")
|
||||
.field("left", def("Pattern"))
|
||||
.field("right", def("Expression"));
|
||||
|
||||
def("RestElement")
|
||||
.bases("Pattern")
|
||||
.build("argument")
|
||||
.field("argument", def("expression"));
|
||||
|
||||
def("DoExpression")
|
||||
.bases("Expression")
|
||||
.build("body")
|
||||
.field("body", [def("Statement")]);
|
||||
|
||||
def("Super")
|
||||
.bases("Expression");
|
||||
|
||||
def("ExportDefaultDeclaration")
|
||||
.bases("Declaration")
|
||||
.build("declaration")
|
||||
.field("declaration", or(
|
||||
def("Declaration"),
|
||||
def("Expression"),
|
||||
null
|
||||
));
|
||||
|
||||
def("ExportNamedDeclaration")
|
||||
.bases("Declaration")
|
||||
.build("declaration")
|
||||
.field("declaration", or(
|
||||
def("Declaration"),
|
||||
def("Expression"),
|
||||
null
|
||||
))
|
||||
.field("specifiers", [or(
|
||||
def("ExportSpecifier")
|
||||
)])
|
||||
.field("source", or(def("ModuleSpecifier"), null));
|
||||
|
||||
def("ExportNamespaceSpecifier")
|
||||
.bases("Specifier")
|
||||
.field("exported", def("Identifier"));
|
||||
|
||||
def("ExportDefaultSpecifier")
|
||||
.bases("Specifier")
|
||||
.field("exported", def("Identifier"));
|
||||
|
||||
def("ExportAllDeclaration")
|
||||
.bases("Declaration")
|
||||
.build("exported", "source")
|
||||
.field("exported", def("Identifier"))
|
||||
.field("source", def("Literal"));
|
||||
|
||||
def("BindExpression")
|
||||
.bases("Expression")
|
||||
.build("object", "callee")
|
||||
.field("object", or(def("Expression"), null))
|
||||
.field("callee", def("Expression"));
|
||||
|
||||
types.finalize();
|
||||
|
||||
15
src/babel/tools/README.md
Normal file
15
src/babel/tools/README.md
Normal file
@@ -0,0 +1,15 @@
|
||||
## Tools
|
||||
|
||||
> This directory is best browsed while listening to
|
||||
> https://www.youtube.com/watch?v=hglVqACd1C8.
|
||||
|
||||
### Protect Babel
|
||||
|
||||
The protect script seen here is to throw errors if someone ever tries to
|
||||
include internal babel files in their script. If you need something to be
|
||||
exposed, you should ask for it, not try to hack your way into getting it.
|
||||
|
||||
### External Helpers
|
||||
|
||||
You'll also find the script for building the external helpers file, this is
|
||||
the Babel "runtime" where all helper functions go instead of the top of a file.
|
||||
@@ -5,6 +5,10 @@ import File from "../transformation/file";
|
||||
import each from "lodash/collection/each";
|
||||
import * as t from "../types";
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
function buildGlobal(namespace, builder) {
|
||||
var body = [];
|
||||
var container = t.functionExpression(null, [t.identifier("global")], t.blockStatement(body));
|
||||
@@ -22,6 +26,10 @@ function buildGlobal(namespace, builder) {
|
||||
return tree;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
function buildUmd(namespace, builder) {
|
||||
var body = [];
|
||||
body.push(t.variableDeclaration("var", [
|
||||
@@ -41,6 +49,10 @@ function buildUmd(namespace, builder) {
|
||||
return t.program([container]);
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
function buildVar(namespace, builder) {
|
||||
var body = [];
|
||||
body.push(t.variableDeclaration("var", [
|
||||
@@ -50,6 +62,10 @@ function buildVar(namespace, builder) {
|
||||
return t.program(body);
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
function buildHelpers(body, namespace, whitelist) {
|
||||
each(File.helpers, function (name) {
|
||||
if (whitelist && whitelist.indexOf(name) === -1) return;
|
||||
@@ -61,6 +77,10 @@ function buildHelpers(body, namespace, whitelist) {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
export default function (whitelist, outputType = "global") {
|
||||
var namespace = t.identifier("babelHelpers");
|
||||
|
||||
|
||||
14
src/babel/tools/protect.js
Normal file
14
src/babel/tools/protect.js
Normal file
@@ -0,0 +1,14 @@
|
||||
import path from "path";
|
||||
|
||||
var root = path.resolve(__dirname, "../../../");
|
||||
|
||||
/**
|
||||
* Protect Babel internals from being hotlinked by other tools.
|
||||
* Sorry, not sorry.
|
||||
*/
|
||||
|
||||
export default function (module) {
|
||||
if (module.parent && module.parent.filename.indexOf(root) !== 0) {
|
||||
throw new Error("Don't hotlink internal Babel files.");
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
import stripJsonComments from "strip-json-comments";
|
||||
import merge from "../helpers/merge";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
|
||||
var cache = {};
|
||||
var jsons = {};
|
||||
|
||||
function exists(filename) {
|
||||
if (!fs.existsSync) return false;
|
||||
|
||||
var cached = cache[filename];
|
||||
if (cached != null) return cached;
|
||||
return cache[filename] = fs.existsSync(filename);
|
||||
}
|
||||
|
||||
export default function (loc, opts = {}) {
|
||||
var rel = ".babelrc";
|
||||
|
||||
if (!opts.babelrc) {
|
||||
opts.babelrc = [];
|
||||
}
|
||||
|
||||
function find(start, rel) {
|
||||
var file = path.join(start, rel);
|
||||
|
||||
if (opts.babelrc.indexOf(file) >= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (exists(file)) {
|
||||
var content = fs.readFileSync(file, "utf8");
|
||||
var json;
|
||||
|
||||
try {
|
||||
json = jsons[content] = jsons[content] || JSON.parse(stripJsonComments(content));
|
||||
} catch (err) {
|
||||
err.message = `${file}: ${err.message}`;
|
||||
throw err;
|
||||
}
|
||||
|
||||
opts.babelrc.push(file);
|
||||
|
||||
if (json.breakConfig) return;
|
||||
merge(opts, json);
|
||||
}
|
||||
|
||||
var up = path.dirname(start);
|
||||
if (up !== start) { // root
|
||||
find(up, rel);
|
||||
}
|
||||
}
|
||||
|
||||
if (opts.babelrc.indexOf(loc) < 0 && opts.breakConfig !== true) {
|
||||
find(loc, rel);
|
||||
}
|
||||
|
||||
return opts;
|
||||
}
|
||||
3
src/babel/transformation/README.md
Normal file
3
src/babel/transformation/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## Transformation
|
||||
|
||||
This is the Transformation directory.
|
||||
3
src/babel/transformation/file/README.md
Normal file
3
src/babel/transformation/file/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## File Transformation
|
||||
|
||||
This is the File Transformation directory.
|
||||
@@ -1,29 +1,28 @@
|
||||
import convertSourceMap from "convert-source-map";
|
||||
import * as optionParsers from "./option-parsers";
|
||||
import moduleFormatters from "../modules";
|
||||
import OptionManager from "./options/option-manager";
|
||||
import PluginManager from "./plugin-manager";
|
||||
import shebangRegex from "shebang-regex";
|
||||
import NodePath from "../../traversal/path";
|
||||
import Transformer from "../transformer";
|
||||
import isFunction from "lodash/lang/isFunction";
|
||||
import isAbsolute from "path-is-absolute";
|
||||
import resolveRc from "../../tools/resolve-rc";
|
||||
import sourceMap from "source-map";
|
||||
import generate from "../../generation";
|
||||
import codeFrame from "../../helpers/code-frame";
|
||||
import defaults from "lodash/object/defaults";
|
||||
import includes from "lodash/collection/includes";
|
||||
import traverse from "../../traversal";
|
||||
import assign from "lodash/object/assign";
|
||||
import Logger from "./logger";
|
||||
import Plugin from "../plugin";
|
||||
import parse from "../../helpers/parse";
|
||||
import merge from "../../helpers/merge";
|
||||
import slash from "slash";
|
||||
import clone from "lodash/lang/clone";
|
||||
import Hub from "../../traversal/hub";
|
||||
import * as util from "../../util";
|
||||
import path from "path";
|
||||
import * as t from "../../types";
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
export default class File {
|
||||
constructor(opts = {}, pipeline) {
|
||||
this.transformerDependencies = {};
|
||||
@@ -35,17 +34,32 @@ export default class File {
|
||||
this.declarations = {};
|
||||
this.usedHelpers = {};
|
||||
this.dynamicData = {};
|
||||
this.metadata = {};
|
||||
this.data = {};
|
||||
|
||||
this.metadata = {
|
||||
modules: {
|
||||
imports: [],
|
||||
exports: {
|
||||
exported: [],
|
||||
specifiers: []
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.pipeline = pipeline;
|
||||
this.log = new Logger(this, opts.filename || "unknown");
|
||||
this.opts = this.normalizeOptions(opts);
|
||||
this.opts = this.initOptions(opts);
|
||||
this.ast = {};
|
||||
|
||||
this.buildTransformers();
|
||||
|
||||
this.hub = new Hub(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
static helpers = [
|
||||
"inherits",
|
||||
"defaults",
|
||||
@@ -80,68 +94,27 @@ export default class File {
|
||||
"instanceof",
|
||||
|
||||
// legacy
|
||||
"interop-require",
|
||||
"interop-require"
|
||||
];
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
static soloHelpers = [];
|
||||
|
||||
static options = require("./options");
|
||||
|
||||
normalizeOptions(opts: Object) {
|
||||
opts = assign({}, opts);
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
if (opts.filename) {
|
||||
var rcFilename = opts.filename;
|
||||
if (!isAbsolute(rcFilename)) rcFilename = path.join(process.cwd(), rcFilename);
|
||||
opts = resolveRc(rcFilename, opts);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
for (let key in opts) {
|
||||
if (key[0] === "_") continue;
|
||||
|
||||
let option = File.options[key];
|
||||
if (!option) this.log.error(`Unknown option: ${key}`, ReferenceError);
|
||||
}
|
||||
|
||||
var envKey = process.env.BABEL_ENV || process.env.NODE_ENV || "development";
|
||||
if (opts.env) merge(opts, opts.env[envKey]);
|
||||
|
||||
for (let key in File.options) {
|
||||
let option = File.options[key];
|
||||
|
||||
var val = opts[key];
|
||||
if (!val && option.optional) continue;
|
||||
|
||||
if (val && option.deprecated) {
|
||||
throw new Error("Deprecated option " + key + ": " + option.deprecated);
|
||||
}
|
||||
|
||||
if (val == null) {
|
||||
val = clone(option.default);
|
||||
}
|
||||
|
||||
var optionParser = optionParsers[option.type];
|
||||
if (optionParser) val = optionParser(key, val, this.pipeline);
|
||||
|
||||
if (option.alias) {
|
||||
opts[option.alias] = opts[option.alias] || val;
|
||||
} else {
|
||||
opts[key] = val;
|
||||
}
|
||||
}
|
||||
initOptions(opts) {
|
||||
opts = new OptionManager(this.log, this.pipeline).init(opts);
|
||||
|
||||
if (opts.inputSourceMap) {
|
||||
opts.sourceMaps = true;
|
||||
}
|
||||
|
||||
// normalize windows path separators to unix
|
||||
opts.filename = slash(opts.filename);
|
||||
if (opts.sourceRoot) {
|
||||
opts.sourceRoot = slash(opts.sourceRoot);
|
||||
}
|
||||
|
||||
if (opts.moduleId) {
|
||||
opts.moduleIds = true;
|
||||
}
|
||||
@@ -149,7 +122,8 @@ export default class File {
|
||||
opts.basename = path.basename(opts.filename, path.extname(opts.filename));
|
||||
|
||||
opts.ignore = util.arrayify(opts.ignore, util.regexify);
|
||||
opts.only = util.arrayify(opts.only, util.regexify);
|
||||
|
||||
if (opts.only) opts.only = util.arrayify(opts.only, util.regexify);
|
||||
|
||||
defaults(opts, {
|
||||
moduleRoot: opts.sourceRoot
|
||||
@@ -175,12 +149,20 @@ export default class File {
|
||||
}
|
||||
|
||||
return opts;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
isLoose(key: string) {
|
||||
return includes(this.opts.loose, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
buildTransformers() {
|
||||
var file = this;
|
||||
|
||||
@@ -226,7 +208,7 @@ export default class File {
|
||||
|
||||
// build dependency graph
|
||||
for (let pass of (stack: Array)) {
|
||||
for (var dep of (pass.transformer.dependencies: Array)) {
|
||||
for (var dep of (pass.plugin.dependencies: Array)) {
|
||||
this.transformerDependencies[dep] = pass.key;
|
||||
}
|
||||
}
|
||||
@@ -235,6 +217,10 @@ export default class File {
|
||||
this.transformerStack = this.collapseStack(stack);
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
collapseStack(_stack) {
|
||||
var stack = [];
|
||||
var ignore = [];
|
||||
@@ -243,7 +229,7 @@ export default class File {
|
||||
// been merged
|
||||
if (ignore.indexOf(pass) >= 0) continue;
|
||||
|
||||
var group = pass.transformer.metadata.group;
|
||||
var group = pass.plugin.metadata.group;
|
||||
|
||||
// can't merge
|
||||
if (!pass.canTransform() || !group) {
|
||||
@@ -253,7 +239,7 @@ export default class File {
|
||||
|
||||
var mergeStack = [];
|
||||
for (let pass of (_stack: Array)) {
|
||||
if (pass.transformer.metadata.group === group) {
|
||||
if (pass.plugin.metadata.group === group) {
|
||||
mergeStack.push(pass);
|
||||
ignore.push(pass);
|
||||
}
|
||||
@@ -261,24 +247,36 @@ export default class File {
|
||||
|
||||
var visitors = [];
|
||||
for (let pass of (mergeStack: Array)) {
|
||||
visitors.push(pass.handlers);
|
||||
visitors.push(pass.plugin.visitor);
|
||||
}
|
||||
var visitor = traverse.visitors.merge(visitors);
|
||||
var mergeTransformer = new Transformer(group, visitor);
|
||||
stack.push(mergeTransformer.buildPass(this));
|
||||
var mergePlugin = new Plugin(group, { visitor });
|
||||
stack.push(mergePlugin.buildPass(this));
|
||||
}
|
||||
|
||||
return stack;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
set(key: string, val): any {
|
||||
return this.data[key] = val;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
setDynamic(key: string, fn: Function) {
|
||||
this.dynamicData[key] = fn;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
get(key: string): any {
|
||||
var data = this.data[key];
|
||||
if (data) {
|
||||
@@ -291,12 +289,20 @@ export default class File {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
resolveModuleSource(source: string): string {
|
||||
var resolveModuleSource = this.opts.resolveModuleSource;
|
||||
if (resolveModuleSource) source = resolveModuleSource(source, this.opts.filename);
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
addImport(source: string, name?: string, type?: string): Object {
|
||||
name = name || source;
|
||||
var id = this.dynamicImportIds[name];
|
||||
@@ -315,7 +321,7 @@ export default class File {
|
||||
}
|
||||
|
||||
if (this.transformers["es6.modules"].canTransform()) {
|
||||
this.moduleFormatter.importSpecifier(specifiers[0], declar, this.dynamicImports);
|
||||
this.moduleFormatter.importSpecifier(specifiers[0], declar, this.dynamicImports, this.scope);
|
||||
this.moduleFormatter.hasLocalImports = true;
|
||||
} else {
|
||||
this.dynamicImports.push(declar);
|
||||
@@ -325,18 +331,36 @@ export default class File {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
attachAuxiliaryComment(node: Object): Object {
|
||||
var comment = this.opts.auxiliaryComment;
|
||||
if (comment) {
|
||||
var beforeComment = this.opts.auxiliaryCommentBefore;
|
||||
if (beforeComment) {
|
||||
node.leadingComments = node.leadingComments || [];
|
||||
node.leadingComments.push({
|
||||
type: "CommentLine",
|
||||
value: " " + comment
|
||||
value: " " + beforeComment
|
||||
});
|
||||
}
|
||||
|
||||
var afterComment = this.opts.auxiliaryCommentAfter;
|
||||
if (afterComment) {
|
||||
node.trailingComments = node.trailingComments || [];
|
||||
node.trailingComments.push({
|
||||
type: "CommentLine",
|
||||
value: " " + afterComment
|
||||
});
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
addHelper(name: string): Object {
|
||||
var isSolo = includes(File.soloHelpers, name);
|
||||
|
||||
@@ -383,18 +407,27 @@ export default class File {
|
||||
return uid;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
errorWithNode(node, msg, Error = SyntaxError) {
|
||||
var err;
|
||||
if (node.loc) {
|
||||
if (node && node.loc) {
|
||||
var loc = node.loc.start;
|
||||
err = new Error(`Line ${loc.line}: ${msg}`);
|
||||
err.loc = loc;
|
||||
} else {
|
||||
// todo: find errors with nodes inside to at least point to something
|
||||
err = new Error("There's been an error on a dynamic node. This is almost certainly an internal error. Please report it.");
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
mergeSourceMap(map: Object) {
|
||||
var opts = this.opts;
|
||||
|
||||
@@ -417,6 +450,9 @@ export default class File {
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
getModuleFormatter(type: string) {
|
||||
if (isFunction(type) || !moduleFormatters[type]) {
|
||||
@@ -437,6 +473,10 @@ export default class File {
|
||||
return new ModuleFormatter(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
parse(code: string) {
|
||||
var opts = this.opts;
|
||||
|
||||
@@ -465,17 +505,26 @@ export default class File {
|
||||
return tree;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
_addAst(ast) {
|
||||
this.path = NodePath.get({
|
||||
this.path = NodePath.get({
|
||||
hub: this.hub,
|
||||
parentPath: null,
|
||||
parent: ast,
|
||||
container: ast,
|
||||
key: "program"
|
||||
}).setContext(null, this);
|
||||
}).setContext();
|
||||
this.scope = this.path.scope;
|
||||
this.ast = ast;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
addAst(ast) {
|
||||
this.log.debug("Start set AST");
|
||||
this._addAst(ast);
|
||||
@@ -486,14 +535,12 @@ export default class File {
|
||||
if (modFormatter.init && this.transformers["es6.modules"].canTransform()) {
|
||||
modFormatter.init();
|
||||
}
|
||||
this.populateModuleMetadata();
|
||||
this.log.debug("End module formatter init");
|
||||
}
|
||||
|
||||
populateModuleMetadata() {
|
||||
var modules = {};
|
||||
this.metadata.modules = modules;
|
||||
}
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
transform() {
|
||||
this.call("pre");
|
||||
@@ -505,11 +552,19 @@ export default class File {
|
||||
return this.generate();
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
wrap(code, callback) {
|
||||
code = code + "";
|
||||
|
||||
try {
|
||||
return callback();
|
||||
if (this.shouldIgnore()) {
|
||||
return this.makeResult({ code, ignored: true });
|
||||
} else {
|
||||
return callback();
|
||||
}
|
||||
} catch (err) {
|
||||
if (err._babel) {
|
||||
throw err;
|
||||
@@ -538,29 +593,49 @@ export default class File {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
addCode(code: string) {
|
||||
code = (code || "") + "";
|
||||
code = this.parseInputSourceMap(code);
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
parseCode() {
|
||||
this.parseShebang();
|
||||
this.addAst(this.parse(this.code));
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
shouldIgnore() {
|
||||
var opts = this.opts;
|
||||
return util.shouldIgnore(opts.filename, opts.ignore, opts.only);
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
call(key: string) {
|
||||
for (var pass of (this.uncollapsedTransformerStack: Array)) {
|
||||
var fn = pass.transformer[key];
|
||||
var fn = pass.plugin[key];
|
||||
if (fn) fn(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
parseInputSourceMap(code: string) {
|
||||
var opts = this.opts;
|
||||
|
||||
@@ -575,6 +650,10 @@ export default class File {
|
||||
return code;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
parseShebang() {
|
||||
var shebangMatch = shebangRegex.exec(this.code);
|
||||
if (shebangMatch) {
|
||||
@@ -583,6 +662,10 @@ export default class File {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
makeResult({ code, map = null, ast, ignored }) {
|
||||
var result = {
|
||||
metadata: null,
|
||||
@@ -608,6 +691,10 @@ export default class File {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
generate() {
|
||||
var opts = this.opts;
|
||||
var ast = this.ast;
|
||||
|
||||
@@ -4,36 +4,82 @@ import buildDebug from "debug/node";
|
||||
var verboseDebug = buildDebug("babel:verbose");
|
||||
var generalDebug = buildDebug("babel");
|
||||
|
||||
var seenDeprecatedMessages = [];
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
export default class Logger {
|
||||
constructor(file: File, filename: string) {
|
||||
this.filename = filename;
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
_buildMessage(msg: string): string {
|
||||
var parts = `[BABEL] ${this.filename}`;
|
||||
if (msg) parts += `: ${msg}`;
|
||||
return parts;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
warn(msg) {
|
||||
console.warn(this._buildMessage(msg));
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
error(msg: string, Constructor = Error) {
|
||||
throw new Constructor(this._buildMessage(msg));
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
deprecate(msg) {
|
||||
if (!this.file.opts.suppressDeprecationMessages) {
|
||||
console.error(this._buildMessage(msg));
|
||||
}
|
||||
if (this.file.opts.suppressDeprecationMessages) return;
|
||||
|
||||
msg = this._buildMessage(msg);
|
||||
|
||||
// already seen this message
|
||||
if (seenDeprecatedMessages.indexOf(msg) >= 0) return;
|
||||
|
||||
// make sure we don't see it again
|
||||
seenDeprecatedMessages.push(msg);
|
||||
|
||||
console.error(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
verbose(msg: string) {
|
||||
if (verboseDebug.enabled) verboseDebug(this._buildMessage(msg));
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
debug(msg: string) {
|
||||
if (generalDebug.enabled) generalDebug(this._buildMessage(msg));
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
deopt(node: Object, msg: string) {
|
||||
this.debug(msg);
|
||||
}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
import * as util from "../../util";
|
||||
|
||||
export function transformerList(key, val, pipeline) {
|
||||
val = util.arrayify(val);
|
||||
|
||||
if (val.indexOf("all") >= 0 || val.indexOf(true) >= 0) {
|
||||
val = Object.keys(pipeline.transformers);
|
||||
}
|
||||
|
||||
return pipeline._ensureTransformerNames(key, val);
|
||||
}
|
||||
|
||||
export function number(key, val) {
|
||||
return +val;
|
||||
}
|
||||
|
||||
export function boolean(key, val) {
|
||||
return !!val;
|
||||
}
|
||||
|
||||
export function booleanString(key, val) {
|
||||
return util.booleanify(val);
|
||||
}
|
||||
|
||||
export function list(key, val) {
|
||||
return util.list(val);
|
||||
}
|
||||
3
src/babel/transformation/file/options/README.md
Normal file
3
src/babel/transformation/file/options/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## File Options
|
||||
|
||||
This is the File Options directory.
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"filename": {
|
||||
"type": "string",
|
||||
"type": "filename",
|
||||
"description": "filename to use when reading from stdin - this will be used in source-maps, errors etc",
|
||||
"default": "unknown",
|
||||
"shorthand": "f"
|
||||
@@ -47,7 +47,9 @@
|
||||
},
|
||||
|
||||
"experimental": {
|
||||
"deprecated": "use `--stage 0`/`{ stage: 0 }` instead"
|
||||
"type": "boolean",
|
||||
"description": "allow use of experimental transformers",
|
||||
"default": false
|
||||
},
|
||||
|
||||
"highlightCode": {
|
||||
@@ -76,7 +78,8 @@
|
||||
"blacklist": {
|
||||
"type": "transformerList",
|
||||
"description": "blacklist of transformers to NOT use",
|
||||
"shorthand": "b"
|
||||
"shorthand": "b",
|
||||
"default": []
|
||||
},
|
||||
|
||||
"whitelist": {
|
||||
@@ -88,7 +91,8 @@
|
||||
|
||||
"optional": {
|
||||
"type": "transformerList",
|
||||
"description": "list of optional transformers to enable"
|
||||
"description": "list of optional transformers to enable",
|
||||
"default": []
|
||||
},
|
||||
|
||||
"modules": {
|
||||
@@ -120,12 +124,14 @@
|
||||
|
||||
"plugins": {
|
||||
"type": "list",
|
||||
"description": ""
|
||||
"description": "",
|
||||
"default": []
|
||||
},
|
||||
|
||||
"ignore": {
|
||||
"type": "list",
|
||||
"description": "list of glob paths to **not** compile"
|
||||
"description": "list of glob paths to **not** compile",
|
||||
"default": []
|
||||
},
|
||||
|
||||
"only": {
|
||||
@@ -171,12 +177,23 @@
|
||||
},
|
||||
|
||||
"auxiliaryComment": {
|
||||
"deprecated": "renamed to auxiliaryCommentBefore",
|
||||
"shorthand": "a",
|
||||
"alias": "auxiliaryCommentBefore"
|
||||
},
|
||||
|
||||
"auxiliaryCommentBefore": {
|
||||
"type": "string",
|
||||
"default": "",
|
||||
"shorthand": "a",
|
||||
"description": "attach a comment before all helper declarations and auxiliary code"
|
||||
},
|
||||
|
||||
"auxiliaryCommentAfter": {
|
||||
"type": "string",
|
||||
"default": "",
|
||||
"description": "attach a comment after all helper declarations and auxiliary code"
|
||||
},
|
||||
|
||||
"externalHelpers": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
@@ -219,12 +236,12 @@
|
||||
},
|
||||
|
||||
"sourceRoot": {
|
||||
"type": "string",
|
||||
"type": "filename",
|
||||
"description": "the root from which all sources are relative"
|
||||
},
|
||||
|
||||
"moduleRoot": {
|
||||
"type": "string",
|
||||
"type": "filename",
|
||||
"description": "optional prefix for the AMD module formatter that will be prepend to the filename on module definitions"
|
||||
},
|
||||
|
||||
@@ -236,7 +253,7 @@
|
||||
},
|
||||
|
||||
"babelrc": {
|
||||
"hidden": true,
|
||||
"description": "do not load the same .babelrc file twice"
|
||||
"description": "Specify a custom list of babelrc files to use",
|
||||
"type": "list"
|
||||
}
|
||||
}
|
||||
39
src/babel/transformation/file/options/index.js
Normal file
39
src/babel/transformation/file/options/index.js
Normal file
@@ -0,0 +1,39 @@
|
||||
import * as parsers from "./parsers";
|
||||
import config from "./config";
|
||||
|
||||
export { config };
|
||||
|
||||
/**
|
||||
* Validate an option.
|
||||
*/
|
||||
|
||||
export function validateOption(key, val, pipeline) {
|
||||
var opt = config[key];
|
||||
var parser = opt && parsers[opt.type];
|
||||
if (parser && parser.validate) {
|
||||
return parser.validate(key, val, pipeline);
|
||||
} else {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize all options.
|
||||
*/
|
||||
|
||||
export function normaliseOptions(options = {}) {
|
||||
for (var key in options) {
|
||||
var val = options[key];
|
||||
if (val == null) continue;
|
||||
|
||||
var opt = config[key];
|
||||
if (!opt) continue;
|
||||
|
||||
var parser = parsers[opt.type];
|
||||
if (parser) val = parser(val);
|
||||
|
||||
options[key] = val;
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
170
src/babel/transformation/file/options/option-manager.js
Normal file
170
src/babel/transformation/file/options/option-manager.js
Normal file
@@ -0,0 +1,170 @@
|
||||
import { validateOption, normaliseOptions } from "./index";
|
||||
import stripJsonComments from "strip-json-comments";
|
||||
import isAbsolute from "path-is-absolute";
|
||||
import pathExists from "path-exists";
|
||||
import clone from "lodash/lang/clone";
|
||||
import merge from "../../../helpers/merge";
|
||||
import config from "./config";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
|
||||
var existsCache = {};
|
||||
var jsonCache = {};
|
||||
|
||||
const CONFIG_FILENAME = ".babelrc";
|
||||
|
||||
function exists(filename) {
|
||||
var cached = existsCache[filename];
|
||||
if (cached != null) {
|
||||
return cached;
|
||||
} else {
|
||||
return existsCache[filename] = pathExists.sync(filename);
|
||||
}
|
||||
}
|
||||
|
||||
export default class OptionManager {
|
||||
constructor(log, pipeline) {
|
||||
this.resolvedConfigs = [];
|
||||
this.options = OptionManager.createBareOptions();
|
||||
this.pipeline = pipeline;
|
||||
this.log = log;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
static createBareOptions() {
|
||||
var opts = {};
|
||||
|
||||
for (var key in config) {
|
||||
var opt = config[key];
|
||||
opts[key] = clone(opt.default);
|
||||
}
|
||||
|
||||
return opts;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
addConfig(loc) {
|
||||
if (this.resolvedConfigs.indexOf(loc) >= 0) return;
|
||||
|
||||
var content = fs.readFileSync(loc, "utf8");
|
||||
var opts;
|
||||
|
||||
try {
|
||||
opts = jsonCache[content] = jsonCache[content] || JSON.parse(stripJsonComments(content));
|
||||
} catch (err) {
|
||||
err.message = `${loc}: ${err.message}`;
|
||||
throw err;
|
||||
}
|
||||
|
||||
this.mergeOptions(opts, loc);
|
||||
this.resolvedConfigs.push(loc);
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
mergeOptions(opts, alias = "foreign") {
|
||||
if (!opts) return;
|
||||
|
||||
for (let key in opts) {
|
||||
if (key[0] === "_") continue;
|
||||
|
||||
let option = config[key];
|
||||
|
||||
// check for an unknown option
|
||||
if (!option) this.log.error(`Unknown option: ${alias}.${key}`, ReferenceError);
|
||||
}
|
||||
|
||||
// normalise options
|
||||
normaliseOptions(opts);
|
||||
|
||||
// merge them into this current files options
|
||||
merge(this.options, opts);
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
findConfigs(loc) {
|
||||
if (!loc) return;
|
||||
|
||||
if (!isAbsolute(loc)) {
|
||||
loc = path.join(process.cwd(), loc);
|
||||
}
|
||||
|
||||
while (loc !== (loc = path.dirname(loc))) {
|
||||
if (this.options.breakConfig) return;
|
||||
|
||||
var configLoc = path.join(loc, CONFIG_FILENAME);
|
||||
if (exists(configLoc)) this.addConfig(configLoc);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
normaliseOptions() {
|
||||
var opts = this.options;
|
||||
|
||||
for (let key in config) {
|
||||
var option = config[key];
|
||||
var val = opts[key];
|
||||
|
||||
// optional
|
||||
if (!val && option.optional) continue;
|
||||
|
||||
// deprecated
|
||||
if (this.log && val && option.deprecated) {
|
||||
this.log.deprecate(`Deprecated option ${key}: ${option.deprecated}`);
|
||||
}
|
||||
|
||||
// validate
|
||||
if (this.pipeline && val) {
|
||||
val = validateOption(key, val, this.pipeline);
|
||||
}
|
||||
|
||||
// aaliases
|
||||
if (option.alias) {
|
||||
opts[option.alias] = opts[option.alias] || val;
|
||||
} else {
|
||||
opts[key] = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
init(opts) {
|
||||
this.mergeOptions(opts, "direct");
|
||||
|
||||
// babelrc option
|
||||
if (opts.babelrc) {
|
||||
for (var loc of (opts.babelrc: Array)) this.addConfig(loc);
|
||||
}
|
||||
|
||||
// resolve all .babelrc files
|
||||
this.findConfigs(opts.filename);
|
||||
|
||||
// merge in env
|
||||
var envKey = process.env.BABEL_ENV || process.env.NODE_ENV || "development";
|
||||
if (this.options.env) {
|
||||
this.mergeOptions(this.options.env[envKey], `direct.env.${envKey}`);
|
||||
}
|
||||
|
||||
// normalise
|
||||
this.normaliseOptions(opts);
|
||||
|
||||
return this.options;
|
||||
}
|
||||
}
|
||||
60
src/babel/transformation/file/options/parsers.js
Normal file
60
src/babel/transformation/file/options/parsers.js
Normal file
@@ -0,0 +1,60 @@
|
||||
import slash from "slash";
|
||||
import * as util from "../../../util";
|
||||
|
||||
/**
|
||||
* Get a transformer list from a value.
|
||||
*/
|
||||
|
||||
export function transformerList(val) {
|
||||
return util.arrayify(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate transformer list. Maps "all" to all transformer names.
|
||||
*/
|
||||
|
||||
transformerList.validate = function (key, val, pipeline) {
|
||||
if (val.indexOf("all") >= 0 || val.indexOf(true) >= 0) {
|
||||
val = Object.keys(pipeline.transformers);
|
||||
}
|
||||
|
||||
return pipeline._ensureTransformerNames(key, val);
|
||||
};
|
||||
|
||||
/**
|
||||
* Cast a value to a number.
|
||||
*/
|
||||
|
||||
export function number(val) {
|
||||
return +val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cast a value to a boolean.
|
||||
*/
|
||||
|
||||
export var filename = slash;
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
export function boolean(val) {
|
||||
return !!val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cast a boolean-like string to a boolean.
|
||||
*/
|
||||
|
||||
export function booleanString(val) {
|
||||
return util.booleanify(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cast a value to an array, splitting strings by ",".
|
||||
*/
|
||||
|
||||
export function list(val) {
|
||||
return util.list(val);
|
||||
}
|
||||
@@ -1,17 +1,48 @@
|
||||
import * as node from "../../api/node";
|
||||
import Transformer from "../transformer";
|
||||
import Plugin from "../plugin";
|
||||
import * as types from "../../types";
|
||||
import * as messages from "../../messages";
|
||||
import traverse from "../../traversal";
|
||||
import parse from "../../helpers/parse";
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
var context = {
|
||||
messages,
|
||||
Transformer,
|
||||
Plugin,
|
||||
types,
|
||||
parse,
|
||||
traverse
|
||||
};
|
||||
|
||||
import * as util from "../../util";
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
export default class PluginManager {
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
static memoisedPlugins = [];
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
static memoisePluginContainer(fn) {
|
||||
for (var i = 0; i < PluginManager.memoisedPlugins.length; i++) {
|
||||
var plugin = PluginManager.memoisedPlugins[i];
|
||||
if (plugin.container === fn) return plugin.transformer;
|
||||
}
|
||||
|
||||
var transformer = fn(node);
|
||||
var transformer = fn(context);
|
||||
PluginManager.memoisedPlugins.push({
|
||||
container: fn,
|
||||
transformer: transformer
|
||||
@@ -19,8 +50,16 @@ export default class PluginManager {
|
||||
return transformer;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
static positions = ["before", "after"];
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
constructor({ file, transformers, before, after } = { transformers: {}, before: [], after: [] }) {
|
||||
this.transformers = transformers;
|
||||
this.file = file;
|
||||
@@ -28,6 +67,10 @@ export default class PluginManager {
|
||||
this.after = after;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
subnormaliseString(name, position) {
|
||||
// this is a plugin in the form of "foobar" or "foobar:after"
|
||||
// where the optional colon is the delimiter for plugin position in the transformer stack
|
||||
@@ -47,6 +90,10 @@ export default class PluginManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
validate(name, plugin) {
|
||||
// validate transformer key
|
||||
var key = plugin.key;
|
||||
@@ -55,7 +102,7 @@ export default class PluginManager {
|
||||
}
|
||||
|
||||
// validate Transformer instance
|
||||
if (!plugin.buildPass || plugin.constructor.name !== "Transformer") {
|
||||
if (!plugin.buildPass || plugin.constructor.name !== "Plugin") {
|
||||
throw new TypeError(messages.get("pluginNotTransformer", name));
|
||||
}
|
||||
|
||||
@@ -63,6 +110,10 @@ export default class PluginManager {
|
||||
plugin.metadata.plugin = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
add(name) {
|
||||
var position;
|
||||
var plugin;
|
||||
|
||||
3
src/babel/transformation/helpers/README.md
Normal file
3
src/babel/transformation/helpers/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## Transformation Helpers
|
||||
|
||||
This is the Transformation Helpers directory.
|
||||
@@ -1,17 +1,33 @@
|
||||
import explode from "./explode-assignable-expression";
|
||||
import * as t from "../../types";
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
export default function (opts) {
|
||||
var exports = {};
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
var isAssignment = function (node) {
|
||||
return node.operator === opts.operator + "=";
|
||||
};
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
var buildAssignment = function (left, right) {
|
||||
return t.assignmentExpression("=", left, right);
|
||||
};
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
exports.ExpressionStatement = function (node, parent, scope, file) {
|
||||
// hit the `AssignmentExpression` one below
|
||||
if (this.isCompletionRecord()) return;
|
||||
@@ -29,6 +45,10 @@ export default function (opts) {
|
||||
return nodes;
|
||||
};
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
exports.AssignmentExpression = function (node, parent, scope, file) {
|
||||
if (!isAssignment(node)) return;
|
||||
|
||||
@@ -38,6 +58,10 @@ export default function (opts) {
|
||||
return nodes;
|
||||
};
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
exports.BinaryExpression = function (node) {
|
||||
if (node.operator !== opts.operator) return;
|
||||
return opts.build(node.left, node.right);
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import * as t from "../../types";
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
export default function build(node, buildBody) {
|
||||
var self = node.blocks.shift();
|
||||
if (!self) return;
|
||||
|
||||
@@ -1,11 +1,24 @@
|
||||
import explode from "./explode-assignable-expression";
|
||||
import * as t from "../../types";
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
export default function (exports, opts) {
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
var buildAssignment = function (left, right) {
|
||||
return t.assignmentExpression("=", left, right);
|
||||
};
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
exports.ExpressionStatement = function (node, parent, scope, file) {
|
||||
// hit the `AssignmentExpression` one below
|
||||
if (this.isCompletionRecord()) return;
|
||||
@@ -25,6 +38,10 @@ export default function (exports, opts) {
|
||||
return nodes;
|
||||
};
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
exports.AssignmentExpression = function (node, parent, scope, file) {
|
||||
if (!opts.is(node, file)) return;
|
||||
|
||||
|
||||
@@ -9,8 +9,18 @@ import esutils from "esutils";
|
||||
import * as react from "./react";
|
||||
import * as t from "../../types";
|
||||
|
||||
export default function (exports, opts) {
|
||||
exports.JSXIdentifier = function (node) {
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
export default function (opts) {
|
||||
var visitor = {};
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
visitor.JSXIdentifier = function (node) {
|
||||
if (node.name === "this" && this.isReferenced()) {
|
||||
return t.thisExpression();
|
||||
} else if (esutils.keyword.isIdentifierNameES6(node.name)) {
|
||||
@@ -20,22 +30,38 @@ export default function (exports, opts) {
|
||||
}
|
||||
};
|
||||
|
||||
exports.JSXNamespacedName = function () {
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
visitor.JSXNamespacedName = function () {
|
||||
throw this.errorWithNode(messages.get("JSXNamespacedTags"));
|
||||
};
|
||||
|
||||
exports.JSXMemberExpression = {
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
visitor.JSXMemberExpression = {
|
||||
exit(node) {
|
||||
node.computed = t.isLiteral(node.property);
|
||||
node.type = "MemberExpression";
|
||||
}
|
||||
};
|
||||
|
||||
exports.JSXExpressionContainer = function (node) {
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
visitor.JSXExpressionContainer = function (node) {
|
||||
return node.expression;
|
||||
};
|
||||
|
||||
exports.JSXAttribute = {
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
visitor.JSXAttribute = {
|
||||
enter(node) {
|
||||
var value = node.value;
|
||||
if (t.isLiteral(value) && isString(value.value)) {
|
||||
@@ -49,7 +75,11 @@ export default function (exports, opts) {
|
||||
}
|
||||
};
|
||||
|
||||
exports.JSXOpeningElement = {
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
visitor.JSXOpeningElement = {
|
||||
exit(node, parent, scope, file) {
|
||||
parent.children = react.buildChildren(parent);
|
||||
|
||||
@@ -139,7 +169,11 @@ export default function (exports, opts) {
|
||||
return attribs;
|
||||
};
|
||||
|
||||
exports.JSXElement = {
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
visitor.JSXElement = {
|
||||
exit(node) {
|
||||
var callExpr = node.openingElement;
|
||||
|
||||
@@ -153,54 +187,5 @@ export default function (exports, opts) {
|
||||
}
|
||||
};
|
||||
|
||||
// display names
|
||||
|
||||
var addDisplayName = function (id, call) {
|
||||
var props = call.arguments[0].properties;
|
||||
var safe = true;
|
||||
|
||||
for (var i = 0; i < props.length; i++) {
|
||||
var prop = props[i];
|
||||
var key = t.toComputedKey(prop);
|
||||
if (t.isLiteral(key, { value: "displayName" })) {
|
||||
safe = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (safe) {
|
||||
props.unshift(t.property("init", t.identifier("displayName"), t.literal(id)));
|
||||
}
|
||||
};
|
||||
|
||||
exports.ExportDefaultDeclaration = function (node, parent, scope, file) {
|
||||
if (react.isCreateClass(node.declaration)) {
|
||||
addDisplayName(file.opts.basename, node.declaration);
|
||||
}
|
||||
};
|
||||
|
||||
exports.AssignmentExpression =
|
||||
exports.Property =
|
||||
exports.VariableDeclarator = function (node) {
|
||||
var left, right;
|
||||
|
||||
if (t.isAssignmentExpression(node)) {
|
||||
left = node.left;
|
||||
right = node.right;
|
||||
} else if (t.isProperty(node)) {
|
||||
left = node.key;
|
||||
right = node.value;
|
||||
} else if (t.isVariableDeclarator(node)) {
|
||||
left = node.id;
|
||||
right = node.init;
|
||||
}
|
||||
|
||||
if (t.isMemberExpression(left)) {
|
||||
left = left.property;
|
||||
}
|
||||
|
||||
if (t.isIdentifier(left) && react.isCreateClass(right)) {
|
||||
addDisplayName(left.name, right);
|
||||
}
|
||||
};
|
||||
return visitor;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
import * as t from "../../types";
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
var visitor = {
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
enter(node, parent, scope, state) {
|
||||
if (this.isThisExpression() || this.isReferencedIdentifier({ name: "arguments" })) {
|
||||
state.found = true;
|
||||
@@ -8,11 +17,19 @@ var visitor = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
Function() {
|
||||
this.skip();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
export default function (node, scope) {
|
||||
var container = t.functionExpression(null, [], node.body, node.generator, node.async);
|
||||
|
||||
|
||||
@@ -2,6 +2,10 @@ import each from "lodash/collection/each";
|
||||
import has from "lodash/object/has";
|
||||
import * as t from "../../types";
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
export function push(mutatorMap, node, kind, file) {
|
||||
var alias = t.toKeyAlias(node);
|
||||
|
||||
@@ -43,6 +47,10 @@ export function push(mutatorMap, node, kind, file) {
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
export function hasComputed(mutatorMap) {
|
||||
for (var key in mutatorMap) {
|
||||
if (mutatorMap[key]._computed) {
|
||||
@@ -52,6 +60,10 @@ export function hasComputed(mutatorMap) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
export function toComputedObjectFromClass(obj) {
|
||||
var objExpr = t.arrayExpression([]);
|
||||
|
||||
@@ -65,6 +77,10 @@ export function toComputedObjectFromClass(obj) {
|
||||
return objExpr;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
export function toClassObject(mutatorMap) {
|
||||
var objExpr = t.objectExpression([]);
|
||||
|
||||
@@ -92,6 +108,10 @@ export function toClassObject(mutatorMap) {
|
||||
return objExpr;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
export function toDefineObject(mutatorMap) {
|
||||
each(mutatorMap, function (map) {
|
||||
if (map.value) map.writable = t.literal(true);
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import * as t from "../../types";
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
var getObjRef = function (node, nodes, file, scope) {
|
||||
var ref;
|
||||
if (t.isIdentifier(node)) {
|
||||
@@ -33,6 +37,10 @@ var getObjRef = function (node, nodes, file, scope) {
|
||||
return temp;
|
||||
};
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
var getPropRef = function (node, nodes, file, scope) {
|
||||
var prop = node.property;
|
||||
var key = t.toComputedKey(node, prop);
|
||||
@@ -45,6 +53,10 @@ var getPropRef = function (node, nodes, file, scope) {
|
||||
return temp;
|
||||
};
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
export default function (node, nodes, file, scope, allowedSingleIdent) {
|
||||
var obj;
|
||||
if (t.isIdentifier(node) && allowedSingleIdent) {
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
import * as t from "../../types";
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
export default function (node) {
|
||||
var lastNonDefault = 0;
|
||||
for (var i = 0; i < node.params.length; i++) {
|
||||
if (!t.isAssignmentPattern(node.params[i])) lastNonDefault = i + 1;
|
||||
var param = node.params[i];
|
||||
if (!t.isAssignmentPattern(param) && !t.isRestElement(param)) {
|
||||
lastNonDefault = i + 1;
|
||||
}
|
||||
}
|
||||
return lastNonDefault;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import * as t from "../../types";
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
export default function (decorators, scope) {
|
||||
for (var i = 0; i < decorators.length; i++) {
|
||||
var decorator = decorators[i];
|
||||
|
||||
@@ -2,6 +2,10 @@ import getFunctionArity from "./get-function-arity";
|
||||
import * as util from "../../util";
|
||||
import * as t from "../../types";
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
function visitIdentifier(context, node, scope, state) {
|
||||
// check if this node matches our function id
|
||||
if (node.name !== state.name) return;
|
||||
@@ -15,19 +19,33 @@ function visitIdentifier(context, node, scope, state) {
|
||||
context.stop();
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
var visitor = {
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
ReferencedIdentifier(node, parent, scope, state) {
|
||||
visitIdentifier(this, node, scope, state);
|
||||
},
|
||||
|
||||
AssignmentExpression(node, parent, scope, state) {
|
||||
var ids = this.getBindingIdentifiers();
|
||||
for (var name in ids) {
|
||||
visitIdentifier(this, ids[name], scope, state);
|
||||
}
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
BindingIdentifier(node, parent, scope, state) {
|
||||
visitIdentifier(this, node, scope, state);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
var wrap = function (state, method, id, scope) {
|
||||
if (state.selfReference) {
|
||||
if (scope.hasBinding(id.name) && !scope.hasGlobal(id.name)) {
|
||||
@@ -59,6 +77,10 @@ var wrap = function (state, method, id, scope) {
|
||||
scope.getProgramParent().references[id.name] = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
var visit = function (node, name, scope) {
|
||||
var state = {
|
||||
selfAssignment: false,
|
||||
@@ -71,10 +93,10 @@ var visit = function (node, name, scope) {
|
||||
// check to see if we have a local binding of the id we're setting inside of
|
||||
// the function, this is important as there are caveats associated
|
||||
|
||||
var bindingInfo = scope.getOwnBindingInfo(name);
|
||||
var binding = scope.getOwnBinding(name);
|
||||
|
||||
if (bindingInfo) {
|
||||
if (bindingInfo.kind === "param") {
|
||||
if (binding) {
|
||||
if (binding.kind === "param") {
|
||||
// safari will blow up in strict mode with code like:
|
||||
//
|
||||
// var t = function t(t) {};
|
||||
@@ -105,17 +127,24 @@ var visit = function (node, name, scope) {
|
||||
return state;
|
||||
};
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
export function custom(node, id, scope) {
|
||||
var state = visit(node, id.name, scope);
|
||||
return wrap(state, node, id, scope);
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
export function property(node, file, scope) {
|
||||
var key = t.toComputedKey(node, node.key);
|
||||
if (!t.isLiteral(key)) return; // we can't set a function id with this
|
||||
|
||||
var name = t.toIdentifier(key.value);
|
||||
if (name === "eval" || name === "arguments") name = "_" + name;
|
||||
var name = t.toBindingIdentifierName(key.value);
|
||||
var id = t.identifier(name);
|
||||
|
||||
var method = node.value;
|
||||
@@ -123,6 +152,10 @@ export function property(node, file, scope) {
|
||||
node.value = wrap(state, method, id, scope) || method;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
export function bare(node, parent, scope) {
|
||||
// has an `id` so we don't need to infer one
|
||||
if (node.id) return;
|
||||
@@ -136,8 +169,8 @@ export function bare(node, parent, scope) {
|
||||
id = parent.id;
|
||||
|
||||
if (t.isIdentifier(id)) {
|
||||
var bindingInfo = scope.parent.getBinding(id.name);
|
||||
if (bindingInfo && bindingInfo.constant && scope.getBinding(id.name) === bindingInfo) {
|
||||
var binding = scope.parent.getBinding(id.name);
|
||||
if (binding && binding.constant && scope.getBinding(id.name) === binding) {
|
||||
// always going to reference this method
|
||||
node.id = id;
|
||||
return;
|
||||
@@ -156,7 +189,7 @@ export function bare(node, parent, scope) {
|
||||
return;
|
||||
}
|
||||
|
||||
name = t.toIdentifier(name);
|
||||
name = t.toBindingIdentifierName(name);
|
||||
id = t.identifier(name);
|
||||
|
||||
var state = visit(node, name, scope);
|
||||
|
||||
31
src/babel/transformation/helpers/react.js
vendored
31
src/babel/transformation/helpers/react.js
vendored
@@ -1,30 +1,19 @@
|
||||
import * as t from "../../types";
|
||||
|
||||
var isCreateClassCallExpression = t.buildMatchMemberExpression("React.createClass");
|
||||
|
||||
export function isCreateClass(node) {
|
||||
if (!node || !t.isCallExpression(node)) return false;
|
||||
|
||||
// not React.createClass call member object
|
||||
if (!isCreateClassCallExpression(node.callee)) return false;
|
||||
|
||||
// no call arguments
|
||||
var args = node.arguments;
|
||||
if (args.length !== 1) return false;
|
||||
|
||||
// first node arg is not an object
|
||||
var first = args[0];
|
||||
if (!t.isObjectExpression(first)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
export var isReactComponent = t.buildMatchMemberExpression("React.Component");
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
export function isCompatTag(tagName) {
|
||||
return tagName && /^[a-z]|\-/.test(tagName);
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
function cleanJSXElementLiteralChild(child, args) {
|
||||
var lines = child.value.split(/\r\n|\n|\r/);
|
||||
|
||||
@@ -70,6 +59,10 @@ function cleanJSXElementLiteralChild(child, args) {
|
||||
if (str) args.push(t.literal(str));
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
export function buildChildren(node) {
|
||||
var elems = [];
|
||||
|
||||
|
||||
@@ -1,10 +1,18 @@
|
||||
import pull from "lodash/array/pull";
|
||||
import * as t from "../../types";
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
export function is(node, flag) {
|
||||
return t.isLiteral(node) && node.regex && node.regex.flags.indexOf(flag) >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
export function pullFlag(node, flag) {
|
||||
var flags = node.regex.flags.split("");
|
||||
if (node.regex.flags.indexOf(flag) < 0) return;
|
||||
|
||||
@@ -1,10 +1,23 @@
|
||||
import * as t from "../../types";
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
var awaitVisitor = {
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
Function() {
|
||||
this.skip();
|
||||
},
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
AwaitExpression(node) {
|
||||
node.type = "YieldExpression";
|
||||
|
||||
@@ -16,7 +29,16 @@ var awaitVisitor = {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
var referenceVisitor = {
|
||||
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
ReferencedIdentifier(node, parent, scope, state) {
|
||||
var name = state.id.name;
|
||||
if (node.name === name && scope.bindingIdentifierEquals(name, state.id)) {
|
||||
@@ -25,11 +47,17 @@ var referenceVisitor = {
|
||||
}
|
||||
};
|
||||
|
||||
export default function (node, callId, scope) {
|
||||
/**
|
||||
* [Please add a description.]
|
||||
*/
|
||||
|
||||
export default function (path, callId) {
|
||||
var node = path.node;
|
||||
|
||||
node.async = false;
|
||||
node.generator = true;
|
||||
|
||||
scope.traverse(node, awaitVisitor, state);
|
||||
path.traverse(awaitVisitor, state);
|
||||
|
||||
var call = t.callExpression(callId, [node]);
|
||||
|
||||
@@ -44,11 +72,11 @@ export default function (node, callId, scope) {
|
||||
return declar;
|
||||
} else {
|
||||
if (id) {
|
||||
var state = { id: id };
|
||||
scope.traverse(node, referenceVisitor, state);
|
||||
var state = { id };
|
||||
path.traverse(referenceVisitor, state);
|
||||
|
||||
if (state.ref) {
|
||||
scope.parent.push({ id: state.ref });
|
||||
path.scope.parent.push({ id: state.ref });
|
||||
return t.assignmentExpression("=", state.ref, call);
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user