Compare commits
769 Commits
initialize
...
initialize
| Author | SHA1 | Date | |
|---|---|---|---|
| 41fd81a8f5 | |||
| bfa97fe782 | |||
| 1518210ee6 | |||
| b1facb18de | |||
| 2c38b52ffb | |||
| 44e7cf615c | |||
| 983ab3bbc0 | |||
| 05dfb60683 | |||
|
|
a8e859bb05 | ||
| f3c530b2c9 | |||
| a12f1771c8 | |||
| fad999bf52 | |||
| 2707780f7e | |||
|
|
b138b5a62e | ||
|
|
a7620bd266 | ||
|
|
6874c244ab | ||
|
|
8fce431d88 | ||
|
|
d0a8982c12 | ||
|
|
a677d59a63 | ||
|
|
c7f7f9b8b5 | ||
|
|
61d01f1114 | ||
|
|
f995f8e02c | ||
|
|
2ccc451e96 | ||
|
|
575eeb370e | ||
|
|
27668377b5 | ||
|
|
d1c93e7e3e | ||
|
|
9647560dd6 | ||
|
|
2486615a74 | ||
|
|
d8e6219ad9 | ||
|
|
81c5f1f22d | ||
|
|
e7b80a2cb9 | ||
|
|
405c1aaad8 | ||
|
|
a1310333f7 | ||
|
|
903ad6160d | ||
|
|
5a3e97073e | ||
|
|
4c28f54152 | ||
|
|
ae06baf22f | ||
|
|
282f81bd67 | ||
|
|
9fec528016 | ||
|
|
80aa7dc3c6 | ||
|
|
4cb2148273 | ||
|
|
3dcb8ca99e | ||
|
|
bfc56ebbab | ||
|
|
e8dac621de | ||
|
|
44f9d85904 | ||
|
|
04354d1556 | ||
|
|
5f807ae45b | ||
|
|
646409b23e | ||
|
|
8415065d99 | ||
|
|
3af02f63de | ||
|
|
c3388ea42f | ||
|
|
5b907e9bb7 | ||
|
|
7bc22e42f5 | ||
|
|
771c730fda | ||
|
|
9f148a1603 | ||
|
|
09cb4273bc | ||
|
|
8fd532db39 | ||
|
|
3fa37d2da3 | ||
|
|
4636321f06 | ||
|
|
a7dac49518 | ||
|
|
03d163a0d9 | ||
|
|
455d782ef0 | ||
|
|
a28353703f | ||
|
|
467667af88 | ||
|
|
6ee8c97e6a | ||
|
|
e5048053aa | ||
|
|
9f832c2716 | ||
|
|
daaa2063bb | ||
|
|
26eb891870 | ||
|
|
0238244268 | ||
|
|
2f3f77926d | ||
|
|
30449fe05d | ||
|
|
86245a83a2 | ||
|
|
197a8da04d | ||
|
|
314513374d | ||
|
|
b91720c1cc | ||
|
|
e9dc74e787 | ||
|
|
30f3b07ebf | ||
|
|
db3c31a8af | ||
|
|
00758308ae | ||
|
|
fc5365fe4a | ||
|
|
ee5b79d75d | ||
|
|
875e9619b7 | ||
|
|
a18166d2a9 | ||
|
|
c09664f35d | ||
|
|
83993b08d5 | ||
|
|
f651f22f96 | ||
|
|
416ce35638 | ||
|
|
c5cfc83182 | ||
|
|
d389b702e6 | ||
|
|
aaa1b1f4b0 | ||
|
|
12da0941c8 | ||
|
|
9be27bcfea | ||
|
|
c0d0bf2e5e | ||
|
|
e85c9b9ec8 | ||
|
|
80e95d0c83 | ||
|
|
dbf3f91f1e | ||
|
|
aa814073b7 | ||
|
|
8afeef2d96 | ||
|
|
3d7bc435d5 | ||
|
|
2b3590929b | ||
|
|
b3c7df9314 | ||
|
|
ff8a295ea7 | ||
|
|
c35ba3d3ab | ||
|
|
4f77a5aaad | ||
|
|
0e9c49606a | ||
|
|
a0d76a8c0e | ||
|
|
bffa415b83 | ||
|
|
0b3f883ed1 | ||
|
|
25f7e6808e | ||
|
|
7b54a94389 | ||
|
|
5156d3ea06 | ||
|
|
20e43ad103 | ||
|
|
de1fa902f0 | ||
|
|
f02e5e6d0a | ||
|
|
2884bac44b | ||
|
|
b7989419c7 | ||
|
|
0164662944 | ||
|
|
fb100eee41 | ||
|
|
b2429fe203 | ||
|
|
f753c48f74 | ||
|
|
4436ffd604 | ||
|
|
655a972737 | ||
|
|
8a8474c321 | ||
|
|
d04508e510 | ||
|
|
d3a37b5d08 | ||
|
|
c9a68984d6 | ||
|
|
c6e966cac9 | ||
|
|
a0bed42aec | ||
|
|
2b472912e4 | ||
|
|
e94da0dce5 | ||
|
|
bb6cc61979 | ||
|
|
3d0c5d2afc | ||
|
|
d18afbd7c3 | ||
|
|
e74efd2c0a | ||
|
|
7195f0d8cf | ||
|
|
5440ae1cae | ||
|
|
8f89167486 | ||
|
|
26c0a32c7c | ||
|
|
a6e8b3843b | ||
|
|
4e774b7264 | ||
|
|
7f732ad019 | ||
|
|
e81bbd69b3 | ||
|
|
52f964126d | ||
|
|
01c33a5719 | ||
|
|
66a70267b6 | ||
|
|
0b06b23b00 | ||
|
|
e239eb4c55 | ||
|
|
d38c4dd57b | ||
|
|
5dbb90ede3 | ||
|
|
75767d87cb | ||
|
|
1b4cfc21d9 | ||
|
|
2dfc06e83b | ||
|
|
2c40b8c706 | ||
|
|
ca88cf1060 | ||
|
|
74e2c2cd78 | ||
|
|
25169901de | ||
|
|
74fb914fe3 | ||
|
|
683adcbb70 | ||
|
|
cc51f2a1f2 | ||
|
|
83fc3f2623 | ||
|
|
fee4d936a3 | ||
|
|
01d6d6dd3b | ||
|
|
6ba113197f | ||
|
|
a502d88043 | ||
|
|
10213655bc | ||
|
|
cfd26fdbf2 | ||
|
|
faf149226b | ||
|
|
dba5bd3012 | ||
|
|
d18d0b6478 | ||
|
|
db2b601886 | ||
|
|
e9e6918df6 | ||
|
|
53a3dac011 | ||
|
|
401c9bbe83 | ||
|
|
c37361ba2e | ||
|
|
f087cf842f | ||
|
|
bcd181f051 | ||
|
|
5ca8acdb38 | ||
|
|
a6d134804a | ||
|
|
1b75fe3cba | ||
|
|
3846d2a7fa | ||
|
|
6c7f8291d4 | ||
|
|
d56911b88d | ||
|
|
72eca8f0c2 | ||
|
|
5bb4ee73da | ||
|
|
b4c42601d1 | ||
|
|
17dfdab7d2 | ||
|
|
927b89bec8 | ||
|
|
ec18c30ce7 | ||
|
|
f7c3d0717a | ||
|
|
f5e482d3f6 | ||
|
|
31c3de6bfa | ||
|
|
cc78743ac8 | ||
|
|
1bd82dd6c1 | ||
|
|
cc2d738343 | ||
|
|
76ece4576e | ||
|
|
ef29bf53ff | ||
|
|
e146ae748e | ||
|
|
ed1cee365f | ||
|
|
b615efba87 | ||
|
|
69cc2c30c5 | ||
|
|
110191d81e | ||
|
|
c59db52954 | ||
|
|
2be54111c0 | ||
|
|
1f7197ec16 | ||
|
|
6285cb9b64 | ||
|
|
3243af3e07 | ||
|
|
f3e2752df3 | ||
|
|
693fa1aa0d | ||
|
|
7061d966ab | ||
|
|
ebe197f12e | ||
|
|
eccbdab734 | ||
|
|
2358ed1bf9 | ||
|
|
e8c0f529a0 | ||
|
|
7c97b5587a | ||
|
|
d86c6dd449 | ||
|
|
f70f68e44a | ||
|
|
d03a00c1a4 | ||
|
|
b3ce66b1ff | ||
|
|
2ea80c845e | ||
|
|
3e7fe7b25e | ||
|
|
562deb8f09 | ||
|
|
ae68b5bf24 | ||
|
|
5b5d9a5dec | ||
|
|
bc15f0627d | ||
|
|
1037e37418 | ||
|
|
8e49bbbb09 | ||
|
|
550dcfc96a | ||
|
|
2624190887 | ||
|
|
b41b3af879 | ||
|
|
15c5245d55 | ||
|
|
da75b8484f | ||
|
|
dc0109ad3d | ||
|
|
399c182ab5 | ||
|
|
c548da9d36 | ||
|
|
71202609b5 | ||
|
|
4b52a4c707 | ||
|
|
7f94d5f75f | ||
|
|
3855f28ebb | ||
|
|
9c9bff745c | ||
|
|
d38551cc23 | ||
|
|
48010c551b | ||
|
|
5b5f8e32a0 | ||
|
|
c7d8d991a8 | ||
|
|
2b52d67ebc | ||
|
|
831a217d00 | ||
|
|
57b06a504a | ||
|
|
6e4d44f312 | ||
|
|
f6c2d2e0e5 | ||
|
|
1daf7f9865 | ||
|
|
cae8513636 | ||
|
|
8cd329f611 | ||
|
|
148e6be60f | ||
|
|
f57dc5227a | ||
|
|
8487ec8a67 | ||
|
|
ba2b2bc04d | ||
|
|
5363ff85cc | ||
|
|
6ac58744fe | ||
|
|
7fa3aa9116 | ||
|
|
7a2ecd2516 | ||
|
|
d58dc7bd1d | ||
|
|
8bc70e3aac | ||
|
|
b5cdcbe06e | ||
|
|
9eebd7b057 | ||
|
|
885bfe95dc | ||
|
|
1168d60564 | ||
|
|
a2c695275d | ||
|
|
fcdf7ec95d | ||
|
|
dd8f357639 | ||
|
|
9d8a2f14dd | ||
|
|
64291d8d52 | ||
|
|
eb438f0f98 | ||
|
|
cc73bb56b6 | ||
|
|
902ae7e6e7 | ||
|
|
f5f7b50e17 | ||
|
|
fc31183a20 | ||
|
|
3eeaa4aa36 | ||
|
|
89011d92fc | ||
|
|
f0a2fb6b7b | ||
|
|
51d6ba733f | ||
|
|
1bfe4aa02f | ||
|
|
fadd5b55ca | ||
|
|
c2c9933797 | ||
|
|
382c3f2bb9 | ||
|
|
e9e6dee39a | ||
|
|
cc35677cff | ||
|
|
c442efa7c5 | ||
|
|
5b35722d63 | ||
|
|
3396fdd7f7 | ||
|
|
6b3e9e3f1e | ||
|
|
030fddb0b8 | ||
|
|
8635063118 | ||
|
|
6748797681 | ||
|
|
f9836caee5 | ||
|
|
3fcfc90a12 | ||
|
|
025fff7871 | ||
|
|
2d64900b46 | ||
|
|
37cf65c6f8 | ||
|
|
0581ce1559 | ||
|
|
bbce2b3807 | ||
|
|
2b9ee42ded | ||
|
|
47de99e1b8 | ||
|
|
bede064c0b | ||
|
|
c209725ada | ||
|
|
de38cfc510 | ||
|
|
22a1681e11 | ||
|
|
40d9bb3a77 | ||
|
|
e56b342e59 | ||
|
|
9adb82e68a | ||
|
|
742aa412a7 | ||
|
|
22fa8e6f20 | ||
|
|
78a2f603ce | ||
|
|
990ea0f1ae | ||
|
|
dae75e1853 | ||
|
|
b6a7601e4a | ||
|
|
c456fdddd7 | ||
|
|
2a1c76e070 | ||
|
|
57c825eebb | ||
|
|
6ab458b512 | ||
|
|
35c49ddf97 | ||
|
|
098ab73be1 | ||
|
|
e675cd7445 | ||
|
|
a1f9458052 | ||
|
|
a17917810d | ||
|
|
dcf55cb730 | ||
|
|
28c4507866 | ||
|
|
4f9e2a5be6 | ||
|
|
8dae11e6d2 | ||
|
|
9342a5b74c | ||
|
|
92507e598f | ||
|
|
42d0769683 | ||
|
|
6a6c2bad50 | ||
|
|
b537da9b53 | ||
|
|
85d8f70478 | ||
|
|
da43afb5de | ||
|
|
077bea0a45 | ||
|
|
99968db2b1 | ||
|
|
3477626973 | ||
|
|
735abb06b4 | ||
|
|
cadb22334e | ||
|
|
b2bc4fe4f4 | ||
|
|
2f7aea98eb | ||
|
|
b2c065976b | ||
|
|
f75f7a0601 | ||
|
|
1bd58fa018 | ||
|
|
c27c2b6e68 | ||
|
|
c03d5c41a5 | ||
|
|
7057e9fb73 | ||
|
|
fbb7ff6e44 | ||
|
|
6d37c551dd | ||
|
|
23d12acd15 | ||
|
|
b6ce2b649f | ||
|
|
2afde99434 | ||
|
|
97c9442511 | ||
|
|
660180b932 | ||
|
|
d0d84aca9b | ||
|
|
624a425f7d | ||
|
|
3cb154df82 | ||
|
|
a706e85b19 | ||
|
|
e988a88af0 | ||
|
|
5b08714a4d | ||
|
|
d33839a9c3 | ||
|
|
5d6d52f04e | ||
|
|
7ed6bfb925 | ||
|
|
3a36eca1b4 | ||
|
|
b6172b2ed3 | ||
|
|
39cef92885 | ||
|
|
0e2bbc3705 | ||
|
|
090269e5a0 | ||
|
|
f43062ebbb | ||
|
|
38f372b8ea | ||
|
|
c958724bbd | ||
|
|
b0d8baf320 | ||
|
|
5b3caf7b66 | ||
|
|
04cf4246b8 | ||
|
|
b576677e9f | ||
|
|
d61b06b8b5 | ||
|
|
15e2aa0a24 | ||
|
|
bc9b69590b | ||
|
|
cf86d94597 | ||
|
|
35f79cb272 | ||
|
|
522140b43f | ||
|
|
c9b8d2dfd1 | ||
|
|
469e679b6d | ||
|
|
dcb4bffee5 | ||
|
|
9a791d175c | ||
|
|
d40a6dd9b7 | ||
|
|
6aec93c468 | ||
|
|
94e69f399b | ||
|
|
001064885d | ||
|
|
bffbaff7e2 | ||
|
|
36a630e023 | ||
|
|
45a9f64174 | ||
|
|
4e4aa05639 | ||
|
|
cb2eb3a1fb | ||
|
|
b4daa5eae2 | ||
|
|
6feaee84e0 | ||
|
|
b5c058bf6e | ||
|
|
267731917b | ||
|
|
b8a3af8cd6 | ||
|
|
9a558bd942 | ||
|
|
d78b0debd7 | ||
|
|
711c1e2f4b | ||
|
|
2ca65d5451 | ||
|
|
e8b91f8862 | ||
|
|
26daac8690 | ||
|
|
1c5400a670 | ||
|
|
700f62e28e | ||
|
|
371488c102 | ||
|
|
1cda9b6a80 | ||
|
|
f9b19189d7 | ||
|
|
d3c40a1851 | ||
|
|
65413344bd | ||
|
|
2bee348c9a | ||
|
|
dccd5a7593 | ||
|
|
b3c41bd5d7 | ||
|
|
ad8a7e78e1 | ||
|
|
4f4d229e0a | ||
|
|
d76cfe05b1 | ||
|
|
fd2093914e | ||
|
|
10864cfa71 | ||
|
|
38072c0716 | ||
|
|
122acf8f81 | ||
|
|
332da936b7 | ||
|
|
f78ab342fd | ||
|
|
49625639f2 | ||
|
|
838bada36d | ||
|
|
1be2c47da6 | ||
|
|
8c12b515b8 | ||
|
|
93a4c3c699 | ||
|
|
1d52247080 | ||
|
|
1f04cab99f | ||
|
|
31f48f0651 | ||
|
|
610cf28dab | ||
|
|
994eea7a53 | ||
|
|
8d48eecc2f | ||
|
|
aa6c5ccd45 | ||
|
|
3c414db312 | ||
|
|
ce6d9df192 | ||
|
|
33343e6688 | ||
|
|
2339c8af0f | ||
|
|
93a73cc483 | ||
|
|
3d4e8cfea3 | ||
|
|
f97d83d847 | ||
|
|
9c70c76cfd | ||
|
|
313388b293 | ||
|
|
2b812b087c | ||
|
|
481329a47e | ||
|
|
50e0abfd16 | ||
|
|
0534eb7644 | ||
|
|
289bf4f84a | ||
|
|
af44a1cc83 | ||
|
|
0cb35ab04e | ||
|
|
b0dbbfcc03 | ||
|
|
1766a21145 | ||
|
|
52d9c34465 | ||
|
|
9ee5e6e59c | ||
|
|
66a4cf578f | ||
|
|
19baee2242 | ||
|
|
ce54b07e2d | ||
|
|
167b8bf0a0 | ||
|
|
ab9afd33d1 | ||
|
|
4d473c3305 | ||
|
|
93a9a8d638 | ||
|
|
c8fe9136d7 | ||
|
|
97af2b0b62 | ||
|
|
81ce743986 | ||
|
|
2b66040f0d | ||
|
|
872449d6fc | ||
|
|
a2f345b24b | ||
|
|
161edcca48 | ||
|
|
cfd35799da | ||
|
|
0ccbceb9e8 | ||
|
|
cbc0475634 | ||
|
|
cf456bfe4a | ||
|
|
fd36e3cf8d | ||
|
|
149dd082f3 | ||
|
|
44ff360379 | ||
|
|
8a089b65fb | ||
|
|
3c9ef8ec7e | ||
|
|
1fe0d4a94b | ||
|
|
cccce9d0ab | ||
|
|
c6401945d9 | ||
|
|
c6a69b763f | ||
|
|
080f0c7b22 | ||
|
|
2c6b323a62 | ||
|
|
b42d59b29c | ||
|
|
c8ff9bad93 | ||
|
|
7fbf6111e3 | ||
|
|
d75bd7b82c | ||
|
|
217f83fd56 | ||
|
|
6e3aa3357c | ||
|
|
e886404171 | ||
|
|
4a8c6d8a8b | ||
|
|
a827ab2d4e | ||
|
|
c3915b9798 | ||
|
|
c28b839c17 | ||
|
|
511862c4ee | ||
|
|
dce22ce5f6 | ||
|
|
edc91849cb | ||
|
|
f117721251 | ||
|
|
5df6babfad | ||
|
|
e4f43aa51b | ||
|
|
05f708c330 | ||
|
|
8f9f800dc5 | ||
|
|
83debbfda0 | ||
|
|
c1bec5c4de | ||
|
|
740a546249 | ||
|
|
a55236d383 | ||
|
|
e2464f462e | ||
|
|
177c0b4979 | ||
|
|
167741b80b | ||
|
|
f083e49a63 | ||
|
|
9380324a0f | ||
|
|
0778f623fb | ||
|
|
1adc834b10 | ||
|
|
c510fa79d0 | ||
|
|
02d63b7ec4 | ||
|
|
c35137040a | ||
|
|
3b673ef4b6 | ||
|
|
318a530dfa | ||
|
|
fa7dfc272a | ||
|
|
423683e7ef | ||
|
|
c078e11bcf | ||
|
|
61e1c5b546 | ||
|
|
4249dcd353 | ||
|
|
f76be581b3 | ||
|
|
faa003168c | ||
|
|
204ba86418 | ||
|
|
c435628b6a | ||
|
|
72e8f9d969 | ||
|
|
27c9abfae5 | ||
|
|
78361c1518 | ||
|
|
12dd87f96b | ||
|
|
2ddb2d4c89 | ||
|
|
3d901f5960 | ||
|
|
0859607b4e | ||
|
|
5352ad41c5 | ||
|
|
8f9cc6b827 | ||
|
|
a294ab4545 | ||
|
|
d08053d483 | ||
|
|
677d42f7ad | ||
|
|
b4fb1d3aca | ||
|
|
dd8ba490ee | ||
|
|
afd72ba541 | ||
|
|
463cda9a10 | ||
|
|
b5e0dbe8e8 | ||
|
|
6dc026c203 | ||
|
|
cc4ce5bbed | ||
|
|
95c4c77df1 | ||
|
|
c0a7ebf51b | ||
|
|
742b1cb65d | ||
|
|
229a1922d8 | ||
|
|
2b17528c5d | ||
|
|
61243967ac | ||
|
|
4cdf59532d | ||
|
|
b2405a9924 | ||
|
|
8812bf735e | ||
|
|
ac163a64fe | ||
|
|
412aee0be0 | ||
|
|
fea7ef937e | ||
|
|
03492bae52 | ||
|
|
e8c6b4e988 | ||
|
|
8d46c00125 | ||
|
|
2140a08e3e | ||
|
|
d06c003344 | ||
|
|
9740af8be4 | ||
|
|
5b57763788 | ||
|
|
69c303ea00 | ||
|
|
7d8de4e2ae | ||
|
|
cd0f5ccc93 | ||
|
|
6476a8d916 | ||
|
|
839c5ed577 | ||
|
|
21294eb228 | ||
|
|
71ab33eff4 | ||
|
|
4255c0f812 | ||
|
|
436716fdd7 | ||
|
|
f79577a7ec | ||
|
|
18b029ca88 | ||
|
|
2c868efbad | ||
|
|
39e9fc9e40 | ||
|
|
19e2f1bb33 | ||
|
|
af51b545ba | ||
|
|
582cf6cc8a | ||
|
|
06ccbca763 | ||
|
|
56a27a0647 | ||
|
|
4437132372 | ||
|
|
c5bbf91892 | ||
|
|
d4318aa0d8 | ||
|
|
80888a1b23 | ||
|
|
8d65e3e894 | ||
|
|
bb29041dce | ||
|
|
9c452f5b14 | ||
|
|
2bb5101112 | ||
|
|
ec9a75173b | ||
|
|
c551545f29 | ||
|
|
8baea68c6c | ||
|
|
e7aecdce71 | ||
|
|
61555c6ebd | ||
|
|
efef3af7b8 | ||
|
|
39fa1c4ac2 | ||
|
|
05f5cc3ea8 | ||
|
|
f57dde1ac3 | ||
|
|
d9bf8d252e | ||
|
|
8c4adbf98d | ||
|
|
4e884f439e | ||
|
|
78a7af3c0a | ||
|
|
b26b8efca4 | ||
|
|
0de11015cc | ||
|
|
6b05576d99 | ||
|
|
dee7261bbe | ||
|
|
1502bf6a2d | ||
|
|
e72e79694f | ||
|
|
b05ae77e41 | ||
|
|
7ff5dd56e8 | ||
|
|
c22414c1fd | ||
|
|
96a9af0a06 | ||
|
|
cec51daa04 | ||
|
|
c3b0bb21e9 | ||
|
|
cf57c817cb | ||
|
|
0de733b66a | ||
|
|
d16f726b15 | ||
|
|
d224153cba | ||
|
|
da3d4bf537 | ||
|
|
0c47ebe881 | ||
|
|
eaec0f1595 | ||
|
|
d5e2ac1fb6 | ||
|
|
1c25c8eed3 | ||
|
|
d83aa7f6ce | ||
|
|
4ba3178d8e | ||
|
|
5d23153aed | ||
|
|
adc009b832 | ||
|
|
c15a7c6b65 | ||
|
|
face6ff6af | ||
|
|
c38ea387e5 | ||
|
|
84a8d342f2 | ||
|
|
8d3a7244c3 | ||
|
|
b10c9b0357 | ||
|
|
6bcdfb11cc | ||
|
|
6a2938deaa | ||
|
|
ade0b3b21b | ||
|
|
e6ba27075e | ||
|
|
a4f6edab85 | ||
|
|
866a77a8cc | ||
|
|
b95ea1092e | ||
|
|
7f0ce79fae | ||
|
|
813ede0cd5 | ||
|
|
b845304ce2 | ||
|
|
9cc077638a | ||
|
|
573020678a | ||
|
|
48c23ad8ef | ||
|
|
1230588b98 | ||
|
|
0e50a0b6e0 | ||
|
|
80114dda35 | ||
|
|
a5f9a8fea0 | ||
|
|
7fa06fa566 | ||
|
|
47a771a7b1 | ||
|
|
82f3fe4147 | ||
|
|
54adf244dd | ||
|
|
b699e4f2aa | ||
|
|
5ba504f809 | ||
|
|
730f2528dc | ||
|
|
9731e496c8 | ||
|
|
d84fc559f2 | ||
|
|
527287aa29 | ||
|
|
758e8d40e5 | ||
|
|
0f13e5708b | ||
|
|
77c5b0f3b7 | ||
|
|
e571aec2ff | ||
|
|
46f65bcf49 | ||
|
|
47c1673092 | ||
|
|
d301c8e099 | ||
|
|
729cedc925 | ||
|
|
4a531aaba4 | ||
|
|
ded2e420b1 | ||
|
|
b9ae556f9f | ||
|
|
ce91f1869b | ||
|
|
0d0cc6bb83 | ||
|
|
665f0d6002 | ||
|
|
fcb367666d | ||
|
|
cbe8c84ec1 | ||
|
|
3fced333e8 | ||
|
|
6762396aec | ||
|
|
7625971974 | ||
|
|
24eef21756 | ||
|
|
64b63e44bf | ||
|
|
47e3808aa4 | ||
|
|
78ca83eb6f | ||
|
|
6556b06f23 | ||
|
|
a31835836d | ||
|
|
71a5782ab7 | ||
|
|
9a77a7dbaa | ||
|
|
955dd1e126 | ||
|
|
02f4f5e885 | ||
|
|
e08a0fab99 | ||
|
|
e4cee14aa6 | ||
|
|
0f1910891d | ||
|
|
1cc579cb5d | ||
|
|
e891659b21 | ||
|
|
bde03060a5 | ||
|
|
24aa904d99 | ||
|
|
5b2df4ce30 | ||
|
|
1ca488c3ec | ||
|
|
9117398452 | ||
|
|
1d1d7a5145 | ||
|
|
a14e1e8fd1 | ||
|
|
932d799e28 | ||
|
|
be9da7ef08 | ||
|
|
65a6fce75c | ||
|
|
041c7e246f | ||
|
|
5c226d0451 | ||
|
|
d70e358a94 | ||
|
|
5d5c7c6ae1 | ||
|
|
b0fcf28267 | ||
|
|
3a5d6ee433 | ||
|
|
7c39f9477f | ||
|
|
0076d85f5d | ||
|
|
ad2ca8dd4b | ||
|
|
a3230ce730 | ||
|
|
e13c2f535c | ||
|
|
7499b0cab0 | ||
|
|
74d47288c0 | ||
|
|
a47d722c07 | ||
|
|
85d858984b | ||
|
|
794e8b12eb | ||
|
|
288a74e55f | ||
|
|
4b35717b04 | ||
|
|
a2f678151d | ||
|
|
8a527d1ef5 | ||
|
|
1ce807d5de | ||
|
|
773c340514 | ||
|
|
50122b7078 | ||
|
|
3bbc507a3f | ||
|
|
cada67daeb | ||
|
|
af4dcb616d | ||
|
|
d4a1e97249 | ||
|
|
292003444d | ||
|
|
d9b467403a | ||
|
|
ff304c3890 | ||
|
|
42ad818e3f | ||
|
|
6117b83b55 | ||
|
|
1f4e239217 | ||
|
|
4819beb149 | ||
|
|
9279489413 | ||
|
|
1536dfda0a | ||
|
|
b2b1416fbc | ||
|
|
c3bc500240 | ||
|
|
0f87764827 | ||
|
|
978f3392c5 | ||
|
|
c88f903374 | ||
|
|
edcf1b59dd | ||
|
|
b95c7aa556 | ||
|
|
bfa69bbdb6 | ||
|
|
5706f0531b | ||
|
|
a48f2e209c | ||
|
|
13feb7278e | ||
|
|
15b0283650 | ||
|
|
e1839e5ec9 | ||
|
|
433b6ba3a4 | ||
|
|
1d1101eb7c | ||
|
|
67ea7f4b4d | ||
|
|
7633f09479 | ||
|
|
ce070ce422 | ||
|
|
f71338baf9 | ||
|
|
ecad667dda | ||
|
|
d9fd07929a | ||
|
|
d413a3078c | ||
|
|
4cb5e0a013 | ||
|
|
b2767c7d8a |
@ -1,4 +1,5 @@
|
||||
version: 2
|
||||
version: 2.1
|
||||
|
||||
aliases:
|
||||
- &restore-node-modules-cache
|
||||
keys:
|
||||
@ -39,50 +40,57 @@ aliases:
|
||||
- &artifact_test262_xunit
|
||||
path: ~/test-results
|
||||
|
||||
jobs:
|
||||
test:
|
||||
working_directory: ~/babel
|
||||
- &artifact_test262_diff_tap
|
||||
path: ~/diff.tap
|
||||
|
||||
executors:
|
||||
node-executor:
|
||||
docker:
|
||||
- image: circleci/node:13
|
||||
working_directory: ~/babel
|
||||
# e2e-vue-cli test requires chromium
|
||||
node-browsers-executor:
|
||||
docker:
|
||||
- image: circleci/node:13-browsers
|
||||
working_directory: ~/babel
|
||||
|
||||
jobs:
|
||||
build-standalone:
|
||||
executor: node-executor
|
||||
steps:
|
||||
- checkout
|
||||
- restore-cache: *restore-yarn-cache
|
||||
- restore-cache: *restore-node-modules-cache
|
||||
- run: yarn --version
|
||||
- run: make test-ci-coverage
|
||||
- restore_cache: *restore-yarn-cache
|
||||
- restore_cache: *restore-node-modules-cache
|
||||
# Builds babel-standalone with the regular Babel config
|
||||
- run: IS_PUBLISH=true make build
|
||||
# test-ci-coverage doesn't test babel-standalone, as trying to gather coverage
|
||||
- run: IS_PUBLISH=true make -j build-standalone-ci
|
||||
# data for a JS file that's several megabytes large is bound to fail. Here,
|
||||
# we just run the babel-standalone test separately.
|
||||
- run: ./node_modules/.bin/jest packages/babel-standalone/test/
|
||||
- run: ./node_modules/.bin/jest packages/babel-preset-env-standalone/test/
|
||||
- run: yarn jest "\-standalone/test"
|
||||
- store_artifacts: *artifact_babel
|
||||
- store_artifacts: *artifact_babel_min
|
||||
- store_artifacts: *artifact_env
|
||||
- store_artifacts: *artifact_env_min
|
||||
- save_cache: *save-node-modules-cache
|
||||
- save_cache: *save-yarn-cache
|
||||
|
||||
test262:
|
||||
working_directory: ~/babel
|
||||
docker:
|
||||
- image: circleci/node:12
|
||||
executor: node-executor
|
||||
steps:
|
||||
- checkout
|
||||
- restore-cache: *restore-yarn-cache
|
||||
- restore-cache: *restore-node-modules-cache
|
||||
- run:
|
||||
name: Sync with latest master branch (only on PRs)
|
||||
command: |
|
||||
if [ -n "$CIRCLE_PULL_REQUEST" ]
|
||||
then
|
||||
git fetch origin refs/pull/$CIRCLE_PR_NUMBER/merge
|
||||
git checkout -qf FETCH_HEAD
|
||||
fi
|
||||
- restore_cache: *restore-yarn-cache
|
||||
- restore_cache: *restore-node-modules-cache
|
||||
- run:
|
||||
name: Build Babel
|
||||
command: BABEL_ENV=test make bootstrap
|
||||
- run:
|
||||
name: Link Babel
|
||||
command: |
|
||||
cd packages
|
||||
for package in */; do
|
||||
cd $package
|
||||
yarn link
|
||||
cd ..
|
||||
done
|
||||
- run:
|
||||
name: Setup Test Runner
|
||||
command: |
|
||||
@ -90,32 +98,111 @@ jobs:
|
||||
cd babel-test262-runner
|
||||
yarn
|
||||
yarn add tap-mocha-reporter --dev
|
||||
curl -L https://github.com/stedolan/jq/releases/download/jq-1.5/jq-linux64 > jq
|
||||
chmod +x ./jq
|
||||
for package in ../packages/*/package.json; do
|
||||
yarn link $(./jq -j ".name" $package)
|
||||
done
|
||||
node lib/download-node
|
||||
- run:
|
||||
name: Download master branch Test262 artifact
|
||||
command: node lib/download-master-artifact ~/master.tap
|
||||
<<: *test262_workdir
|
||||
- run:
|
||||
name: Run Test262
|
||||
command: node lib/run-tests I_AM_SURE | tee ~/test262.tap
|
||||
command: BABEL_PATH=.. node lib/run-tests I_AM_SURE | tee ~/test262.tap
|
||||
<<: *test262_workdir
|
||||
- store_artifacts: *artifact_test262_tap
|
||||
- run:
|
||||
name: Output test262 results
|
||||
name: Output Test262 results
|
||||
command: |
|
||||
cat ~/test262.tap | $(npm bin)/tap-mocha-reporter spec || true
|
||||
<<: *test262_workdir
|
||||
- run:
|
||||
name: Compare previous master branch & current job results
|
||||
command: |
|
||||
mkdir -p ~/test-results/test262
|
||||
node lib/compare-results ~/master.tap ~/test262.tap | tee ~/diff.tap
|
||||
<<: *test262_workdir
|
||||
- store_artifacts: *artifact_test262_diff_tap
|
||||
- run:
|
||||
name: Output comparision results and report to CircleCI
|
||||
command: |
|
||||
mkdir -p ~/test-results/test262
|
||||
cat ~/diff.tap | $(npm bin)/tap-merge | $(npm bin)/tap-mocha-reporter xunit | tee ~/test-results/test262/results.xml
|
||||
<<: *test262_workdir
|
||||
- store_test_results: *artifact_test262_xunit
|
||||
- save_cache: *save-node-modules-cache
|
||||
- save_cache: *save-yarn-cache
|
||||
|
||||
publish-verdaccio:
|
||||
executor: node-executor
|
||||
steps:
|
||||
- checkout
|
||||
- run: yarn install
|
||||
- run: ./scripts/integration-tests/publish-local.sh
|
||||
- persist_to_workspace:
|
||||
root: /tmp/verdaccio-workspace
|
||||
paths:
|
||||
- storage
|
||||
- htpasswd
|
||||
|
||||
e2e-babel:
|
||||
executor: node-executor
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/verdaccio-workspace
|
||||
- run: ./scripts/integration-tests/e2e-babel.sh
|
||||
|
||||
e2e-create-react-app:
|
||||
executor: node-executor
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/verdaccio-workspace
|
||||
- run: ./scripts/integration-tests/e2e-create-react-app.sh
|
||||
|
||||
e2e-vue-cli:
|
||||
executor: node-browsers-executor
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/verdaccio-workspace
|
||||
- run: ./scripts/integration-tests/e2e-vue-cli.sh
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
test:
|
||||
build-standalone:
|
||||
jobs:
|
||||
- test
|
||||
master:
|
||||
- build-standalone
|
||||
test262-master:
|
||||
jobs:
|
||||
- test262:
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
test262:
|
||||
jobs:
|
||||
- approve-test262-run:
|
||||
type: approval
|
||||
filters:
|
||||
branches:
|
||||
ignore:
|
||||
- master
|
||||
- test262:
|
||||
requires:
|
||||
- approve-test262-run
|
||||
filters:
|
||||
branches:
|
||||
ignore:
|
||||
- master
|
||||
e2e:
|
||||
jobs:
|
||||
- publish-verdaccio
|
||||
- e2e-babel:
|
||||
requires:
|
||||
- publish-verdaccio
|
||||
- e2e-create-react-app:
|
||||
requires:
|
||||
- publish-verdaccio
|
||||
- e2e-vue-cli:
|
||||
requires:
|
||||
- publish-verdaccio
|
||||
|
||||
|
||||
5
.codesandbox/ci.json
Normal file
5
.codesandbox/ci.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"installCommand": "bootstrap",
|
||||
"buildCommand": false,
|
||||
"sandboxes": ["kypop"]
|
||||
}
|
||||
@ -17,10 +17,15 @@ codemods/*/lib
|
||||
codemods/*/dist
|
||||
codemods/*/test/fixtures
|
||||
codemods/*/test/tmp
|
||||
packages/babel-preset-env/data
|
||||
packages/babel-preset-env/data/[^(plugin-features|shipped-proposals).js]
|
||||
packages/babel-preset-env/test/debug-fixtures
|
||||
packages/babel-preset-env-standalone/babel-preset-env.js
|
||||
packages/babel-preset-env-standalone/babel-preset-env.min.js
|
||||
packages/babel-standalone/babel.js
|
||||
packages/babel-standalone/babel.min.js
|
||||
packages/babel-parser/test/expressions
|
||||
|
||||
eslint/*/lib
|
||||
eslint/*/node_modules
|
||||
eslint/*/test
|
||||
eslint/*/tests
|
||||
|
||||
48
.eslintrc.js
Normal file
48
.eslintrc.js
Normal file
@ -0,0 +1,48 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
plugins: ["prettier", "@babel/development", "import"],
|
||||
extends: "babel",
|
||||
rules: {
|
||||
"prettier/prettier": "error",
|
||||
// TODO: remove after babel-eslint-config-internal is fully integrated into this repository.
|
||||
"max-len": "off",
|
||||
},
|
||||
env: {
|
||||
node: true,
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: [
|
||||
"packages/*/src/**/*.js",
|
||||
"codemods/*/src/**/*.js",
|
||||
"eslint/*/src/**/*.js",
|
||||
],
|
||||
rules: {
|
||||
"@babel/development/no-undefined-identifier": "error",
|
||||
"@babel/development/no-deprecated-clone": "error",
|
||||
"import/no-extraneous-dependencies": "error",
|
||||
"guard-for-in": "error",
|
||||
},
|
||||
},
|
||||
{
|
||||
files: [
|
||||
"packages/*/test/**/*.js",
|
||||
"codemods/*/test/**/*.js",
|
||||
"eslint/*/test/**/*.js",
|
||||
"packages/babel-helper-transform-fixture-test-runner/src/helpers.js",
|
||||
"test/**/*.js",
|
||||
],
|
||||
env: {
|
||||
jest: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ["packages/babel-plugin-*/src/index.js"],
|
||||
excludedFiles: ["packages/babel-plugin-transform-regenerator/**/*.js"],
|
||||
rules: {
|
||||
"@babel/development/plugin-name": "error",
|
||||
eqeqeq: ["error", "always", { null: "ignore" }],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
@ -1,41 +0,0 @@
|
||||
{
|
||||
"root": true,
|
||||
"plugins": ["prettier", "@babel/development", "import"],
|
||||
"extends": "babel",
|
||||
"rules": {
|
||||
"prettier/prettier": "error"
|
||||
},
|
||||
"env": {
|
||||
"node": true
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["packages/*/src/**/*.js", "codemods/*/src/**/*.js"],
|
||||
"rules": {
|
||||
"@babel/development/no-undefined-identifier": "error",
|
||||
"@babel/development/no-deprecated-clone": "error",
|
||||
"import/no-extraneous-dependencies": "error",
|
||||
"guard-for-in": "error"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"packages/*/test/**/*.js",
|
||||
"codemods/*/test/**/*.js",
|
||||
"packages/babel-helper-transform-fixture-test-runner/src/helpers.js",
|
||||
"test/**/*.js"
|
||||
],
|
||||
"env": {
|
||||
"jest": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["packages/babel-plugin-*/src/index.js"],
|
||||
"excludedFiles": ["packages/babel-plugin-transform-regenerator/**/*.js"],
|
||||
"rules": {
|
||||
"@babel/development/plugin-name": "error",
|
||||
"eqeqeq": ["error", "always", { "null": "ignore" }]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
17
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
17
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
@ -9,6 +9,14 @@ assignees: ''
|
||||
|
||||
## Bug Report
|
||||
|
||||
<!-- Check this if you would like to implement a PR, we are more than happy to help you go through the process !-->
|
||||
- [ ] I would like to work on a fix!
|
||||
|
||||
<!--
|
||||
@babel/eslint-parser:
|
||||
If you are having issues with JSX you might want to check out eslint-plugin-react. If there's an issue with new experimental syntax you might need check if it's supported by @babel/eslint-plugin.
|
||||
-->
|
||||
|
||||
**Current Behavior**
|
||||
A clear and concise description of the behavior.
|
||||
|
||||
@ -22,7 +30,8 @@ var your => (code) => here;
|
||||
**Expected behavior/code**
|
||||
A clear and concise description of what you expected to happen (or code).
|
||||
|
||||
**Babel Configuration (.babelrc, package.json, cli command)**
|
||||
**Babel Configuration (babel.config.js, .babelrc, package.json#babel, cli command, .eslintrc)**
|
||||
- Filename: `babel.config.js`
|
||||
|
||||
```js
|
||||
{
|
||||
@ -31,6 +40,10 @@ A clear and concise description of what you expected to happen (or code).
|
||||
```
|
||||
|
||||
**Environment**
|
||||
<!--- Tip: Instead of filling out the questions below, you can run `npx envinfo --preset babel` and paste the result below ``` -->
|
||||
```
|
||||
|
||||
```
|
||||
- Babel version(s): [e.g. v6.0.0, v7.0.0-beta.34]
|
||||
- Node/npm version: [e.g. Node 8/npm 5]
|
||||
- OS: [e.g. OSX 10.13.4, Windows 10]
|
||||
@ -38,7 +51,7 @@ A clear and concise description of what you expected to happen (or code).
|
||||
- How you are using Babel: [e.g. `cli`, `register`, `loader`]
|
||||
|
||||
**Possible Solution**
|
||||
<!--- Only if you have suggestions on a fix for the bug -->
|
||||
<!--- If you have suggestions on a fix for the bug -->
|
||||
|
||||
**Additional context/Screenshots**
|
||||
Add any other context about the problem here. If applicable, add screenshots to help explain.
|
||||
|
||||
3
.github/ISSUE_TEMPLATE/Feature_request.md
vendored
3
.github/ISSUE_TEMPLATE/Feature_request.md
vendored
@ -9,6 +9,9 @@ assignees: ''
|
||||
|
||||
## Feature Request
|
||||
|
||||
<!-- Check this if you would like to implement a PR, we are more than happy to help you go through the process !-->
|
||||
- [ ] I would like to work on this feature!
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I have an issue when [...]
|
||||
|
||||
|
||||
15
.github/ISSUE_TEMPLATE/Regression-v7.md
vendored
15
.github/ISSUE_TEMPLATE/Regression-v7.md
vendored
@ -10,6 +10,9 @@ assignees: ''
|
||||
|
||||
# v7 Regression
|
||||
|
||||
<!-- Check this if you would like to implement a PR, we are more than happy to help you go through the process !-->
|
||||
- [ ] I would like to work on a fix!
|
||||
|
||||
> First check out: https://babeljs.io/docs/en/v7-migration
|
||||
> Also a partial upgrade tool: https://github.com/babel/babel-upgrade
|
||||
|
||||
@ -26,7 +29,10 @@ A clear and concise description of what the regression is.
|
||||
var your => (code) => here;
|
||||
```
|
||||
|
||||
**Babel Configuration (.babelrc, package.json, cli command)**
|
||||
**Expected behavior/code**
|
||||
A clear and concise description of what you expected to happen (or code).
|
||||
|
||||
**Babel Configuration (babel.config.js, .babelrc, package.json#babel, cli command)**
|
||||
|
||||
```js
|
||||
{
|
||||
@ -34,10 +40,11 @@ var your => (code) => here;
|
||||
}
|
||||
```
|
||||
|
||||
**Expected behavior/code**
|
||||
A clear and concise description of what you expected to happen (or code).
|
||||
|
||||
**Environment**
|
||||
<!--- Tip: Instead of filling out the questions below, you can run `npx envinfo --preset babel` and paste the result below ``` -->
|
||||
```
|
||||
|
||||
```
|
||||
- Babel version(s): [e.g. v6.0.0, v7.0.0-beta.34]
|
||||
- Node/npm version: [e.g. Node 8/npm 5]
|
||||
- OS: [e.g. OSX 10.13.4, Windows 10]
|
||||
|
||||
29
.github/workflows/coverage.yml
vendored
Normal file
29
.github/workflows/coverage.yml
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
name: Report Coverage
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [13.x]
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v1
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Environment log
|
||||
id: env
|
||||
run: |
|
||||
yarn --version
|
||||
- name: Generate coverage report
|
||||
run: |
|
||||
yarn --version
|
||||
make -j test-ci-coverage
|
||||
- name: Upload coverage report
|
||||
uses: codecov/codecov-action@v1
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
9
.gitignore
vendored
9
.gitignore
vendored
@ -20,6 +20,8 @@ dist
|
||||
package-lock.json
|
||||
!/.github/actions/*/package-lock.json
|
||||
|
||||
/packages/babel-compat-data/build
|
||||
|
||||
/packages/babel-runtime/helpers/*.js
|
||||
!/packages/babel-runtime/helpers/toArray.js
|
||||
!/packages/babel-runtime/helpers/iterableToArray.js
|
||||
@ -52,11 +54,18 @@ package-lock.json
|
||||
.nyc_output
|
||||
/babel.sublime-workspace
|
||||
packages/babel-standalone/babel.js
|
||||
packages/babel-standalone/babel.js.map
|
||||
packages/babel-standalone/babel.min.js
|
||||
packages/babel-preset-env-standalone/babel-preset-env.js
|
||||
packages/babel-preset-env-standalone/babel-preset-env.js.map
|
||||
packages/babel-preset-env-standalone/babel-preset-env.min.js
|
||||
/codemods/*/lib
|
||||
/codemods/*/node_modules
|
||||
/packages/babel-parser/build
|
||||
.idea/
|
||||
/.changelog
|
||||
|
||||
/eslint/*/lib
|
||||
/eslint/*/node_modules
|
||||
/eslint/*/LICENSE
|
||||
!/packages/babel-eslint-plugin/LICENSE
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package.json
|
||||
packages/babel-preset-env/data
|
||||
packages/babel-compat-data/data
|
||||
packages/babel-compat-data/scripts/data/overlapping-plugins.js
|
||||
packages/*/test/fixtures/**/input.*
|
||||
packages/*/test/fixtures/**/exec.*
|
||||
packages/*/test/fixtures/**/output.*
|
||||
|
||||
@ -13,10 +13,12 @@
|
||||
"**/codemods/*/src/**/*.js",
|
||||
"**/codemods/*/test/**/*.js",
|
||||
"**/packages/*/src/**/*.js",
|
||||
"**/packages/*/test/**/*.js"
|
||||
"**/packages/*/test/**/*.js",
|
||||
"**/eslint/*/src/**/*.js",
|
||||
"**/eslint/*/test/**/*.js"
|
||||
],
|
||||
"parser": "babylon",
|
||||
"options": {
|
||||
"parser": "babel",
|
||||
"trailingComma": "all"
|
||||
}
|
||||
}]
|
||||
|
||||
@ -20,6 +20,7 @@ script:
|
||||
- if [ "$JOB" = "test" ]; then make -j test-ci; fi
|
||||
- if [ "$JOB" = "lint" ]; then make -j code-quality-ci; fi
|
||||
- if [ "$JOB" = "babel-parser-flow-tests" ]; then make -j test-flow-ci; fi
|
||||
- if [ "$JOB" = "babel-parser-typescript-tests" ]; then make -j test-typescript-ci; fi
|
||||
- if [ "$JOB" = "babel-parser-test262-tests" ]; then make -j test-test262-ci; fi
|
||||
|
||||
matrix:
|
||||
@ -36,12 +37,18 @@ matrix:
|
||||
- JOB=test
|
||||
# https://travis-ci.community/t/build-doesnt-finish-after-completing-tests/288/9
|
||||
- YARN_GPG=no
|
||||
cache:
|
||||
yarn: true
|
||||
directories:
|
||||
- $HOME/AppData/Local/Temp/chocolatey
|
||||
# Continue node_js matrix
|
||||
- node_js: "6"
|
||||
- node_js: "10"
|
||||
- node_js: "8"
|
||||
- node_js: "node"
|
||||
env: JOB=babel-parser-flow-tests
|
||||
- node_js: "node"
|
||||
env: JOB=babel-parser-typescript-tests
|
||||
- node_js: "node"
|
||||
env: JOB=babel-parser-test262-tests
|
||||
|
||||
|
||||
263
CHANGELOG.md
263
CHANGELOG.md
File diff suppressed because one or more lines are too long
@ -1,4 +1,4 @@
|
||||
----
|
||||
---
|
||||
|
||||
<p align="center" class="toc">
|
||||
<strong><a href="#setup">Setup</a></strong>
|
||||
@ -12,8 +12,7 @@
|
||||
<strong><a href="#internals">Internals</a></strong>
|
||||
</p>
|
||||
|
||||
----
|
||||
|
||||
---
|
||||
|
||||
# Contributing
|
||||
|
||||
@ -49,8 +48,12 @@ Installation instructions can be found here: https://yarnpkg.com/en/docs/install
|
||||
|
||||
### Setup
|
||||
|
||||
Fork the `babel` repository to your GitHub Account.
|
||||
|
||||
Then, run:
|
||||
|
||||
```sh
|
||||
$ git clone https://github.com/babel/babel
|
||||
$ git clone https://github.com/<your-github-username>/babel
|
||||
$ cd babel
|
||||
$ make bootstrap
|
||||
```
|
||||
@ -158,12 +161,12 @@ $ ./scripts/test-cov.sh
|
||||
|
||||
In case you're not able to reproduce an error on CI locally, it may be due to
|
||||
|
||||
- Node Version: Travis CI runs the tests against all major node versions. If your tests use JavaScript features unsupported by lower versions of node, then use [minNodeVersion option](#writing-tests) in options.json.
|
||||
- Timeout: Check the CI log and if the only errors are timeout errors and you are sure that it's not related to the changes you made, ask someone in the slack channel to trigger rebuild on the CI build and it might be resolved
|
||||
- Node Version: Travis CI runs the tests against all major node versions. If your tests use JavaScript features unsupported by lower versions of node, then use [minNodeVersion option](#writing-tests) in options.json.
|
||||
- Timeout: Check the CI log and if the only errors are timeout errors and you are sure that it's not related to the changes you made, ask someone in the slack channel to trigger rebuild on the CI build and it might be resolved
|
||||
|
||||
In case you're locally getting errors which are not on the CI, it may be due to
|
||||
|
||||
- Updates in Dependencies: Make sure you run `make bootstrap` before you run `make build` or `make watch` before you run the tests.
|
||||
- Updates in Dependencies: Make sure you run `make bootstrap` before you run `make build` or `make watch` before you run the tests.
|
||||
|
||||
### Writing tests
|
||||
|
||||
@ -177,6 +180,7 @@ For example, in [`@babel/plugin-transform-exponentiation-operator/test`](https:/
|
||||
|
||||
- There is an `index.js` file. It imports our [test helper](https://github.com/babel/babel/tree/master/packages/babel-helper-plugin-test-runner). (You don't have to worry about this).
|
||||
- There can be multiple folders under [`/fixtures`](https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-exponentiation-operator/test/fixtures)
|
||||
|
||||
- There is an [`options.json`](https://github.com/babel/babel/blob/master/packages/babel-plugin-transform-exponentiation-operator/test/fixtures/exponentian-operator/options.json) file whose function is similar to a `.babelrc` file, allowing you to pass in the plugins and settings you need for your tests.
|
||||
- For this test, we only need the relevant plugin, so it's just `{ "plugins": ["@babel/plugin-transform-exponentiation-operator"] }`.
|
||||
- If necessary, you can have an `options.json` with different options in each subfolder.
|
||||
@ -200,6 +204,7 @@ and the expected output after transforming it with your `options.json` in `outpu
|
||||
// output.js
|
||||
Math.pow(2, 2);
|
||||
```
|
||||
|
||||
In an `exec.js` test, we run or check that the code actually does what it's supposed to do rather than just check the static output.
|
||||
|
||||
```js
|
||||
@ -235,9 +240,9 @@ Inside the `packages/babel-parser/test/fixtures` folder are categories/groupings
|
||||
etc.). To add a test, create a folder under one of these groupings (or create a new one) with a
|
||||
descriptive name, and add the following:
|
||||
|
||||
* Create an `input.js` file that contains the code you want the babel parser to parse.
|
||||
- Create an `input.js` file that contains the code you want the babel parser to parse.
|
||||
|
||||
* Add an `output.json` file with the expected parser output. For added convenience, if there is no `output.json` present, the test runner will generate one for you.
|
||||
- Add an `output.json` file with the expected parser output. For added convenience, if there is no `output.json` present, the test runner will generate one for you.
|
||||
|
||||
After writing tests for @babel/parser, just build it by running:
|
||||
|
||||
@ -317,6 +322,7 @@ Note that the code shown in Chrome DevTools is compiled code and therefore diffe
|
||||
- Start working about the Babel transform itself!
|
||||
|
||||
## Internals
|
||||
|
||||
- AST spec ([babel-parser/ast/spec.md](https://github.com/babel/babel/blob/master/packages/babel-parser/ast/spec.md))
|
||||
- Versioning ([doc/design/versioning.md](https://github.com/babel/babel/blob/master/doc/design/versioning.md))
|
||||
- Monorepo ([doc/design/monorepo.md](https://github.com/babel/babel/blob/master/doc/design/monorepo.md))
|
||||
|
||||
246
Gulpfile.js
246
Gulpfile.js
@ -10,14 +10,19 @@ const fancyLog = require("fancy-log");
|
||||
const filter = require("gulp-filter");
|
||||
const gulp = require("gulp");
|
||||
const path = require("path");
|
||||
const webpack = require("webpack");
|
||||
const rollup = require("rollup");
|
||||
const rollupAlias = require("@rollup/plugin-alias");
|
||||
const rollupBabel = require("rollup-plugin-babel");
|
||||
const rollupBabelSource = require("./scripts/rollup-plugin-babel-source");
|
||||
const rollupCommonJs = require("rollup-plugin-commonjs");
|
||||
const rollupJson = require("@rollup/plugin-json");
|
||||
const rollupNodeBuiltins = require("rollup-plugin-node-builtins");
|
||||
const rollupNodeGlobals = require("rollup-plugin-node-globals");
|
||||
const rollupNodeResolve = require("rollup-plugin-node-resolve");
|
||||
const rollupReplace = require("rollup-plugin-replace");
|
||||
const { registerStandalonePackageTask } = require("./scripts/gulp-tasks");
|
||||
const { terser: rollupTerser } = require("rollup-plugin-terser");
|
||||
|
||||
const defaultSourcesGlob = "./@(codemods|packages)/*/src/**/*.js";
|
||||
const defaultSourcesGlob = "./@(codemods|packages|eslint)/*/src/**/*.js";
|
||||
|
||||
function swapSrcWithLib(srcPath) {
|
||||
const parts = srcPath.split(path.sep);
|
||||
@ -75,42 +80,209 @@ function buildBabel(exclude, sourcesGlob = defaultSourcesGlob) {
|
||||
.pipe(gulp.dest(base));
|
||||
}
|
||||
|
||||
let babelVersion = require("./packages/babel-core/package.json").version;
|
||||
function buildRollup(packages) {
|
||||
const sourcemap = process.env.NODE_ENV === "production";
|
||||
const minify = !!process.env.IS_PUBLISH;
|
||||
return Promise.all(
|
||||
packages.map(pkg => {
|
||||
const input = getIndexFromPackage(pkg);
|
||||
packages.map(
|
||||
({ src, format, dest, name, filename, version = babelVersion }) => {
|
||||
const extraPlugins = [];
|
||||
let inputExternal = undefined,
|
||||
outputGlobals = undefined,
|
||||
nodeResolveBrowser = false,
|
||||
babelEnvName = "rollup";
|
||||
switch (src) {
|
||||
case "packages/babel-standalone":
|
||||
nodeResolveBrowser = true;
|
||||
babelEnvName = "standalone";
|
||||
if (minify) {
|
||||
extraPlugins.push(
|
||||
rollupTerser({
|
||||
include: /^.+\.min\.js$/,
|
||||
})
|
||||
);
|
||||
}
|
||||
break;
|
||||
case "packages/babel-preset-env-standalone":
|
||||
nodeResolveBrowser = true;
|
||||
babelEnvName = "standalone";
|
||||
if (minify) {
|
||||
extraPlugins.push(
|
||||
rollupTerser({
|
||||
include: /^.+\.min\.js$/,
|
||||
})
|
||||
);
|
||||
}
|
||||
inputExternal = ["@babel/standalone"];
|
||||
outputGlobals = {
|
||||
"@babel/standalone": "Babel",
|
||||
};
|
||||
extraPlugins.push(
|
||||
rollupAlias({
|
||||
entries: [
|
||||
{
|
||||
find: "./available-plugins",
|
||||
replacement: require.resolve(
|
||||
path.join(__dirname, src, "./src/available-plugins")
|
||||
),
|
||||
},
|
||||
{
|
||||
find: "caniuse-lite/data/regions",
|
||||
replacement: require.resolve(
|
||||
path.join(__dirname, src, "./src/caniuse-lite-regions")
|
||||
),
|
||||
},
|
||||
],
|
||||
})
|
||||
);
|
||||
break;
|
||||
}
|
||||
// If this build is part of a pull request, include the pull request number in
|
||||
// the version number.
|
||||
if (process.env.CIRCLE_PR_NUMBER) {
|
||||
const prVersion = "+pr." + process.env.CIRCLE_PR_NUMBER;
|
||||
babelVersion += prVersion;
|
||||
version += prVersion;
|
||||
}
|
||||
const input = getIndexFromPackage(src);
|
||||
fancyLog(`Compiling '${chalk.cyan(input)}' with rollup ...`);
|
||||
return rollup
|
||||
.rollup({
|
||||
input,
|
||||
external: inputExternal,
|
||||
plugins: [
|
||||
...extraPlugins,
|
||||
rollupBabelSource(),
|
||||
rollupReplace({
|
||||
"process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV),
|
||||
BABEL_VERSION: JSON.stringify(babelVersion),
|
||||
VERSION: JSON.stringify(version),
|
||||
}),
|
||||
rollupBabel({
|
||||
envName: "babel-parser",
|
||||
envName: babelEnvName,
|
||||
babelrc: false,
|
||||
extends: "./babel.config.js",
|
||||
}),
|
||||
rollupNodeResolve(),
|
||||
rollupNodeResolve({
|
||||
browser: nodeResolveBrowser,
|
||||
preferBuiltins: true,
|
||||
//todo: When Yarn workspaces is enabled, remove `dedupe` option
|
||||
dedupe(importee) {
|
||||
return (
|
||||
importee.startsWith("lodash/") ||
|
||||
[
|
||||
"babel-plugin-dynamic-import-node/utils",
|
||||
"esutils",
|
||||
"semver",
|
||||
"source-map",
|
||||
].includes(importee)
|
||||
);
|
||||
},
|
||||
}),
|
||||
rollupCommonJs({
|
||||
include: [
|
||||
/node_modules/,
|
||||
"packages/babel-runtime/regenerator/**",
|
||||
"packages/babel-preset-env/data/*.js",
|
||||
// Rollup doesn't read export maps, so it loads the cjs fallback
|
||||
"packages/babel-compat-data/*.js",
|
||||
],
|
||||
namedExports: {
|
||||
"babel-plugin-dynamic-import-node/utils.js": [
|
||||
"createDynamicImportTransform",
|
||||
"getImportSource",
|
||||
],
|
||||
"@babel/standalone": ["availablePlugins", "registerPlugin"],
|
||||
},
|
||||
}),
|
||||
rollupJson(),
|
||||
rollupNodeBuiltins(),
|
||||
rollupNodeGlobals({ sourceMap: sourcemap }),
|
||||
],
|
||||
})
|
||||
.then(bundle => {
|
||||
return bundle.write({
|
||||
file: path.join(pkg, "lib/index.js"),
|
||||
format: "cjs",
|
||||
name: "babel-parser",
|
||||
sourcemap: process.env.NODE_ENV !== "production",
|
||||
});
|
||||
});
|
||||
const outputFile = path.resolve(src, dest, filename || "index.js");
|
||||
return bundle
|
||||
.write({
|
||||
file: outputFile,
|
||||
format,
|
||||
name,
|
||||
globals: outputGlobals,
|
||||
sourcemap: sourcemap,
|
||||
})
|
||||
.then(() => {
|
||||
if (!process.env.IS_PUBLISH) {
|
||||
fancyLog(
|
||||
chalk.yellow(
|
||||
`Skipped minification of '${chalk.cyan(
|
||||
path.relative(path.join(__dirname, ".."), outputFile)
|
||||
)}' because not publishing`
|
||||
)
|
||||
);
|
||||
return undefined;
|
||||
}
|
||||
fancyLog(
|
||||
`Minifying '${chalk.cyan(
|
||||
path.relative(path.join(__dirname, ".."), outputFile)
|
||||
)}'...`
|
||||
);
|
||||
|
||||
return bundle.write({
|
||||
file: outputFile.replace(/\.js$/, ".min.js"),
|
||||
format,
|
||||
name,
|
||||
globals: outputGlobals,
|
||||
sourcemap: sourcemap,
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
const bundles = ["packages/babel-parser"];
|
||||
const libBundles = [
|
||||
{
|
||||
src: "packages/babel-parser",
|
||||
format: "cjs",
|
||||
dest: "lib",
|
||||
version: require("./packages/babel-parser/package").version,
|
||||
},
|
||||
];
|
||||
|
||||
gulp.task("build-rollup", () => buildRollup(bundles));
|
||||
gulp.task("build-babel", () => buildBabel(/* exclude */ bundles));
|
||||
const standaloneBundle = [
|
||||
{
|
||||
src: "packages/babel-standalone",
|
||||
format: "umd",
|
||||
name: "Babel",
|
||||
filename: "babel.js",
|
||||
dest: "",
|
||||
version: require("./packages/babel-core/package").version,
|
||||
},
|
||||
];
|
||||
|
||||
const presetEnvStandaloneBundle = [
|
||||
{
|
||||
src: "packages/babel-preset-env-standalone",
|
||||
format: "umd",
|
||||
name: "BabelPresetEnv",
|
||||
filename: "babel-preset-env.js",
|
||||
dest: "",
|
||||
version: require("./packages/babel-preset-env/package").version,
|
||||
},
|
||||
];
|
||||
|
||||
gulp.task("build-rollup", () => buildRollup(libBundles));
|
||||
gulp.task("build-babel-standalone", () => buildRollup(standaloneBundle));
|
||||
|
||||
gulp.task("build-babel-preset-env-standalone", () =>
|
||||
buildRollup(presetEnvStandaloneBundle)
|
||||
);
|
||||
|
||||
gulp.task("build-babel", () => buildBabel(/* exclude */ libBundles));
|
||||
gulp.task("build-babel-types", () =>
|
||||
buildBabel(/* exclude */ bundles, "packages/babel-types/src/**/*.js")
|
||||
buildBabel(/* exclude */ libBundles, "packages/babel-types/src/**/*.js")
|
||||
);
|
||||
gulp.task("build", gulp.parallel("build-rollup", "build-babel"));
|
||||
|
||||
@ -128,41 +300,3 @@ gulp.task(
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
registerStandalonePackageTask(
|
||||
gulp,
|
||||
"babel",
|
||||
"Babel",
|
||||
path.join(__dirname, "packages"),
|
||||
require("./packages/babel-standalone/package.json").version
|
||||
);
|
||||
|
||||
const presetEnvWebpackPlugins = [
|
||||
new webpack.NormalModuleReplacementPlugin(
|
||||
/\.\/available-plugins/,
|
||||
require.resolve(
|
||||
path.join(
|
||||
__dirname,
|
||||
"./packages/babel-preset-env-standalone/src/available-plugins"
|
||||
)
|
||||
)
|
||||
),
|
||||
new webpack.NormalModuleReplacementPlugin(
|
||||
/caniuse-lite\/data\/regions\/.+/,
|
||||
require.resolve(
|
||||
path.join(
|
||||
__dirname,
|
||||
"./packages/babel-preset-env-standalone/src/caniuse-lite-regions"
|
||||
)
|
||||
)
|
||||
),
|
||||
];
|
||||
|
||||
registerStandalonePackageTask(
|
||||
gulp,
|
||||
"babel-preset-env",
|
||||
"babelPresetEnv",
|
||||
path.join(__dirname, "packages"),
|
||||
require("./packages/babel-preset-env-standalone/package.json").version,
|
||||
presetEnvWebpackPlugins
|
||||
);
|
||||
|
||||
100
Makefile
100
Makefile
@ -1,10 +1,19 @@
|
||||
FLOW_COMMIT = 09669846b7a7ca5a6c23c12d56bb3bebdafd67e9
|
||||
TEST262_COMMIT = 8688c4ab79059c3097098605e69f1ee5eda6c409
|
||||
FLOW_COMMIT = a1f9a4c709dcebb27a5084acf47755fbae699c25
|
||||
TEST262_COMMIT = 28b4fcca4b1b1d278dfe0cc0e69c7d9d59b31aab
|
||||
TYPESCRIPT_COMMIT = 5fc917be2e4dd64c8e9504d36615cd7fbfdd4cd3
|
||||
|
||||
FORCE_PUBLISH = "@babel/runtime,@babel/runtime-corejs2,@babel/runtime-corejs3,@babel/standalone,@babel/preset-env-standalone"
|
||||
|
||||
# Fix color output until TravisCI fixes https://github.com/travis-ci/travis-ci/issues/7967
|
||||
export FORCE_COLOR = true
|
||||
|
||||
SOURCES = packages codemods
|
||||
SOURCES = packages codemods eslint
|
||||
|
||||
COMMA := ,
|
||||
EMPTY :=
|
||||
SPACE := $(EMPTY) $(EMPTY)
|
||||
COMMA_SEPARATED_SOURCES = $(subst $(SPACE),$(COMMA),$(SOURCES))
|
||||
|
||||
|
||||
.PHONY: build build-dist watch lint fix clean test-clean test-only test test-ci publish bootstrap
|
||||
|
||||
@ -103,7 +112,7 @@ lint-js:
|
||||
yarn eslint scripts $(SOURCES) '*.js' --format=codeframe
|
||||
|
||||
lint-ts:
|
||||
scripts/tests/typescript/lint.sh
|
||||
scripts/lint-ts-typings.sh
|
||||
|
||||
fix: fix-json fix-js
|
||||
|
||||
@ -111,7 +120,7 @@ fix-js:
|
||||
yarn eslint scripts $(SOURCES) '*.js' --format=codeframe --fix
|
||||
|
||||
fix-json:
|
||||
yarn prettier "{packages,codemod}/*/test/fixtures/**/options.json" --write --loglevel warn
|
||||
yarn prettier "{$(COMMA_SEPARATED_SOURCES)}/*/test/fixtures/**/options.json" --write --loglevel warn
|
||||
|
||||
clean: test-clean
|
||||
rm -f .npmrc
|
||||
@ -127,7 +136,8 @@ test-clean:
|
||||
# Does not work on Windows; use "yarn jest" instead
|
||||
test-only:
|
||||
BABEL_ENV=test ./scripts/test.sh
|
||||
$(MAKE) test-clean
|
||||
YARN jest
|
||||
#$(MAKE) test-clean
|
||||
|
||||
test: lint test-only
|
||||
|
||||
@ -151,28 +161,43 @@ bootstrap-flow:
|
||||
cd build/flow && git checkout $(FLOW_COMMIT)
|
||||
|
||||
test-flow:
|
||||
node scripts/tests/flow/run_babel_parser_flow_tests.js
|
||||
node scripts/parser-tests/flow
|
||||
|
||||
test-flow-ci: build-bundle-ci bootstrap-flow
|
||||
$(MAKE) test-flow
|
||||
|
||||
test-flow-update-whitelist:
|
||||
node scripts/tests/flow/run_babel_parser_flow_tests.js --update-whitelist
|
||||
node scripts/parser-tests/flow --update-whitelist
|
||||
|
||||
bootstrap-typescript:
|
||||
rm -rf ./build/typescript
|
||||
mkdir -p ./build
|
||||
git clone --branch=master --single-branch --shallow-since=2019-09-01 https://github.com/microsoft/TypeScript.git ./build/typescript
|
||||
cd build/typescript && git checkout $(TYPESCRIPT_COMMIT)
|
||||
|
||||
test-typescript:
|
||||
node scripts/parser-tests/typescript
|
||||
|
||||
test-typescript-ci: build-bundle-ci bootstrap-typescript
|
||||
$(MAKE) test-typescript
|
||||
|
||||
test-typescript-update-whitelist:
|
||||
node scripts/parser-tests/typescript --update-whitelist
|
||||
|
||||
bootstrap-test262:
|
||||
rm -rf build/test262
|
||||
mkdir -p build
|
||||
git clone --branch=master --single-branch --shallow-since=2019-09-01 https://github.com/tc39/test262.git build/test262
|
||||
git clone --branch=master --single-branch --shallow-since=2019-12-01 https://github.com/tc39/test262.git build/test262
|
||||
cd build/test262 && git checkout $(TEST262_COMMIT)
|
||||
|
||||
test-test262:
|
||||
node scripts/tests/test262/run_babel_parser_test262.js
|
||||
node scripts/parser-tests/test262
|
||||
|
||||
test-test262-ci: build-bundle-ci bootstrap-test262
|
||||
$(MAKE) test-test262
|
||||
|
||||
test-test262-update-whitelist:
|
||||
node scripts/tests/test262/run_babel_parser_test262.js --update-whitelist
|
||||
node scripts/parser-tests/test262 --update-whitelist
|
||||
|
||||
# Does not work on Windows
|
||||
clone-license:
|
||||
@ -185,11 +210,17 @@ prepublish-build: clean-lib clean-runtime-helpers
|
||||
prepublish:
|
||||
$(MAKE) bootstrap-only
|
||||
$(MAKE) prepublish-build
|
||||
$(MAKE) test
|
||||
#$(MAKE) test #fuck your tests babel...
|
||||
|
||||
new-version:
|
||||
git pull --rebase
|
||||
yarn lerna version --force-publish="@babel/runtime,@babel/runtime-corejs2,@babel/runtime-corejs3,@babel/standalone,@babel/preset-env-standalone"
|
||||
yarn lerna version --force-publish=$(FORCE_PUBLISH)
|
||||
|
||||
version-cerxes:
|
||||
yarn lerna version prerelease --allow-branch initializers-fix --preid csx
|
||||
|
||||
publish-cerxes: prepublish
|
||||
yarn lerna publish --registry="https://npm.cerxes.net" --force-publish --allow-branch initializer-fix-v7.8.3 --dist-tag csx --skip-git --exact
|
||||
|
||||
# NOTE: Run make new-version first
|
||||
publish: prepublish
|
||||
@ -207,24 +238,43 @@ endif
|
||||
rm -f .npmrc
|
||||
$(MAKE) clean
|
||||
|
||||
publish-test:
|
||||
ifneq ("$(I_AM_USING_VERDACCIO)", "I_AM_SURE")
|
||||
echo "You probably don't know what you are doing"
|
||||
exit 1
|
||||
endif
|
||||
$(MAKE) prepublish-build
|
||||
yarn lerna version patch --force-publish=$(FORCE_PUBLISH) --no-push --yes --tag-version-prefix="version-e2e-test-"
|
||||
yarn lerna publish from-git --registry http://localhost:4873 --yes --tag-version-prefix="version-e2e-test-"
|
||||
$(MAKE) clean
|
||||
|
||||
publish-eslint:
|
||||
$(call set-json-field, ./eslint/$(PKG)/package.json, private, false)
|
||||
cd eslint/$(PKG); yarn publish
|
||||
$(call set-json-field, ./eslint/$(PKG)/package.json, private, true)
|
||||
|
||||
bootstrap-only: lerna-bootstrap
|
||||
|
||||
yarn-install: clean-all
|
||||
yarn --ignore-engines
|
||||
|
||||
lerna-bootstrap: yarn-install
|
||||
yarn lerna bootstrap
|
||||
# todo: remove `-- -- --ignore-engines` in Babel 8
|
||||
yarn lerna bootstrap -- -- --ignore-engines
|
||||
|
||||
bootstrap: bootstrap-only
|
||||
$(MAKE) build
|
||||
|
||||
clean-lib:
|
||||
# TODO: Don't delete eslint/*/lib when they use src
|
||||
$(foreach source, $(SOURCES), \
|
||||
$(call clean-source-lib, $(source)))
|
||||
$(if $(filter-out $(source), eslint), \
|
||||
$(call clean-source-lib, $(source))))
|
||||
|
||||
clean-runtime-helpers:
|
||||
rm -rf packages/babel-runtime/helpers
|
||||
rm -rf packages/babel-runtime-corejs2/helpers
|
||||
rm -f packages/babel-runtime/helpers/**/*.js
|
||||
rm -f packages/babel-runtime-corejs2/helpers/**/*.js
|
||||
rm -f packages/babel-runtime-corejs3/helpers/**/*.js
|
||||
rm -rf packages/babel-runtime-corejs2/core-js
|
||||
|
||||
clean-all:
|
||||
@ -237,6 +287,12 @@ clean-all:
|
||||
|
||||
$(MAKE) clean
|
||||
|
||||
update-env-corejs-fixture:
|
||||
rm -rf packages/babel-preset-env/node_modules/core-js-compat
|
||||
$(YARN) lerna bootstrap
|
||||
$(MAKE) build-bundle
|
||||
OVERWRITE=true $(YARN) jest packages/babel-preset-env
|
||||
|
||||
define clean-source-lib
|
||||
rm -rf $(1)/*/lib
|
||||
|
||||
@ -249,8 +305,16 @@ define clean-source-test
|
||||
endef
|
||||
|
||||
define clean-source-all
|
||||
rm -rf $(1)/*/lib
|
||||
# TODO: Don't delete eslint/*/lib when they use src
|
||||
$(if $(filter-out $1, eslint), $(call clean-source-lib, $1))
|
||||
rm -rf $(1)/*/node_modules
|
||||
rm -rf $(1)/*/package-lock.json
|
||||
|
||||
endef
|
||||
|
||||
define set-json-field
|
||||
node -e "\
|
||||
require('fs').writeFileSync('$1'.trim(), \
|
||||
JSON.stringify({ ...require('$1'.trim()), $2: $3 }, null, 2) + '\\n' \
|
||||
)"
|
||||
endef
|
||||
|
||||
@ -108,7 +108,7 @@ Some resources:
|
||||
- Our [CONTRIBUTING.md](CONTRIBUTING.md) to get started with setting up the repo.
|
||||
- Our discussions/notes/roadmap: [babel/notes](https://github.com/babel/notes)
|
||||
- Our progress on TC39 proposals: [babel/proposals](https://github.com/babel/proposals)
|
||||
- Our blog which contains release posts and explainations: [/blog](https://babeljs.io/blog)
|
||||
- Our blog which contains release posts and explanations: [/blog](https://babeljs.io/blog)
|
||||
- Our videos page with talks about open source and Babel: [/videos](https://babeljs.io/videos)
|
||||
- Our [podcast](https://podcast.babeljs.io)
|
||||
|
||||
|
||||
@ -14,22 +14,38 @@ module.exports = function(api) {
|
||||
|
||||
let convertESM = true;
|
||||
let ignoreLib = true;
|
||||
let includeRuntime = false;
|
||||
let includeRegeneratorRuntime = false;
|
||||
|
||||
let transformRuntimeOptions;
|
||||
|
||||
const nodeVersion = "6.9";
|
||||
// The vast majority of our src files are modules, but we use
|
||||
// unambiguous to keep things simple until we get around to renaming
|
||||
// the modules to be more easily distinguished from CommonJS
|
||||
const unambiguousSources = [
|
||||
"packages/*/src",
|
||||
"packages/*/test",
|
||||
"codemods/*/src",
|
||||
"codemods/*/test",
|
||||
"eslint/*/src",
|
||||
"eslint/*/test",
|
||||
];
|
||||
|
||||
switch (env) {
|
||||
// Configs used during bundling builds.
|
||||
case "babel-parser":
|
||||
convertESM = false;
|
||||
ignoreLib = false;
|
||||
envOpts.targets = {
|
||||
node: nodeVersion,
|
||||
};
|
||||
break;
|
||||
case "standalone":
|
||||
includeRegeneratorRuntime = true;
|
||||
unambiguousSources.push("packages/babel-runtime/regenerator");
|
||||
case "rollup":
|
||||
convertESM = false;
|
||||
ignoreLib = false;
|
||||
includeRuntime = true;
|
||||
// rollup-commonjs will converts node_modules to ESM
|
||||
unambiguousSources.push(
|
||||
"**/node_modules",
|
||||
"packages/babel-preset-env/data",
|
||||
"packages/babel-compat-data"
|
||||
);
|
||||
if (env === "rollup") envOpts.targets = { node: nodeVersion };
|
||||
break;
|
||||
case "production":
|
||||
// Config during builds before publish.
|
||||
@ -50,6 +66,16 @@ module.exports = function(api) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (includeRegeneratorRuntime) {
|
||||
const babelRuntimePkgPath = require.resolve("@babel/runtime/package.json");
|
||||
|
||||
transformRuntimeOptions = {
|
||||
helpers: false, // Helpers are handled by rollup when needed
|
||||
regenerator: true,
|
||||
version: require(babelRuntimePkgPath).version,
|
||||
};
|
||||
}
|
||||
|
||||
const config = {
|
||||
// Our dependencies are all standard CommonJS, along with all sorts of
|
||||
// other random files in Babel's codebase, so we use script as the default,
|
||||
@ -77,10 +103,14 @@ module.exports = function(api) {
|
||||
"@babel/proposal-object-rest-spread",
|
||||
{ useBuiltIns: true, loose: true },
|
||||
],
|
||||
"@babel/plugin-proposal-optional-chaining",
|
||||
"@babel/plugin-proposal-nullish-coalescing-operator",
|
||||
["@babel/plugin-proposal-optional-chaining", { loose: true }],
|
||||
["@babel/plugin-proposal-nullish-coalescing-operator", { loose: true }],
|
||||
|
||||
convertESM ? "@babel/transform-modules-commonjs" : null,
|
||||
// Until Jest supports native mjs, we must simulate it 🤷
|
||||
env === "test" || env === "development"
|
||||
? "@babel/plugin-proposal-dynamic-import"
|
||||
: null,
|
||||
].filter(Boolean),
|
||||
overrides: [
|
||||
{
|
||||
@ -104,28 +134,12 @@ module.exports = function(api) {
|
||||
presets: [["@babel/env", envOptsNoTargets]],
|
||||
},
|
||||
{
|
||||
// The vast majority of our src files are modules, but we use
|
||||
// unambiguous to keep things simple until we get around to renaming
|
||||
// the modules to be more easily distinguished from CommonJS
|
||||
test: [
|
||||
"packages/*/src",
|
||||
"packages/*/test",
|
||||
"codemods/*/src",
|
||||
"codemods/*/test",
|
||||
],
|
||||
test: unambiguousSources,
|
||||
sourceType: "unambiguous",
|
||||
},
|
||||
{
|
||||
// The runtime transform shouldn't process its own runtime or core-js.
|
||||
exclude: [
|
||||
"packages/babel-runtime",
|
||||
/[\\/]node_modules[\\/](?:@babel\/runtime|babel-runtime|core-js)[\\/]/,
|
||||
],
|
||||
plugins: [
|
||||
includeRuntime
|
||||
? ["@babel/transform-runtime", { version: "7.4.4" }]
|
||||
: null,
|
||||
].filter(Boolean),
|
||||
includeRegeneratorRuntime && {
|
||||
exclude: /regenerator-runtime/,
|
||||
plugins: [["@babel/transform-runtime", transformRuntimeOptions]],
|
||||
},
|
||||
].filter(Boolean),
|
||||
};
|
||||
|
||||
@ -5,7 +5,7 @@ coverage:
|
||||
status:
|
||||
project:
|
||||
default:
|
||||
target: "80%"
|
||||
target: "90%"
|
||||
patch:
|
||||
enabled: false
|
||||
ignore:
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@babel/plugin-codemod-object-assign-to-object-spread",
|
||||
"version": "7.0.0",
|
||||
"version": "7.7.4",
|
||||
"description": "Transforms Object.assign into object spread syntax",
|
||||
"repository": "https://github.com/babel/babel/tree/master/codemods/babel-plugin-codemod-object-assign-to-object-spread",
|
||||
"license": "MIT",
|
||||
@ -13,16 +13,13 @@
|
||||
"@babel/plugin"
|
||||
],
|
||||
"dependencies": {
|
||||
"@babel/plugin-syntax-object-rest-spread": "^7.0.0"
|
||||
"@babel/plugin-syntax-object-rest-spread": "^7.7.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "^7.0.0-0"
|
||||
"@babel/core": "^7.0.0-0 || csx"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.0.0",
|
||||
"@babel/helper-plugin-test-runner": "^7.0.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
"@babel/core": "^7.7.4",
|
||||
"@babel/helper-plugin-test-runner": "^7.7.4"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@babel/plugin-codemod-optional-catch-binding",
|
||||
"version": "7.0.0",
|
||||
"version": "7.7.4",
|
||||
"description": "Remove unused catch bindings",
|
||||
"repository": "https://github.com/babel/babel/tree/master/codemods/babel-plugin-codemod-remove-unused-catch-binding",
|
||||
"license": "MIT",
|
||||
@ -13,13 +13,13 @@
|
||||
"@babel/plugin"
|
||||
],
|
||||
"dependencies": {
|
||||
"@babel/plugin-syntax-optional-catch-binding": "^7.0.0"
|
||||
"@babel/plugin-syntax-optional-catch-binding": "^7.7.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "^7.0.0-0"
|
||||
"@babel/core": "^7.0.0-0 || csx"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.0.0",
|
||||
"@babel/helper-plugin-test-runner": "^7.0.0"
|
||||
"@babel/core": "^7.7.4",
|
||||
"@babel/helper-plugin-test-runner": "^7.7.4"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
{
|
||||
"plugins": ["../../../../lib"]
|
||||
}
|
||||
}
|
||||
|
||||
4
eslint/babel-eslint-config-internal/.npmignore
Normal file
4
eslint/babel-eslint-config-internal/.npmignore
Normal file
@ -0,0 +1,4 @@
|
||||
src
|
||||
test
|
||||
.*
|
||||
*.log
|
||||
4
eslint/babel-eslint-config-internal/README.md
Normal file
4
eslint/babel-eslint-config-internal/README.md
Normal file
@ -0,0 +1,4 @@
|
||||
## @babel/eslint-config-internal
|
||||
---
|
||||
|
||||
ESLint config for the Babel codebase (originally taken from `eslint-config-kittens`)
|
||||
49
eslint/babel-eslint-config-internal/index.js
Normal file
49
eslint/babel-eslint-config-internal/index.js
Normal file
@ -0,0 +1,49 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
parser: "babel-eslint",
|
||||
extends: "eslint:recommended",
|
||||
plugins: ["flowtype"],
|
||||
parserOptions: {
|
||||
ecmaVersion: 2020,
|
||||
sourceType: "module",
|
||||
},
|
||||
globals: {
|
||||
// Flow
|
||||
Iterator: true,
|
||||
$Keys: true,
|
||||
},
|
||||
env: {
|
||||
node: true,
|
||||
es2020: true,
|
||||
browser: true,
|
||||
},
|
||||
rules: {
|
||||
camelcase: "off",
|
||||
"consistent-return": "off",
|
||||
curly: ["error", "multi-line"],
|
||||
"linebreak-style": ["error", "unix"],
|
||||
"new-cap": "off",
|
||||
"no-case-declarations": "error",
|
||||
"no-cond-assign": "off",
|
||||
"no-confusing-arrow": "error",
|
||||
"no-console": "off",
|
||||
"no-constant-condition": "off",
|
||||
"no-empty": "off",
|
||||
"no-fallthrough": "off",
|
||||
"no-inner-declarations": "off",
|
||||
"no-labels": "off",
|
||||
"no-loop-func": "off",
|
||||
"no-process-exit": "off",
|
||||
"no-return-assign": "off",
|
||||
"no-shadow": "off",
|
||||
"no-underscore-dangle": "off",
|
||||
"no-unreachable": "off",
|
||||
"no-use-before-define": "off",
|
||||
"no-var": "error",
|
||||
"prefer-const": "error",
|
||||
strict: "off",
|
||||
"flowtype/define-flow-type": "warn",
|
||||
"flowtype/use-flow-type": "warn",
|
||||
},
|
||||
};
|
||||
15
eslint/babel-eslint-config-internal/package.json
Normal file
15
eslint/babel-eslint-config-internal/package.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "@babel/eslint-config-internal",
|
||||
"version": "7.8.3-csx.2",
|
||||
"description": "The Babel Team's ESLint configuration. Since it's internal, it might not respect semver.",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||
"homepage": "https://babeljs.io/",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"repository": "https://github.com/babel/babel/tree/master/eslint/babel-eslint-config-internal",
|
||||
"main": "lib/index.js",
|
||||
"peerDependencies": {
|
||||
"babel-eslint": "^10.0.0 || ^11.0.0-0",
|
||||
"eslint-plugin-flowtype": "^3.0.0"
|
||||
}
|
||||
}
|
||||
4
eslint/babel-eslint-parser/.npmignore
Normal file
4
eslint/babel-eslint-parser/.npmignore
Normal file
@ -0,0 +1,4 @@
|
||||
src
|
||||
test
|
||||
.*
|
||||
*.log
|
||||
124
eslint/babel-eslint-parser/README.md
Normal file
124
eslint/babel-eslint-parser/README.md
Normal file
@ -0,0 +1,124 @@
|
||||
# @babel/eslint-parser [](https://www.npmjs.com/package/@babel/eslint-parser) [](https://travis-ci.org/babel/@babel/eslint-parser) [](https://www.npmjs.com/package/@babel/eslint-parser)
|
||||
|
||||
**@babel/eslint-parser** allows you to lint **ALL** valid Babel code with the fantastic
|
||||
[ESLint](https://github.com/eslint/eslint).
|
||||
|
||||
## When should I use @babel/eslint-parser?
|
||||
|
||||
ESLint's default parser and core rules [only support the latest final ECMAScript standard](https://github.com/eslint/eslint/blob/a675c89573836adaf108a932696b061946abf1e6/README.md#what-about-experimental-features) and do not support experimental (such as new features) and non-standard (such as Flow or TypeScript types) syntax provided by Babel. @babel/eslint-parser is a parser that allows ESLint to run on source code that is transformed by Babel.
|
||||
|
||||
**Note:** You only need to use @babel/parser-eslint if you are using Babel to transform your code. If this is not the case, please use the relevant parser for your chosen flavor of ECMAScript (note that the default parser supports all non-experimental syntax as well as JSX).
|
||||
|
||||
## How does it work?
|
||||
|
||||
ESLint allows for the use of [custom parsers](https://eslint.org/docs/developer-guide/working-with-custom-parsers). When using this plugin, your code is parsed by Babel's parser (using the configuration specified in your [Babel configuration file](https://babeljs.io/docs/en/configuration)) and the resulting AST is
|
||||
transformed into an [ESTree](https://github.com/estree/estree)-compliant structure that ESLint can understand. All location info such as line numbers,
|
||||
columns is also retained so you can track down errors with ease.
|
||||
|
||||
**Note:** ESLint's core rules do not support experimental syntax and may therefore not work as expected when using `@babel/eslint-parser`. Please use the companion [`@babel/eslint-plugin`](https://github.com/babel/babel/tree/master/eslint/babel-eslint-plugin) plugin for core rules that you have issues with.
|
||||
|
||||
## Usage
|
||||
|
||||
### Installation
|
||||
|
||||
```sh
|
||||
$ npm install eslint @babel/core @babel/eslint-parser --save-dev
|
||||
# or
|
||||
$ yarn add eslint @babel/core @babel/eslint-parser -D
|
||||
```
|
||||
|
||||
**Note:** @babel/eslint-parser requires `@babel/core@>=7.2.0` and a valid Babel configuration file to run. If you do not have this already set up, please see the [Babel Usage Guide](https://babeljs.io/docs/en/usage).
|
||||
|
||||
### Setup
|
||||
|
||||
To use @babel/eslint-parser, `"@babel/eslint-parser"` must be specified as the `parser` in your ESLint configuration file (see [here](https://eslint.org/docs/user-guide/configuring#specifying-parser) for more detailed information).
|
||||
|
||||
**.eslintrc.js**
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
parser: "@babel/eslint-parser",
|
||||
};
|
||||
```
|
||||
|
||||
With the parser set, your configuration can be configured as described in the [Configuring ESLint](https://eslint.org/docs/user-guide/configuring) documentation.
|
||||
|
||||
**Note:** The `parserOptions` described in the [official documentation](https://eslint.org/docs/user-guide/configuring#specifying-parser-options) are for the default parser and are not necessarily supported by @babel/eslint-parser. Please see the section directly below for supported `parserOptions`.
|
||||
|
||||
### Additional parser configuration
|
||||
|
||||
Additional configuration options can be set in your ESLint configuration under the `parserOptions` key. Please note that the `ecmaFeatures` config property may still be required for ESLint to work properly with features not in ECMAScript 5 by default.
|
||||
|
||||
- `requireConfigFile` (default `true`) can be set to `false` to allow @babel/eslint-parser to run on files that do not have a Babel configuration associated with them. This can be useful for linting files that are not transformed by Babel (such as tooling configuration files), though we recommend using the default parser via [glob-based configuration](https://eslint.org/docs/user-guide/configuring#configuration-based-on-glob-patterns). Note: @babel/eslint-parser will not parse any experimental syntax when no configuration file is found.
|
||||
- `sourceType` can be set to `"module"`(default) or `"script"` if your code isn't using ECMAScript modules.
|
||||
- `allowImportExportEverywhere` (default `false`) can be set to `true` to allow import and export declarations to appear anywhere a statement is allowed if your build environment supports that. Otherwise import and export declarations can only appear at a program's top level.
|
||||
- `ecmaFeatures.globalReturn` (default `false`) allow return statements in the global scope when used with `sourceType: "script"`.
|
||||
- `babelOptions` passes through Babel's configuration [loading](https://babeljs.io/docs/en/options#config-loading-options) and [merging](https://babeljs.io/docs/en/options#config-merging-options) options (for instance, in case of a monorepo). When not defined, @babel/eslint-parser will use Babel's default configuration file resolution logic.
|
||||
|
||||
**.eslintrc.js**
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
parser: "@babel/eslint-parser",
|
||||
parserOptions: {
|
||||
sourceType: "module",
|
||||
allowImportExportEverywhere: false,
|
||||
ecmaFeatures: {
|
||||
globalReturn: false,
|
||||
},
|
||||
babelOptions: {
|
||||
configFile: "path/to/config.js",
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
**.eslintrc.js using glob-based configuration**
|
||||
|
||||
This configuration would use the default parser for all files except for those found by the `"files/transformed/by/babel/*.js"` glob.
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
rules: {
|
||||
indent: "error"
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ["files/transformed/by/babel/*.js"],
|
||||
parser: "@babel/eslint-parser",
|
||||
}
|
||||
]
|
||||
};
|
||||
```
|
||||
|
||||
### Run
|
||||
|
||||
```sh
|
||||
$ ./node_modules/.bin/eslint yourfile.js
|
||||
```
|
||||
|
||||
## Known issues
|
||||
|
||||
Flow:
|
||||
|
||||
> Check out [eslint-plugin-flowtype](https://github.com/gajus/eslint-plugin-flowtype): An `eslint` plugin that makes flow type annotations global variables and marks declarations as used. Solves the problem of false positives with `no-undef` and `no-unused-vars`.
|
||||
|
||||
- `no-undef` for global flow types: `ReactElement`, `ReactClass` [#130](https://github.com/babel/@babel/eslint-parser/issues/130#issuecomment-111215076)
|
||||
- Workaround: define types as globals in `.eslintrc` or define types and import them `import type ReactElement from './types'`
|
||||
- `no-unused-vars/no-undef` with Flow declarations (`declare module A {}`) [#132](https://github.com/babel/@babel/eslint-parser/issues/132#issuecomment-112815926)
|
||||
|
||||
Modules/strict mode
|
||||
|
||||
- `no-unused-vars: ["error", { vars: local }]` [#136](https://github.com/babel/@babel/eslint-parser/issues/136)
|
||||
|
||||
Please check out [eslint-plugin-react](https://github.com/yannickcr/eslint-plugin-react) for React/JSX issues.
|
||||
|
||||
- `no-unused-vars` with jsx
|
||||
|
||||
Please check out [eslint-plugin-babel](https://github.com/babel/eslint-plugin-babel) for other issues.
|
||||
|
||||
## Questions and support
|
||||
|
||||
If you have an issue, please first check if it can be reproduced with the default parser and with the latest versions of `eslint` and `@babel/eslint-parser`. If it is not reproducible with the default parser, it is most likely an issue with `@babel/eslint-parser`.
|
||||
|
||||
For questions and support please visit the [`#discussion`](https://babeljs.slack.com/messages/discussion/) Babel Slack channel (sign up [here](https://github.com/babel/notes/issues/38)) or the ESLint [Gitter](https://gitter.im/eslint/eslint).
|
||||
37
eslint/babel-eslint-parser/package.json
Normal file
37
eslint/babel-eslint-parser/package.json
Normal file
@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "@babel/eslint-parser",
|
||||
"version": "7.8.3-csx.2",
|
||||
"description": "ESLint parser that allows for linting of experimental syntax transformed by Babel",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/babel/babel.git",
|
||||
"directory": "eslint/babel-eslint-parser"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/babel/babel/issues"
|
||||
},
|
||||
"homepage": "https://github.com/babel/babel/tree/master/eslint/babel-eslint-parser",
|
||||
"engines": {
|
||||
"node": ">=10.9"
|
||||
},
|
||||
"main": "lib/index.js",
|
||||
"peerDependencies": {
|
||||
"@babel/core": ">=7.2.0",
|
||||
"eslint": ">=6.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"eslint-scope": "5.0.0",
|
||||
"eslint-visitor-keys": "^1.1.0",
|
||||
"semver": "^6.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.2.0",
|
||||
"@babel/eslint-shared-fixtures": "7.8.3-csx.2",
|
||||
"dedent": "^0.7.0",
|
||||
"eslint": "^6.0.1",
|
||||
"espree": "^6.0.0"
|
||||
}
|
||||
}
|
||||
344
eslint/babel-eslint-parser/src/analyze-scope.js
Normal file
344
eslint/babel-eslint-parser/src/analyze-scope.js
Normal file
@ -0,0 +1,344 @@
|
||||
import { types as t } from "@babel/core";
|
||||
import escope from "eslint-scope";
|
||||
import { Definition } from "eslint-scope/lib/definition";
|
||||
import OriginalPatternVisitor from "eslint-scope/lib/pattern-visitor";
|
||||
import OriginalReferencer from "eslint-scope/lib/referencer";
|
||||
import { getKeys as fallback } from "eslint-visitor-keys";
|
||||
import childVisitorKeys from "./visitor-keys";
|
||||
|
||||
const flowFlippedAliasKeys = t.FLIPPED_ALIAS_KEYS.Flow.concat([
|
||||
"ArrayPattern",
|
||||
"ClassDeclaration",
|
||||
"ClassExpression",
|
||||
"FunctionDeclaration",
|
||||
"FunctionExpression",
|
||||
"Identifier",
|
||||
"ObjectPattern",
|
||||
"RestElement",
|
||||
]);
|
||||
|
||||
const visitorKeysMap = Object.entries(t.VISITOR_KEYS).reduce(
|
||||
(acc, [key, value]) => {
|
||||
if (!flowFlippedAliasKeys.includes(value)) {
|
||||
acc[key] = value;
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{},
|
||||
);
|
||||
|
||||
const propertyTypes = {
|
||||
// loops
|
||||
callProperties: { type: "loop", values: ["value"] },
|
||||
indexers: { type: "loop", values: ["key", "value"] },
|
||||
properties: { type: "loop", values: ["argument", "value"] },
|
||||
types: { type: "loop" },
|
||||
params: { type: "loop" },
|
||||
// single property
|
||||
argument: { type: "single" },
|
||||
elementType: { type: "single" },
|
||||
qualification: { type: "single" },
|
||||
rest: { type: "single" },
|
||||
returnType: { type: "single" },
|
||||
// others
|
||||
typeAnnotation: { type: "typeAnnotation" },
|
||||
typeParameters: { type: "typeParameters" },
|
||||
id: { type: "id" },
|
||||
};
|
||||
|
||||
class PatternVisitor extends OriginalPatternVisitor {
|
||||
ArrayPattern(node) {
|
||||
node.elements.forEach(this.visit, this);
|
||||
}
|
||||
|
||||
ObjectPattern(node) {
|
||||
node.properties.forEach(this.visit, this);
|
||||
}
|
||||
}
|
||||
|
||||
class Referencer extends OriginalReferencer {
|
||||
// inherits.
|
||||
visitPattern(node, options, callback) {
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Visit type annotations.
|
||||
this._checkIdentifierOrVisit(node.typeAnnotation);
|
||||
if (t.isAssignmentPattern(node)) {
|
||||
this._checkIdentifierOrVisit(node.left.typeAnnotation);
|
||||
}
|
||||
|
||||
// Overwrite `super.visitPattern(node, options, callback)` in order to not visit `ArrayPattern#typeAnnotation` and `ObjectPattern#typeAnnotation`.
|
||||
if (typeof options === "function") {
|
||||
callback = options;
|
||||
options = { processRightHandNodes: false };
|
||||
}
|
||||
|
||||
const visitor = new PatternVisitor(this.options, node, callback);
|
||||
visitor.visit(node);
|
||||
|
||||
// Process the right hand nodes recursively.
|
||||
if (options.processRightHandNodes) {
|
||||
visitor.rightHandNodes.forEach(this.visit, this);
|
||||
}
|
||||
}
|
||||
|
||||
// inherits.
|
||||
visitClass(node) {
|
||||
// Decorators.
|
||||
this._visitArray(node.decorators);
|
||||
|
||||
// Flow type parameters.
|
||||
const typeParamScope = this._nestTypeParamScope(node);
|
||||
|
||||
// Flow super types.
|
||||
this._visitTypeAnnotation(node.implements);
|
||||
this._visitTypeAnnotation(
|
||||
node.superTypeParameters && node.superTypeParameters.params,
|
||||
);
|
||||
|
||||
// Basic.
|
||||
super.visitClass(node);
|
||||
|
||||
// Close the type parameter scope.
|
||||
if (typeParamScope) {
|
||||
this.close(node);
|
||||
}
|
||||
}
|
||||
|
||||
// inherits.
|
||||
visitFunction(node) {
|
||||
const typeParamScope = this._nestTypeParamScope(node);
|
||||
|
||||
// Flow return types.
|
||||
this._checkIdentifierOrVisit(node.returnType);
|
||||
|
||||
// Basic.
|
||||
super.visitFunction(node);
|
||||
|
||||
// Close the type parameter scope.
|
||||
if (typeParamScope) {
|
||||
this.close(node);
|
||||
}
|
||||
}
|
||||
|
||||
// inherits.
|
||||
visitProperty(node) {
|
||||
if (node.value?.type === "TypeCastExpression") {
|
||||
this._visitTypeAnnotation(node.value);
|
||||
}
|
||||
this._visitArray(node.decorators);
|
||||
super.visitProperty(node);
|
||||
}
|
||||
|
||||
InterfaceDeclaration(node) {
|
||||
this._createScopeVariable(node, node.id);
|
||||
|
||||
const typeParamScope = this._nestTypeParamScope(node);
|
||||
|
||||
// TODO: Handle mixins
|
||||
this._visitArray(node.extends);
|
||||
this.visit(node.body);
|
||||
|
||||
if (typeParamScope) {
|
||||
this.close(node);
|
||||
}
|
||||
}
|
||||
|
||||
TypeAlias(node) {
|
||||
this._createScopeVariable(node, node.id);
|
||||
|
||||
const typeParamScope = this._nestTypeParamScope(node);
|
||||
|
||||
this.visit(node.right);
|
||||
|
||||
if (typeParamScope) {
|
||||
this.close(node);
|
||||
}
|
||||
}
|
||||
|
||||
ClassProperty(node) {
|
||||
this._visitClassProperty(node);
|
||||
}
|
||||
|
||||
ClassPrivateProperty(node) {
|
||||
this._visitClassProperty(node);
|
||||
}
|
||||
|
||||
// TODO: Update to visit type annotations when TypeScript/Flow support this syntax.
|
||||
ClassPrivateMethod(node) {
|
||||
super.MethodDefinition(node);
|
||||
}
|
||||
|
||||
DeclareModule(node) {
|
||||
this._visitDeclareX(node);
|
||||
}
|
||||
|
||||
DeclareFunction(node) {
|
||||
this._visitDeclareX(node);
|
||||
}
|
||||
|
||||
DeclareVariable(node) {
|
||||
this._visitDeclareX(node);
|
||||
}
|
||||
|
||||
DeclareClass(node) {
|
||||
this._visitDeclareX(node);
|
||||
}
|
||||
|
||||
// visit OptionalMemberExpression as a MemberExpression.
|
||||
OptionalMemberExpression(node) {
|
||||
super.MemberExpression(node);
|
||||
}
|
||||
|
||||
_visitClassProperty(node) {
|
||||
this._visitTypeAnnotation(node.typeAnnotation);
|
||||
this.visitProperty(node);
|
||||
}
|
||||
|
||||
_visitDeclareX(node) {
|
||||
if (node.id) {
|
||||
this._createScopeVariable(node, node.id);
|
||||
}
|
||||
|
||||
const typeParamScope = this._nestTypeParamScope(node);
|
||||
if (typeParamScope) {
|
||||
this.close(node);
|
||||
}
|
||||
}
|
||||
|
||||
_createScopeVariable(node, name) {
|
||||
this.currentScope().variableScope.__define(
|
||||
name,
|
||||
new Definition("Variable", name, node, null, null, null),
|
||||
);
|
||||
}
|
||||
|
||||
_nestTypeParamScope(node) {
|
||||
if (!node.typeParameters) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const parentScope = this.scopeManager.__currentScope;
|
||||
const scope = new escope.Scope(
|
||||
this.scopeManager,
|
||||
"type-parameters",
|
||||
parentScope,
|
||||
node,
|
||||
false,
|
||||
);
|
||||
|
||||
this.scopeManager.__nestScope(scope);
|
||||
for (let j = 0; j < node.typeParameters.params.length; j++) {
|
||||
const name = node.typeParameters.params[j];
|
||||
scope.__define(name, new Definition("TypeParameter", name, name));
|
||||
if (name.typeAnnotation) {
|
||||
this._checkIdentifierOrVisit(name);
|
||||
}
|
||||
}
|
||||
scope.__define = function() {
|
||||
return parentScope.__define.apply(parentScope, arguments);
|
||||
};
|
||||
|
||||
return scope;
|
||||
}
|
||||
|
||||
_visitTypeAnnotation(node) {
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
if (Array.isArray(node)) {
|
||||
node.forEach(this._visitTypeAnnotation, this);
|
||||
return;
|
||||
}
|
||||
|
||||
// get property to check (params, id, etc...)
|
||||
const visitorValues = visitorKeysMap[node.type];
|
||||
if (!visitorValues) {
|
||||
return;
|
||||
}
|
||||
|
||||
// can have multiple properties
|
||||
for (let i = 0; i < visitorValues.length; i++) {
|
||||
const visitorValue = visitorValues[i];
|
||||
const propertyType = propertyTypes[visitorValue];
|
||||
const nodeProperty = node[visitorValue];
|
||||
// check if property or type is defined
|
||||
if (propertyType == null || nodeProperty == null) {
|
||||
continue;
|
||||
}
|
||||
if (propertyType.type === "loop") {
|
||||
for (let j = 0; j < nodeProperty.length; j++) {
|
||||
if (Array.isArray(propertyType.values)) {
|
||||
for (let k = 0; k < propertyType.values.length; k++) {
|
||||
const loopPropertyNode = nodeProperty[j][propertyType.values[k]];
|
||||
if (loopPropertyNode) {
|
||||
this._checkIdentifierOrVisit(loopPropertyNode);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this._checkIdentifierOrVisit(nodeProperty[j]);
|
||||
}
|
||||
}
|
||||
} else if (propertyType.type === "single") {
|
||||
this._checkIdentifierOrVisit(nodeProperty);
|
||||
} else if (propertyType.type === "typeAnnotation") {
|
||||
this._visitTypeAnnotation(node.typeAnnotation);
|
||||
} else if (propertyType.type === "typeParameters") {
|
||||
for (let l = 0; l < node.typeParameters.params.length; l++) {
|
||||
this._checkIdentifierOrVisit(node.typeParameters.params[l]);
|
||||
}
|
||||
} else if (propertyType.type === "id") {
|
||||
if (node.id.type === "Identifier") {
|
||||
this._checkIdentifierOrVisit(node.id);
|
||||
} else {
|
||||
this._visitTypeAnnotation(node.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_checkIdentifierOrVisit(node) {
|
||||
if (node?.typeAnnotation) {
|
||||
this._visitTypeAnnotation(node.typeAnnotation);
|
||||
} else if (node?.type === "Identifier") {
|
||||
this.visit(node);
|
||||
} else {
|
||||
this._visitTypeAnnotation(node);
|
||||
}
|
||||
}
|
||||
|
||||
_visitArray(nodeList) {
|
||||
if (nodeList) {
|
||||
for (const node of nodeList) {
|
||||
this.visit(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default function(ast, parserOptions) {
|
||||
const options = {
|
||||
ignoreEval: true,
|
||||
optimistic: false,
|
||||
directive: false,
|
||||
nodejsScope:
|
||||
ast.sourceType === "script" &&
|
||||
(parserOptions.ecmaFeatures &&
|
||||
parserOptions.ecmaFeatures.globalReturn) === true,
|
||||
impliedStrict: false,
|
||||
sourceType: ast.sourceType,
|
||||
ecmaVersion: parserOptions.ecmaVersion,
|
||||
fallback,
|
||||
};
|
||||
|
||||
options.childVisitorKeys = childVisitorKeys;
|
||||
|
||||
const scopeManager = new escope.ScopeManager(options);
|
||||
const referencer = new Referencer(options, scopeManager);
|
||||
|
||||
referencer.visit(ast);
|
||||
|
||||
return scopeManager;
|
||||
}
|
||||
@ -0,0 +1,96 @@
|
||||
import { types as t, traverse } from "@babel/core";
|
||||
import convertProgramNode from "./convertProgramNode";
|
||||
|
||||
const astTransformVisitor = {
|
||||
noScope: true,
|
||||
enter(path) {
|
||||
const node = path.node;
|
||||
|
||||
// private var to track original node type
|
||||
node._babelType = node.type;
|
||||
|
||||
if (node.innerComments) {
|
||||
delete node.innerComments;
|
||||
}
|
||||
|
||||
if (node.trailingComments) {
|
||||
delete node.trailingComments;
|
||||
}
|
||||
|
||||
if (node.leadingComments) {
|
||||
delete node.leadingComments;
|
||||
}
|
||||
},
|
||||
exit(path) {
|
||||
const node = path.node;
|
||||
|
||||
if (path.isTypeParameter()) {
|
||||
node.type = "Identifier";
|
||||
node.typeAnnotation = node.bound;
|
||||
delete node.bound;
|
||||
}
|
||||
|
||||
// flow: prevent "no-undef"
|
||||
// for "Component" in: "let x: React.Component"
|
||||
if (path.isQualifiedTypeIdentifier()) {
|
||||
delete node.id;
|
||||
}
|
||||
// for "b" in: "var a: { b: Foo }"
|
||||
if (path.isObjectTypeProperty()) {
|
||||
delete node.key;
|
||||
}
|
||||
// for "indexer" in: "var a: {[indexer: string]: number}"
|
||||
if (path.isObjectTypeIndexer()) {
|
||||
delete node.id;
|
||||
}
|
||||
// for "param" in: "var a: { func(param: Foo): Bar };"
|
||||
if (path.isFunctionTypeParam()) {
|
||||
delete node.name;
|
||||
}
|
||||
|
||||
// modules
|
||||
if (path.isImportDeclaration()) {
|
||||
delete node.isType;
|
||||
}
|
||||
|
||||
// template string range fixes
|
||||
if (path.isTemplateLiteral()) {
|
||||
for (let i = 0; i < node.quasis.length; i++) {
|
||||
const q = node.quasis[i];
|
||||
q.range[0] -= 1;
|
||||
if (q.tail) {
|
||||
q.range[1] += 1;
|
||||
} else {
|
||||
q.range[1] += 2;
|
||||
}
|
||||
q.loc.start.column -= 1;
|
||||
if (q.tail) {
|
||||
q.loc.end.column += 1;
|
||||
} else {
|
||||
q.loc.end.column += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default function(ast, code) {
|
||||
const state = { source: code };
|
||||
|
||||
// Monkey patch visitor keys in order to be able to traverse the estree nodes
|
||||
t.VISITOR_KEYS.Property = t.VISITOR_KEYS.ObjectProperty;
|
||||
t.VISITOR_KEYS.MethodDefinition = [
|
||||
"key",
|
||||
"value",
|
||||
"decorators",
|
||||
"returnType",
|
||||
"typeParameters",
|
||||
];
|
||||
|
||||
traverse(ast, astTransformVisitor, null, state);
|
||||
|
||||
delete t.VISITOR_KEYS.Property;
|
||||
delete t.VISITOR_KEYS.MethodDefinition;
|
||||
|
||||
convertProgramNode(ast);
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
export default function(comments) {
|
||||
for (let i = 0; i < comments.length; i++) {
|
||||
const comment = comments[i];
|
||||
if (comment.type === "CommentBlock") {
|
||||
comment.type = "Block";
|
||||
} else if (comment.type === "CommentLine") {
|
||||
comment.type = "Line";
|
||||
}
|
||||
// sometimes comments don't get ranges computed,
|
||||
// even with options.ranges === true
|
||||
if (!comment.range) {
|
||||
comment.range = [comment.start, comment.end];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
export default function(ast) {
|
||||
ast.type = "Program";
|
||||
ast.sourceType = ast.program.sourceType;
|
||||
ast.directives = ast.program.directives;
|
||||
ast.body = ast.program.body;
|
||||
delete ast.program;
|
||||
|
||||
if (ast.comments.length) {
|
||||
const lastComment = ast.comments[ast.comments.length - 1];
|
||||
|
||||
if (!ast.tokens.length) {
|
||||
// if no tokens, the program starts at the end of the last comment
|
||||
ast.start = lastComment.end;
|
||||
ast.loc.start.line = lastComment.loc.end.line;
|
||||
ast.loc.start.column = lastComment.loc.end.column;
|
||||
} else {
|
||||
const lastToken = ast.tokens[ast.tokens.length - 1];
|
||||
|
||||
if (lastComment.end > lastToken.end) {
|
||||
// If there is a comment after the last token, the program ends at the
|
||||
// last token and not the comment
|
||||
ast.range[1] = lastToken.end;
|
||||
ast.loc.end.line = lastToken.loc.end.line;
|
||||
ast.loc.end.column = lastToken.loc.end.column;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!ast.tokens.length) {
|
||||
ast.loc.start.line = 1;
|
||||
ast.loc.end.line = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ast.body && ast.body.length > 0) {
|
||||
ast.loc.start.line = ast.body[0].loc.start.line;
|
||||
ast.range[0] = ast.body[0].start;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,92 @@
|
||||
import { tokTypes as tt } from "@babel/core";
|
||||
|
||||
export default function(tokens) {
|
||||
let curlyBrace = null;
|
||||
let templateTokens = [];
|
||||
const result = [];
|
||||
|
||||
function addTemplateType() {
|
||||
const start = templateTokens[0];
|
||||
const end = templateTokens[templateTokens.length - 1];
|
||||
|
||||
const value = templateTokens.reduce((result, token) => {
|
||||
if (token.value) {
|
||||
result += token.value;
|
||||
} else if (token.type !== tt.template) {
|
||||
result += token.type.label;
|
||||
}
|
||||
|
||||
return result;
|
||||
}, "");
|
||||
|
||||
result.push({
|
||||
type: "Template",
|
||||
value: value,
|
||||
start: start.start,
|
||||
end: end.end,
|
||||
loc: {
|
||||
start: start.loc.start,
|
||||
end: end.loc.end,
|
||||
},
|
||||
});
|
||||
|
||||
templateTokens = [];
|
||||
}
|
||||
|
||||
tokens.forEach(token => {
|
||||
switch (token.type) {
|
||||
case tt.backQuote:
|
||||
if (curlyBrace) {
|
||||
result.push(curlyBrace);
|
||||
curlyBrace = null;
|
||||
}
|
||||
|
||||
templateTokens.push(token);
|
||||
|
||||
if (templateTokens.length > 1) {
|
||||
addTemplateType();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case tt.dollarBraceL:
|
||||
templateTokens.push(token);
|
||||
addTemplateType();
|
||||
break;
|
||||
|
||||
case tt.braceR:
|
||||
if (curlyBrace) {
|
||||
result.push(curlyBrace);
|
||||
}
|
||||
|
||||
curlyBrace = token;
|
||||
break;
|
||||
|
||||
case tt.template:
|
||||
if (curlyBrace) {
|
||||
templateTokens.push(curlyBrace);
|
||||
curlyBrace = null;
|
||||
}
|
||||
|
||||
templateTokens.push(token);
|
||||
break;
|
||||
|
||||
case tt.eof:
|
||||
if (curlyBrace) {
|
||||
result.push(curlyBrace);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
if (curlyBrace) {
|
||||
result.push(curlyBrace);
|
||||
curlyBrace = null;
|
||||
}
|
||||
|
||||
result.push(token);
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -0,0 +1,88 @@
|
||||
import { tokTypes as tt } from "@babel/core";
|
||||
|
||||
export default function(token, source) {
|
||||
const type = token.type;
|
||||
token.range = [token.start, token.end];
|
||||
|
||||
if (type === tt.name) {
|
||||
token.type = "Identifier";
|
||||
} else if (
|
||||
type === tt.semi ||
|
||||
type === tt.comma ||
|
||||
type === tt.parenL ||
|
||||
type === tt.parenR ||
|
||||
type === tt.braceL ||
|
||||
type === tt.braceR ||
|
||||
type === tt.slash ||
|
||||
type === tt.dot ||
|
||||
type === tt.bracketL ||
|
||||
type === tt.bracketR ||
|
||||
type === tt.ellipsis ||
|
||||
type === tt.arrow ||
|
||||
type === tt.pipeline ||
|
||||
type === tt.star ||
|
||||
type === tt.incDec ||
|
||||
type === tt.colon ||
|
||||
type === tt.question ||
|
||||
type === tt.questionDot ||
|
||||
type === tt.template ||
|
||||
type === tt.backQuote ||
|
||||
type === tt.dollarBraceL ||
|
||||
type === tt.at ||
|
||||
type === tt.logicalOR ||
|
||||
type === tt.logicalAND ||
|
||||
type === tt.nullishCoalescing ||
|
||||
type === tt.bitwiseOR ||
|
||||
type === tt.bitwiseXOR ||
|
||||
type === tt.bitwiseAND ||
|
||||
type === tt.equality ||
|
||||
type === tt.relational ||
|
||||
type === tt.bitShift ||
|
||||
type === tt.plusMin ||
|
||||
type === tt.modulo ||
|
||||
type === tt.exponent ||
|
||||
type === tt.bang ||
|
||||
type === tt.tilde ||
|
||||
type === tt.doubleColon ||
|
||||
type === tt.hash ||
|
||||
type.isAssign
|
||||
) {
|
||||
token.type = "Punctuator";
|
||||
if (!token.value) token.value = type.label;
|
||||
} else if (type === tt.jsxTagStart) {
|
||||
token.type = "Punctuator";
|
||||
token.value = "<";
|
||||
} else if (type === tt.jsxTagEnd) {
|
||||
token.type = "Punctuator";
|
||||
token.value = ">";
|
||||
} else if (type === tt.jsxName) {
|
||||
token.type = "JSXIdentifier";
|
||||
} else if (type === tt.jsxText) {
|
||||
token.type = "JSXText";
|
||||
} else if (type.keyword === "null") {
|
||||
token.type = "Null";
|
||||
} else if (type.keyword === "false" || type.keyword === "true") {
|
||||
token.type = "Boolean";
|
||||
} else if (type.keyword) {
|
||||
token.type = "Keyword";
|
||||
} else if (type === tt.num) {
|
||||
token.type = "Numeric";
|
||||
token.value = source.slice(token.start, token.end);
|
||||
} else if (type === tt.string) {
|
||||
token.type = "String";
|
||||
token.value = source.slice(token.start, token.end);
|
||||
} else if (type === tt.regexp) {
|
||||
token.type = "RegularExpression";
|
||||
const value = token.value;
|
||||
token.regex = {
|
||||
pattern: value.pattern,
|
||||
flags: value.flags,
|
||||
};
|
||||
token.value = `/${value.pattern}/${value.flags}`;
|
||||
} else if (type === tt.bigint) {
|
||||
token.type = "Numeric";
|
||||
token.value = `${token.value}n`;
|
||||
}
|
||||
|
||||
return token;
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
import convertTemplateType from "./convertTemplateType";
|
||||
import convertToken from "./convertToken";
|
||||
|
||||
export default function(tokens, code) {
|
||||
return convertTemplateType(tokens)
|
||||
.filter(t => t.type !== "CommentLine" && t.type !== "CommentBlock")
|
||||
.map(t => convertToken(t, code));
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
import convertTokens from "./convertTokens";
|
||||
import convertComments from "./convertComments";
|
||||
import convertAST from "./convertAST";
|
||||
|
||||
export default function(ast, code) {
|
||||
ast.tokens = convertTokens(ast.tokens, code);
|
||||
convertComments(ast.comments);
|
||||
convertAST(ast, code);
|
||||
}
|
||||
61
eslint/babel-eslint-parser/src/configuration.js
Normal file
61
eslint/babel-eslint-parser/src/configuration.js
Normal file
@ -0,0 +1,61 @@
|
||||
import { loadPartialConfig } from "@babel/core";
|
||||
|
||||
export function normalizeESLintConfig(options) {
|
||||
const defaultOptions = {
|
||||
babelOptions: {},
|
||||
ecmaVersion: 2020,
|
||||
sourceType: "module",
|
||||
allowImportExportEverywhere: false,
|
||||
};
|
||||
|
||||
return Object.assign(defaultOptions, options);
|
||||
}
|
||||
|
||||
export function normalizeBabelParseConfig(options) {
|
||||
const parseOptions = {
|
||||
sourceType: options.sourceType,
|
||||
filename: options.filePath,
|
||||
cwd: options.babelOptions.cwd,
|
||||
root: options.babelOptions.root,
|
||||
rootMode: options.babelOptions.rootMode,
|
||||
envName: options.babelOptions.envName,
|
||||
configFile: options.babelOptions.configFile,
|
||||
babelrc: options.babelOptions.babelrc,
|
||||
babelrcRoots: options.babelOptions.babelrcRoots,
|
||||
extends: options.babelOptions.extends,
|
||||
env: options.babelOptions.env,
|
||||
overrides: options.babelOptions.overrides,
|
||||
test: options.babelOptions.test,
|
||||
include: options.babelOptions.include,
|
||||
exclude: options.babelOptions.exclude,
|
||||
ignore: options.babelOptions.ignore,
|
||||
only: options.babelOptions.only,
|
||||
parserOpts: {
|
||||
allowImportExportEverywhere: options.allowImportExportEverywhere,
|
||||
allowReturnOutsideFunction: true,
|
||||
allowSuperOutsideMethod: true,
|
||||
ranges: true,
|
||||
tokens: true,
|
||||
plugins: ["estree"],
|
||||
},
|
||||
caller: {
|
||||
name: "@babel/eslint-parser",
|
||||
},
|
||||
};
|
||||
|
||||
if (options.requireConfigFile !== false) {
|
||||
const config = loadPartialConfig(parseOptions);
|
||||
|
||||
if (config !== null) {
|
||||
if (!config.hasFilesystemConfig()) {
|
||||
throw new Error(
|
||||
`No Babel config file detected for ${config.options.filename}. Either disable config file checking with requireConfigFile: false, or configure Babel so that it can find the config files.`,
|
||||
);
|
||||
}
|
||||
|
||||
return config.options;
|
||||
}
|
||||
}
|
||||
|
||||
return parseOptions;
|
||||
}
|
||||
26
eslint/babel-eslint-parser/src/index.js
Normal file
26
eslint/babel-eslint-parser/src/index.js
Normal file
@ -0,0 +1,26 @@
|
||||
import semver from "semver";
|
||||
import { version as CURRENT_BABEL_VERSION } from "@babel/core";
|
||||
import parseWithScope from "./parse-with-scope";
|
||||
import { normalizeESLintConfig } from "./configuration";
|
||||
import packageJson from "../package.json";
|
||||
|
||||
const SUPPORTED_BABEL_VERSION_RANGE =
|
||||
packageJson.peerDependencies["@babel/core"];
|
||||
const IS_RUNNING_SUPPORTED_VERSION = semver.satisfies(
|
||||
semver.coerce(CURRENT_BABEL_VERSION).raw,
|
||||
SUPPORTED_BABEL_VERSION_RANGE,
|
||||
);
|
||||
|
||||
export function parse(code, options) {
|
||||
return parseForESLint(code, options).ast;
|
||||
}
|
||||
|
||||
export function parseForESLint(code, options = {}) {
|
||||
if (!IS_RUNNING_SUPPORTED_VERSION) {
|
||||
throw new Error(
|
||||
`babel-eslint@${packageJson.version} does not support @babel/core@${CURRENT_BABEL_VERSION}. Please downgrade to babel-eslint@^10 or upgrade to @babel/core@${SUPPORTED_BABEL_VERSION_RANGE}`,
|
||||
);
|
||||
}
|
||||
|
||||
return parseWithScope(code, normalizeESLintConfig(options));
|
||||
}
|
||||
10
eslint/babel-eslint-parser/src/parse-with-scope.js
Normal file
10
eslint/babel-eslint-parser/src/parse-with-scope.js
Normal file
@ -0,0 +1,10 @@
|
||||
import visitorKeys from "./visitor-keys";
|
||||
import analyzeScope from "./analyze-scope";
|
||||
import parse from "./parse";
|
||||
|
||||
export default function(code, options) {
|
||||
const ast = parse(code, options);
|
||||
const scopeManager = analyzeScope(ast, options);
|
||||
|
||||
return { ast, scopeManager, visitorKeys };
|
||||
}
|
||||
23
eslint/babel-eslint-parser/src/parse.js
Normal file
23
eslint/babel-eslint-parser/src/parse.js
Normal file
@ -0,0 +1,23 @@
|
||||
import { parseSync as babelParse } from "@babel/core";
|
||||
import babylonToEspree from "./babylon-to-espree";
|
||||
import { normalizeBabelParseConfig } from "./configuration";
|
||||
|
||||
export default function parse(code, options) {
|
||||
const parseOptions = normalizeBabelParseConfig(options);
|
||||
let ast;
|
||||
|
||||
try {
|
||||
ast = babelParse(code, parseOptions);
|
||||
} catch (err) {
|
||||
if (err instanceof SyntaxError) {
|
||||
err.lineNumber = err.loc.line;
|
||||
err.column = err.loc.column;
|
||||
}
|
||||
|
||||
throw err;
|
||||
}
|
||||
|
||||
babylonToEspree(ast, code);
|
||||
|
||||
return ast;
|
||||
}
|
||||
15
eslint/babel-eslint-parser/src/visitor-keys.js
Normal file
15
eslint/babel-eslint-parser/src/visitor-keys.js
Normal file
@ -0,0 +1,15 @@
|
||||
import { types as t } from "@babel/core";
|
||||
import { KEYS as ESLINT_VISITOR_KEYS } from "eslint-visitor-keys";
|
||||
|
||||
const { VISITOR_KEYS: BABEL_VISITOR_KEYS } = t;
|
||||
|
||||
export default Object.assign(
|
||||
{
|
||||
Literal: ESLINT_VISITOR_KEYS.Literal,
|
||||
MethodDefinition: ["decorators"].concat(
|
||||
ESLINT_VISITOR_KEYS.MethodDefinition,
|
||||
),
|
||||
Property: ["decorators"].concat(ESLINT_VISITOR_KEYS.Property),
|
||||
},
|
||||
BABEL_VISITOR_KEYS,
|
||||
);
|
||||
535
eslint/babel-eslint-parser/test/babel-eslint-parser.js
Normal file
535
eslint/babel-eslint-parser/test/babel-eslint-parser.js
Normal file
@ -0,0 +1,535 @@
|
||||
import assert from "assert";
|
||||
import espree from "espree";
|
||||
import escope from "eslint-scope";
|
||||
import unpad from "dedent";
|
||||
import { parseForESLint } from "../src";
|
||||
import assertImplementsAST from "./helpers/assert-implements-ast";
|
||||
|
||||
const babelOptions = {
|
||||
configFile: require.resolve(
|
||||
"@babel/eslint-shared-fixtures/config/babel.config.js",
|
||||
),
|
||||
};
|
||||
|
||||
function parseAndAssertSame(code) {
|
||||
code = unpad(code);
|
||||
const esAST = espree.parse(code, {
|
||||
ecmaFeatures: {
|
||||
// enable JSX parsing
|
||||
jsx: true,
|
||||
// enable return in global scope
|
||||
globalReturn: true,
|
||||
// enable implied strict mode (if ecmaVersion >= 5)
|
||||
impliedStrict: true,
|
||||
// allow experimental object rest/spread
|
||||
experimentalObjectRestSpread: true,
|
||||
},
|
||||
tokens: true,
|
||||
loc: true,
|
||||
range: true,
|
||||
comment: true,
|
||||
ecmaVersion: 2020,
|
||||
sourceType: "module",
|
||||
});
|
||||
const babylonAST = parseForESLint(code, {
|
||||
eslintVisitorKeys: true,
|
||||
eslintScopeManager: true,
|
||||
babelOptions,
|
||||
}).ast;
|
||||
assertImplementsAST(esAST, babylonAST);
|
||||
}
|
||||
|
||||
describe("babylon-to-espree", () => {
|
||||
describe("compatibility", () => {
|
||||
it("should allow ast.analyze to be called without options", function() {
|
||||
const esAST = parseForESLint("`test`", {
|
||||
eslintScopeManager: true,
|
||||
eslintVisitorKeys: true,
|
||||
babelOptions,
|
||||
}).ast;
|
||||
expect(() => {
|
||||
escope.analyze(esAST);
|
||||
}).not.toThrow(new TypeError("Should allow no options argument."));
|
||||
});
|
||||
});
|
||||
|
||||
describe("templates", () => {
|
||||
it("empty template string", () => {
|
||||
parseAndAssertSame("``");
|
||||
});
|
||||
|
||||
it("template string", () => {
|
||||
parseAndAssertSame("`test`");
|
||||
});
|
||||
|
||||
it("template string using $", () => {
|
||||
parseAndAssertSame("`$`");
|
||||
});
|
||||
|
||||
it("template string with expression", () => {
|
||||
parseAndAssertSame("`${a}`");
|
||||
});
|
||||
|
||||
it("template string with multiple expressions", () => {
|
||||
parseAndAssertSame("`${a}${b}${c}`");
|
||||
});
|
||||
|
||||
it("template string with expression and strings", () => {
|
||||
parseAndAssertSame("`a${a}a`");
|
||||
});
|
||||
|
||||
it("template string with binary expression", () => {
|
||||
parseAndAssertSame("`a${a + b}a`");
|
||||
});
|
||||
|
||||
it("tagged template", () => {
|
||||
parseAndAssertSame("jsx`<Button>Click</Button>`");
|
||||
});
|
||||
|
||||
it("tagged template with expression", () => {
|
||||
parseAndAssertSame("jsx`<Button>Hi ${name}</Button>`");
|
||||
});
|
||||
|
||||
it("tagged template with new operator", () => {
|
||||
parseAndAssertSame("new raw`42`");
|
||||
});
|
||||
|
||||
it("template with nested function/object", () => {
|
||||
parseAndAssertSame(
|
||||
"`outer${{x: {y: 10}}}bar${`nested${function(){return 1;}}endnest`}end`",
|
||||
);
|
||||
});
|
||||
|
||||
it("template with braces inside and outside of template string #96", () => {
|
||||
parseAndAssertSame(
|
||||
"if (a) { var target = `{}a:${webpackPort}{}}}}`; } else { app.use(); }",
|
||||
);
|
||||
});
|
||||
|
||||
it("template also with braces #96", () => {
|
||||
parseAndAssertSame(`
|
||||
export default function f1() {
|
||||
function f2(foo) {
|
||||
const bar = 3;
|
||||
return \`\${foo} \${bar}\`;
|
||||
}
|
||||
return f2;
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
it("template with destructuring #31", () => {
|
||||
parseAndAssertSame(`
|
||||
module.exports = {
|
||||
render() {
|
||||
var {name} = this.props;
|
||||
return Math.max(null, \`Name: \${name}, Name: \${name}\`);
|
||||
}
|
||||
};
|
||||
`);
|
||||
});
|
||||
|
||||
it("template with arrow returning template #603", () => {
|
||||
parseAndAssertSame(`
|
||||
var a = \`\${() => {
|
||||
\`\${''}\`
|
||||
}}\`;
|
||||
`);
|
||||
});
|
||||
|
||||
it("template string with object with template string inside", () => {
|
||||
parseAndAssertSame("`${ { a:`${2}` } }`");
|
||||
});
|
||||
});
|
||||
|
||||
it("simple expression", () => {
|
||||
parseAndAssertSame("a = 1");
|
||||
});
|
||||
|
||||
it("logical NOT", () => {
|
||||
parseAndAssertSame("!0");
|
||||
});
|
||||
|
||||
it("bitwise NOT", () => {
|
||||
parseAndAssertSame("~0");
|
||||
});
|
||||
|
||||
it("class declaration", () => {
|
||||
parseAndAssertSame("class Foo {}");
|
||||
});
|
||||
|
||||
it("class expression", () => {
|
||||
parseAndAssertSame("var a = class Foo {}");
|
||||
});
|
||||
|
||||
it("jsx expression", () => {
|
||||
parseAndAssertSame("<App />");
|
||||
});
|
||||
|
||||
it("jsx expression with 'this' as identifier", () => {
|
||||
parseAndAssertSame("<this />");
|
||||
});
|
||||
|
||||
it("jsx expression with a dynamic attribute", () => {
|
||||
parseAndAssertSame("<App foo={bar} />");
|
||||
});
|
||||
|
||||
it("jsx expression with a member expression as identifier", () => {
|
||||
parseAndAssertSame("<foo.bar />");
|
||||
});
|
||||
|
||||
it("jsx expression with spread", () => {
|
||||
parseAndAssertSame("var myDivElement = <div {...this.props} />;");
|
||||
});
|
||||
|
||||
it("empty jsx text", () => {
|
||||
parseAndAssertSame("<a></a>");
|
||||
});
|
||||
|
||||
it("jsx text with content", () => {
|
||||
parseAndAssertSame("<a>Hello, world!</a>");
|
||||
});
|
||||
|
||||
it("nested jsx", () => {
|
||||
parseAndAssertSame("<div>\n<h1>Wat</h1>\n</div>");
|
||||
});
|
||||
|
||||
it("default import", () => {
|
||||
parseAndAssertSame('import foo from "foo";');
|
||||
});
|
||||
|
||||
it("import specifier", () => {
|
||||
parseAndAssertSame('import { foo } from "foo";');
|
||||
});
|
||||
|
||||
it("import specifier with name", () => {
|
||||
parseAndAssertSame('import { foo as bar } from "foo";');
|
||||
});
|
||||
|
||||
it("import bare", () => {
|
||||
parseAndAssertSame('import "foo";');
|
||||
});
|
||||
|
||||
it("export default class declaration", () => {
|
||||
parseAndAssertSame("export default class Foo {}");
|
||||
});
|
||||
|
||||
it("export default class expression", () => {
|
||||
parseAndAssertSame("export default class {}");
|
||||
});
|
||||
|
||||
it("export default function declaration", () => {
|
||||
parseAndAssertSame("export default function Foo() {}");
|
||||
});
|
||||
|
||||
it("export default function expression", () => {
|
||||
parseAndAssertSame("export default function () {}");
|
||||
});
|
||||
|
||||
it("export all", () => {
|
||||
parseAndAssertSame('export * from "foo";');
|
||||
});
|
||||
|
||||
it("export named", () => {
|
||||
parseAndAssertSame("var foo = 1;export { foo };");
|
||||
});
|
||||
|
||||
it("export named alias", () => {
|
||||
parseAndAssertSame("var foo = 1;export { foo as bar };");
|
||||
});
|
||||
|
||||
// Espree doesn't support the optional chaining operator yet
|
||||
it("optional chaining operator (token)", () => {
|
||||
const code = "foo?.bar";
|
||||
const babylonAST = parseForESLint(code, {
|
||||
eslintVisitorKeys: true,
|
||||
eslintScopeManager: true,
|
||||
babelOptions,
|
||||
}).ast;
|
||||
assert.strictEqual(babylonAST.tokens[1].type, "Punctuator");
|
||||
});
|
||||
|
||||
// Espree doesn't support the nullish coalescing operator yet
|
||||
it("nullish coalescing operator (token)", () => {
|
||||
const code = "foo ?? bar";
|
||||
const babylonAST = parseForESLint(code, {
|
||||
eslintVisitorKeys: true,
|
||||
eslintScopeManager: true,
|
||||
babelOptions,
|
||||
}).ast;
|
||||
assert.strictEqual(babylonAST.tokens[1].type, "Punctuator");
|
||||
});
|
||||
|
||||
// Espree doesn't support the pipeline operator yet
|
||||
it("pipeline operator (token)", () => {
|
||||
const code = "foo |> bar";
|
||||
const babylonAST = parseForESLint(code, {
|
||||
eslintVisitorKeys: true,
|
||||
eslintScopeManager: true,
|
||||
babelOptions,
|
||||
}).ast;
|
||||
assert.strictEqual(babylonAST.tokens[1].type, "Punctuator");
|
||||
});
|
||||
|
||||
// Espree doesn't support private fields yet
|
||||
it("hash (token)", () => {
|
||||
const code = "class A { #x }";
|
||||
const babylonAST = parseForESLint(code, {
|
||||
eslintVisitorKeys: true,
|
||||
eslintScopeManager: true,
|
||||
babelOptions,
|
||||
}).ast;
|
||||
assert.strictEqual(babylonAST.tokens[3].type, "Punctuator");
|
||||
assert.strictEqual(babylonAST.tokens[3].value, "#");
|
||||
});
|
||||
|
||||
it.skip("empty program with line comment", () => {
|
||||
parseAndAssertSame("// single comment");
|
||||
});
|
||||
|
||||
it.skip("empty program with block comment", () => {
|
||||
parseAndAssertSame(" /* multiline\n * comment\n*/");
|
||||
});
|
||||
|
||||
it("line comments", () => {
|
||||
parseAndAssertSame(`
|
||||
// single comment
|
||||
var foo = 15; // comment next to statement
|
||||
// second comment after statement
|
||||
`);
|
||||
});
|
||||
|
||||
it("block comments", () => {
|
||||
parseAndAssertSame(`
|
||||
/* single comment */
|
||||
var foo = 15; /* comment next to statement */
|
||||
/*
|
||||
* multiline
|
||||
* comment
|
||||
*/
|
||||
`);
|
||||
});
|
||||
|
||||
it("block comments #124", () => {
|
||||
parseAndAssertSame(`
|
||||
React.createClass({
|
||||
render() {
|
||||
// return (
|
||||
// <div />
|
||||
// ); // <-- this is the line that is reported
|
||||
}
|
||||
});
|
||||
`);
|
||||
});
|
||||
|
||||
it("null", () => {
|
||||
parseAndAssertSame("null");
|
||||
});
|
||||
|
||||
it("boolean", () => {
|
||||
parseAndAssertSame("if (true) {} else if (false) {}");
|
||||
});
|
||||
|
||||
it("regexp", () => {
|
||||
parseAndAssertSame("/affix-top|affix-bottom|affix|[a-z]/");
|
||||
});
|
||||
|
||||
it("regexp", () => {
|
||||
parseAndAssertSame("const foo = /foo/;");
|
||||
});
|
||||
|
||||
it("regexp y flag", () => {
|
||||
parseAndAssertSame("const foo = /foo/y;");
|
||||
});
|
||||
|
||||
it("regexp u flag", () => {
|
||||
parseAndAssertSame("const foo = /foo/u;");
|
||||
});
|
||||
|
||||
it("regexp in a template string", () => {
|
||||
parseAndAssertSame('`${/\\d/.exec("1")[0]}`');
|
||||
});
|
||||
|
||||
it("first line is empty", () => {
|
||||
parseAndAssertSame('\nimport Immutable from "immutable";');
|
||||
});
|
||||
|
||||
it("empty", () => {
|
||||
parseAndAssertSame("");
|
||||
});
|
||||
|
||||
it("jsdoc", () => {
|
||||
parseAndAssertSame(`
|
||||
/**
|
||||
* @param {object} options
|
||||
* @return {number}
|
||||
*/
|
||||
const test = function({ a, b, c }) {
|
||||
return a + b + c;
|
||||
};
|
||||
module.exports = test;
|
||||
`);
|
||||
});
|
||||
|
||||
it("empty block with comment", () => {
|
||||
parseAndAssertSame(`
|
||||
function a () {
|
||||
try {
|
||||
b();
|
||||
} catch (e) {
|
||||
// asdf
|
||||
}
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
describe("babel tests", () => {
|
||||
it("MethodDefinition", () => {
|
||||
parseAndAssertSame(`
|
||||
export default class A {
|
||||
a() {}
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
it("MethodDefinition 2", () => {
|
||||
parseAndAssertSame(
|
||||
"export default class Bar { get bar() { return 42; }}",
|
||||
);
|
||||
});
|
||||
|
||||
it("ClassMethod", () => {
|
||||
parseAndAssertSame(`
|
||||
class A {
|
||||
constructor() {
|
||||
}
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
it("ClassMethod multiple params", () => {
|
||||
parseAndAssertSame(`
|
||||
class A {
|
||||
constructor(a, b, c) {
|
||||
}
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
it("ClassMethod multiline", () => {
|
||||
parseAndAssertSame(`
|
||||
class A {
|
||||
constructor (
|
||||
a,
|
||||
b,
|
||||
c
|
||||
)
|
||||
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
it("ClassMethod oneline", () => {
|
||||
parseAndAssertSame("class A { constructor(a, b, c) {} }");
|
||||
});
|
||||
|
||||
it("ObjectMethod", () => {
|
||||
parseAndAssertSame(`
|
||||
var a = {
|
||||
b(c) {
|
||||
}
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
it("do not allow import export everywhere", () => {
|
||||
assert.throws(() => {
|
||||
parseAndAssertSame('function F() { import a from "a"; }');
|
||||
}, /SyntaxError: 'import' and 'export' may only appear at the top level/);
|
||||
});
|
||||
|
||||
it("return outside function", () => {
|
||||
parseAndAssertSame("return;");
|
||||
});
|
||||
|
||||
it("super outside method", () => {
|
||||
assert.throws(() => {
|
||||
parseAndAssertSame("function F() { super(); }");
|
||||
}, /SyntaxError: 'super' keyword outside a method/);
|
||||
});
|
||||
|
||||
it("StringLiteral", () => {
|
||||
parseAndAssertSame("");
|
||||
parseAndAssertSame("");
|
||||
parseAndAssertSame("a");
|
||||
});
|
||||
|
||||
it("getters and setters", () => {
|
||||
parseAndAssertSame("class A { get x ( ) { ; } }");
|
||||
parseAndAssertSame(`
|
||||
class A {
|
||||
get x(
|
||||
)
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
`);
|
||||
parseAndAssertSame("class A { set x (a) { ; } }");
|
||||
parseAndAssertSame(`
|
||||
class A {
|
||||
set x(a
|
||||
)
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
`);
|
||||
parseAndAssertSame(`
|
||||
var B = {
|
||||
get x () {
|
||||
return this.ecks;
|
||||
},
|
||||
set x (ecks) {
|
||||
this.ecks = ecks;
|
||||
}
|
||||
};
|
||||
`);
|
||||
});
|
||||
|
||||
it("RestOperator", () => {
|
||||
parseAndAssertSame("var { a, ...b } = c");
|
||||
parseAndAssertSame("var [ a, ...b ] = c");
|
||||
parseAndAssertSame("var a = function (...b) {}");
|
||||
});
|
||||
|
||||
it("SpreadOperator", () => {
|
||||
parseAndAssertSame("var a = { b, ...c }");
|
||||
parseAndAssertSame("var a = [ a, ...b ]");
|
||||
parseAndAssertSame("var a = sum(...b)");
|
||||
});
|
||||
|
||||
it("Async/Await", () => {
|
||||
parseAndAssertSame(`
|
||||
async function a() {
|
||||
await 1;
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
it("BigInt", () => {
|
||||
parseAndAssertSame(`
|
||||
const a = 1n;
|
||||
`);
|
||||
});
|
||||
|
||||
it("Dynamic Import", () => {
|
||||
parseAndAssertSame(`
|
||||
const a = import('a');
|
||||
`);
|
||||
});
|
||||
});
|
||||
});
|
||||
11
eslint/babel-eslint-parser/test/fixtures/eslint-plugin-import/.eslintrc.yml
vendored
Normal file
11
eslint/babel-eslint-parser/test/fixtures/eslint-plugin-import/.eslintrc.yml
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
root: true
|
||||
|
||||
# babel-eslint
|
||||
parser: ../../../lib/index.js
|
||||
|
||||
# use eslint-plugin-import
|
||||
plugins:
|
||||
- import
|
||||
rules:
|
||||
import/no-named-as-default: error
|
||||
no-unused-vars: error
|
||||
1
eslint/babel-eslint-parser/test/fixtures/eslint-plugin-import/a.js
vendored
Normal file
1
eslint/babel-eslint-parser/test/fixtures/eslint-plugin-import/a.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
export default function foo() { }
|
||||
1
eslint/babel-eslint-parser/test/fixtures/eslint-plugin-import/b.js
vendored
Normal file
1
eslint/babel-eslint-parser/test/fixtures/eslint-plugin-import/b.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
import foo from './a.js';
|
||||
4
eslint/babel-eslint-parser/test/fixtures/eslint-plugin-import/c.js
vendored
Normal file
4
eslint/babel-eslint-parser/test/fixtures/eslint-plugin-import/c.js
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
// @flow
|
||||
type Foo = {};
|
||||
|
||||
const FlowTypeButton = ({ }: Foo) => { };
|
||||
3
eslint/babel-eslint-parser/test/fixtures/rules/strict/function-with.js
vendored
Normal file
3
eslint/babel-eslint-parser/test/fixtures/rules/strict/function-with.js
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
function x () {
|
||||
"use strict";
|
||||
}
|
||||
1
eslint/babel-eslint-parser/test/fixtures/rules/strict/function-without.js
vendored
Normal file
1
eslint/babel-eslint-parser/test/fixtures/rules/strict/function-without.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
function x () {}
|
||||
5
eslint/babel-eslint-parser/test/fixtures/rules/strict/global-with-function-with.js
vendored
Normal file
5
eslint/babel-eslint-parser/test/fixtures/rules/strict/global-with-function-with.js
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
function x () {
|
||||
"use strict";
|
||||
}
|
||||
3
eslint/babel-eslint-parser/test/fixtures/rules/strict/global-with-function-without.js
vendored
Normal file
3
eslint/babel-eslint-parser/test/fixtures/rules/strict/global-with-function-without.js
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
function x () {}
|
||||
6
eslint/babel-eslint-parser/test/fixtures/rules/strict/global-with.js
vendored
Normal file
6
eslint/babel-eslint-parser/test/fixtures/rules/strict/global-with.js
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
"use strict";
|
||||
/*
|
||||
The empty statement is intentional. As of now, ESLint won't enforce
|
||||
string: [2, "global"] on a program with an empty body. A test for that without
|
||||
massaging the AST to ESlint's input format should fail.
|
||||
*/
|
||||
1
eslint/babel-eslint-parser/test/fixtures/rules/strict/none.js
vendored
Normal file
1
eslint/babel-eslint-parser/test/fixtures/rules/strict/none.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
"no use strict anywhere";
|
||||
6
eslint/babel-eslint-parser/test/fixtures/rules/syntax-error.js
vendored
Normal file
6
eslint/babel-eslint-parser/test/fixtures/rules/syntax-error.js
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
class ClassName {
|
||||
constructor() {
|
||||
|
||||
},
|
||||
aMethod() {}
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
// Checks if the source ast implements the target ast. Ignores extra keys on source ast
|
||||
export default function assertImplementsAST(target, source, path) {
|
||||
if (!path) {
|
||||
path = [];
|
||||
}
|
||||
|
||||
function error(text) {
|
||||
const err = new Error(`At ${path.join(".")}: ${text}:`);
|
||||
err.depth = path.length + 1;
|
||||
throw err;
|
||||
}
|
||||
|
||||
const typeA = target === null ? "null" : typeof target;
|
||||
const typeB = source === null ? "null" : typeof source;
|
||||
if (typeA !== typeB) {
|
||||
error(
|
||||
`have different types (${typeA} !== ${typeB}) (${target} !== ${source})`,
|
||||
);
|
||||
} else if (
|
||||
typeA === "object" &&
|
||||
["RegExp"].indexOf(target.constructor.name) !== -1 &&
|
||||
target.constructor.name !== source.constructor.name
|
||||
) {
|
||||
error(
|
||||
`object have different constructors (${target.constructor.name} !== ${source.constructor.name}`,
|
||||
);
|
||||
} else if (typeA === "object") {
|
||||
const keysTarget = Object.keys(target);
|
||||
for (const i in keysTarget) {
|
||||
const key = keysTarget[i];
|
||||
path.push(key);
|
||||
assertImplementsAST(target[key], source[key], path);
|
||||
path.pop();
|
||||
}
|
||||
} else if (target !== source) {
|
||||
error(
|
||||
`are different (${JSON.stringify(target)} !== ${JSON.stringify(source)})`,
|
||||
);
|
||||
}
|
||||
}
|
||||
237
eslint/babel-eslint-parser/test/integration.js
Normal file
237
eslint/babel-eslint-parser/test/integration.js
Normal file
@ -0,0 +1,237 @@
|
||||
import eslint from "eslint";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import * as parser from "../src";
|
||||
|
||||
eslint.linter.defineParser("current-babel-eslint", parser);
|
||||
|
||||
const paths = {
|
||||
fixtures: path.join(__dirname, "fixtures", "rules"),
|
||||
};
|
||||
|
||||
const encoding = "utf8";
|
||||
const errorLevel = 2;
|
||||
|
||||
const baseEslintOpts = {
|
||||
parser: "current-babel-eslint",
|
||||
parserOptions: {
|
||||
sourceType: "script",
|
||||
requireConfigFile: false,
|
||||
babelOptions: { configFile: false }
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Load a fixture and run eslint.linter.verify() on it.
|
||||
* Pass the return value to done().
|
||||
* @param object opts
|
||||
* @param function done
|
||||
*/
|
||||
function lint(opts, done) {
|
||||
readFixture(opts.fixture, (err, src) => {
|
||||
if (err) return done(err);
|
||||
done(null, eslint.linter.verify(src, opts.eslint));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a fixture file, passing the content to done().
|
||||
* @param string|array id
|
||||
* @param function done
|
||||
*/
|
||||
function readFixture(id, done) {
|
||||
if (Array.isArray(id)) id = path.join.apply(path, id);
|
||||
if (!path.extname(id)) id += ".js";
|
||||
fs.readFile(path.join(paths.fixtures, id), encoding, done);
|
||||
}
|
||||
// readFixture
|
||||
|
||||
describe("Rules:", () => {
|
||||
describe("`strict`", strictSuite);
|
||||
});
|
||||
// describe
|
||||
|
||||
function strictSuite() {
|
||||
const ruleId = "strict";
|
||||
|
||||
describe("when set to 'never'", () => {
|
||||
const eslintOpts = Object.assign({}, baseEslintOpts, {
|
||||
rules: {},
|
||||
});
|
||||
eslintOpts.rules[ruleId] = [errorLevel, "never"];
|
||||
|
||||
["global-with", "function-with"].forEach(fixture => {
|
||||
it(`should error on ${fixture.match(/^[^-]+/)[0]} directive`, done => {
|
||||
lint(
|
||||
{
|
||||
fixture: ["strict", fixture],
|
||||
eslint: eslintOpts,
|
||||
},
|
||||
(err, report) => {
|
||||
if (err) return done(err);
|
||||
expect(report[0].ruleId).toBe(ruleId);
|
||||
done();
|
||||
},
|
||||
);
|
||||
});
|
||||
// it
|
||||
});
|
||||
});
|
||||
// describe
|
||||
|
||||
describe("when set to 'global'", () => {
|
||||
const eslintOpts = Object.assign({}, baseEslintOpts, {
|
||||
rules: {},
|
||||
});
|
||||
eslintOpts.rules[ruleId] = [errorLevel, "global"];
|
||||
|
||||
it("shouldn't error on single global directive", done => {
|
||||
lint(
|
||||
{
|
||||
fixture: ["strict", "global-with"],
|
||||
eslint: eslintOpts,
|
||||
},
|
||||
(err, report) => {
|
||||
if (err) return done(err);
|
||||
expect(report.length).toBe(0);
|
||||
done();
|
||||
},
|
||||
);
|
||||
});
|
||||
// it
|
||||
|
||||
it("should error twice on global directive: no and function directive: yes", done => {
|
||||
lint(
|
||||
{
|
||||
fixture: ["strict", "function-with"],
|
||||
eslint: eslintOpts,
|
||||
},
|
||||
(err, report) => {
|
||||
if (err) return done(err);
|
||||
[0, 1].forEach(i => {
|
||||
expect(report[0].ruleId).toBe(ruleId);
|
||||
});
|
||||
done();
|
||||
},
|
||||
);
|
||||
});
|
||||
// it
|
||||
|
||||
it("should error on function directive", done => {
|
||||
lint(
|
||||
{
|
||||
fixture: ["strict", "global-with-function-with"],
|
||||
eslint: eslintOpts,
|
||||
},
|
||||
(err, report) => {
|
||||
if (err) return done(err);
|
||||
expect(report[0].ruleId).toBe(ruleId);
|
||||
// This is to make sure the test fails prior to adapting Babel AST
|
||||
// directive representation to ESLint format. Otherwise it reports an
|
||||
// error for missing global directive that masquerades as the expected
|
||||
// result of the previous assertion.
|
||||
expect(report[0].nodeType).not.toBe("Program");
|
||||
done();
|
||||
},
|
||||
);
|
||||
});
|
||||
// it
|
||||
|
||||
it("should error on no directive", done => {
|
||||
lint(
|
||||
{
|
||||
fixture: ["strict", "none"],
|
||||
eslint: eslintOpts,
|
||||
},
|
||||
(err, report) => {
|
||||
if (err) return done(err);
|
||||
expect(report[0].ruleId).toBe(ruleId);
|
||||
done();
|
||||
},
|
||||
);
|
||||
});
|
||||
// it
|
||||
});
|
||||
// describe
|
||||
|
||||
describe("when set to 'function'", () => {
|
||||
const eslintOpts = Object.assign({}, baseEslintOpts, {
|
||||
rules: {},
|
||||
});
|
||||
eslintOpts.rules[ruleId] = [errorLevel, "function"];
|
||||
|
||||
it("shouldn't error on single function directive", done => {
|
||||
lint(
|
||||
{
|
||||
fixture: ["strict", "function-with"],
|
||||
eslint: eslintOpts,
|
||||
},
|
||||
(err, report) => {
|
||||
if (err) return done(err);
|
||||
expect(report.length).toBe(0);
|
||||
done();
|
||||
},
|
||||
);
|
||||
});
|
||||
// it
|
||||
|
||||
it("should error twice on function directive: no and global directive: yes", done => {
|
||||
lint(
|
||||
{
|
||||
fixture: ["strict", "global-with-function-without"],
|
||||
eslint: eslintOpts,
|
||||
},
|
||||
(err, report) => {
|
||||
if (err) return done(err);
|
||||
[0, 1].forEach(i => {
|
||||
expect(report[i].ruleId).toBe(ruleId);
|
||||
});
|
||||
done();
|
||||
},
|
||||
);
|
||||
});
|
||||
// it
|
||||
|
||||
it("should error on only global directive", done => {
|
||||
lint(
|
||||
{
|
||||
fixture: ["strict", "global-with"],
|
||||
eslint: eslintOpts,
|
||||
},
|
||||
(err, report) => {
|
||||
if (err) return done(err);
|
||||
expect(report[0].ruleId).toBe(ruleId);
|
||||
done();
|
||||
},
|
||||
);
|
||||
});
|
||||
// it
|
||||
|
||||
it("should error on extraneous global directive", done => {
|
||||
lint(
|
||||
{
|
||||
fixture: ["strict", "global-with-function-with"],
|
||||
eslint: eslintOpts,
|
||||
},
|
||||
(err, report) => {
|
||||
if (err) return done(err);
|
||||
expect(report[0].ruleId).toBe(ruleId);
|
||||
expect(report[0].nodeType.indexOf("Function")).toBe(-1);
|
||||
done();
|
||||
},
|
||||
);
|
||||
});
|
||||
// it
|
||||
});
|
||||
}
|
||||
|
||||
describe("https://github.com/babel/babel-eslint/issues/558", () => {
|
||||
it("doesn't crash with eslint-plugin-import", () => {
|
||||
const engine = new eslint.CLIEngine({ ignore: false });
|
||||
const files = ["a.js", "b.js", "c.js"];
|
||||
let fileWithPath = files.map(file =>
|
||||
path.resolve(__dirname, `./fixtures/eslint-plugin-import/${file}`),
|
||||
);
|
||||
engine.executeOnFiles(fileWithPath);
|
||||
});
|
||||
});
|
||||
1955
eslint/babel-eslint-parser/test/non-regression.js
Normal file
1955
eslint/babel-eslint-parser/test/non-regression.js
Normal file
File diff suppressed because it is too large
Load Diff
4
eslint/babel-eslint-plugin-development/.npmignore
Normal file
4
eslint/babel-eslint-plugin-development/.npmignore
Normal file
@ -0,0 +1,4 @@
|
||||
src
|
||||
test
|
||||
.*
|
||||
*.log
|
||||
38
eslint/babel-eslint-plugin-development/README.md
Normal file
38
eslint/babel-eslint-plugin-development/README.md
Normal file
@ -0,0 +1,38 @@
|
||||
# @babel/eslint-plugin-development
|
||||
|
||||
A set of eslint rules to enforce best practices in the development of Babel plugins.
|
||||
|
||||
## Installation
|
||||
|
||||
You'll first need to install [ESLint](http://eslint.org):
|
||||
|
||||
```
|
||||
$ npm install --save-dev eslint
|
||||
```
|
||||
|
||||
Next, install `@babel/eslint-plugin-development`:
|
||||
|
||||
```
|
||||
$ npm install --save-dev @babel/eslint-plugin-development
|
||||
```
|
||||
|
||||
Then, load the plugin in your `.eslintrc` configuration file. You can omit the `eslint-plugin-` prefix:
|
||||
|
||||
```json
|
||||
{
|
||||
"plugins": ["@babel/development"]
|
||||
}
|
||||
```
|
||||
|
||||
## Supported Rules
|
||||
|
||||
> Note: Rules marked with :wrench: are autofixable.
|
||||
|
||||
* `@babel/development/no-deprecated-clone` (:wrench:): Disallows using the deprecated
|
||||
`t.clone(node)` and `t.cloneDeep(node)` methods from `@babel/types`. Those
|
||||
calls are replaced with `t.cloneNode(node)` when using `eslint --fix`.
|
||||
* `@babel/development/no-undefined-identifier`: Disallows using
|
||||
`t.identifier("undefined")` to create a node which represents an `undefined`
|
||||
value, since it might cause problem if `undefined` is redeclared.
|
||||
* `@babel/development/plugin-name`: Requires plugins to have a `name` property, which
|
||||
can be useful for debugging purposes.
|
||||
36
eslint/babel-eslint-plugin-development/package.json
Normal file
36
eslint/babel-eslint-plugin-development/package.json
Normal file
@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "@babel/eslint-plugin-development",
|
||||
"version": "7.8.3-csx.2",
|
||||
"description": "ESLint rules that enforce best practices in the development of Babel plugins.",
|
||||
"private": true,
|
||||
"keywords": [
|
||||
"eslint",
|
||||
"eslintplugin",
|
||||
"eslint-plugin"
|
||||
],
|
||||
"author": {
|
||||
"name": "Nicolò Ribaudo",
|
||||
"email": "nicolo.ribaudo@gmail.com",
|
||||
"url": "https://github.com/nicolo-ribaudo"
|
||||
},
|
||||
"main": "lib/index.js",
|
||||
"devDependencies": {
|
||||
"eslint": "^5.9.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.9"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/babel/babel.git",
|
||||
"directory": "eslint/babel-eslint-plugin-development"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/babel/babel/issues"
|
||||
},
|
||||
"homepage": "https://github.com/babel/babel/tree/master/eslint/babel-eslint-plugin-development"
|
||||
}
|
||||
11
eslint/babel-eslint-plugin-development/src/index.js
Normal file
11
eslint/babel-eslint-plugin-development/src/index.js
Normal file
@ -0,0 +1,11 @@
|
||||
import noDeprecatedClone from "./rules/no-deprecated-clone";
|
||||
import noUndefinedIdentifier from "./rules/no-undefined-identifier";
|
||||
import pluginName from "./rules/plugin-name";
|
||||
|
||||
export default {
|
||||
rules: {
|
||||
"no-deprecated-clone": noDeprecatedClone,
|
||||
"no-undefined-identifier": noUndefinedIdentifier,
|
||||
"plugin-name": pluginName,
|
||||
},
|
||||
};
|
||||
@ -0,0 +1,39 @@
|
||||
import getReferenceOrigin from "../utils/get-reference-origin";
|
||||
import isFromBabelTypes from "../utils/is-from-babel-types";
|
||||
|
||||
export default {
|
||||
meta: {
|
||||
schema: [],
|
||||
fixable: "code",
|
||||
},
|
||||
create(context) {
|
||||
return {
|
||||
CallExpression(node) {
|
||||
const { callee } = node;
|
||||
const scope = context.getScope();
|
||||
|
||||
const origin = getReferenceOrigin(callee, scope);
|
||||
if (!origin) return;
|
||||
|
||||
const { name } = origin;
|
||||
if (
|
||||
(name === "clone" || name === "cloneDeep") &&
|
||||
isFromBabelTypes(origin, scope)
|
||||
) {
|
||||
const isMemberExpression = callee.type === "MemberExpression";
|
||||
const id = isMemberExpression ? callee.property : callee;
|
||||
|
||||
context.report({
|
||||
node: id,
|
||||
message: `t.${name}() is deprecated. Use t.cloneNode() instead.`,
|
||||
fix(fixer) {
|
||||
if (isMemberExpression) {
|
||||
return fixer.replaceText(id, "cloneNode");
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
@ -0,0 +1,39 @@
|
||||
import getReferenceOrigin from "../utils/get-reference-origin";
|
||||
import isFromBabelTypes from "../utils/is-from-babel-types";
|
||||
|
||||
function firstArgumentIsUndefinedString(argumentsArray) {
|
||||
return (
|
||||
argumentsArray.length > 0 &&
|
||||
argumentsArray[0].type === "Literal" &&
|
||||
argumentsArray[0].value === "undefined"
|
||||
);
|
||||
}
|
||||
|
||||
export default {
|
||||
meta: {
|
||||
schema: [],
|
||||
},
|
||||
create(context) {
|
||||
return {
|
||||
CallExpression(node) {
|
||||
const { callee } = node;
|
||||
const scope = context.getScope();
|
||||
|
||||
const origin = getReferenceOrigin(callee, scope);
|
||||
if (!origin) return;
|
||||
|
||||
const { name } = origin;
|
||||
if (
|
||||
(name === "identifier" || name === "Identifier") &&
|
||||
firstArgumentIsUndefinedString(node.arguments) &&
|
||||
isFromBabelTypes(origin, scope)
|
||||
) {
|
||||
context.report(
|
||||
node,
|
||||
"Use path.scope.buildUndefinedNode() to create an undefined identifier directly.",
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
@ -0,0 +1,50 @@
|
||||
import isBabelPluginFactory from "../utils/is-babel-plugin-factory";
|
||||
|
||||
function getReturnValue(node) {
|
||||
const { body } = node;
|
||||
|
||||
if (body.type === "BlockStatement") {
|
||||
const returnNode = body.body.find(n => n.type === "ReturnStatement");
|
||||
return returnNode && returnNode.argument;
|
||||
}
|
||||
|
||||
// Arrow functions with implicit return
|
||||
return body;
|
||||
}
|
||||
|
||||
export default {
|
||||
meta: {
|
||||
schema: [],
|
||||
},
|
||||
create(context /*: Context */) {
|
||||
let pluginFound = false;
|
||||
|
||||
return {
|
||||
FunctionDeclaration: functionVisitor,
|
||||
FunctionExpression: functionVisitor,
|
||||
ArrowFunctionExpression: functionVisitor,
|
||||
|
||||
"Program:exit"(node) {
|
||||
if (!pluginFound) {
|
||||
context.report(node, "This file does not export a Babel plugin.");
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
function functionVisitor(node) {
|
||||
if (!isBabelPluginFactory(node, context.getScope())) return;
|
||||
|
||||
const returnValue = getReturnValue(node);
|
||||
if (!returnValue || returnValue.type !== "ObjectExpression") return;
|
||||
|
||||
pluginFound = true;
|
||||
|
||||
if (!returnValue.properties.some(p => p.key.name === "name")) {
|
||||
context.report(
|
||||
returnValue,
|
||||
"This Babel plugin doesn't have a 'name' property.",
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
@ -0,0 +1,22 @@
|
||||
export default function getExportName(node) {
|
||||
const { parent } = node;
|
||||
|
||||
if (parent.type === "ExportDefaultDeclaration") {
|
||||
return "default";
|
||||
}
|
||||
|
||||
if (parent.type === "ExportNamedDeclaration") {
|
||||
return node.id.name;
|
||||
}
|
||||
|
||||
if (
|
||||
parent.type === "AssignmentExpression" &&
|
||||
parent.left.type === "MemberExpression" &&
|
||||
parent.left.object.type === "Identifier" &&
|
||||
parent.left.object.name === "module" &&
|
||||
parent.left.property.type === "Identifier" &&
|
||||
parent.left.property.name === "exports"
|
||||
) {
|
||||
return "module.exports";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,141 @@
|
||||
/*::
|
||||
type ReferenceOriginImport = { kind: "import", source: string, name: string };
|
||||
type ReferenceOriginParam = {
|
||||
kind: "param",
|
||||
index: number,
|
||||
functionNode: Node,
|
||||
};
|
||||
|
||||
type ReferenceOrigin =
|
||||
| ReferenceOriginImport
|
||||
| ReferenceOriginParam
|
||||
| { kind: "import *", source: string }
|
||||
| {
|
||||
kind: "property",
|
||||
base: ReferenceOriginImport | ReferenceOriginParam,
|
||||
path: string,
|
||||
name: string,
|
||||
};
|
||||
*/
|
||||
|
||||
// Given a node and a context, returns a description of where its value comes
|
||||
// from.
|
||||
// It resolves imports, parameters of exported functions and property accesses.
|
||||
// See the ReferenceOrigin type for more informations.
|
||||
export default function getReferenceOrigin(
|
||||
node,
|
||||
scope,
|
||||
) /*: ?ReferenceOrigin */ {
|
||||
if (node.type === "Identifier") {
|
||||
const variable = getVariableDefinition(node.name, scope);
|
||||
if (!variable) return null;
|
||||
|
||||
const definition = variable.definition;
|
||||
const defNode = definition.node;
|
||||
|
||||
if (definition.type === "ImportBinding") {
|
||||
if (defNode.type === "ImportSpecifier") {
|
||||
return {
|
||||
kind: "import",
|
||||
source: definition.parent.source.value,
|
||||
name: defNode.imported.name,
|
||||
};
|
||||
}
|
||||
if (defNode.type === "ImportNamespaceSpecifier") {
|
||||
return {
|
||||
kind: "import *",
|
||||
source: definition.parent.source.value,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (definition.type === "Variable" && defNode.init) {
|
||||
const origin = getReferenceOrigin(defNode.init, variable.scope);
|
||||
return origin && patternToProperty(definition.name, origin);
|
||||
}
|
||||
|
||||
if (definition.type === "Parameter") {
|
||||
return patternToProperty(definition.name, {
|
||||
kind: "param",
|
||||
index: definition.index,
|
||||
functionNode: definition.node,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (node.type === "MemberExpression" && !node.computed) {
|
||||
const origin = getReferenceOrigin(node.object, scope);
|
||||
return origin && addProperty(origin, node.property.name);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function getVariableDefinition(name, scope) {
|
||||
let currentScope = scope;
|
||||
do {
|
||||
const variable = currentScope.set.get(name);
|
||||
if (variable && variable.defs[0]) {
|
||||
return { scope: currentScope, definition: variable.defs[0] };
|
||||
}
|
||||
} while ((currentScope = currentScope.upper));
|
||||
}
|
||||
|
||||
function patternToProperty(id, base) {
|
||||
const path = getPatternPath(id);
|
||||
return path && path.reduce(addProperty, base);
|
||||
}
|
||||
|
||||
// Adds a property to a given origin. If it was a namespace import it becomes
|
||||
// a named import, so that `import * as x from "foo"; x.bar` and
|
||||
// `import { bar } from "foo"` have the same origin.
|
||||
function addProperty(origin, name) {
|
||||
if (origin.kind === "import *") {
|
||||
return {
|
||||
kind: "import",
|
||||
source: origin.source,
|
||||
name,
|
||||
};
|
||||
}
|
||||
if (origin.kind === "property") {
|
||||
return {
|
||||
kind: "property",
|
||||
base: origin.base,
|
||||
path: origin.path + "." + name,
|
||||
name,
|
||||
};
|
||||
}
|
||||
return {
|
||||
kind: "property",
|
||||
base: origin,
|
||||
path: name,
|
||||
name,
|
||||
};
|
||||
}
|
||||
|
||||
// if "node" is c of { a: { b: c } }, the result is ["a","b"]
|
||||
function getPatternPath(node) {
|
||||
let current = node;
|
||||
const path = [];
|
||||
|
||||
// Unshift keys to path while going up
|
||||
do {
|
||||
const property = current.parent;
|
||||
if (
|
||||
property.type === "ArrayPattern" ||
|
||||
property.type === "AssignmentPattern" ||
|
||||
property.computed
|
||||
) {
|
||||
// These nodes are not supported.
|
||||
return null;
|
||||
}
|
||||
if (property.type === "Property") {
|
||||
path.unshift(property.key.name);
|
||||
} else {
|
||||
// The destructuring pattern is finished
|
||||
break;
|
||||
}
|
||||
} while ((current = current.parent.parent));
|
||||
|
||||
return path;
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
import getReferenceOrigin from "./get-reference-origin";
|
||||
import getExportName from "./get-export-name";
|
||||
|
||||
export default function isBabelPluginFactory(node, scope) {
|
||||
const { parent } = node;
|
||||
|
||||
if (parent.type === "CallExpression") {
|
||||
const calleeOrigin = getReferenceOrigin(parent.callee, scope);
|
||||
|
||||
// Using "declare" from "@babel/helper-plugin-utils"
|
||||
return !!(
|
||||
calleeOrigin &&
|
||||
calleeOrigin.kind === "import" &&
|
||||
calleeOrigin.name === "declare" &&
|
||||
calleeOrigin.source === "@babel/helper-plugin-utils"
|
||||
);
|
||||
}
|
||||
|
||||
const exportName = getExportName(node);
|
||||
|
||||
// export default function ({ types: t }) {}
|
||||
// module.exports = function ({ types: t }) {}
|
||||
return exportName === "default" || exportName === "module.exports";
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
import isBabelPluginFactory from "./is-babel-plugin-factory";
|
||||
|
||||
// Check if a ReferenceOrigin (returned by ./get-reference-origin.js)
|
||||
// is a reference to a @babel/types export.
|
||||
export default function isFromBabelTypes(
|
||||
origin /*: ReferenceOrigin */,
|
||||
scope /*: Scope */,
|
||||
) {
|
||||
if (origin.kind === "import" && origin.source === "@babel/types") {
|
||||
// imported from @babel/types
|
||||
return true;
|
||||
}
|
||||
|
||||
if (
|
||||
origin.kind === "property" &&
|
||||
origin.base.kind === "import" &&
|
||||
origin.base.name === "types" &&
|
||||
origin.base.source === "@babel/core"
|
||||
) {
|
||||
// imported from @babel/core
|
||||
return true;
|
||||
}
|
||||
|
||||
if (
|
||||
origin.kind === "property" &&
|
||||
origin.base.kind === "param" &&
|
||||
origin.base.index === 0
|
||||
) {
|
||||
return isBabelPluginFactory(origin.base.functionNode, scope);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -0,0 +1,136 @@
|
||||
import rule from "../../src/rules/no-deprecated-clone";
|
||||
import { RuleTester } from "eslint";
|
||||
|
||||
const cloneError = "t.clone() is deprecated. Use t.cloneNode() instead.";
|
||||
const cloneDeepError =
|
||||
"t.cloneDeep() is deprecated. Use t.cloneNode() instead.";
|
||||
|
||||
const ruleTester = new RuleTester({
|
||||
parserOptions: { sourceType: "module" },
|
||||
});
|
||||
|
||||
ruleTester.run("no-deprecated-clone", rule, {
|
||||
valid: [
|
||||
`_.clone(obj)`,
|
||||
`_.cloneDeep(obj)`,
|
||||
`import * as t from "lib"; t.clone();`,
|
||||
`import * as t from "lib"; t.cloneDeep();`,
|
||||
`function f(_) { _.types.clone(); }`,
|
||||
`function f(_) { _.types.cloneDeep(); }`,
|
||||
`import * as t from "@babel/types"; t.cloneNode();`,
|
||||
],
|
||||
invalid: [
|
||||
{
|
||||
code: `import { clone } from "@babel/types"; clone();`,
|
||||
errors: [cloneError],
|
||||
},
|
||||
{
|
||||
code: `import { cloneDeep } from "@babel/types"; cloneDeep();`,
|
||||
errors: [cloneDeepError],
|
||||
},
|
||||
{
|
||||
code: `import { clone } from "@babel/types"; var clone2 = clone; clone2();`,
|
||||
errors: [cloneError],
|
||||
},
|
||||
{
|
||||
code: `import { cloneDeep } from "@babel/types"; var cloneDeep2 = cloneDeep; cloneDeep2();`,
|
||||
errors: [cloneDeepError],
|
||||
},
|
||||
{
|
||||
code: `import * as t from "@babel/types"; t.clone();`,
|
||||
errors: [cloneError],
|
||||
},
|
||||
{
|
||||
code: `import * as t from "@babel/types"; t.cloneDeep();`,
|
||||
errors: [cloneDeepError],
|
||||
},
|
||||
{
|
||||
code: `import * as t from "@babel/types"; var { clone } = t; clone();`,
|
||||
errors: [cloneError],
|
||||
},
|
||||
{
|
||||
code: `import * as t from "@babel/types"; var { cloneDeep } = t; cloneDeep();`,
|
||||
errors: [cloneDeepError],
|
||||
},
|
||||
{
|
||||
code: `import { clone as c } from "@babel/types"; c();`,
|
||||
errors: [cloneError],
|
||||
},
|
||||
{
|
||||
code: `import { cloneDeep as cD } from "@babel/types"; cD();`,
|
||||
errors: [cloneDeepError],
|
||||
},
|
||||
{
|
||||
code: `import * as babel from "@babel/core"; babel.types.clone();`,
|
||||
errors: [cloneError],
|
||||
},
|
||||
{
|
||||
code: `import * as babel from "@babel/core"; babel.types.cloneDeep();`,
|
||||
errors: [cloneDeepError],
|
||||
},
|
||||
{
|
||||
code: `import { types } from "@babel/core"; types.clone();`,
|
||||
errors: [cloneError],
|
||||
},
|
||||
{
|
||||
code: `import { types } from "@babel/core"; types.cloneDeep();`,
|
||||
errors: [cloneDeepError],
|
||||
},
|
||||
{
|
||||
code: `import { types as t } from "@babel/core"; t.clone();`,
|
||||
errors: [cloneError],
|
||||
},
|
||||
{
|
||||
code: `import { types as t } from "@babel/core"; t.cloneDeep();`,
|
||||
errors: [cloneDeepError],
|
||||
},
|
||||
{
|
||||
code: `export default function plugin(babel) { babel.types.clone() }`,
|
||||
errors: [cloneError],
|
||||
},
|
||||
{
|
||||
code: `export default function plugin(babel) { babel.types.cloneDeep() }`,
|
||||
errors: [cloneDeepError],
|
||||
},
|
||||
{
|
||||
code: `export default function plugin({ types }) { types.clone() }`,
|
||||
errors: [cloneError],
|
||||
},
|
||||
{
|
||||
code: `export default function plugin({ types }) { types.cloneDeep() }`,
|
||||
errors: [cloneDeepError],
|
||||
},
|
||||
{
|
||||
code: `export default function plugin({ types: t }) { t.clone() }`,
|
||||
errors: [cloneError],
|
||||
},
|
||||
{
|
||||
code: `export default function plugin({ types: t }) { t.cloneDeep() }`,
|
||||
errors: [cloneDeepError],
|
||||
},
|
||||
{
|
||||
code: `export default ({ types }) => { types.clone() }`,
|
||||
errors: [cloneError],
|
||||
},
|
||||
{
|
||||
code: `export default ({ types }) => { types.cloneDeep() }`,
|
||||
errors: [cloneDeepError],
|
||||
},
|
||||
{
|
||||
code: `module.exports = function plugin({ types }) { types.clone() }`,
|
||||
errors: [cloneError],
|
||||
},
|
||||
{
|
||||
code: `module.exports = function plugin({ types }) { types.cloneDeep() }`,
|
||||
errors: [cloneDeepError],
|
||||
},
|
||||
{
|
||||
code: `import { declare } from "@babel/helper-plugin-utils"; declare(({ types }) => { types.clone() });`,
|
||||
errors: [cloneError],
|
||||
},
|
||||
{
|
||||
code: `import { declare } from "@babel/helper-plugin-utils"; declare(({ types }) => { types.cloneDeep() });`,
|
||||
errors: [cloneDeepError],
|
||||
},
|
||||
],
|
||||
});
|
||||
@ -0,0 +1,78 @@
|
||||
import rule from "../../src/rules/no-undefined-identifier";
|
||||
import { RuleTester } from "eslint";
|
||||
|
||||
const error =
|
||||
"Use path.scope.buildUndefinedNode() to create an undefined identifier directly.";
|
||||
|
||||
const ruleTester = new RuleTester({
|
||||
parserOptions: { sourceType: "module" },
|
||||
});
|
||||
|
||||
ruleTester.run("no-undefined-identifier", rule, {
|
||||
valid: [
|
||||
`_.identifier("undefined")`,
|
||||
`_.Identifier("undefined")`,
|
||||
`import * as t from "lib"; t.identifier("undefined");`,
|
||||
`function f(_) { _.types.identifier("undefined"); }`,
|
||||
`import * as t from "@babel/types"; t.identifier("not_undefined");`,
|
||||
`path.scope.buildUndefinedNode();`,
|
||||
],
|
||||
invalid: [
|
||||
{
|
||||
code: `import { identifier } from "@babel/types"; identifier("undefined");`,
|
||||
errors: [error],
|
||||
},
|
||||
{
|
||||
code: `import { Identifier } from "@babel/types"; Identifier("undefined");`,
|
||||
errors: [error],
|
||||
},
|
||||
{
|
||||
code: `import * as t from "@babel/types"; t.identifier("undefined");`,
|
||||
errors: [error],
|
||||
},
|
||||
{
|
||||
code: `import * as t from "@babel/types"; var { identifier } = t; identifier("undefined");`,
|
||||
errors: [error],
|
||||
},
|
||||
{
|
||||
code: `import { identifier as id } from "@babel/types"; id("undefined");`,
|
||||
errors: [error],
|
||||
},
|
||||
{
|
||||
code: `import * as babel from "@babel/core"; babel.types.identifier("undefined");`,
|
||||
errors: [error],
|
||||
},
|
||||
{
|
||||
code: `import { types } from "@babel/core"; types.identifier("undefined");`,
|
||||
errors: [error],
|
||||
},
|
||||
{
|
||||
code: `import { types as t } from "@babel/core"; t.identifier("undefined");`,
|
||||
errors: [error],
|
||||
},
|
||||
{
|
||||
code: `export default function plugin(babel) { babel.types.identifier("undefined") }`,
|
||||
errors: [error],
|
||||
},
|
||||
{
|
||||
code: `export default function plugin({ types }) { types.identifier("undefined") }`,
|
||||
errors: [error],
|
||||
},
|
||||
{
|
||||
code: `export default function plugin({ types: t }) { t.identifier("undefined") }`,
|
||||
errors: [error],
|
||||
},
|
||||
{
|
||||
code: `export default ({ types }) => { types.identifier("undefined") }`,
|
||||
errors: [error],
|
||||
},
|
||||
{
|
||||
code: `module.exports = function plugin({ types }) { types.identifier("undefined") }`,
|
||||
errors: [error],
|
||||
},
|
||||
{
|
||||
code: `import { declare } from "@babel/helper-plugin-utils"; declare(({ types }) => { types.identifier("undefined") });`,
|
||||
errors: [error],
|
||||
},
|
||||
],
|
||||
});
|
||||
@ -0,0 +1,52 @@
|
||||
import rule from "../../src/rules/plugin-name";
|
||||
import { RuleTester } from "eslint";
|
||||
|
||||
const missingPluginError = "This file does not export a Babel plugin.";
|
||||
const missingNameError = "This Babel plugin doesn't have a 'name' property.";
|
||||
|
||||
const ruleTester = new RuleTester({
|
||||
parserOptions: { sourceType: "module" },
|
||||
});
|
||||
|
||||
ruleTester.run("plugin-name", rule, {
|
||||
valid: [
|
||||
`export default function () { return { name: "test-plugin" } }`,
|
||||
`import { declare } from "@babel/helper-plugin-utils"; declare(() => { return { name: "test-plugin" } })`,
|
||||
`import { declare } from "@babel/helper-plugin-utils"; declare(() => ({ name: "test-plugin" }))`,
|
||||
`module.exports = function () { return { name: "foo" }; }`,
|
||||
],
|
||||
invalid: [
|
||||
{
|
||||
code: `function fn() { return { name: "foo" } }`,
|
||||
errors: [missingPluginError],
|
||||
},
|
||||
{
|
||||
code: `export function fn() { return { name: "foo" } }`,
|
||||
errors: [missingPluginError],
|
||||
},
|
||||
{
|
||||
code: `(function fn() { return { name: "foo" } })`,
|
||||
errors: [missingPluginError],
|
||||
},
|
||||
{
|
||||
code: `() => { return { name: "foo" } }`,
|
||||
errors: [missingPluginError],
|
||||
},
|
||||
{
|
||||
code: `export default function fn() {}`,
|
||||
errors: [missingPluginError],
|
||||
},
|
||||
{
|
||||
code: `export default function fn() { return {} }`,
|
||||
errors: [missingNameError],
|
||||
},
|
||||
{
|
||||
code: `import { declare } from "@babel/helper-plugin-utils"; declare(() => ({}))`,
|
||||
errors: [missingNameError],
|
||||
},
|
||||
{
|
||||
code: `module.exports = function () { return {} }`,
|
||||
errors: [missingNameError],
|
||||
},
|
||||
],
|
||||
});
|
||||
4
eslint/babel-eslint-plugin/.npmignore
Normal file
4
eslint/babel-eslint-plugin/.npmignore
Normal file
@ -0,0 +1,4 @@
|
||||
src
|
||||
test
|
||||
.*
|
||||
*.log
|
||||
23
eslint/babel-eslint-plugin/LICENSE
Normal file
23
eslint/babel-eslint-plugin/LICENSE
Normal file
@ -0,0 +1,23 @@
|
||||
Copyright (c) 2014-2015 Jason Quense <jason@quense.me>
|
||||
Original work by respective rule authors; copywrites noted in files.
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
47
eslint/babel-eslint-plugin/README.md
Normal file
47
eslint/babel-eslint-plugin/README.md
Normal file
@ -0,0 +1,47 @@
|
||||
# @babel/eslint-plugin
|
||||
|
||||
Companion rules for `@babel/eslint-parser`. `@babel/eslint-parser` does a great job at adapting `eslint`
|
||||
for use with Babel, but it can't change the built-in rules to support experimental features.
|
||||
`@babel/eslint-plugin` re-implements problematic rules so they do not give false positives or negatives.
|
||||
|
||||
> Requires Node 10.9 or greater
|
||||
|
||||
### Install
|
||||
|
||||
```sh
|
||||
npm install @babel/eslint-plugin --save-dev
|
||||
```
|
||||
|
||||
Load the plugin in your `.eslintrc.json` file:
|
||||
|
||||
```json
|
||||
{
|
||||
"plugins": ["@babel/eslint-plugin"]
|
||||
}
|
||||
```
|
||||
|
||||
Finally enable all the rules you would like to use (remember to disable the
|
||||
original ones as well!).
|
||||
|
||||
```json
|
||||
{
|
||||
"rules": {
|
||||
"babel/new-cap": "error",
|
||||
"babel/no-invalid-this": "error",
|
||||
"babel/no-unused-expressions": "error",
|
||||
"babel/object-curly-spacing": "error",
|
||||
"babel/semi": "error",
|
||||
}
|
||||
}
|
||||
```
|
||||
### Rules
|
||||
|
||||
Each rule corresponds to a core `eslint` rule and has the same options.
|
||||
|
||||
🛠: means it's autofixable with `--fix`.
|
||||
|
||||
- `babel/new-cap`: handles decorators (`@Decorator`)
|
||||
- `babel/no-invalid-this`: handles class fields and private class methods (`class A { a = this.b; }`)
|
||||
- `babel/no-unused-expressions`: handles `do` expressions
|
||||
- `babel/object-curly-spacing`: handles `export * as x from "mod";` (🛠)
|
||||
- `babel/semi`: Handles class properties (🛠)
|
||||
41
eslint/babel-eslint-plugin/package.json
Normal file
41
eslint/babel-eslint-plugin/package.json
Normal file
@ -0,0 +1,41 @@
|
||||
{
|
||||
"name": "@babel/eslint-plugin",
|
||||
"version": "7.8.3-csx.2",
|
||||
"description": "Companion rules for @babel/eslint-parser",
|
||||
"main": "lib/index.js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/babel/babel.git",
|
||||
"directory": "eslint/babel-eslint-plugin"
|
||||
},
|
||||
"keywords": [
|
||||
"babel",
|
||||
"eslint",
|
||||
"eslintplugin",
|
||||
"eslint-plugin",
|
||||
"babel-eslint"
|
||||
],
|
||||
"author": "Jason Quense @monasticpanic",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"engines": {
|
||||
"node": ">=10.9"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/babel/babel/issues"
|
||||
},
|
||||
"homepage": "https://github.com/babel/babel/tree/master/eslint/babel-eslint-plugin",
|
||||
"peerDependencies": {
|
||||
"@babel/eslint-parser": "0.0.0",
|
||||
"eslint": ">=6.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"eslint-rule-composer": "^0.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/eslint-parser": "7.8.3-csx.2",
|
||||
"@babel/eslint-shared-fixtures": "7.8.3-csx.2",
|
||||
"eslint": "^6.0.0",
|
||||
"lodash.clonedeep": "^4.5.0"
|
||||
}
|
||||
}
|
||||
22
eslint/babel-eslint-plugin/src/index.js
Normal file
22
eslint/babel-eslint-plugin/src/index.js
Normal file
@ -0,0 +1,22 @@
|
||||
import newCap from "./rules/new-cap";
|
||||
import noInvalidThis from "./rules/no-invalid-this";
|
||||
import noUnusedExpressions from "./rules/no-unused-expressions";
|
||||
import objectCurlySpacing from "./rules/object-curly-spacing";
|
||||
import semi from "./rules/semi";
|
||||
|
||||
module.exports = {
|
||||
rules: {
|
||||
"new-cap": newCap,
|
||||
"no-invalid-this": noInvalidThis,
|
||||
"no-unused-expressions": noUnusedExpressions,
|
||||
"object-curly-spacing": objectCurlySpacing,
|
||||
semi,
|
||||
},
|
||||
rulesConfig: {
|
||||
"new-cap": "off",
|
||||
"no-invalid-this": "off",
|
||||
"no-unused-expressions": "off",
|
||||
"object-curly-spacing": "off",
|
||||
semi: "off",
|
||||
},
|
||||
};
|
||||
18
eslint/babel-eslint-plugin/src/rules/new-cap.js
Normal file
18
eslint/babel-eslint-plugin/src/rules/new-cap.js
Normal file
@ -0,0 +1,18 @@
|
||||
import ruleComposer from "eslint-rule-composer";
|
||||
import eslint from "eslint";
|
||||
|
||||
const rule = new eslint.Linter().getRules().get("new-cap");
|
||||
|
||||
/**
|
||||
* Returns whether a node is under a decorator or not.
|
||||
* @param {ASTNode} node CallExpression node
|
||||
* @returns {Boolean} Returns true if the node is under a decorator.
|
||||
*/
|
||||
function isDecorator(node) {
|
||||
return node.parent.type === "Decorator";
|
||||
}
|
||||
|
||||
export default ruleComposer.filterReports(
|
||||
rule,
|
||||
problem => !isDecorator(problem.node),
|
||||
);
|
||||
20
eslint/babel-eslint-plugin/src/rules/no-invalid-this.js
Normal file
20
eslint/babel-eslint-plugin/src/rules/no-invalid-this.js
Normal file
@ -0,0 +1,20 @@
|
||||
import ruleComposer from "eslint-rule-composer";
|
||||
import eslint from "eslint";
|
||||
|
||||
const noInvalidThisRule = new eslint.Linter().getRules().get("no-invalid-this");
|
||||
|
||||
export default ruleComposer.filterReports(noInvalidThisRule, problem => {
|
||||
let inClassProperty = false;
|
||||
let node = problem.node;
|
||||
|
||||
while (node) {
|
||||
if (node.type === "ClassProperty" || node.type === "ClassPrivateProperty") {
|
||||
inClassProperty = true;
|
||||
return;
|
||||
}
|
||||
|
||||
node = node.parent;
|
||||
}
|
||||
|
||||
return !inClassProperty;
|
||||
});
|
||||
@ -0,0 +1,64 @@
|
||||
import ruleComposer from "eslint-rule-composer";
|
||||
import eslint from "eslint";
|
||||
|
||||
const rule = new eslint.Linter().getRules().get("no-unused-expressions");
|
||||
|
||||
/**
|
||||
* @param {ASTNode} node - any node
|
||||
* @returns {boolean} whether the given node is either an IfStatement or an
|
||||
* ExpressionStatement and is the last node in the body of a BlockStatement
|
||||
*/
|
||||
function isFinalStatementInBlockStatement(node) {
|
||||
const parent = node.parent;
|
||||
return (
|
||||
/^(?:If|Expression)Statement$/.test(node.type) &&
|
||||
parent.type === "BlockStatement" &&
|
||||
parent.body[parent.body.length - 1] === node
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ASTNode} node - any node
|
||||
* @returns {boolean} whether the given node represents an unbroken chain of
|
||||
* tail ExpressionStatements and IfStatements within a DoExpression
|
||||
* https://github.com/tc39/proposal-do-expressions
|
||||
*/
|
||||
function isInDoStatement(node) {
|
||||
if (!node) return false;
|
||||
|
||||
if (node.type === "DoExpression") return true;
|
||||
|
||||
// this is an `else if`
|
||||
if (
|
||||
node.type === "IfStatement" &&
|
||||
node.parent &&
|
||||
node.parent.type === "IfStatement"
|
||||
) {
|
||||
return isInDoStatement(node.parent);
|
||||
}
|
||||
|
||||
if (isFinalStatementInBlockStatement(node)) {
|
||||
return isInDoStatement(node.parent.parent);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ASTNode} node - any node
|
||||
* @returns {boolean} whether the given node is an optional call expression,
|
||||
* https://github.com/tc39/proposal-optional-chaining
|
||||
*/
|
||||
function isOptionalCallExpression(node) {
|
||||
return (
|
||||
!!node &&
|
||||
node.type === "ExpressionStatement" &&
|
||||
node.expression.type === "OptionalCallExpression"
|
||||
);
|
||||
}
|
||||
|
||||
export default ruleComposer.filterReports(
|
||||
rule,
|
||||
problem =>
|
||||
!isInDoStatement(problem.node) && !isOptionalCallExpression(problem.node),
|
||||
);
|
||||
20
eslint/babel-eslint-plugin/src/rules/object-curly-spacing.js
Normal file
20
eslint/babel-eslint-plugin/src/rules/object-curly-spacing.js
Normal file
@ -0,0 +1,20 @@
|
||||
import ruleComposer from "eslint-rule-composer";
|
||||
import eslint from "eslint";
|
||||
|
||||
const rule = new eslint.Linter().getRules().get("object-curly-spacing");
|
||||
|
||||
export default ruleComposer.filterReports(rule, problem => {
|
||||
const node = problem.node;
|
||||
|
||||
// Allow exportDefaultFrom syntax:
|
||||
// export x from '...';
|
||||
if (
|
||||
node.type === "ExportNamedDeclaration" &&
|
||||
node.specifiers.length === 1 &&
|
||||
node.specifiers[0].type === "ExportDefaultSpecifier"
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
105
eslint/babel-eslint-plugin/src/rules/semi.js
Normal file
105
eslint/babel-eslint-plugin/src/rules/semi.js
Normal file
@ -0,0 +1,105 @@
|
||||
import ruleComposer from "eslint-rule-composer";
|
||||
import eslint from "eslint";
|
||||
|
||||
const OPT_OUT_PATTERN = /^[-[(/+`]/; // One of [(/+-`
|
||||
|
||||
const rule = new eslint.Linter().getRules().get("semi");
|
||||
|
||||
function isSemicolon(token) {
|
||||
return token.type === "Punctuator" && token.value === ";";
|
||||
}
|
||||
|
||||
function isUnnecessarySemicolon(context, lastToken) {
|
||||
if (!isSemicolon(lastToken)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const nextToken = context.getSourceCode().getTokenAfter(lastToken);
|
||||
|
||||
if (!nextToken) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const lastTokenLine = lastToken.loc.end.line;
|
||||
const nextTokenLine = nextToken.loc.start.line;
|
||||
const isOptOutToken =
|
||||
OPT_OUT_PATTERN.test(nextToken.value) &&
|
||||
nextToken.value !== "++" &&
|
||||
nextToken.value !== "--";
|
||||
const isDivider = nextToken.value === "}" || nextToken.value === ";";
|
||||
|
||||
return (lastTokenLine !== nextTokenLine && !isOptOutToken) || isDivider;
|
||||
}
|
||||
|
||||
function isOneLinerBlock(context, node) {
|
||||
const nextToken = context.getSourceCode().getTokenAfter(node);
|
||||
|
||||
if (!nextToken || nextToken.value !== "}") {
|
||||
return false;
|
||||
}
|
||||
|
||||
const parent = node.parent;
|
||||
|
||||
return (
|
||||
parent &&
|
||||
parent.type === "BlockStatement" &&
|
||||
parent.loc.start.line === parent.loc.end.line
|
||||
);
|
||||
}
|
||||
|
||||
function report(context, node, missing) {
|
||||
const lastToken = context.getSourceCode().getLastToken(node);
|
||||
|
||||
let message,
|
||||
fix,
|
||||
loc = lastToken.loc;
|
||||
|
||||
if (!missing) {
|
||||
message = "Missing semicolon.";
|
||||
loc = loc.end;
|
||||
fix = function(fixer) {
|
||||
return fixer.insertTextAfter(lastToken, ";");
|
||||
};
|
||||
} else {
|
||||
message = "Extra semicolon.";
|
||||
loc = loc.start;
|
||||
fix = function(fixer) {
|
||||
return fixer.remove(lastToken);
|
||||
};
|
||||
}
|
||||
|
||||
context.report({
|
||||
node,
|
||||
loc,
|
||||
message,
|
||||
fix,
|
||||
});
|
||||
}
|
||||
|
||||
export default ruleComposer.joinReports([
|
||||
rule,
|
||||
context => ({
|
||||
ClassProperty(node) {
|
||||
const options = context.options[1];
|
||||
const exceptOneLine = options && options.omitLastInOneLineBlock === true;
|
||||
const sourceCode = context.getSourceCode();
|
||||
const lastToken = sourceCode.getLastToken(node);
|
||||
|
||||
if (context.options[0] === "never") {
|
||||
if (isUnnecessarySemicolon(context, lastToken)) {
|
||||
report(context, node, true);
|
||||
}
|
||||
} else {
|
||||
if (!isSemicolon(lastToken)) {
|
||||
if (!exceptOneLine || !isOneLinerBlock(context, node)) {
|
||||
report(context, node);
|
||||
}
|
||||
} else {
|
||||
if (exceptOneLine && isOneLinerBlock(context, node)) {
|
||||
report(context, node, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}),
|
||||
]);
|
||||
14
eslint/babel-eslint-plugin/test/helpers/RuleTester.js
Normal file
14
eslint/babel-eslint-plugin/test/helpers/RuleTester.js
Normal file
@ -0,0 +1,14 @@
|
||||
import { RuleTester } from "eslint";
|
||||
|
||||
RuleTester.setDefaultConfig({
|
||||
parser: require.resolve("@babel/eslint-parser"),
|
||||
parserOptions: {
|
||||
babelOptions: {
|
||||
configFile: require.resolve(
|
||||
"@babel/eslint-shared-fixtures/config/babel.config.js",
|
||||
),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export default RuleTester;
|
||||
12
eslint/babel-eslint-plugin/test/rules/new-cap.js
Normal file
12
eslint/babel-eslint-plugin/test/rules/new-cap.js
Normal file
@ -0,0 +1,12 @@
|
||||
import rule from "../../src/rules/new-cap";
|
||||
import RuleTester from "../helpers/RuleTester";
|
||||
|
||||
const ruleTester = new RuleTester();
|
||||
ruleTester.run("@babel/new-cap", rule, {
|
||||
valid: [
|
||||
{
|
||||
code: "@MyDecorator(123) class MyClass{}",
|
||||
},
|
||||
],
|
||||
invalid: [],
|
||||
});
|
||||
121
eslint/babel-eslint-plugin/test/rules/no-invalid-this.js
Normal file
121
eslint/babel-eslint-plugin/test/rules/no-invalid-this.js
Normal file
@ -0,0 +1,121 @@
|
||||
import cloneDeep from "lodash.clonedeep";
|
||||
import rule from "../../src/rules/no-invalid-this";
|
||||
import RuleTester from "../helpers/RuleTester";
|
||||
|
||||
/**
|
||||
* A constant value for non strict mode environment.
|
||||
* @returns {void}
|
||||
*/
|
||||
function NORMAL(pattern) {
|
||||
pattern.parserOptions.sourceType = "script";
|
||||
}
|
||||
|
||||
/**
|
||||
* A constant value for strict mode environment.
|
||||
* This modifies pattern object to make strict mode.
|
||||
* @param {Object} pattern - A pattern object to modify.
|
||||
* @returns {void}
|
||||
*/
|
||||
function USE_STRICT(pattern) {
|
||||
pattern.code = '"use strict"; ' + pattern.code;
|
||||
}
|
||||
|
||||
/**
|
||||
* A constant value for implied strict mode.
|
||||
* This modifies pattern object to impose strict mode.
|
||||
* @param {Object} pattern - A pattern object to modify.
|
||||
* @returns {void}
|
||||
*/
|
||||
function IMPLIED_STRICT(pattern) {
|
||||
pattern.code = "/* implied strict mode */ " + pattern.code;
|
||||
pattern.parserOptions.ecmaFeatures = pattern.parserOptions.ecmaFeatures || {};
|
||||
pattern.parserOptions.ecmaFeatures.impliedStrict = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* A constant value for modules environment.
|
||||
* This modifies pattern object to make modules.
|
||||
* @param {Object} pattern - A pattern object to modify.
|
||||
* @returns {void}
|
||||
*/
|
||||
function MODULES(pattern) {
|
||||
pattern.code = "/* modules */ " + pattern.code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts patterns each condition for a specified type. The type is `valid` or `invalid`.
|
||||
* @param {Object[]} patterns - Original patterns.
|
||||
* @param {string} type - One of `"valid"` or `"invalid"`.
|
||||
* @returns {Object[]} Test patterns.
|
||||
*/
|
||||
function extractPatterns(patterns, type) {
|
||||
// Clone and apply the pattern environment.
|
||||
const patternsList = patterns.map(function(pattern) {
|
||||
return pattern[type].map(function(applyCondition) {
|
||||
const thisPattern = cloneDeep(pattern);
|
||||
|
||||
applyCondition(thisPattern);
|
||||
|
||||
if (type === "valid") {
|
||||
thisPattern.errors = [];
|
||||
} else {
|
||||
thisPattern.code += " /* should error */";
|
||||
}
|
||||
|
||||
delete thisPattern.invalid;
|
||||
delete thisPattern.valid;
|
||||
|
||||
return thisPattern;
|
||||
});
|
||||
});
|
||||
|
||||
// Flatten.
|
||||
return Array.prototype.concat.apply([], patternsList);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Tests
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const errors = [
|
||||
{ message: "Unexpected 'this'.", type: "ThisExpression" },
|
||||
{ message: "Unexpected 'this'.", type: "ThisExpression" },
|
||||
];
|
||||
|
||||
const patterns = [
|
||||
// Class private fields
|
||||
{
|
||||
code: "class A {a = this.b;};",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
|
||||
{
|
||||
code: "class A {a = () => {return this.b;};};",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
|
||||
// Class Private methods
|
||||
{
|
||||
code: "class A {#a = this.b;};",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
|
||||
{
|
||||
code: "class A {#a = () => {return this.b;};};",
|
||||
parserOptions: { ecmaVersion: 6 },
|
||||
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
|
||||
invalid: [],
|
||||
},
|
||||
];
|
||||
|
||||
const ruleTester = new RuleTester();
|
||||
ruleTester.run("@babel/no-invalid-this", rule, {
|
||||
valid: extractPatterns(patterns, "valid"),
|
||||
invalid: extractPatterns(patterns, "invalid"),
|
||||
});
|
||||
@ -0,0 +1,37 @@
|
||||
import rule from "../../src/rules/no-unused-expressions";
|
||||
import RuleTester from "../helpers/RuleTester";
|
||||
|
||||
const ruleTester = new RuleTester();
|
||||
ruleTester.run("@babel/no-unused-expressions", rule, {
|
||||
valid: [
|
||||
"let a = do { if (foo) { foo.bar; } }",
|
||||
"let a = do { foo; }",
|
||||
"let a = do { let b = 2; foo; }",
|
||||
"let a = do { (foo + 1); }",
|
||||
"let a = do { if (foo) { if (foo.bar) { foo.bar; } } }",
|
||||
"let a = do { if (foo) { if (foo.bar) { foo.bar; } else if (foo.baz) { foo.baz; } } }",
|
||||
"foo.bar?.();",
|
||||
],
|
||||
invalid: [
|
||||
{
|
||||
code: "let a = do { foo; let b = 2; }",
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"Expected an assignment or function call and instead saw an expression.",
|
||||
type: "ExpressionStatement",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "let a = do { if (foo) { foo.bar } else { a; bar.foo } }",
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"Expected an assignment or function call and instead saw an expression.",
|
||||
type: "ExpressionStatement",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
@ -0,0 +1,13 @@
|
||||
import rule from "../../src/rules/object-curly-spacing";
|
||||
import RuleTester from "../helpers/RuleTester";
|
||||
|
||||
const ruleTester = new RuleTester();
|
||||
ruleTester.run("@babel/object-curly-spacing", rule, {
|
||||
valid: [
|
||||
{
|
||||
code: 'export x from "mod";',
|
||||
},
|
||||
],
|
||||
|
||||
invalid: [],
|
||||
});
|
||||
52
eslint/babel-eslint-plugin/test/rules/semi.js
Normal file
52
eslint/babel-eslint-plugin/test/rules/semi.js
Normal file
@ -0,0 +1,52 @@
|
||||
import rule from "../../src/rules/semi";
|
||||
import RuleTester from "../helpers/RuleTester";
|
||||
|
||||
const ruleTester = new RuleTester();
|
||||
|
||||
ruleTester.run("semi", rule, {
|
||||
valid: [
|
||||
"class Foo { bar = 'example'; }",
|
||||
"class Foo { static bar = 'example'; }",
|
||||
{
|
||||
code: "class Foo { bar = () => {}; }",
|
||||
options: ["always", { omitLastInOneLineBlock: true }],
|
||||
},
|
||||
|
||||
// never
|
||||
{ code: "class Foo { bar = 'example' }", options: ["never"] },
|
||||
{ code: "class Foo { static bar = 'example' }", options: ["never"] },
|
||||
{ code: "class Foo { bar = () => {} }", options: ["never"] },
|
||||
],
|
||||
invalid: [
|
||||
{
|
||||
code: "class Foo { bar = 'example' }",
|
||||
errors: [{ message: "Missing semicolon." }],
|
||||
},
|
||||
{
|
||||
code: "class Foo { static bar = 'example' }",
|
||||
errors: [{ message: "Missing semicolon." }],
|
||||
},
|
||||
{
|
||||
code: "class Foo { bar = () => {} }",
|
||||
options: ["always", { omitLastInOneLineBlock: true }],
|
||||
errors: [{ message: "Missing semicolon." }],
|
||||
},
|
||||
|
||||
// "never"
|
||||
{
|
||||
code: "class Foo { bar = 'example'; }",
|
||||
options: ["never"],
|
||||
errors: [{ message: "Extra semicolon." }],
|
||||
},
|
||||
{
|
||||
code: "class Foo { static bar = 'example'; }",
|
||||
options: ["never"],
|
||||
errors: [{ message: "Extra semicolon." }],
|
||||
},
|
||||
{
|
||||
code: "class Foo { bar = () => {}; }",
|
||||
options: ["never"],
|
||||
errors: [{ message: "Extra semicolon." }],
|
||||
},
|
||||
],
|
||||
});
|
||||
@ -0,0 +1,6 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
presets: [["@babel/preset-env", { forceAllTransforms: true }]],
|
||||
plugins: [["@babel/plugin-proposal-decorators", { legacy: true }]],
|
||||
};
|
||||
24
eslint/babel-eslint-shared-fixtures/config/babel.config.js
Normal file
24
eslint/babel-eslint-shared-fixtures/config/babel.config.js
Normal file
@ -0,0 +1,24 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
presets: [
|
||||
["@babel/preset-env", { forceAllTransforms: true }],
|
||||
["@babel/preset-flow", { all: true }],
|
||||
"@babel/preset-react",
|
||||
],
|
||||
plugins: [
|
||||
"@babel/plugin-syntax-dynamic-import",
|
||||
"@babel/plugin-syntax-import-meta",
|
||||
"@babel/plugin-syntax-export-default-from",
|
||||
"@babel/plugin-proposal-class-properties",
|
||||
"@babel/plugin-proposal-nullish-coalescing-operator",
|
||||
"@babel/plugin-proposal-optional-chaining",
|
||||
"@babel/plugin-syntax-numeric-separator",
|
||||
"@babel/plugin-syntax-export-namespace-from",
|
||||
["@babel/plugin-proposal-decorators", { decoratorsBeforeExport: false }],
|
||||
["@babel/plugin-proposal-pipeline-operator", { proposal: "minimal" }],
|
||||
"@babel/plugin-syntax-bigint",
|
||||
"@babel/plugin-proposal-private-methods",
|
||||
"@babel/plugin-proposal-do-expressions",
|
||||
],
|
||||
};
|
||||
25
eslint/babel-eslint-shared-fixtures/package.json
Normal file
25
eslint/babel-eslint-shared-fixtures/package.json
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "@babel/eslint-shared-fixtures",
|
||||
"version": "7.8.3-csx.2",
|
||||
"description": "Shared fixtures for testing @babel/eslint-* packages",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@babel/plugin-proposal-class-properties": "^7.1.0",
|
||||
"@babel/plugin-proposal-decorators": "^7.1.2",
|
||||
"@babel/plugin-proposal-do-expressions": "^7.7.4",
|
||||
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0",
|
||||
"@babel/plugin-proposal-optional-chaining": "^7.0.0",
|
||||
"@babel/plugin-proposal-pipeline-operator": "^7.0.0",
|
||||
"@babel/plugin-proposal-private-methods": "^7.7.4",
|
||||
"@babel/plugin-syntax-bigint": "^7.7.4",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
|
||||
"@babel/plugin-syntax-export-default-from": "^7.0.0",
|
||||
"@babel/plugin-syntax-export-namespace-from": "^7.0.0",
|
||||
"@babel/plugin-syntax-import-meta": "^7.0.0",
|
||||
"@babel/plugin-syntax-numeric-separator": "^7.0.0",
|
||||
"@babel/preset-env": "^7.1.5",
|
||||
"@babel/preset-flow": "^7.0.0",
|
||||
"@babel/preset-react": "^7.0.0"
|
||||
}
|
||||
}
|
||||
68
jest.config.js
Normal file
68
jest.config.js
Normal file
@ -0,0 +1,68 @@
|
||||
// These packages undet the @babel namespace aren't in this monorepo.
|
||||
const externalBabelPackages = [
|
||||
"plugin-syntax-async-generators",
|
||||
"plugin-syntax-bigint",
|
||||
"plugin-syntax-dynamic-import",
|
||||
"plugin-syntax-json-strings",
|
||||
"plugin-syntax-nullish-coalescing-operator",
|
||||
"plugin-syntax-object-rest-spread",
|
||||
"plugin-syntax-optional-catch-binding",
|
||||
"plugin-syntax-optional-chaining",
|
||||
];
|
||||
|
||||
// prettier-ignore
|
||||
const monorepoPackagePattern =
|
||||
`^@babel/(?!eslint-)(?!${externalBabelPackages.join("|")})([a-zA-Z0-9_-]+)$`;
|
||||
|
||||
module.exports = {
|
||||
collectCoverageFrom: [
|
||||
"packages/*/src/**/*.mjs",
|
||||
"packages/*/src/**/*.js",
|
||||
"codemods/*/src/**/*.mjs",
|
||||
"codemods/*/src/**/*.js",
|
||||
"eslint/*/src/**/*.mjs",
|
||||
"eslint/*/src/**/*.js",
|
||||
],
|
||||
// The eslint/* packages use ESLint v6, which has dropped support for Node v6.
|
||||
// TODO: Remove this process.version check in Babel 8.
|
||||
testRegex: `./(packages|codemods${
|
||||
/^v6./u.test(process.version) ? "" : "|eslint"
|
||||
})/[^/]+/test/.+\\.m?js$`,
|
||||
testPathIgnorePatterns: [
|
||||
"/node_modules/",
|
||||
"/test/fixtures/",
|
||||
"/test/debug-fixtures/",
|
||||
"/babel-parser/test/expressions/",
|
||||
"/test/tmp/",
|
||||
"/test/__data__/",
|
||||
"/test/helpers/",
|
||||
"<rootDir>/test/warning\\.js",
|
||||
"<rootDir>/build/",
|
||||
"_browser\\.js",
|
||||
],
|
||||
testEnvironment: "node",
|
||||
setupFilesAfterEnv: ["<rootDir>/test/testSetupFile.js"],
|
||||
transformIgnorePatterns: [
|
||||
"/node_modules/",
|
||||
"<rootDir>/packages/babel-standalone/babel(\\.min)?\\.js",
|
||||
"<rootDir>/packages/babel-preset-env-standalone/babel-preset-env(\\.min)?\\.js",
|
||||
"/test/(fixtures|tmp|__data__)/",
|
||||
"<rootDir>/(packages|codemods|eslint)/[^/]+/lib/",
|
||||
],
|
||||
coveragePathIgnorePatterns: [
|
||||
"/node_modules/",
|
||||
"<rootDir>/packages/babel-standalone/babel(\\.min)?\\.js",
|
||||
"<rootDir>/packages/babel-preset-env-standalone/babel-preset-env(\\.min)?\\.js",
|
||||
"/test/(fixtures|tmp|__data__)/",
|
||||
],
|
||||
modulePathIgnorePatterns: [
|
||||
"/test/fixtures/",
|
||||
"/test/tmp/",
|
||||
"/test/__data__/",
|
||||
"<rootDir>/build/",
|
||||
],
|
||||
moduleNameMapper: {
|
||||
[monorepoPackagePattern]: "<rootDir>/packages/babel-$1/",
|
||||
"^@babel/eslint-([a-zA-Z0-9_-]+)$": "<rootDir>/eslint/babel-eslint-$1/",
|
||||
},
|
||||
};
|
||||
11
lerna.json
11
lerna.json
@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "7.7.3",
|
||||
"version": "7.8.3-csx.2",
|
||||
"changelog": {
|
||||
"repo": "babel/babel",
|
||||
"cacheDir": ".changelog",
|
||||
@ -11,7 +11,8 @@
|
||||
"PR: Polish :nail_care:": ":nail_care: Polish",
|
||||
"PR: Docs :memo:": ":memo: Documentation",
|
||||
"PR: Internal :house:": ":house: Internal",
|
||||
"PR: Performance :running_woman:": ":running_woman: Performance"
|
||||
"PR: Performance :running_woman:": ":running_woman: Performance",
|
||||
"PR: Revert :leftwards_arrow_with_hook:": ":leftwards_arrow_with_hook: Revert"
|
||||
}
|
||||
},
|
||||
"command": {
|
||||
@ -20,14 +21,18 @@
|
||||
"*.md",
|
||||
"*.txt",
|
||||
"test/**",
|
||||
"**/test/**",
|
||||
"codemods/**",
|
||||
"# We ignore every JSON file, except for built-in-modules, built-ins and plugins defined in babel-preset-env/data.",
|
||||
"@(!(built-in-modules|built-ins|plugins|package)).json"
|
||||
"@(!(built-in-modules|built-ins|plugins|package)).json",
|
||||
"# Until the ESLint packages version are aligned with Babel's, we ignore them",
|
||||
"eslint/**"
|
||||
]
|
||||
}
|
||||
},
|
||||
"packages": [
|
||||
"codemods/*",
|
||||
"eslint/*",
|
||||
"packages/*"
|
||||
],
|
||||
"npmClient": "yarn",
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
declare module "resolve" {
|
||||
declare export default {
|
||||
(string, {| basedir: string |}, (err: ?Error, res: string) => void): void;
|
||||
sync: (string, {| basedir: string |}) => string;
|
||||
};
|
||||
}
|
||||
@ -178,7 +179,7 @@ declare module "convert-source-map" {
|
||||
SourceMap: SourceMap,
|
||||
Converter: Converter,
|
||||
fromObject(obj: SourceMap | SourceMapGenerator): Converter,
|
||||
fromJSON(str: string): Converter,
|
||||
fromJSON(str: string | Buffer): Converter,
|
||||
fromBase64(str: string): Converter,
|
||||
fromComment(str: string): Converter,
|
||||
fromMapFileComment(str: string, dir: string): Converter,
|
||||
@ -190,12 +191,6 @@ declare module "convert-source-map" {
|
||||
};
|
||||
}
|
||||
|
||||
declare module "js-levenshtein" {
|
||||
declare module.exports: {
|
||||
(string, string): number,
|
||||
};
|
||||
}
|
||||
|
||||
declare module "core-js-compat/data" {
|
||||
declare type Target = "node" | "chrome" | "opera" | "edge" | "firefox" | "safari" | "ie" | "ios" | "android" | "electron" | "samsung";
|
||||
|
||||
|
||||
94
package.json
94
package.json
@ -3,39 +3,44 @@
|
||||
"private": true,
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"bootstrap": "make bootstrap",
|
||||
"build": "make build",
|
||||
"fix": "make fix",
|
||||
"lint": "make lint",
|
||||
"test": "make test"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.6.0",
|
||||
"@babel/core": "^7.6.0",
|
||||
"@babel/cli": "^7.7.0",
|
||||
"@babel/core": "^7.7.2",
|
||||
"@babel/eslint-plugin-development": "^1.0.1",
|
||||
"@babel/plugin-proposal-class-properties": "^7.5.5",
|
||||
"@babel/plugin-proposal-class-properties": "^7.7.0",
|
||||
"@babel/plugin-proposal-export-namespace-from": "^7.5.2",
|
||||
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.4.4",
|
||||
"@babel/plugin-proposal-numeric-separator": "^7.2.0",
|
||||
"@babel/plugin-proposal-object-rest-spread": "^7.7.4",
|
||||
"@babel/plugin-proposal-optional-chaining": "^7.6.0",
|
||||
"@babel/plugin-transform-modules-commonjs": "^7.6.0",
|
||||
"@babel/plugin-transform-runtime": "^7.6.0",
|
||||
"@babel/preset-env": "^7.6.0",
|
||||
"@babel/plugin-transform-flow-strip-types": "^7.7.4",
|
||||
"@babel/plugin-transform-for-of": "^7.7.4",
|
||||
"@babel/plugin-transform-modules-commonjs": "^7.7.0",
|
||||
"@babel/plugin-transform-runtime": "^7.6.2",
|
||||
"@babel/preset-env": "^7.7.1",
|
||||
"@babel/preset-flow": "^7.0.0",
|
||||
"@babel/register": "^7.6.0",
|
||||
"@babel/runtime": "^7.6.0",
|
||||
"babel-eslint": "^11.0.0-beta.0",
|
||||
"@babel/register": "^7.7.0",
|
||||
"@babel/runtime": "^7.7.2",
|
||||
"@rollup/plugin-alias": "^2.2.0",
|
||||
"@rollup/plugin-json": "^4.0.0",
|
||||
"babel-eslint": "^11.0.0-beta.2",
|
||||
"babel-jest": "^24.9.0",
|
||||
"babel-loader": "^8.0.6",
|
||||
"babel-plugin-transform-charcodes": "^0.2.0",
|
||||
"browserify": "^16.2.3",
|
||||
"bundle-collapser": "^1.2.1",
|
||||
"chalk": "^2.4.2",
|
||||
"charcodes": "^0.2.0",
|
||||
"derequire": "^2.0.2",
|
||||
"duplicate-package-checker-webpack-plugin": "^2.1.0",
|
||||
"enhanced-resolve": "^3.0.0",
|
||||
"eslint": "^6.0.1",
|
||||
"eslint-config-babel": "^9.0.0",
|
||||
"eslint-import-resolver-node": "^0.3.2",
|
||||
"eslint-plugin-flowtype": "^3.8.2",
|
||||
"eslint-plugin-import": "^2.17.2",
|
||||
"eslint-plugin-prettier": "^3.1.0",
|
||||
@ -48,32 +53,32 @@
|
||||
"gulp-newer": "^1.0.0",
|
||||
"gulp-plumber": "^1.2.1",
|
||||
"gulp-rename": "^1.4.0",
|
||||
"gulp-uglify": "^3.0.2",
|
||||
"gulp-watch": "^5.0.1",
|
||||
"husky": "^3.0.0",
|
||||
"jest": "^24.9.0",
|
||||
"lerna": "^3.16.0",
|
||||
"lerna": "^3.19.0",
|
||||
"lerna-changelog": "^0.5.0",
|
||||
"lint-staged": "^9.2.0",
|
||||
"lodash": "^4.17.13",
|
||||
"mergeiterator": "^1.2.5",
|
||||
"output-file-sync": "^2.0.0",
|
||||
"prettier": "^1.17.1",
|
||||
"prettier": "^1.19.1",
|
||||
"pump": "^3.0.0",
|
||||
"rimraf": "^2.6.3",
|
||||
"rollup": "^1.12.0",
|
||||
"rollup": "^1.27.5",
|
||||
"rollup-plugin-babel": "^4.0.0",
|
||||
"rollup-plugin-commonjs": "^10.1.0",
|
||||
"rollup-plugin-node-builtins": "^2.1.2",
|
||||
"rollup-plugin-node-globals": "^1.4.0",
|
||||
"rollup-plugin-node-resolve": "^5.0.0",
|
||||
"rollup-plugin-replace": "^2.2.0",
|
||||
"rollup-plugin-terser": "^5.1.2",
|
||||
"test262-stream": "^1.3.0",
|
||||
"through2": "^2.0.0",
|
||||
"typescript": "^3.6.3",
|
||||
"warnings-to-errors-webpack-plugin": "^2.0.0",
|
||||
"webpack": "^3.4.1",
|
||||
"webpack-dependency-suite": "^2.4.4",
|
||||
"webpack-stream": "^4.0.0"
|
||||
"typescript": "^3.6.3"
|
||||
},
|
||||
"resolutions": {
|
||||
"@lerna/**/@lerna/collect-updates": "https://github.com/babel/lerna.git#babel-collect-updates"
|
||||
"@lerna/collect-updates": "https://github.com/babel/lerna.git#babel-collect-updates"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6.9.0 < 14.0.0",
|
||||
@ -89,52 +94,5 @@
|
||||
"hooks": {
|
||||
"pre-commit": "lint-staged"
|
||||
}
|
||||
},
|
||||
"jest": {
|
||||
"collectCoverageFrom": [
|
||||
"packages/*/src/**/*.mjs",
|
||||
"packages/*/src/**/*.js",
|
||||
"codemods/*/src/**/*.mjs",
|
||||
"codemods/*/src/**/*.js"
|
||||
],
|
||||
"testRegex": "./(packages|codemods)/[^/]+/test/.+\\.m?js$",
|
||||
"testPathIgnorePatterns": [
|
||||
"/node_modules/",
|
||||
"/test/fixtures/",
|
||||
"/test/debug-fixtures/",
|
||||
"/babel-parser/test/expressions/",
|
||||
"/test/tmp/",
|
||||
"/test/__data__/",
|
||||
"/test/helpers/",
|
||||
"<rootDir>/test/warning\\.js",
|
||||
"<rootDir>/build/",
|
||||
"_browser\\.js"
|
||||
],
|
||||
"testEnvironment": "node",
|
||||
"setupFilesAfterEnv": [
|
||||
"<rootDir>/test/testSetupFile.js"
|
||||
],
|
||||
"transformIgnorePatterns": [
|
||||
"/node_modules/",
|
||||
"<rootDir>/packages/babel-standalone/babel(\\.min)?\\.js",
|
||||
"<rootDir>/packages/babel-preset-env-standalone/babel-preset-env(\\.min)?\\.js",
|
||||
"/test/(fixtures|tmp|__data__)/",
|
||||
"<rootDir>/(packages|codemods)/[^/]+/lib/"
|
||||
],
|
||||
"coveragePathIgnorePatterns": [
|
||||
"/node_modules/",
|
||||
"<rootDir>/packages/babel-standalone/babel(\\.min)?\\.js",
|
||||
"<rootDir>/packages/babel-preset-env-standalone/babel-preset-env(\\.min)?\\.js",
|
||||
"/test/(fixtures|tmp|__data__)/"
|
||||
],
|
||||
"modulePathIgnorePatterns": [
|
||||
"/test/fixtures/",
|
||||
"/test/tmp/",
|
||||
"/test/__data__/",
|
||||
"<rootDir>/build/"
|
||||
],
|
||||
"moduleNameMapper": {
|
||||
"^@babel/([a-zA-Z0-9_-]+)$": "<rootDir>/packages/babel-$1/"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@babel/cli",
|
||||
"version": "7.7.0",
|
||||
"version": "7.8.3-csx.2",
|
||||
"description": "Babel command line.",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||
"homepage": "https://babeljs.io/",
|
||||
@ -19,7 +19,7 @@
|
||||
"compiler"
|
||||
],
|
||||
"dependencies": {
|
||||
"commander": "^2.8.1",
|
||||
"commander": "^4.0.1",
|
||||
"convert-source-map": "^1.1.0",
|
||||
"fs-readdir-recursive": "^1.1.0",
|
||||
"glob": "^7.0.0",
|
||||
@ -32,11 +32,12 @@
|
||||
"chokidar": "^2.1.8"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "^7.0.0-0"
|
||||
"@babel/core": "^7.0.0-0 || csx"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.7.0",
|
||||
"@babel/helper-fixtures": "^7.6.3"
|
||||
"@babel/core": "7.8.3-csx.2",
|
||||
"@babel/helper-fixtures": "7.8.3-csx.2",
|
||||
"rimraf": "^3.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"babel": "./bin/babel.js",
|
||||
|
||||
@ -9,6 +9,13 @@ import fs from "fs";
|
||||
import * as util from "./util";
|
||||
import { type CmdOptions } from "./options";
|
||||
|
||||
const FILE_TYPE = Object.freeze({
|
||||
NON_COMPILABLE: "NON_COMPILABLE",
|
||||
COMPILED: "COMPILED",
|
||||
IGNORED: "IGNORED",
|
||||
ERR_COMPILATION: "ERR_COMPILATION",
|
||||
});
|
||||
|
||||
function outputFileSync(filePath: string, data: string | Buffer): void {
|
||||
makeDirSync(path.dirname(filePath));
|
||||
fs.writeFileSync(filePath, data);
|
||||
@ -20,15 +27,22 @@ export default async function({
|
||||
}: CmdOptions): Promise<void> {
|
||||
const filenames = cliOptions.filenames;
|
||||
|
||||
async function write(src: string, base: string): Promise<boolean> {
|
||||
async function write(
|
||||
src: string,
|
||||
base: string,
|
||||
): Promise<$Keys<typeof FILE_TYPE>> {
|
||||
let relative = path.relative(base, src);
|
||||
|
||||
if (!util.isCompilableExtension(relative, cliOptions.extensions)) {
|
||||
return false;
|
||||
return FILE_TYPE.NON_COMPILABLE;
|
||||
}
|
||||
|
||||
// remove extension and then append back on .js
|
||||
relative = util.adjustRelative(relative, cliOptions.keepFileExtension);
|
||||
relative = util.withExtension(
|
||||
relative,
|
||||
cliOptions.keepFileExtension
|
||||
? path.extname(relative)
|
||||
: cliOptions.outFileExtension,
|
||||
);
|
||||
|
||||
const dest = getDest(relative, base);
|
||||
|
||||
@ -43,7 +57,7 @@ export default async function({
|
||||
),
|
||||
);
|
||||
|
||||
if (!res) return false;
|
||||
if (!res) return FILE_TYPE.IGNORED;
|
||||
|
||||
// we've requested explicit sourcemaps to be written to disk
|
||||
if (
|
||||
@ -64,11 +78,11 @@ export default async function({
|
||||
console.log(src + " -> " + dest);
|
||||
}
|
||||
|
||||
return true;
|
||||
return FILE_TYPE.COMPILED;
|
||||
} catch (err) {
|
||||
if (cliOptions.watch) {
|
||||
console.error(err);
|
||||
return false;
|
||||
return FILE_TYPE.ERR_COMPILATION;
|
||||
}
|
||||
|
||||
throw err;
|
||||
@ -85,13 +99,16 @@ export default async function({
|
||||
async function handleFile(src: string, base: string): Promise<boolean> {
|
||||
const written = await write(src, base);
|
||||
|
||||
if (!written && cliOptions.copyFiles) {
|
||||
if (
|
||||
(cliOptions.copyFiles && written === FILE_TYPE.NON_COMPILABLE) ||
|
||||
(cliOptions.copyIgnored && written === FILE_TYPE.IGNORED)
|
||||
) {
|
||||
const filename = path.relative(base, src);
|
||||
const dest = getDest(filename, base);
|
||||
outputFileSync(dest, fs.readFileSync(src));
|
||||
util.chmod(src, dest);
|
||||
}
|
||||
return written;
|
||||
return written === FILE_TYPE.COMPILED;
|
||||
}
|
||||
|
||||
async function handle(filenameOrDir: string): Promise<number> {
|
||||
@ -145,7 +162,7 @@ export default async function({
|
||||
if (cliOptions.watch) {
|
||||
const chokidar = util.requireChokidar();
|
||||
|
||||
filenames.forEach(function(filenameOrDir) {
|
||||
filenames.forEach(function(filenameOrDir: string): void {
|
||||
const watcher = chokidar.watch(filenameOrDir, {
|
||||
persistent: true,
|
||||
ignoreInitial: true,
|
||||
@ -155,8 +172,8 @@ export default async function({
|
||||
},
|
||||
});
|
||||
|
||||
["add", "change"].forEach(function(type) {
|
||||
watcher.on(type, function(filename) {
|
||||
["add", "change"].forEach(function(type: string): void {
|
||||
watcher.on(type, function(filename: string): void {
|
||||
handleFile(
|
||||
filename,
|
||||
filename === filenameOrDir
|
||||
|
||||
@ -216,6 +216,7 @@ export default async function({
|
||||
const chokidar = util.requireChokidar();
|
||||
chokidar
|
||||
.watch(filenames, {
|
||||
disableGlobbing: true,
|
||||
persistent: true,
|
||||
ignoreInitial: true,
|
||||
awaitWriteFinish: {
|
||||
@ -223,8 +224,11 @@ export default async function({
|
||||
pollInterval: 10,
|
||||
},
|
||||
})
|
||||
.on("all", function(type: string, filename: string) {
|
||||
if (!util.isCompilableExtension(filename, cliOptions.extensions)) {
|
||||
.on("all", function(type: string, filename: string): void {
|
||||
if (
|
||||
!util.isCompilableExtension(filename, cliOptions.extensions) &&
|
||||
!filenames.includes(filename)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -74,8 +74,8 @@ commander.option(
|
||||
booleanify,
|
||||
);
|
||||
commander.option(
|
||||
"--minified [true|false]",
|
||||
"Save as many bytes when printing.",
|
||||
"--minified",
|
||||
"Save as many bytes when printing. (false by default)",
|
||||
);
|
||||
commander.option(
|
||||
"--auxiliary-comment-before [string]",
|
||||
@ -160,9 +160,22 @@ commander.option(
|
||||
"--delete-dir-on-start",
|
||||
"Delete the out directory before compilation.",
|
||||
);
|
||||
commander.option(
|
||||
"--out-file-extension [string]",
|
||||
"Use a specific extension for the output files",
|
||||
);
|
||||
|
||||
commander.option(
|
||||
"--copy-ignored",
|
||||
"Include ignored files when copying non-compilable files.",
|
||||
);
|
||||
|
||||
commander.version(pkg.version + " (@babel/core " + version + ")");
|
||||
commander.usage("[options] <files ...>");
|
||||
// register an empty action handler so that commander.js can throw on
|
||||
// unknown options _after_ args
|
||||
// see https://github.com/tj/commander.js/issues/561#issuecomment-522209408
|
||||
commander.action(() => {});
|
||||
|
||||
export type CmdOptions = {
|
||||
babelOptions: Object,
|
||||
@ -233,6 +246,12 @@ export default function parseArgv(args: Array<string>): CmdOptions | null {
|
||||
);
|
||||
}
|
||||
|
||||
if (commander.keepFileExtension && commander.outFileExtension) {
|
||||
errors.push(
|
||||
"--out-file-extension cannot be used with --keep-file-extension",
|
||||
);
|
||||
}
|
||||
|
||||
if (errors.length) {
|
||||
console.error("babel:");
|
||||
errors.forEach(function(e) {
|
||||
@ -289,6 +308,7 @@ export default function parseArgv(args: Array<string>): CmdOptions | null {
|
||||
filenames,
|
||||
extensions: opts.extensions,
|
||||
keepFileExtension: opts.keepFileExtension,
|
||||
outFileExtension: opts.outFileExtension,
|
||||
watch: opts.watch,
|
||||
skipInitialBuild: opts.skipInitialBuild,
|
||||
outFile: opts.outFile,
|
||||
@ -300,6 +320,7 @@ export default function parseArgv(args: Array<string>): CmdOptions | null {
|
||||
quiet: opts.quiet,
|
||||
deleteDirOnStart: opts.deleteDirOnStart,
|
||||
sourceMapTarget: opts.sourceMapTarget,
|
||||
copyIgnored: opts.copyIgnored,
|
||||
},
|
||||
};
|
||||
}
|
||||
@ -316,7 +337,10 @@ function booleanify(val: any): boolean | any {
|
||||
return val;
|
||||
}
|
||||
|
||||
function collect(value, previousValue): Array<string> {
|
||||
function collect(
|
||||
value: string | any,
|
||||
previousValue: Array<string>,
|
||||
): Array<string> {
|
||||
// If the user passed the option with no value, like "babel file.js --presets", do nothing.
|
||||
if (typeof value !== "string") return previousValue;
|
||||
|
||||
|
||||
@ -127,12 +127,7 @@ export function requireChokidar(): Object {
|
||||
}
|
||||
}
|
||||
|
||||
export function adjustRelative(
|
||||
relative: string,
|
||||
keepFileExtension: boolean,
|
||||
): string {
|
||||
if (keepFileExtension) {
|
||||
return relative;
|
||||
}
|
||||
return relative.replace(/\.(\w*?)$/, "") + ".js";
|
||||
export function withExtension(filename: string, ext: string = ".js") {
|
||||
const newBasename = path.basename(filename, path.extname(filename)) + ext;
|
||||
return path.join(path.dirname(filename), newBasename);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user