Compare commits
1135 Commits
harmony-v3
...
v3.11.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6c7226c10e | ||
|
|
dc575919e2 | ||
|
|
4298201938 | ||
|
|
4f833937fe | ||
|
|
3d71e97dd1 | ||
|
|
7f35d9cee0 | ||
|
|
9f8106e1d8 | ||
|
|
b7b8435721 | ||
|
|
c0c04c33bb | ||
|
|
0e234a25c5 | ||
|
|
3096f6fdad | ||
|
|
176c09c6a5 | ||
|
|
9272f662c0 | ||
|
|
4d33cb2f94 | ||
|
|
00d0eda85b | ||
|
|
1cdf810f0b | ||
|
|
b512726cf3 | ||
|
|
9b7a13c8c7 | ||
|
|
74ff6ce261 | ||
|
|
b1b8898e7c | ||
|
|
55451e7b78 | ||
|
|
ffcce28ce1 | ||
|
|
9c0feb69e5 | ||
|
|
bc6e105174 | ||
|
|
b91a2459c0 | ||
|
|
b7a57fc69d | ||
|
|
2dbe40b01b | ||
|
|
813ac3ba96 | ||
|
|
220dc95c0d | ||
|
|
8f0521d51d | ||
|
|
f9946767c9 | ||
|
|
58ac5b9bd5 | ||
|
|
66140b459e | ||
|
|
1786c69070 | ||
|
|
95ef4d5377 | ||
|
|
04017215cc | ||
|
|
142bd1bd1a | ||
|
|
8cb509d50e | ||
|
|
baf4903aa7 | ||
|
|
35465d590e | ||
|
|
ccd91b9952 | ||
|
|
47a5e6e17a | ||
|
|
090ee895e1 | ||
|
|
1cd1a1e5ee | ||
|
|
1d835ac17d | ||
|
|
9e07ac4102 | ||
|
|
92d1391e5e | ||
|
|
b4ff6d0f2d | ||
|
|
9882a9f4af | ||
|
|
40f36b9e01 | ||
|
|
6e105c5ca6 | ||
|
|
af35cd32f2 | ||
|
|
7de8daa4b1 | ||
|
|
305a4bdcee | ||
|
|
3472cf1a90 | ||
|
|
6d4c0fa6fa | ||
|
|
3cca0d6249 | ||
|
|
12ac49b970 | ||
|
|
8c670cae93 | ||
|
|
0e3da27727 | ||
|
|
13cdc167a2 | ||
|
|
51803cdcb2 | ||
|
|
8fa470c17c | ||
|
|
90410f9fc3 | ||
|
|
ef3831437d | ||
|
|
171c544705 | ||
|
|
3c609e2f4a | ||
|
|
f0ae03ed39 | ||
|
|
31c6b45036 | ||
|
|
3ac533e644 | ||
|
|
38a46c86d7 | ||
|
|
0f0759ec15 | ||
|
|
7f501f9fed | ||
|
|
72844eb5a4 | ||
|
|
09d93cc6c8 | ||
|
|
dd1374aa8a | ||
|
|
fdf2e8c5b0 | ||
|
|
a9d934ab4e | ||
|
|
2a053710bd | ||
|
|
219aac6a84 | ||
|
|
2039185051 | ||
|
|
ad27c14202 | ||
|
|
a62b086184 | ||
|
|
335456cf77 | ||
|
|
d64d0b0bec | ||
|
|
3ac575f2e8 | ||
|
|
d33a3a3253 | ||
|
|
d7456a2dc2 | ||
|
|
d97672613d | ||
|
|
30761eede5 | ||
|
|
fb30aeccaf | ||
|
|
226aa1f76b | ||
|
|
6e235602fb | ||
|
|
980fcbb56b | ||
|
|
375ebe316d | ||
|
|
2500930234 | ||
|
|
2f0da2ff05 | ||
|
|
83a3cbf151 | ||
|
|
da8d154571 | ||
|
|
e33c727e8b | ||
|
|
f886b3fb2b | ||
|
|
b1cc15e85b | ||
|
|
3aa765e429 | ||
|
|
93d084a1d1 | ||
|
|
c7a3e09407 | ||
|
|
09525c7530 | ||
|
|
a7e15fe73c | ||
|
|
a31c27c7cf | ||
|
|
1caf7c7bd2 | ||
|
|
0eb0c9b388 | ||
|
|
7dc61cdc89 | ||
|
|
af1b2f30c9 | ||
|
|
37b4fc7e31 | ||
|
|
da85d102e3 | ||
|
|
35fe1092d3 | ||
|
|
f2d486e771 | ||
|
|
fee677786e | ||
|
|
aa83ecdb3b | ||
|
|
a153176469 | ||
|
|
1c6384b6a5 | ||
|
|
e8db526f51 | ||
|
|
fa13ed4391 | ||
|
|
23f0dca992 | ||
|
|
45ab3b51d8 | ||
|
|
49670d216b | ||
|
|
e2237d8cd2 | ||
|
|
91f078fe35 | ||
|
|
a546cb881d | ||
|
|
84d5dffd9f | ||
|
|
a8e286f7e1 | ||
|
|
9b05494ebc | ||
|
|
30ef20a208 | ||
|
|
a4002ef467 | ||
|
|
9d758a216b | ||
|
|
af13f8dd2c | ||
|
|
88423f2574 | ||
|
|
ee632a5519 | ||
|
|
dfe47bcc42 | ||
|
|
6d3dcaa59e | ||
|
|
1bc0df1569 | ||
|
|
a98ba994bd | ||
|
|
cd671221c5 | ||
|
|
bce3919748 | ||
|
|
61b66e83f1 | ||
|
|
a5db8cd14c | ||
|
|
2021c2fa3e | ||
|
|
484d3fd8c7 | ||
|
|
3bf8699f95 | ||
|
|
58c24f8007 | ||
|
|
e61bc34eb1 | ||
|
|
8b2cfd45fa | ||
|
|
ae9f56be10 | ||
|
|
9aed0e3a73 | ||
|
|
88850a6e05 | ||
|
|
9e881407bd | ||
|
|
3188db7b90 | ||
|
|
a82ca62b66 | ||
|
|
e9465717ab | ||
|
|
e89031f1af | ||
|
|
596fad182e | ||
|
|
ed69adedcd | ||
|
|
1dbf7d4a3a | ||
|
|
2a9d0fc6fb | ||
|
|
45db96679e | ||
|
|
1d15f51238 | ||
|
|
ed7c82fa5e | ||
|
|
3b273cecac | ||
|
|
d764b6cc3b | ||
|
|
08c4729eb4 | ||
|
|
5561d3e7f3 | ||
|
|
491d6ce1d5 | ||
|
|
cd55eeb77c | ||
|
|
3230952d57 | ||
|
|
df3bb8028a | ||
|
|
28b7b15da1 | ||
|
|
aa37b19698 | ||
|
|
02e889e449 | ||
|
|
486ce00b8e | ||
|
|
eb481cee8c | ||
|
|
fbc9d8009b | ||
|
|
04fd3d90f8 | ||
|
|
a489f8cb5e | ||
|
|
e2e4b7fb37 | ||
|
|
c97ad98f92 | ||
|
|
b24eb22c6b | ||
|
|
06ba4e2ce8 | ||
|
|
0eb4577a82 | ||
|
|
43498769f0 | ||
|
|
60c0bc1e6b | ||
|
|
6a5c63e1e3 | ||
|
|
d47ea77811 | ||
|
|
7840746bd9 | ||
|
|
49ea629f3f | ||
|
|
13c72a986c | ||
|
|
08af3eae44 | ||
|
|
27bdcbbd83 | ||
|
|
2c4d7d66ef | ||
|
|
d1cc5270a3 | ||
|
|
75c5b6029b | ||
|
|
fa14a9cfcd | ||
|
|
aeb9ea5ac2 | ||
|
|
798841be82 | ||
|
|
cc6eb4b15f | ||
|
|
14eee81dc6 | ||
|
|
55ebb27878 | ||
|
|
87046410ef | ||
|
|
f9b3198714 | ||
|
|
48b62393a4 | ||
|
|
a00f8dade7 | ||
|
|
9daa2fb6f5 | ||
|
|
8d81d264f4 | ||
|
|
5ef7060098 | ||
|
|
938368ba21 | ||
|
|
fe2f1965d6 | ||
|
|
30ed8f5580 | ||
|
|
dc9e7cd1fe | ||
|
|
76f40e2528 | ||
|
|
8024f7f7a8 | ||
|
|
eb7fa25270 | ||
|
|
ee7647dc67 | ||
|
|
bd2f53bc8b | ||
|
|
e8a7956b6f | ||
|
|
2b24dc25fb | ||
|
|
35cc5aa06f | ||
|
|
c1dd49e075 | ||
|
|
c76ee4b868 | ||
|
|
e23bf48052 | ||
|
|
7e0ad232b0 | ||
|
|
63adfb1590 | ||
|
|
f9806b43c3 | ||
|
|
c4c9c6d37d | ||
|
|
33f3b0c1d9 | ||
|
|
abb8ae02a5 | ||
|
|
97728c4f0b | ||
|
|
f74b7f7401 | ||
|
|
b06fd8a933 | ||
|
|
1bb0804d60 | ||
|
|
998245ffd6 | ||
|
|
7a033bb825 | ||
|
|
a441b00951 | ||
|
|
88985a46ed | ||
|
|
34ead0430b | ||
|
|
66ab2df97f | ||
|
|
b656f7c083 | ||
|
|
873db281e8 | ||
|
|
6bf1486935 | ||
|
|
ffa1943177 | ||
|
|
ac429dc8e1 | ||
|
|
3766d5c962 | ||
|
|
20f9a1d908 | ||
|
|
dcb74f558e | ||
|
|
0794aaa2c2 | ||
|
|
74801de315 | ||
|
|
f80d5b8c9e | ||
|
|
d900006973 | ||
|
|
39f849590b | ||
|
|
818738beec | ||
|
|
bc2a4a3bb8 | ||
|
|
a4a8ccea8c | ||
|
|
36dcfa3e82 | ||
|
|
94f33570e3 | ||
|
|
44d6912a55 | ||
|
|
3a4497a1c3 | ||
|
|
3ee13cae02 | ||
|
|
99cf3a38c5 | ||
|
|
3ae24329eb | ||
|
|
01b13d797c | ||
|
|
306e8e9873 | ||
|
|
9577c8c1b7 | ||
|
|
925a0ca1a0 | ||
|
|
b694bfa351 | ||
|
|
a2fc32c64b | ||
|
|
88504ab869 | ||
|
|
e38754e802 | ||
|
|
eb6f32bfc3 | ||
|
|
f110601fb4 | ||
|
|
2a508c6e5f | ||
|
|
fd6144d95b | ||
|
|
60d4e7b09f | ||
|
|
b38838c6bf | ||
|
|
708973e51d | ||
|
|
dac9e69f9e | ||
|
|
39aa33749b | ||
|
|
da68ec6e19 | ||
|
|
15a3ebd467 | ||
|
|
9110fac9a2 | ||
|
|
83f42ede36 | ||
|
|
0ce71bbec0 | ||
|
|
46d142cbf6 | ||
|
|
38c3bcf9a0 | ||
|
|
6e9afdc94f | ||
|
|
c4d28e3b2a | ||
|
|
77261e1ee0 | ||
|
|
903a5df9a5 | ||
|
|
c810ecd081 | ||
|
|
dce9dfce0e | ||
|
|
3d72663689 | ||
|
|
a2b16e89a4 | ||
|
|
b35f4c5a83 | ||
|
|
41eb4f1725 | ||
|
|
94bc221669 | ||
|
|
822d298a55 | ||
|
|
273c6020ba | ||
|
|
1b07f64057 | ||
|
|
80d9c44b22 | ||
|
|
dc0cd088cf | ||
|
|
c69c026728 | ||
|
|
b5f4e1187f | ||
|
|
827bcec186 | ||
|
|
d105ab9722 | ||
|
|
b39228892d | ||
|
|
ff72eaa3c3 | ||
|
|
0a1c9b34ce | ||
|
|
03e968be62 | ||
|
|
421bb7083a | ||
|
|
bdc8ef2218 | ||
|
|
bca52fcba2 | ||
|
|
d6d31cbb5a | ||
|
|
a051846d22 | ||
|
|
3485472866 | ||
|
|
c8d60d6983 | ||
|
|
6092bf23de | ||
|
|
7052ce5aef | ||
|
|
d13b71297e | ||
|
|
457f958af3 | ||
|
|
53517db3e4 | ||
|
|
c13caf4876 | ||
|
|
fbfa6178a6 | ||
|
|
5315dd95b0 | ||
|
|
31a7bf2a22 | ||
|
|
f0a29902ac | ||
|
|
0d820e4c0a | ||
|
|
f01f580d6c | ||
|
|
c01ff76288 | ||
|
|
83a42716c3 | ||
|
|
2557148bba | ||
|
|
dd22eda888 | ||
|
|
f4c77886e7 | ||
|
|
df547ffd97 | ||
|
|
70551febc8 | ||
|
|
44499a6643 | ||
|
|
470a7d4df1 | ||
|
|
551420132c | ||
|
|
b0040ba654 | ||
|
|
c93ca6ee53 | ||
|
|
df506439b1 | ||
|
|
36b2d35bf3 | ||
|
|
79c60032a5 | ||
|
|
a3754068dd | ||
|
|
2ba5f391e0 | ||
|
|
87119e44a0 | ||
|
|
b499e03f82 | ||
|
|
a478f275e4 | ||
|
|
e9e76dcf04 | ||
|
|
0dcedad2d5 | ||
|
|
36a430cd1e | ||
|
|
41a6eb892a | ||
|
|
91d87ae663 | ||
|
|
5beb7e4797 | ||
|
|
46caaa82ba | ||
|
|
5d258259a4 | ||
|
|
14c35739dd | ||
|
|
f5ceff6e4b | ||
|
|
4d6771b9b1 | ||
|
|
d17191111a | ||
|
|
0ff607cb80 | ||
|
|
1988495d71 | ||
|
|
fdc10086da | ||
|
|
746f5f6c62 | ||
|
|
d83d3d741a | ||
|
|
99ac73a635 | ||
|
|
a2e4c2fd97 | ||
|
|
94785e8e14 | ||
|
|
4dbdac9c31 | ||
|
|
78c8efd851 | ||
|
|
af310ba2d0 | ||
|
|
2f3930d1b9 | ||
|
|
d1a78920d9 | ||
|
|
d9cd3d33c8 | ||
|
|
22b47cdd63 | ||
|
|
4cf612dc9f | ||
|
|
a19d31dd33 | ||
|
|
01d6e0f223 | ||
|
|
ab050e7a94 | ||
|
|
75aa6ef848 | ||
|
|
519a00bd8a | ||
|
|
3ff0feddee | ||
|
|
74396acc86 | ||
|
|
036bca980c | ||
|
|
18c2b1841b | ||
|
|
fe19ab7c57 | ||
|
|
9074f05129 | ||
|
|
04fbb1f949 | ||
|
|
bf7e4ca1a3 | ||
|
|
d68ddc31f9 | ||
|
|
500e31e03b | ||
|
|
bef856addb | ||
|
|
9a6faf365b | ||
|
|
e915832a36 | ||
|
|
0593892d6e | ||
|
|
b866a23671 | ||
|
|
1283d73853 | ||
|
|
1b61a81b5d | ||
|
|
5a88c30d65 | ||
|
|
168ae747ad | ||
|
|
d4b7010678 | ||
|
|
e27493f3c2 | ||
|
|
292d1de363 | ||
|
|
6768e6578f | ||
|
|
48a0f6fe41 | ||
|
|
81caadb709 | ||
|
|
d959e0b86f | ||
|
|
67278e76c8 | ||
|
|
c289ba1139 | ||
|
|
02cc4a0d03 | ||
|
|
4e06e1ca34 | ||
|
|
644f65feca | ||
|
|
8504a4ea0e | ||
|
|
10c1a78772 | ||
|
|
a6a0319f1c | ||
|
|
d1b2ecec27 | ||
|
|
552be61c4d | ||
|
|
dcfc4aca5b | ||
|
|
4027f87717 | ||
|
|
910799ca99 | ||
|
|
4bd36dc8da | ||
|
|
ab15c40770 | ||
|
|
fe65ce9658 | ||
|
|
d6fd18d0b0 | ||
|
|
0d17c5b0fa | ||
|
|
5b20bad4b3 | ||
|
|
765a06340f | ||
|
|
5045e140b1 | ||
|
|
10648c9af6 | ||
|
|
87e67ec299 | ||
|
|
61a0dad9fe | ||
|
|
3e2c51a4da | ||
|
|
0e29ad5eb9 | ||
|
|
0f2687ecfc | ||
|
|
1c0defdc03 | ||
|
|
dcbf2236c7 | ||
|
|
24bb288832 | ||
|
|
6ad8e1081f | ||
|
|
815eff1f7c | ||
|
|
1e9b576ee9 | ||
|
|
3797458365 | ||
|
|
1858c2018c | ||
|
|
ec7f071272 | ||
|
|
f1eb03f2c0 | ||
|
|
0f4cfa877a | ||
|
|
1d5c2becbd | ||
|
|
22a09ea7c5 | ||
|
|
bad664c632 | ||
|
|
8a191c0a84 | ||
|
|
83fb8b4ca1 | ||
|
|
f38e31bd1e | ||
|
|
24e8b47977 | ||
|
|
95618793a4 | ||
|
|
2f3b460212 | ||
|
|
06e135e35f | ||
|
|
ebbf3d4a51 | ||
|
|
a270ba6b59 | ||
|
|
37f35e4ac2 | ||
|
|
50a578c1f6 | ||
|
|
85237b08d4 | ||
|
|
27b159e711 | ||
|
|
82b3eed5ef | ||
|
|
0f7aa41e33 | ||
|
|
370c8e0385 | ||
|
|
4240fba9b8 | ||
|
|
267bc70d33 | ||
|
|
a53ab99378 | ||
|
|
02308a7b56 | ||
|
|
0b3705e82f | ||
|
|
da5a21b240 | ||
|
|
5bd0cf8633 | ||
|
|
9199ab5846 | ||
|
|
ca6dce43fe | ||
|
|
543dd7d3d7 | ||
|
|
6b4886c908 | ||
|
|
0201cb4b52 | ||
|
|
cd072317d0 | ||
|
|
0785a15ace | ||
|
|
b1279a46d9 | ||
|
|
b571619d31 | ||
|
|
7b5350b459 | ||
|
|
1549db70e6 | ||
|
|
8ff9a3c8fb | ||
|
|
91cae51d8f | ||
|
|
8af2f5fbcf | ||
|
|
86a8016323 | ||
|
|
009dcdae01 | ||
|
|
f86f615d83 | ||
|
|
d3d1d11926 | ||
|
|
736019b767 | ||
|
|
a39bdb5840 | ||
|
|
e8ab0a44b2 | ||
|
|
c3ca293e6b | ||
|
|
516b67a43b | ||
|
|
eba3a37bb5 | ||
|
|
6d57ca1a59 | ||
|
|
3320251b4b | ||
|
|
33c94d3bd9 | ||
|
|
b18f717b46 | ||
|
|
a0d4b648bb | ||
|
|
6db880e16d | ||
|
|
a82003d6ac | ||
|
|
da9f1622fc | ||
|
|
8a4c7077bb | ||
|
|
0a63f2f2b0 | ||
|
|
931ac66638 | ||
|
|
35338a100f | ||
|
|
d57b606e73 | ||
|
|
00ada04111 | ||
|
|
a31c477fea | ||
|
|
bde7418ce1 | ||
|
|
70bb304a0a | ||
|
|
9d3b1efd86 | ||
|
|
482e1baea3 | ||
|
|
e4f5ba1d29 | ||
|
|
b9053c7a25 | ||
|
|
d357a7aabc | ||
|
|
ae77ebe5a5 | ||
|
|
04439edcec | ||
|
|
a246195412 | ||
|
|
8939a36bc7 | ||
|
|
a21c348d93 | ||
|
|
1f0def10eb | ||
|
|
f87caac9d8 | ||
|
|
d538a73250 | ||
|
|
2e4fbdeb08 | ||
|
|
3bc7cc82bb | ||
|
|
45fbdbc2dc | ||
|
|
54cb678055 | ||
|
|
e88c439eac | ||
|
|
9fc8cd4076 | ||
|
|
5476cb8f05 | ||
|
|
6a30e1d6be | ||
|
|
e4881245d9 | ||
|
|
354fec8a9c | ||
|
|
11cdab745d | ||
|
|
a89d424a0b | ||
|
|
429d2b56b7 | ||
|
|
2ea96549c5 | ||
|
|
fba008e298 | ||
|
|
c37a8e927e | ||
|
|
413bbe0480 | ||
|
|
34075fc4c4 | ||
|
|
e5436ca566 | ||
|
|
cfde686eab | ||
|
|
a206964c0a | ||
|
|
c56d89f804 | ||
|
|
c215706350 | ||
|
|
d3b93ec682 | ||
|
|
6fe20dbe33 | ||
|
|
7ccdf3337b | ||
|
|
dafed54764 | ||
|
|
a84beafd1b | ||
|
|
f01cc1e413 | ||
|
|
338dd144b8 | ||
|
|
c719552317 | ||
|
|
855964a87a | ||
|
|
a438e2fca9 | ||
|
|
00833e893a | ||
|
|
f1a77e4fc0 | ||
|
|
b55a2fd531 | ||
|
|
e8a2c0b5bf | ||
|
|
21cd7e3f57 | ||
|
|
5172ba5f2a | ||
|
|
a57b069409 | ||
|
|
4454656c3b | ||
|
|
fa43768ce0 | ||
|
|
a74e600fa0 | ||
|
|
4b21526310 | ||
|
|
a7a7b1daed | ||
|
|
7436977aa5 | ||
|
|
e3c565b46f | ||
|
|
54b0b49b68 | ||
|
|
65648d84a5 | ||
|
|
fd788590f6 | ||
|
|
143f9054da | ||
|
|
f2286c33f1 | ||
|
|
b9615f7a62 | ||
|
|
c520e99eda | ||
|
|
615ae37ca3 | ||
|
|
7aa7f21872 | ||
|
|
4430a436eb | ||
|
|
9707ccdc9f | ||
|
|
cb8f3a2a31 | ||
|
|
8b3259e0c2 | ||
|
|
b66f47b8dd | ||
|
|
8d2e6f333e | ||
|
|
b3ef5e514d | ||
|
|
627f5fb41e | ||
|
|
d90777b724 | ||
|
|
e49297e5eb | ||
|
|
ebd82b3fb6 | ||
|
|
d074aa6e27 | ||
|
|
b052f62710 | ||
|
|
d4ac84b255 | ||
|
|
e250396d7e | ||
|
|
c6fa39b482 | ||
|
|
9aae4f2424 | ||
|
|
008c236137 | ||
|
|
b1c0664066 | ||
|
|
ea999b0e92 | ||
|
|
ce7e220de4 | ||
|
|
2bdaca10ae | ||
|
|
aa0029204e | ||
|
|
f352bcec3a | ||
|
|
08514030f4 | ||
|
|
694ca5d045 | ||
|
|
57fb58b263 | ||
|
|
18c1c9b38a | ||
|
|
5c1ae3662d | ||
|
|
cfebeb2f63 | ||
|
|
fc78423f1d | ||
|
|
2a5277b391 | ||
|
|
d47547dc71 | ||
|
|
304db15a20 | ||
|
|
7cf72b8d66 | ||
|
|
cea685f8d9 | ||
|
|
8d4b5344f4 | ||
|
|
34a0ab6f2c | ||
|
|
bcebacbb9e | ||
|
|
018a5a750a | ||
|
|
b468103f26 | ||
|
|
66c126ffde | ||
|
|
fdee083465 | ||
|
|
5ffc17d4aa | ||
|
|
6aa750010f | ||
|
|
76df77c08c | ||
|
|
957d5537a8 | ||
|
|
88c8f4e363 | ||
|
|
ab36b9b10a | ||
|
|
28330913d8 | ||
|
|
766a4147d4 | ||
|
|
915c7e234d | ||
|
|
e54ddcbb8a | ||
|
|
9e19e63551 | ||
|
|
bce7ee5f6a | ||
|
|
b39043f3ab | ||
|
|
caf96acb08 | ||
|
|
c76749084b | ||
|
|
5843494ee2 | ||
|
|
efa21ae3e6 | ||
|
|
24d9633a35 | ||
|
|
7963b96681 | ||
|
|
8c62d854ce | ||
|
|
69931574e1 | ||
|
|
b5af8a1914 | ||
|
|
c14d09ba84 | ||
|
|
4fc39d8dad | ||
|
|
0b7c70f726 | ||
|
|
f72d3029dd | ||
|
|
1a0d6edc81 | ||
|
|
7b59b2f5b2 | ||
|
|
7bc7704edf | ||
|
|
14e712ee80 | ||
|
|
f83adcc995 | ||
|
|
df8a99439a | ||
|
|
6b91d12ec3 | ||
|
|
f37b91879f | ||
|
|
d835c72c80 | ||
|
|
c4cebb4b01 | ||
|
|
d51a00a450 | ||
|
|
fc0f168a0c | ||
|
|
a0ca595c2c | ||
|
|
1a314e9f60 | ||
|
|
6fcbd5e217 | ||
|
|
22cea023d1 | ||
|
|
70d4477e05 | ||
|
|
838f837379 | ||
|
|
82a8b6f612 | ||
|
|
69fc7ca8da | ||
|
|
0a79496e0a | ||
|
|
9e87edfc2e | ||
|
|
27211cf2d5 | ||
|
|
b5ce199711 | ||
|
|
c71ed91e63 | ||
|
|
f7545d0f1c | ||
|
|
59eecb6bf5 | ||
|
|
d83c6490ab | ||
|
|
7362f57966 | ||
|
|
eaa2c1f6af | ||
|
|
6a916523d4 | ||
|
|
ba7069d52b | ||
|
|
4dd7d0e39b | ||
|
|
90199d0a96 | ||
|
|
b82fd0ad41 | ||
|
|
183da16896 | ||
|
|
87857b0f1b | ||
|
|
e5f6a88233 | ||
|
|
8d0b00317e | ||
|
|
db49daf365 | ||
|
|
923deeff35 | ||
|
|
0b62a28b47 | ||
|
|
44116c6d2b | ||
|
|
b5bab254ce | ||
|
|
81603ecd15 | ||
|
|
e67553fa55 | ||
|
|
fcf542f262 | ||
|
|
8adfc29f91 | ||
|
|
02f47e1713 | ||
|
|
07f64d4050 | ||
|
|
6982a0554c | ||
|
|
fa3250199a | ||
|
|
06b9894c19 | ||
|
|
9f9db504d7 | ||
|
|
82ae95c334 | ||
|
|
9a5e2052c4 | ||
|
|
b1410be443 | ||
|
|
12985d86c2 | ||
|
|
49bfc6b555 | ||
|
|
d1c6bb8c7c | ||
|
|
5c169615a8 | ||
|
|
73d77f4f64 | ||
|
|
ccf0e2ef4f | ||
|
|
20ca0f5906 | ||
|
|
b29d435bb5 | ||
|
|
90585e29c2 | ||
|
|
d8fc281915 | ||
|
|
188c39e8d5 | ||
|
|
5429234138 | ||
|
|
b9f72a4a81 | ||
|
|
fc6ebd04a5 | ||
|
|
7e00a12741 | ||
|
|
10b3752b1e | ||
|
|
fe51a91395 | ||
|
|
951d87ca94 | ||
|
|
798fc21530 | ||
|
|
a75a046abb | ||
|
|
38f2b4579f | ||
|
|
56e2a369d0 | ||
|
|
0daa199fa8 | ||
|
|
73e98dcda4 | ||
|
|
36bca6934d | ||
|
|
ace5811691 | ||
|
|
ba7bad0dbd | ||
|
|
b8b2ac5230 | ||
|
|
ea2359381b | ||
|
|
52de64cf16 | ||
|
|
455790202a | ||
|
|
f40f5eb228 | ||
|
|
604caa09e7 | ||
|
|
29a71d3aae | ||
|
|
39a907bde3 | ||
|
|
70474310f3 | ||
|
|
b5f0f4f3a1 | ||
|
|
2905fd625a | ||
|
|
4facd94029 | ||
|
|
4b5993ff15 | ||
|
|
2351a672ea | ||
|
|
4a528c469c | ||
|
|
82d1ef0242 | ||
|
|
7fdd2082a6 | ||
|
|
e529f54e90 | ||
|
|
d626e9bf19 | ||
|
|
a2a9459684 | ||
|
|
a3dfeea144 | ||
|
|
d316fb139d | ||
|
|
83d8aa8b12 | ||
|
|
4f1c12b6fd | ||
|
|
d8e0e34354 | ||
|
|
0c4f315c02 | ||
|
|
0809699bdc | ||
|
|
2088e1c19d | ||
|
|
bf1d47180c | ||
|
|
0cfbd79aa1 | ||
|
|
d66d86f20b | ||
|
|
905325d3e2 | ||
|
|
dea0cc0662 | ||
|
|
d69d8007d6 | ||
|
|
c0b8f2a16d | ||
|
|
cb0257dbbf | ||
|
|
9637f51b68 | ||
|
|
3026bd8975 | ||
|
|
78a44d5ab0 | ||
|
|
7e13c0db40 | ||
|
|
e6a2e9e4d0 | ||
|
|
e773f03927 | ||
|
|
b16380d669 | ||
|
|
334b07a3db | ||
|
|
3cc1527f00 | ||
|
|
525a61fb55 | ||
|
|
c3a002ff97 | ||
|
|
fad6766a90 | ||
|
|
aa664dea0a | ||
|
|
102f994b9d | ||
|
|
2a4c68be4f | ||
|
|
541e6011af | ||
|
|
6fa3fbeae8 | ||
|
|
4eb4cb656c | ||
|
|
193612ac67 | ||
|
|
95cfce68ea | ||
|
|
ec4202590d | ||
|
|
5e2cd07d6f | ||
|
|
06166df999 | ||
|
|
e2dc9cf091 | ||
|
|
069df27bf1 | ||
|
|
3e7873217c | ||
|
|
e21bab7ce6 | ||
|
|
ac9a168fba | ||
|
|
81b64549ce | ||
|
|
082e004b87 | ||
|
|
983e69128b | ||
|
|
b335912e86 | ||
|
|
cc07f3b806 | ||
|
|
07e4b64f3a | ||
|
|
d3ce2bc9e7 | ||
|
|
cff3bf4914 | ||
|
|
79cfac77bd | ||
|
|
224c14d49d | ||
|
|
7857354d85 | ||
|
|
b4aef753e7 | ||
|
|
424173d311 | ||
|
|
ec7cd1dcf7 | ||
|
|
7def684730 | ||
|
|
10f961c27b | ||
|
|
b483678ca7 | ||
|
|
cbbe6fad60 | ||
|
|
f96929c031 | ||
|
|
2b6657e967 | ||
|
|
7c0c92943f | ||
|
|
62a66dfff4 | ||
|
|
2cab348341 | ||
|
|
460218a3f8 | ||
|
|
e49416e4aa | ||
|
|
d4d7d99b70 | ||
|
|
6a696d0a7b | ||
|
|
1c9e13f47d | ||
|
|
b757450cd8 | ||
|
|
23ec484806 | ||
|
|
f1e1bb419a | ||
|
|
6a0af85c8b | ||
|
|
09269be974 | ||
|
|
bf832cde16 | ||
|
|
2972d58dbb | ||
|
|
2e22d38a02 | ||
|
|
ce27bcd69a | ||
|
|
9336cc8247 | ||
|
|
9809567dfc | ||
|
|
1ee8be8d91 | ||
|
|
8430c2f9f8 | ||
|
|
659c8a7632 | ||
|
|
3564b4f20d | ||
|
|
3505a3604a | ||
|
|
9b1bc6c014 | ||
|
|
9f23185f2b | ||
|
|
b82feb9302 | ||
|
|
7f2a591c7e | ||
|
|
afbcebddf6 | ||
|
|
484e484571 | ||
|
|
6f3f21233f | ||
|
|
a6873a3859 | ||
|
|
7a6d452b54 | ||
|
|
9b58b54e2d | ||
|
|
c598a12af9 | ||
|
|
cfe3a98ce5 | ||
|
|
14778e049b | ||
|
|
446fb0198b | ||
|
|
7d3cddf9d6 | ||
|
|
6dead95eb3 | ||
|
|
cc931b3ad8 | ||
|
|
d838b4b52e | ||
|
|
2f3bddbaca | ||
|
|
673b071637 | ||
|
|
da82fa59a7 | ||
|
|
333792352e | ||
|
|
e2ec270b04 | ||
|
|
ed7a0a454e | ||
|
|
d819559a01 | ||
|
|
8ca49155a8 | ||
|
|
b95e3338d9 | ||
|
|
e40a0ee9c6 | ||
|
|
cb62bd98d3 | ||
|
|
f30790b11b | ||
|
|
5205dbcbf4 | ||
|
|
3ff625de7e | ||
|
|
4832bc5d88 | ||
|
|
7f342cb3e3 | ||
|
|
05e7d34ed4 | ||
|
|
86607156e3 | ||
|
|
0fe259e9c5 | ||
|
|
8701a99a15 | ||
|
|
1476c78b53 | ||
|
|
cb6a92892f | ||
|
|
f1556cb945 | ||
|
|
efffb81735 | ||
|
|
202f90ef8f | ||
|
|
c07ea17c01 | ||
|
|
edb4e3bd52 | ||
|
|
4113609dd4 | ||
|
|
7ac7b0872f | ||
|
|
86ae5881b7 | ||
|
|
fac003c64f | ||
|
|
2273655c17 | ||
|
|
01057cf76d | ||
|
|
032f096b7f | ||
|
|
4b334edf49 | ||
|
|
8ddcbc39e6 | ||
|
|
0b0eac1d5d | ||
|
|
b29fc8b27c | ||
|
|
5de369fa67 | ||
|
|
7918a50d52 | ||
|
|
21794c9b8d | ||
|
|
6c686ce593 | ||
|
|
db902af4c6 | ||
|
|
7d6907cb99 | ||
|
|
092d9affb8 | ||
|
|
8f681b1d17 | ||
|
|
90313875f7 | ||
|
|
3f18a61532 | ||
|
|
02a6ce07eb | ||
|
|
738fd52bc4 | ||
|
|
d18979bb23 | ||
|
|
8266993c6e | ||
|
|
9a137e8613 | ||
|
|
ef618332ea | ||
|
|
7f418978c9 | ||
|
|
04cc395c35 | ||
|
|
e008dc1bde | ||
|
|
ddf96cfda2 | ||
|
|
ebfd5c5c74 | ||
|
|
f2ad542679 | ||
|
|
c43118be4f | ||
|
|
93f3b2b114 | ||
|
|
bf000beae7 | ||
|
|
0e16d92786 | ||
|
|
2441827408 | ||
|
|
0aff037a35 | ||
|
|
74a2f53683 | ||
|
|
e20935c3f2 | ||
|
|
3e34f62a1c | ||
|
|
d21cb84696 | ||
|
|
3dd495ecdd | ||
|
|
b9f3ddfb30 | ||
|
|
77332a0315 | ||
|
|
85c56adbd1 | ||
|
|
8da3754e51 | ||
|
|
9a6b11f8e6 | ||
|
|
7ac6fdcc99 | ||
|
|
f6610baaa8 | ||
|
|
09b320e8a5 | ||
|
|
5a1e99d713 | ||
|
|
b762f2d6f4 | ||
|
|
172079a47f | ||
|
|
c58d3936a3 | ||
|
|
18302bf8e9 | ||
|
|
bc5047c1e7 | ||
|
|
206a54a746 | ||
|
|
32def5ebf5 | ||
|
|
ecc9f6b770 | ||
|
|
b37a68c84f | ||
|
|
c141ae6f8d | ||
|
|
97c464dbf5 | ||
|
|
3b28b915eb | ||
|
|
eb001dc1d9 | ||
|
|
aa9bdf416e | ||
|
|
8987780db6 | ||
|
|
30cfea2e7a | ||
|
|
f4e2fb9864 | ||
|
|
b80062c490 | ||
|
|
667fc4d08b | ||
|
|
6142117cdd | ||
|
|
ae28a24c7f | ||
|
|
ebe761cad0 | ||
|
|
fa7a7c5c5a | ||
|
|
557636f3b7 | ||
|
|
49fbe9c5ac | ||
|
|
2ac5086831 | ||
|
|
c6cfa04d10 | ||
|
|
346fa12e0e | ||
|
|
cda27b0970 | ||
|
|
3c74047368 | ||
|
|
94525d859f | ||
|
|
1127a2caf3 | ||
|
|
246d9d4e83 | ||
|
|
4c0b0177b6 | ||
|
|
38bfb73f06 | ||
|
|
bbedbf4ea0 | ||
|
|
2cfb5aa7da | ||
|
|
6c45101870 | ||
|
|
2c2fd89e34 | ||
|
|
f46281e2b7 | ||
|
|
25a18883f5 | ||
|
|
5b4b07e9a7 | ||
|
|
a8aa28a7a6 | ||
|
|
fe5a68f9d5 | ||
|
|
71e61153b1 | ||
|
|
c8b6f4733d | ||
|
|
a48f87abf2 | ||
|
|
2fd927a7cc | ||
|
|
8428326ea1 | ||
|
|
31f8209193 | ||
|
|
9b0f86f5a1 | ||
|
|
ee082ace1b | ||
|
|
ae67a49850 | ||
|
|
4178289c38 | ||
|
|
74ae16f9f8 | ||
|
|
1968203d83 | ||
|
|
86ea38a259 | ||
|
|
8a713e449f | ||
|
|
24aa07855b | ||
|
|
5fd723f143 | ||
|
|
516eaef50c | ||
|
|
4ae1fb3ed8 | ||
|
|
011123223b | ||
|
|
96439ca246 | ||
|
|
c927cea632 | ||
|
|
9f4b98f8e4 | ||
|
|
0f2ef3367c | ||
|
|
7e5b5cac97 | ||
|
|
c1346e06b7 | ||
|
|
0d2fe8e3ef | ||
|
|
f2b9c11e2a | ||
|
|
fe647b083e | ||
|
|
dfe4f6c6de | ||
|
|
a09c8ad666 | ||
|
|
ec598c351b | ||
|
|
eba0f93bc0 | ||
|
|
99800d4aa9 | ||
|
|
70d56c951a | ||
|
|
b810e2f8da | ||
|
|
1abe14296e | ||
|
|
6920e898d1 | ||
|
|
dd71639264 | ||
|
|
2dcc552ce0 | ||
|
|
55387e8fd0 | ||
|
|
7e3e9da860 | ||
|
|
00f509405b | ||
|
|
aceb0af36b | ||
|
|
4f0953f7e9 | ||
|
|
182a47bfb1 | ||
|
|
cd27f4ec38 | ||
|
|
8158b1bdcf | ||
|
|
aacf3edc68 | ||
|
|
8b89072190 | ||
|
|
395a17ccda | ||
|
|
3f355866cf | ||
|
|
71d52f147d | ||
|
|
eb7adaa6fc | ||
|
|
e5cf7972ea | ||
|
|
f81ff10a9b | ||
|
|
16d40915b4 | ||
|
|
e7c21e87e3 | ||
|
|
c4c2ef44d0 | ||
|
|
a845897758 | ||
|
|
32ea2c5530 | ||
|
|
bc61deeca9 | ||
|
|
6a5e74b44e | ||
|
|
54446341ee | ||
|
|
4e12a6f740 | ||
|
|
b35dfc2599 | ||
|
|
9e1da9235e | ||
|
|
a5ffe2c23f | ||
|
|
9282e7b0c6 | ||
|
|
5229cb2b1b | ||
|
|
458e3e15f0 | ||
|
|
c615a1e80a | ||
|
|
10a938cb79 | ||
|
|
4956ad311b | ||
|
|
145874e504 | ||
|
|
bd7be07c38 | ||
|
|
71ee91e716 | ||
|
|
4f70d2e28c | ||
|
|
4b6ca5e742 | ||
|
|
9306da3c58 | ||
|
|
1ac25fc032 | ||
|
|
5f046c724b | ||
|
|
af0262b7e5 | ||
|
|
6b3aeff1d8 | ||
|
|
20e4f8277f | ||
|
|
f3a487a368 | ||
|
|
2dde41615a | ||
|
|
8b69a3d18e | ||
|
|
d40950b741 | ||
|
|
7659ea1d2e | ||
|
|
bdeadffbf5 | ||
|
|
5e6f26445f | ||
|
|
f0a99125ee | ||
|
|
1e4de2e6d3 | ||
|
|
8b4dcd8f3e | ||
|
|
285401ced8 | ||
|
|
9db4c42380 | ||
|
|
94e5e00c03 | ||
|
|
dc6bcaa18e | ||
|
|
d58b184835 | ||
|
|
b3a57ff019 | ||
|
|
3d5bc08185 | ||
|
|
0692435f01 | ||
|
|
f67a6b0e43 | ||
|
|
343ea326c2 | ||
|
|
1c150c632f | ||
|
|
0a0f4f5591 | ||
|
|
931daa85bf | ||
|
|
00e4f7b3c1 | ||
|
|
11e63bc335 | ||
|
|
33405bb24b | ||
|
|
57dc4fb32f | ||
|
|
b85a358deb | ||
|
|
43697958f3 | ||
|
|
3f961bbba0 | ||
|
|
0a1e523cd5 | ||
|
|
4231f7323e | ||
|
|
da2de350c3 | ||
|
|
41beae4dd7 | ||
|
|
82db9188ac | ||
|
|
3dc9e140e4 | ||
|
|
fed0096556 | ||
|
|
2bdc8802dd | ||
|
|
5ef7cb372a | ||
|
|
4ad7b1dae4 | ||
|
|
9186859cb7 | ||
|
|
47c0713747 | ||
|
|
293c566d6c | ||
|
|
9c306406f1 | ||
|
|
9db0695b10 | ||
|
|
f2af093402 | ||
|
|
b9ad53d1ab | ||
|
|
b0eab71470 | ||
|
|
3493a182b2 | ||
|
|
27c5284d3d | ||
|
|
540220b91b | ||
|
|
84634da4b5 | ||
|
|
1743621889 | ||
|
|
f330ab743a | ||
|
|
4377e932ca | ||
|
|
bac14ba881 | ||
|
|
ec095ed647 | ||
|
|
17e73121fa | ||
|
|
f71e8fd948 | ||
|
|
3e62faa64f | ||
|
|
e9645e017f | ||
|
|
55b5f2a8aa |
21
.github/ISSUE_TEMPLATE.md
vendored
21
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,20 +1,25 @@
|
|||||||
**Bug report or feature request?**
|
**Bug report or feature request?**
|
||||||
|
|
||||||
<!-- Note: sub-optimal but correct code is not a bug -->
|
<!-- Note: sub-optimal but correct code is not a bug -->
|
||||||
|
|
||||||
**ES5 or ES6+ input?**
|
|
||||||
|
|
||||||
<!-- Note: for ES6 see: https://github.com/mishoo/UglifyJS2/tree/harmony#harmony -->
|
|
||||||
|
|
||||||
**Uglify version (`uglifyjs -V`)**
|
**Uglify version (`uglifyjs -V`)**
|
||||||
|
|
||||||
**JavaScript input** <!-- ideally as small as possible -->
|
**JavaScript input**
|
||||||
|
|
||||||
|
<!--
|
||||||
|
A complete parsable JS program exhibiting the issue with
|
||||||
|
UglifyJS alone - without third party tools or libraries.
|
||||||
|
Ideally the input should be as small as possible.
|
||||||
|
Post a link to a gist if necessary.
|
||||||
|
|
||||||
|
Issues without a reproducible test case will be closed.
|
||||||
|
-->
|
||||||
|
|
||||||
**The `uglifyjs` CLI command executed or `minify()` options used.**
|
**The `uglifyjs` CLI command executed or `minify()` options used.**
|
||||||
|
|
||||||
**JavaScript output or error produced.**
|
**JavaScript output or error produced.**
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Note: `uglify-js` only supports ES5.
|
Note: `uglify-js` only supports JavaScript.
|
||||||
Those wishing to minify ES6 should use `uglify-es`.
|
Those wishing to minify ES6+ should transpile first.
|
||||||
-->
|
-->
|
||||||
|
|||||||
48
.github/workflows/ci.yml
vendored
Normal file
48
.github/workflows/ci.yml
vendored
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
name: CI
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
push:
|
||||||
|
branches: [ master ]
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
node: [ "0.8", "0.10", "0.12", "4", "6", "8", "10", "12", latest ]
|
||||||
|
os: [ ubuntu-latest, windows-latest ]
|
||||||
|
script: [ compress, mocha, release/benchmark, release/jetstream ]
|
||||||
|
exclude:
|
||||||
|
- node: "0.8"
|
||||||
|
script: release/benchmark
|
||||||
|
- node: "0.8"
|
||||||
|
script: release/jetstream
|
||||||
|
name: ${{ matrix.node }} ${{ matrix.os }} ${{ matrix.script }}
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
env:
|
||||||
|
NODE: ${{ matrix.node }}
|
||||||
|
TYPE: ${{ matrix.script }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: tmp
|
||||||
|
key: tmp ${{ matrix.script }}
|
||||||
|
- name: Perform tests
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
git clone --branch v1.5.4 --depth 1 https://github.com/jasongin/nvs.git ~/.nvs
|
||||||
|
while ! timeout 60 bash -c '. ~/.nvs/nvs.sh add $NODE && nvs use $NODE'; do
|
||||||
|
cd ~/.nvs
|
||||||
|
while !(git clean -xdf); do echo "'git clean' failed - retrying..."; done
|
||||||
|
cd -
|
||||||
|
done
|
||||||
|
. ~/.nvs/nvs.sh --version
|
||||||
|
nvs use $NODE
|
||||||
|
node --version
|
||||||
|
npm config set audit false
|
||||||
|
npm config set optional false
|
||||||
|
npm config set save false
|
||||||
|
npm config set strict-ssl false
|
||||||
|
npm config set update-notifier false
|
||||||
|
npm --version
|
||||||
|
while !(npm install); do echo "'npm install' failed - retrying..."; done
|
||||||
|
node test/$TYPE
|
||||||
44
.github/workflows/ufuzz.yml
vendored
Normal file
44
.github/workflows/ufuzz.yml
vendored
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
name: Fuzzing
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
schedule:
|
||||||
|
- cron: "*/5 * * * *"
|
||||||
|
env:
|
||||||
|
BASE_URL: https://api.github.com/repos/${{ github.repository }}
|
||||||
|
CAUSE: ${{ github.event_name }}
|
||||||
|
RUN_NUM: ${{ github.run_number }}
|
||||||
|
TOKEN: ${{ github.token }}
|
||||||
|
jobs:
|
||||||
|
ufuzz:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os: [ ubuntu-latest, windows-latest ]
|
||||||
|
name: ${{ matrix.os }}
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Perform fuzzing
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
git clone --branch v1.5.4 --depth 1 https://github.com/jasongin/nvs.git ~/.nvs
|
||||||
|
while ! timeout 60 bash -c '. ~/.nvs/nvs.sh add 8 && nvs use 8'; do
|
||||||
|
cd ~/.nvs
|
||||||
|
while !(git clean -xdf); do echo "'git clean' failed - retrying..."; done
|
||||||
|
cd -
|
||||||
|
done
|
||||||
|
. ~/.nvs/nvs.sh --version
|
||||||
|
nvs use 8
|
||||||
|
node --version
|
||||||
|
npm config set audit false
|
||||||
|
npm config set optional false
|
||||||
|
npm config set save false
|
||||||
|
npm config set strict-ssl false
|
||||||
|
npm config set update-notifier false
|
||||||
|
npm --version
|
||||||
|
while !(npm install); do echo "'npm install' failed - retrying..."; done
|
||||||
|
if [[ $CAUSE == "schedule" ]]; then
|
||||||
|
node test/ufuzz/job $BASE_URL $TOKEN $RUN_NUM
|
||||||
|
else
|
||||||
|
node test/ufuzz/job 5000
|
||||||
|
fi
|
||||||
11
.travis.yml
11
.travis.yml
@@ -1,11 +0,0 @@
|
|||||||
language: node_js
|
|
||||||
node_js:
|
|
||||||
- "0.10"
|
|
||||||
- "0.12"
|
|
||||||
- "4"
|
|
||||||
- "6"
|
|
||||||
env:
|
|
||||||
- UGLIFYJS_TEST_ALL=1
|
|
||||||
matrix:
|
|
||||||
fast_finish: true
|
|
||||||
sudo: false
|
|
||||||
61
CONTRIBUTING.md
Normal file
61
CONTRIBUTING.md
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
Contributing
|
||||||
|
============
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
Every new feature and API change should be accompanied by a README additon.
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
All features and bugs should have tests that verify the fix. You can run all
|
||||||
|
tests using `npm test`.
|
||||||
|
|
||||||
|
The most common type of test are tests that verify input and output of the
|
||||||
|
Uglify transforms. These tests exist in `test/compress`. New tests can be added
|
||||||
|
either to an existing file or in a new file `issue-xxx.js`.
|
||||||
|
|
||||||
|
Tests that cannot be expressed as a simple AST can be found in `test/mocha`.
|
||||||
|
|
||||||
|
## Code style
|
||||||
|
|
||||||
|
- File encoding must be `UTF-8`.
|
||||||
|
- `LF` is always used as a line ending.
|
||||||
|
- Statements end with semicolons.
|
||||||
|
- Indentation uses 4 spaces, switch `case` 2 spaces.
|
||||||
|
- Identifiers use `snake_case`.
|
||||||
|
- Strings use double quotes (`"`).
|
||||||
|
- Use a trailing comma for multiline array and object literals to minimize diffs.
|
||||||
|
- The Uglify code only uses ES5, even in the `harmony` branch.
|
||||||
|
- Line length should be at most 80 cols, except when it is easier to read a
|
||||||
|
longer line.
|
||||||
|
- If both sides of a comparison are of the same type, `==` and `!=` are used.
|
||||||
|
- Multiline conditions place `&&` and `||` first on the line.
|
||||||
|
|
||||||
|
**Example feature**
|
||||||
|
|
||||||
|
```js
|
||||||
|
OPT(AST_Debugger, function(self, compressor) {
|
||||||
|
if (compressor.option("drop_debugger"))
|
||||||
|
return make_node(AST_EmptyStatement, self);
|
||||||
|
return self;
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example test case**
|
||||||
|
|
||||||
|
```js
|
||||||
|
drop_debugger: {
|
||||||
|
options = {
|
||||||
|
drop_debugger: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
debugger;
|
||||||
|
if (foo) debugger;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
if (foo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
|||||||
UglifyJS is released under the BSD license:
|
UglifyJS is released under the BSD license:
|
||||||
|
|
||||||
Copyright 2012-2013 (c) Mihai Bazon <mihai.bazon@gmail.com>
|
Copyright 2012-2019 (c) Mihai Bazon <mihai.bazon@gmail.com>
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions
|
modification, are permitted provided that the following conditions
|
||||||
|
|||||||
514
README.md
514
README.md
@@ -4,11 +4,10 @@ UglifyJS 3
|
|||||||
UglifyJS is a JavaScript parser, minifier, compressor and beautifier toolkit.
|
UglifyJS is a JavaScript parser, minifier, compressor and beautifier toolkit.
|
||||||
|
|
||||||
#### Note:
|
#### Note:
|
||||||
- **`uglify-js@3` has a simplified [API](#api-reference) and [CLI](#command-line-usage) that is not backwards compatible with [`uglify-js@2`](https://github.com/mishoo/UglifyJS2/tree/v2.x)**.
|
- **`uglify-js@3` has a simplified [API](#api-reference) and [CLI](#command-line-usage) that is not backwards compatible with [`uglify-js@2`](https://github.com/mishoo/UglifyJS/tree/v2.x)**.
|
||||||
- **Documentation for UglifyJS `2.x` releases can be found [here](https://github.com/mishoo/UglifyJS2/tree/v2.x)**.
|
- **Documentation for UglifyJS `2.x` releases can be found [here](https://github.com/mishoo/UglifyJS/tree/v2.x)**.
|
||||||
- `uglify-js` only supports ECMAScript 5 (ES5).
|
- `uglify-js` only supports JavaScript (ECMAScript 5).
|
||||||
- Those wishing to minify
|
- To minify ECMAScript 2015 or above, transpile using tools like [Babel](https://babeljs.io/).
|
||||||
ES2015+ (ES6+) should use the `npm` package [**uglify-es**](https://github.com/mishoo/UglifyJS2/tree/harmony).
|
|
||||||
|
|
||||||
Install
|
Install
|
||||||
-------
|
-------
|
||||||
@@ -70,7 +69,7 @@ a double dash to prevent input files being used as option arguments:
|
|||||||
`debug` Add debug prefix and suffix.
|
`debug` Add debug prefix and suffix.
|
||||||
`domprops` Mangle property names that overlaps
|
`domprops` Mangle property names that overlaps
|
||||||
with DOM properties.
|
with DOM properties.
|
||||||
`keep_quoted` Only mangle unquoted properies.
|
`keep_quoted` Only mangle unquoted properties.
|
||||||
`regex` Only mangle matched property names.
|
`regex` Only mangle matched property names.
|
||||||
`reserved` List of names that should not be mangled.
|
`reserved` List of names that should not be mangled.
|
||||||
-b, --beautify [options] Beautify output/specify output options:
|
-b, --beautify [options] Beautify output/specify output options:
|
||||||
@@ -88,6 +87,7 @@ a double dash to prevent input files being used as option arguments:
|
|||||||
`wrap_iife` Wrap IIFEs in parenthesis. Note: you may
|
`wrap_iife` Wrap IIFEs in parenthesis. Note: you may
|
||||||
want to disable `negate_iife` under
|
want to disable `negate_iife` under
|
||||||
compressor options.
|
compressor options.
|
||||||
|
-O, --output-opts [options] Specify output options (`beautify` disabled by default).
|
||||||
-o, --output <file> Output file path (default STDOUT). Specify `ast` or
|
-o, --output <file> Output file path (default STDOUT). Specify `ast` or
|
||||||
`spidermonkey` to write UglifyJS or SpiderMonkey AST
|
`spidermonkey` to write UglifyJS or SpiderMonkey AST
|
||||||
as JSON to STDOUT respectively.
|
as JSON to STDOUT respectively.
|
||||||
@@ -105,13 +105,15 @@ a double dash to prevent input files being used as option arguments:
|
|||||||
sequences.
|
sequences.
|
||||||
--config-file <file> Read `minify()` options from JSON file.
|
--config-file <file> Read `minify()` options from JSON file.
|
||||||
-d, --define <expr>[=value] Global definitions.
|
-d, --define <expr>[=value] Global definitions.
|
||||||
|
-e, --enclose [arg[:value]] Embed everything in a big function, with configurable
|
||||||
|
argument(s) & value(s).
|
||||||
--ie8 Support non-standard Internet Explorer 8.
|
--ie8 Support non-standard Internet Explorer 8.
|
||||||
Equivalent to setting `ie8: true` in `minify()`
|
Equivalent to setting `ie8: true` in `minify()`
|
||||||
for `compress`, `mangle` and `output` options.
|
for `compress`, `mangle` and `output` options.
|
||||||
By default UglifyJS will not try to be IE-proof.
|
By default UglifyJS will not try to be IE-proof.
|
||||||
--keep-fnames Do not mangle/drop function names. Useful for
|
--keep-fnames Do not mangle/drop function names. Useful for
|
||||||
code relying on Function.prototype.name.
|
code relying on Function.prototype.name.
|
||||||
--name-cache File to hold mangled name mappings.
|
--name-cache <file> File to hold mangled name mappings.
|
||||||
--self Build UglifyJS as a library (implies --wrap UglifyJS)
|
--self Build UglifyJS as a library (implies --wrap UglifyJS)
|
||||||
--source-map [options] Enable source map/specify source map options:
|
--source-map [options] Enable source map/specify source map options:
|
||||||
`base` Path to compute relative paths from input files.
|
`base` Path to compute relative paths from input files.
|
||||||
@@ -119,10 +121,12 @@ a double dash to prevent input files being used as option arguments:
|
|||||||
JS that was generated from some other original
|
JS that was generated from some other original
|
||||||
code. Specify "inline" if the source map is
|
code. Specify "inline" if the source map is
|
||||||
included within the sources.
|
included within the sources.
|
||||||
`filename` Name and/or location of the output source.
|
`filename` Filename and/or location of the output source
|
||||||
|
(sets `file` attribute in source map).
|
||||||
`includeSources` Pass this flag if you want to include
|
`includeSources` Pass this flag if you want to include
|
||||||
the content of source files in the
|
the content of source files in the
|
||||||
source map as sourcesContent property.
|
source map as sourcesContent property.
|
||||||
|
`names` Include symbol names in the source map.
|
||||||
`root` Path to the original source to be included in
|
`root` Path to the original source to be included in
|
||||||
the source map.
|
the source map.
|
||||||
`url` If specified, path to the source map to append in
|
`url` If specified, path to the source map to append in
|
||||||
@@ -150,19 +154,24 @@ debugging your compressed JavaScript. To get a source map, pass
|
|||||||
|
|
||||||
Additional options:
|
Additional options:
|
||||||
|
|
||||||
- `--source-map filename=<NAME>` to specify the name of the source map.
|
- `--source-map "filename='<NAME>'"` to specify the name of the source map. The value of
|
||||||
|
`filename` is only used to set `file` attribute (see [the spec][sm-spec])
|
||||||
|
in source map file.
|
||||||
|
|
||||||
- `--source-map root=<URL>` to pass the URL where the original files can be found.
|
- `--source-map "root='<URL>'"` to pass the URL where the original files can be found.
|
||||||
|
|
||||||
|
- `--source-map "names=false"` to omit symbol names if you want to reduce size
|
||||||
|
of the source map file.
|
||||||
|
|
||||||
|
- `--source-map "url='<URL>'"` to specify the URL where the source map can be found.
|
||||||
Otherwise UglifyJS assumes HTTP `X-SourceMap` is being used and will omit the
|
Otherwise UglifyJS assumes HTTP `X-SourceMap` is being used and will omit the
|
||||||
`//# sourceMappingURL=` directive.
|
`//# sourceMappingURL=` directive.
|
||||||
|
|
||||||
- `--source-map url=<URL>` to specify the URL where the source map can be found.
|
|
||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
uglifyjs js/file1.js js/file2.js \
|
uglifyjs js/file1.js js/file2.js \
|
||||||
-o foo.min.js -c -m \
|
-o foo.min.js -c -m \
|
||||||
--source-map root="http://foo.com/src",url=foo.min.js.map
|
--source-map "root='http://foo.com/src',url='foo.min.js.map'"
|
||||||
|
|
||||||
The above will compress and mangle `file1.js` and `file2.js`, will drop the
|
The above will compress and mangle `file1.js` and `file2.js`, will drop the
|
||||||
output in `foo.min.js` and the source map in `foo.min.js.map`. The source
|
output in `foo.min.js` and the source map in `foo.min.js.map`. The source
|
||||||
@@ -181,8 +190,8 @@ CoffeeScript → compiled JS, UglifyJS can generate a map from CoffeeScript →
|
|||||||
compressed JS by mapping every token in the compiled JS to its original
|
compressed JS by mapping every token in the compiled JS to its original
|
||||||
location.
|
location.
|
||||||
|
|
||||||
To use this feature pass `--source-map content="/path/to/input/source.map"`
|
To use this feature pass `--source-map "content='/path/to/input/source.map'"`
|
||||||
or `--source-map content=inline` if the source map is included inline with
|
or `--source-map "content=inline"` if the source map is included inline with
|
||||||
the sources.
|
the sources.
|
||||||
|
|
||||||
## CLI compress options
|
## CLI compress options
|
||||||
@@ -203,19 +212,16 @@ Example:
|
|||||||
To enable the mangler you need to pass `--mangle` (`-m`). The following
|
To enable the mangler you need to pass `--mangle` (`-m`). The following
|
||||||
(comma-separated) options are supported:
|
(comma-separated) options are supported:
|
||||||
|
|
||||||
- `toplevel` — mangle names declared in the top level scope (disabled by
|
- `eval` (default `false`) -- mangle names visible in scopes where `eval` or
|
||||||
default).
|
`with` are used.
|
||||||
|
|
||||||
- `eval` — mangle names visible in scopes where `eval` or `with` are used
|
- `reserved` (default: `[]`) -- when mangling is enabled but you want to
|
||||||
(disabled by default).
|
prevent certain names from being mangled, you can declare those names with
|
||||||
|
`--mangle reserved` — pass a comma-separated list of names. For example:
|
||||||
|
|
||||||
When mangling is enabled but you want to prevent certain names from being
|
uglifyjs ... -m reserved=['$','require','exports']
|
||||||
mangled, you can declare those names with `--mangle reserved` — pass a
|
|
||||||
comma-separated list of names. For example:
|
|
||||||
|
|
||||||
uglifyjs ... -m reserved=[$,require,exports]
|
to prevent the `require`, `exports` and `$` names from being changed.
|
||||||
|
|
||||||
to prevent the `require`, `exports` and `$` names from being changed.
|
|
||||||
|
|
||||||
### CLI mangling property names (`--mangle-props`)
|
### CLI mangling property names (`--mangle-props`)
|
||||||
|
|
||||||
@@ -223,7 +229,7 @@ to prevent the `require`, `exports` and `$` names from being changed.
|
|||||||
is a separate step, different from variable name mangling. Pass
|
is a separate step, different from variable name mangling. Pass
|
||||||
`--mangle-props` to enable it. It will mangle all properties in the
|
`--mangle-props` to enable it. It will mangle all properties in the
|
||||||
input code with the exception of built in DOM properties and properties
|
input code with the exception of built in DOM properties and properties
|
||||||
in core javascript classes. For example:
|
in core JavaScript classes. For example:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
// example.js
|
// example.js
|
||||||
@@ -238,7 +244,7 @@ x.bar_ = 2;
|
|||||||
x["baz_"] = 3;
|
x["baz_"] = 3;
|
||||||
console.log(x.calc());
|
console.log(x.calc());
|
||||||
```
|
```
|
||||||
Mangle all properties (except for javascript `builtins`):
|
Mangle all properties (except for JavaScript `builtins`):
|
||||||
```bash
|
```bash
|
||||||
$ uglifyjs example.js -c -m --mangle-props
|
$ uglifyjs example.js -c -m --mangle-props
|
||||||
```
|
```
|
||||||
@@ -383,7 +389,47 @@ var code = {
|
|||||||
var options = { toplevel: true };
|
var options = { toplevel: true };
|
||||||
var result = UglifyJS.minify(code, options);
|
var result = UglifyJS.minify(code, options);
|
||||||
console.log(result.code);
|
console.log(result.code);
|
||||||
// console.log(function(n,o){return n+o}(3,7));
|
// console.log(3+7);
|
||||||
|
```
|
||||||
|
|
||||||
|
The `nameCache` option:
|
||||||
|
```javascript
|
||||||
|
var options = {
|
||||||
|
mangle: {
|
||||||
|
toplevel: true,
|
||||||
|
},
|
||||||
|
nameCache: {}
|
||||||
|
};
|
||||||
|
var result1 = UglifyJS.minify({
|
||||||
|
"file1.js": "function add(first, second) { return first + second; }"
|
||||||
|
}, options);
|
||||||
|
var result2 = UglifyJS.minify({
|
||||||
|
"file2.js": "console.log(add(1 + 2, 3 + 4));"
|
||||||
|
}, options);
|
||||||
|
console.log(result1.code);
|
||||||
|
// function n(n,r){return n+r}
|
||||||
|
console.log(result2.code);
|
||||||
|
// console.log(n(3,7));
|
||||||
|
```
|
||||||
|
|
||||||
|
You may persist the name cache to the file system in the following way:
|
||||||
|
```javascript
|
||||||
|
var cacheFileName = "/tmp/cache.json";
|
||||||
|
var options = {
|
||||||
|
mangle: {
|
||||||
|
properties: true,
|
||||||
|
},
|
||||||
|
nameCache: JSON.parse(fs.readFileSync(cacheFileName, "utf8"))
|
||||||
|
};
|
||||||
|
fs.writeFileSync("part1.js", UglifyJS.minify({
|
||||||
|
"file1.js": fs.readFileSync("file1.js", "utf8"),
|
||||||
|
"file2.js": fs.readFileSync("file2.js", "utf8")
|
||||||
|
}, options).code, "utf8");
|
||||||
|
fs.writeFileSync("part2.js", UglifyJS.minify({
|
||||||
|
"file3.js": fs.readFileSync("file3.js", "utf8"),
|
||||||
|
"file4.js": fs.readFileSync("file4.js", "utf8")
|
||||||
|
}, options).code, "utf8");
|
||||||
|
fs.writeFileSync(cacheFileName, JSON.stringify(options.nameCache), "utf8");
|
||||||
```
|
```
|
||||||
|
|
||||||
An example of a combination of `minify()` options:
|
An example of a combination of `minify()` options:
|
||||||
@@ -436,38 +482,47 @@ if (result.error) throw result.error;
|
|||||||
|
|
||||||
## Minify options
|
## Minify options
|
||||||
|
|
||||||
- `warnings` (default `false`) — pass `true` to return compressor warnings
|
|
||||||
in `result.warnings`. Use the value `"verbose"` for more detailed warnings.
|
|
||||||
|
|
||||||
- `parse` (default `{}`) — pass an object if you wish to specify some
|
|
||||||
additional [parse options](#parse-options).
|
|
||||||
|
|
||||||
- `compress` (default `{}`) — pass `false` to skip compressing entirely.
|
- `compress` (default `{}`) — pass `false` to skip compressing entirely.
|
||||||
Pass an object to specify custom [compress options](#compress-options).
|
Pass an object to specify custom [compress options](#compress-options).
|
||||||
|
|
||||||
|
- `ie8` (default `false`) -- set to `true` to support IE8.
|
||||||
|
|
||||||
|
- `keep_fnames` (default: `false`) -- pass `true` to prevent discarding or mangling
|
||||||
|
of function names. Useful for code relying on `Function.prototype.name`.
|
||||||
|
|
||||||
- `mangle` (default `true`) — pass `false` to skip mangling names, or pass
|
- `mangle` (default `true`) — pass `false` to skip mangling names, or pass
|
||||||
an object to specify [mangle options](#mangle-options) (see below).
|
an object to specify [mangle options](#mangle-options) (see below).
|
||||||
|
|
||||||
- `mangle.properties` (default `false`) — a subcategory of the mangle option.
|
- `mangle.properties` (default `false`) — a subcategory of the mangle option.
|
||||||
Pass an object to specify custom [mangle property options](#mangle-properties-options).
|
Pass an object to specify custom [mangle property options](#mangle-properties-options).
|
||||||
|
|
||||||
|
- `nameCache` (default `null`) -- pass an empty object `{}` or a previously
|
||||||
|
used `nameCache` object if you wish to cache mangled variable and
|
||||||
|
property names across multiple invocations of `minify()`. Note: this is
|
||||||
|
a read/write property. `minify()` will read the name cache state of this
|
||||||
|
object and update it during minification so that it may be
|
||||||
|
reused or externally persisted by the user.
|
||||||
|
|
||||||
- `output` (default `null`) — pass an object if you wish to specify
|
- `output` (default `null`) — pass an object if you wish to specify
|
||||||
additional [output options](#output-options). The defaults are optimized
|
additional [output options](#output-options). The defaults are optimized
|
||||||
for best compression.
|
for best compression.
|
||||||
|
|
||||||
- `sourceMap` (default `false`) - pass an object if you wish to specify
|
- `parse` (default `{}`) — pass an object if you wish to specify some
|
||||||
|
additional [parse options](#parse-options).
|
||||||
|
|
||||||
|
- `sourceMap` (default `false`) -- pass an object if you wish to specify
|
||||||
[source map options](#source-map-options).
|
[source map options](#source-map-options).
|
||||||
|
|
||||||
- `toplevel` (default `false`) - set to `true` if you wish to enable top level
|
- `toplevel` (default `false`) -- set to `true` if you wish to enable top level
|
||||||
variable and function name mangling and to drop unused variables and functions.
|
variable and function name mangling and to drop unused variables and functions.
|
||||||
|
|
||||||
- `ie8` (default `false`) - set to `true` to support IE8.
|
- `warnings` (default `false`) — pass `true` to return compressor warnings
|
||||||
|
in `result.warnings`. Use the value `"verbose"` for more detailed warnings.
|
||||||
|
|
||||||
## Minify options structure
|
## Minify options structure
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
{
|
{
|
||||||
warnings: false,
|
|
||||||
parse: {
|
parse: {
|
||||||
// parse options
|
// parse options
|
||||||
},
|
},
|
||||||
@@ -487,8 +542,10 @@ if (result.error) throw result.error;
|
|||||||
sourceMap: {
|
sourceMap: {
|
||||||
// source map options
|
// source map options
|
||||||
},
|
},
|
||||||
|
nameCache: null, // or specify a name cache object
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
ie8: false,
|
ie8: false,
|
||||||
|
warnings: false,
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -539,105 +596,114 @@ var result = UglifyJS.minify({"compiled.js": "compiled code"}, {
|
|||||||
|
|
||||||
If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.url`.
|
If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.url`.
|
||||||
|
|
||||||
|
If you wish to reduce file size of the source map, set option `sourceMap.names`
|
||||||
|
to be `false` and all symbol names will be omitted.
|
||||||
|
|
||||||
## Parse options
|
## Parse options
|
||||||
|
|
||||||
- `bare_returns` (default `false`) -- support top level `return` statements
|
- `bare_returns` (default `false`) -- support top level `return` statements
|
||||||
|
|
||||||
- `html5_comments` (default `true`)
|
- `html5_comments` (default `true`)
|
||||||
|
|
||||||
- `shebang` (default `true`) -- support `#!command` as the first line
|
- `shebang` (default `true`) -- support `#!command` as the first line
|
||||||
|
|
||||||
## Compress options
|
## Compress options
|
||||||
|
|
||||||
- `sequences` (default: true) -- join consecutive simple statements using the
|
- `arguments` (default: `true`) -- replace `arguments[index]` with function
|
||||||
comma operator. May be set to a positive integer to specify the maximum number
|
parameter name whenever possible.
|
||||||
of consecutive comma sequences that will be generated. If this option is set to
|
|
||||||
`true` then the default `sequences` limit is `200`. Set option to `false` or `0`
|
|
||||||
to disable. The smallest `sequences` length is `2`. A `sequences` value of `1`
|
|
||||||
is grandfathered to be equivalent to `true` and as such means `200`. On rare
|
|
||||||
occasions the default sequences limit leads to very slow compress times in which
|
|
||||||
case a value of `20` or less is recommended.
|
|
||||||
|
|
||||||
- `properties` -- rewrite property access using the dot notation, for
|
- `assignments` (default: `true`) -- apply optimizations to assignment expressions.
|
||||||
example `foo["bar"] → foo.bar`
|
|
||||||
|
|
||||||
- `dead_code` -- remove unreachable code
|
- `booleans` (default: `true`) -- various optimizations for boolean context,
|
||||||
|
for example `!!a ? b : c → a ? b : c`
|
||||||
|
|
||||||
- `drop_debugger` -- remove `debugger;` statements
|
- `collapse_vars` (default: `true`) -- Collapse single-use non-constant variables,
|
||||||
|
side effects permitting.
|
||||||
|
|
||||||
- `unsafe` (default: false) -- apply "unsafe" transformations (discussion below)
|
- `comparisons` (default: `true`) -- apply certain optimizations to binary nodes,
|
||||||
|
e.g. `!(a <= b) → a > b`, attempts to negate binary nodes, e.g.
|
||||||
|
`a = !b && !c && !d && !e → a=!(b||c||d||e)` etc.
|
||||||
|
|
||||||
- `unsafe_comps` (default: false) -- Reverse `<` and `<=` to `>` and `>=` to
|
- `conditionals` (default: `true`) -- apply optimizations for `if`-s and conditional
|
||||||
allow improved compression. This might be unsafe when an at least one of two
|
|
||||||
operands is an object with computed values due the use of methods like `get`,
|
|
||||||
or `valueOf`. This could cause change in execution order after operands in the
|
|
||||||
comparison are switching. Compression only works if both `comparisons` and
|
|
||||||
`unsafe_comps` are both set to true.
|
|
||||||
|
|
||||||
- `unsafe_math` (default: false) -- optimize numerical expressions like
|
|
||||||
`2 * x * 3` into `6 * x`, which may give imprecise floating point results.
|
|
||||||
|
|
||||||
- `unsafe_proto` (default: false) -- optimize expressions like
|
|
||||||
`Array.prototype.slice.call(a)` into `[].slice.call(a)`
|
|
||||||
|
|
||||||
- `unsafe_regexp` (default: false) -- enable substitutions of variables with
|
|
||||||
`RegExp` values the same way as if they are constants.
|
|
||||||
|
|
||||||
- `conditionals` -- apply optimizations for `if`-s and conditional
|
|
||||||
expressions
|
expressions
|
||||||
|
|
||||||
- `comparisons` -- apply certain optimizations to binary nodes, for example:
|
- `dead_code` (default: `true`) -- remove unreachable code
|
||||||
`!(a <= b) → a > b` (only when `unsafe_comps`), attempts to negate binary
|
|
||||||
nodes, e.g. `a = !b && !c && !d && !e → a=!(b||c||d||e)` etc.
|
|
||||||
|
|
||||||
- `evaluate` -- attempt to evaluate constant expressions
|
- `directives` (default: `true`) -- remove redundant or non-standard directives
|
||||||
|
|
||||||
- `booleans` -- various optimizations for boolean context, for example `!!a
|
- `drop_console` (default: `false`) -- Pass `true` to discard calls to
|
||||||
? b : c → a ? b : c`
|
`console.*` functions. If you wish to drop a specific function call
|
||||||
|
such as `console.info` and/or retain side effects from function arguments
|
||||||
|
after dropping the function call then use `pure_funcs` instead.
|
||||||
|
|
||||||
- `loops` -- optimizations for `do`, `while` and `for` loops when we can
|
- `drop_debugger` (default: `true`) -- remove `debugger;` statements
|
||||||
statically determine the condition
|
|
||||||
|
|
||||||
- `unused` -- drop unreferenced functions and variables (simple direct variable
|
- `evaluate` (default: `true`) -- Evaluate expression for shorter constant
|
||||||
assignments do not count as references unless set to `"keep_assign"`)
|
representation. Pass `"eager"` to always replace function calls whenever
|
||||||
|
possible, or a positive integer to specify an upper bound for each individual
|
||||||
|
evaluation in number of characters.
|
||||||
|
|
||||||
- `toplevel` -- drop unreferenced functions (`"funcs"`) and/or variables (`"vars"`)
|
- `expression` (default: `false`) -- Pass `true` to preserve completion values
|
||||||
in the top level scope (`false` by default, `true` to drop both unreferenced
|
from terminal statements without `return`, e.g. in bookmarklets.
|
||||||
functions and variables)
|
|
||||||
|
|
||||||
- `top_retain` -- prevent specific toplevel functions and variables from `unused`
|
- `functions` (default: `true`) -- convert declarations from `var`to `function`
|
||||||
removal (can be array, comma-separated, RegExp or function. Implies `toplevel`)
|
whenever possible.
|
||||||
|
|
||||||
- `hoist_funs` -- hoist function declarations
|
- `global_defs` (default: `{}`) -- see [conditional compilation](#conditional-compilation)
|
||||||
|
|
||||||
- `hoist_vars` (default: false) -- hoist `var` declarations (this is `false`
|
- `hoist_funs` (default: `false`) -- hoist function declarations
|
||||||
|
|
||||||
|
- `hoist_props` (default: `true`) -- hoist properties from constant object and
|
||||||
|
array literals into regular variables subject to a set of constraints. For example:
|
||||||
|
`var o={p:1, q:2}; f(o.p, o.q);` is converted to `f(1, 2);`. Note: `hoist_props`
|
||||||
|
works best with `toplevel` and `mangle` enabled, alongside with `compress` option
|
||||||
|
`passes` set to `2` or higher.
|
||||||
|
|
||||||
|
- `hoist_vars` (default: `false`) -- hoist `var` declarations (this is `false`
|
||||||
by default because it seems to increase the size of the output in general)
|
by default because it seems to increase the size of the output in general)
|
||||||
|
|
||||||
- `if_return` -- optimizations for if/return and if/continue
|
- `if_return` (default: `true`) -- optimizations for if/return and if/continue
|
||||||
|
|
||||||
- `join_vars` -- join consecutive `var` statements
|
- `inline` (default: `true`) -- inline calls to function with simple/`return` statement:
|
||||||
|
- `false` -- same as `0`
|
||||||
|
- `0` -- disabled inlining
|
||||||
|
- `1` -- inline simple functions
|
||||||
|
- `2` -- inline functions with arguments
|
||||||
|
- `3` -- inline functions with arguments and variables
|
||||||
|
- `true` -- same as `3`
|
||||||
|
|
||||||
- `cascade` -- small optimization for sequences, transform `x, x` into `x`
|
- `join_vars` (default: `true`) -- join consecutive `var` statements
|
||||||
and `x = something(), x` into `x = something()`
|
|
||||||
|
|
||||||
- `collapse_vars` -- Collapse single-use non-constant variables - side
|
- `keep_fargs` (default: `strict`) -- Discard unused function arguments. Code
|
||||||
effects permitting.
|
which relies on `Function.length` will break if this is done indiscriminately,
|
||||||
|
i.e. when passing `true`. Pass `false` to always retain function arguments.
|
||||||
|
|
||||||
- `reduce_vars` -- Improve optimization on variables assigned with and
|
- `keep_fnames` (default: `false`) -- Pass `true` to prevent the
|
||||||
used as constant values.
|
compressor from discarding function names. Useful for code relying on
|
||||||
|
`Function.prototype.name`. See also: the `keep_fnames` [mangle option](#mangle-options).
|
||||||
|
|
||||||
- `warnings` -- display warnings when dropping unreachable code or unused
|
- `keep_infinity` (default: `false`) -- Pass `true` to prevent `Infinity` from
|
||||||
declarations etc.
|
being compressed into `1/0`, which may cause performance issues on Chrome.
|
||||||
|
|
||||||
- `negate_iife` -- negate "Immediately-Called Function Expressions"
|
- `loops` (default: `true`) -- optimizations for `do`, `while` and `for` loops
|
||||||
|
when we can statically determine the condition.
|
||||||
|
|
||||||
|
- `merge_vars` (default: `true`) -- combine and reuse variables.
|
||||||
|
|
||||||
|
- `negate_iife` (default: `true`) -- negate "Immediately-Called Function Expressions"
|
||||||
where the return value is discarded, to avoid the parens that the
|
where the return value is discarded, to avoid the parens that the
|
||||||
code generator would insert.
|
code generator would insert.
|
||||||
|
|
||||||
- `pure_getters` -- the default is `false`. If you pass `true` for
|
- `objects` (default: `true`) -- compact duplicate keys in object literals.
|
||||||
this, UglifyJS will assume that object property access
|
|
||||||
(e.g. `foo.bar` or `foo["bar"]`) doesn't have any side effects.
|
|
||||||
Specify `"strict"` to treat `foo.bar` as side-effect-free only when
|
|
||||||
`foo` is certain to not throw, i.e. not `null` or `undefined`.
|
|
||||||
|
|
||||||
- `pure_funcs` -- default `null`. You can pass an array of names and
|
- `passes` (default: `1`) -- The maximum number of times to run compress.
|
||||||
|
In some cases more than one pass leads to further compressed code. Keep in
|
||||||
|
mind more passes will take more time.
|
||||||
|
|
||||||
|
- `properties` (default: `true`) -- rewrite property access using the dot notation, for
|
||||||
|
example `foo["bar"] → foo.bar`
|
||||||
|
|
||||||
|
- `pure_funcs` (default: `null`) -- You can pass an array of names and
|
||||||
UglifyJS will assume that those functions do not produce side
|
UglifyJS will assume that those functions do not produce side
|
||||||
effects. DANGER: will not check if the name is redefined in scope.
|
effects. DANGER: will not check if the name is redefined in scope.
|
||||||
An example case here, for instance `var q = Math.floor(a/b)`. If
|
An example case here, for instance `var q = Math.floor(a/b)`. If
|
||||||
@@ -646,49 +712,92 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
|||||||
pass `pure_funcs: [ 'Math.floor' ]` to let it know that this
|
pass `pure_funcs: [ 'Math.floor' ]` to let it know that this
|
||||||
function won't produce any side effect, in which case the whole
|
function won't produce any side effect, in which case the whole
|
||||||
statement would get discarded. The current implementation adds some
|
statement would get discarded. The current implementation adds some
|
||||||
overhead (compression will be slower).
|
overhead (compression will be slower). Make sure symbols under `pure_funcs`
|
||||||
|
are also under `mangle.reserved` to avoid mangling.
|
||||||
|
|
||||||
- `drop_console` -- default `false`. Pass `true` to discard calls to
|
- `pure_getters` (default: `"strict"`) -- If you pass `true` for
|
||||||
`console.*` functions. If you wish to drop a specific function call
|
this, UglifyJS will assume that object property access
|
||||||
such as `console.info` and/or retain side effects from function arguments
|
(e.g. `foo.bar` or `foo["bar"]`) doesn't have any side effects.
|
||||||
after dropping the function call then use `pure_funcs` instead.
|
Specify `"strict"` to treat `foo.bar` as side-effect-free only when
|
||||||
|
`foo` is certain to not throw, i.e. not `null` or `undefined`.
|
||||||
|
|
||||||
- `expression` -- default `false`. Pass `true` to preserve completion values
|
- `reduce_funcs` (default: `true`) -- Allows single-use functions to be
|
||||||
from terminal statements without `return`, e.g. in bookmarklets.
|
inlined as function expressions when permissible allowing further
|
||||||
|
optimization. Enabled by default. Option depends on `reduce_vars`
|
||||||
|
being enabled. Some code runs faster in the Chrome V8 engine if this
|
||||||
|
option is disabled. Does not negatively impact other major browsers.
|
||||||
|
|
||||||
- `keep_fargs` -- default `true`. Prevents the
|
- `reduce_vars` (default: `true`) -- Improve optimization on variables assigned with and
|
||||||
compressor from discarding unused function arguments. You need this
|
used as constant values.
|
||||||
for code which relies on `Function.length`.
|
|
||||||
|
|
||||||
- `keep_fnames` -- default `false`. Pass `true` to prevent the
|
- `sequences` (default: `true`) -- join consecutive simple statements using the
|
||||||
compressor from discarding function names. Useful for code relying on
|
comma operator. May be set to a positive integer to specify the maximum number
|
||||||
`Function.prototype.name`. See also: the `keep_fnames` [mangle option](#mangle).
|
of consecutive comma sequences that will be generated. If this option is set to
|
||||||
|
`true` then the default `sequences` limit is `200`. Set option to `false` or `0`
|
||||||
|
to disable. The smallest `sequences` length is `2`. A `sequences` value of `1`
|
||||||
|
is grandfathered to be equivalent to `true` and as such means `200`. On rare
|
||||||
|
occasions the default sequences limit leads to very slow compress times in which
|
||||||
|
case a value of `20` or less is recommended.
|
||||||
|
|
||||||
- `passes` -- default `1`. Number of times to run compress with a maximum of 3.
|
- `side_effects` (default: `true`) -- Pass `false` to disable potentially dropping
|
||||||
In some cases more than one pass leads to further compressed code. Keep in
|
|
||||||
mind more passes will take more time.
|
|
||||||
|
|
||||||
- `keep_infinity` -- default `false`. Pass `true` to prevent `Infinity` from
|
|
||||||
being compressed into `1/0`, which may cause performance issues on Chrome.
|
|
||||||
|
|
||||||
- `side_effects` -- default `true`. Pass `false` to disable potentially dropping
|
|
||||||
functions marked as "pure". A function call is marked as "pure" if a comment
|
functions marked as "pure". A function call is marked as "pure" if a comment
|
||||||
annotation `/*@__PURE__*/` or `/*#__PURE__*/` immediately precedes the call. For
|
annotation `/*@__PURE__*/` or `/*#__PURE__*/` immediately precedes the call. For
|
||||||
example: `/*@__PURE__*/foo();`
|
example: `/*@__PURE__*/foo();`
|
||||||
|
|
||||||
|
- `strings` (default: `true`) -- compact string concatenations.
|
||||||
|
|
||||||
|
- `switches` (default: `true`) -- de-duplicate and remove unreachable `switch` branches
|
||||||
|
|
||||||
|
- `toplevel` (default: `false`) -- drop unreferenced functions (`"funcs"`) and/or
|
||||||
|
variables (`"vars"`) in the top level scope (`false` by default, `true` to drop
|
||||||
|
both unreferenced functions and variables)
|
||||||
|
|
||||||
|
- `top_retain` (default: `null`) -- prevent specific toplevel functions and
|
||||||
|
variables from `unused` removal (can be array, comma-separated, RegExp or
|
||||||
|
function. Implies `toplevel`)
|
||||||
|
|
||||||
|
- `typeofs` (default: `true`) -- Transforms `typeof foo == "undefined"` into
|
||||||
|
`foo === void 0`. Note: recommend to set this value to `false` for IE10 and
|
||||||
|
earlier versions due to known issues.
|
||||||
|
|
||||||
|
- `unsafe` (default: `false`) -- apply "unsafe" transformations (discussion below)
|
||||||
|
|
||||||
|
- `unsafe_comps` (default: `false`) -- compress expressions like `a <= b` assuming
|
||||||
|
none of the operands can be (coerced to) `NaN`.
|
||||||
|
|
||||||
|
- `unsafe_Function` (default: `false`) -- compress and mangle `Function(args, code)`
|
||||||
|
when both `args` and `code` are string literals.
|
||||||
|
|
||||||
|
- `unsafe_math` (default: `false`) -- optimize numerical expressions like
|
||||||
|
`2 * x * 3` into `6 * x`, which may give imprecise floating point results.
|
||||||
|
|
||||||
|
- `unsafe_proto` (default: `false`) -- optimize expressions like
|
||||||
|
`Array.prototype.slice.call(a)` into `[].slice.call(a)`
|
||||||
|
|
||||||
|
- `unsafe_regexp` (default: `false`) -- enable substitutions of variables with
|
||||||
|
`RegExp` values the same way as if they are constants.
|
||||||
|
|
||||||
|
- `unsafe_undefined` (default: `false`) -- substitute `void 0` if there is a
|
||||||
|
variable named `undefined` in scope (variable name will be mangled, typically
|
||||||
|
reduced to a single character)
|
||||||
|
|
||||||
|
- `unused` (default: `true`) -- drop unreferenced functions and variables (simple
|
||||||
|
direct variable assignments do not count as references unless set to `"keep_assign"`)
|
||||||
|
|
||||||
## Mangle options
|
## Mangle options
|
||||||
|
|
||||||
- `reserved` - pass an array of identifiers that should be excluded from mangling
|
- `eval` (default `false`) -- Pass `true` to mangle names visible in scopes
|
||||||
|
where `eval` or `with` are used.
|
||||||
|
|
||||||
- `toplevel` — mangle names declared in the top level scope (disabled by
|
- `keep_fnames` (default `false`) -- Pass `true` to not mangle function names.
|
||||||
default).
|
Useful for code relying on `Function.prototype.name`. See also: the `keep_fnames`
|
||||||
|
[compress option](#compress-options).
|
||||||
|
|
||||||
- `eval` — mangle names visible in scopes where eval or with are used
|
- `reserved` (default `[]`) -- Pass an array of identifiers that should be
|
||||||
(disabled by default).
|
excluded from mangling. Example: `["foo", "bar"]`.
|
||||||
|
|
||||||
- `keep_fnames` -- default `false`. Pass `true` to not mangle
|
- `toplevel` (default `false`) -- Pass `true` to mangle names declared in the
|
||||||
function names. Useful for code relying on `Function.prototype.name`.
|
top level scope.
|
||||||
See also: the `keep_fnames` [compress option](#compress-options).
|
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
@@ -714,16 +823,20 @@ UglifyJS.minify(code, { mangle: { toplevel: true } }).code;
|
|||||||
|
|
||||||
### Mangle properties options
|
### Mangle properties options
|
||||||
|
|
||||||
- `reserved` (default: `[]`) -- Do not mangle property names listed in the
|
|
||||||
`reserved` array.
|
|
||||||
- `regex` (default: `null`) -— Pass a RegExp literal to only mangle property
|
|
||||||
names matching the regular expression.
|
|
||||||
- `keep_quoted` (default: `false`) -— Only mangle unquoted property names.
|
|
||||||
- `debug` (default: `false`) -— Mangle names with the original name still present.
|
|
||||||
Pass an empty string `""` to enable, or a non-empty string to set the debug suffix.
|
|
||||||
- `builtins` (default: `false`) -- Use `true` to allow the mangling of builtin
|
- `builtins` (default: `false`) -- Use `true` to allow the mangling of builtin
|
||||||
DOM properties. Not recommended to override this setting.
|
DOM properties. Not recommended to override this setting.
|
||||||
|
|
||||||
|
- `debug` (default: `false`) -— Mangle names with the original name still present.
|
||||||
|
Pass an empty string `""` to enable, or a non-empty string to set the debug suffix.
|
||||||
|
|
||||||
|
- `keep_quoted` (default: `false`) -— Only mangle unquoted property names.
|
||||||
|
|
||||||
|
- `regex` (default: `null`) -— Pass a RegExp literal to only mangle property
|
||||||
|
names matching the regular expression.
|
||||||
|
|
||||||
|
- `reserved` (default: `[]`) -- Do not mangle property names listed in the
|
||||||
|
`reserved` array.
|
||||||
|
|
||||||
## Output options
|
## Output options
|
||||||
|
|
||||||
The code generator tries to output shortest code possible by default. In
|
The code generator tries to output shortest code possible by default. In
|
||||||
@@ -732,51 +845,76 @@ can pass additional arguments that control the code output:
|
|||||||
|
|
||||||
- `ascii_only` (default `false`) -- escape Unicode characters in strings and
|
- `ascii_only` (default `false`) -- escape Unicode characters in strings and
|
||||||
regexps (affects directives with non-ascii characters becoming invalid)
|
regexps (affects directives with non-ascii characters becoming invalid)
|
||||||
|
|
||||||
- `beautify` (default `true`) -- whether to actually beautify the output.
|
- `beautify` (default `true`) -- whether to actually beautify the output.
|
||||||
Passing `-b` will set this to true, but you might need to pass `-b` even
|
Passing `-b` will set this to true, but you might need to pass `-b` even
|
||||||
when you want to generate minified code, in order to specify additional
|
when you want to generate minified code, in order to specify additional
|
||||||
arguments, so you can use `-b beautify=false` to override it.
|
arguments, so you can use `-b beautify=false` to override it.
|
||||||
- `bracketize` (default `false`) -- always insert brackets in `if`, `for`,
|
|
||||||
|
- `braces` (default `false`) -- always insert braces in `if`, `for`,
|
||||||
`do`, `while` or `with` statements, even if their body is a single
|
`do`, `while` or `with` statements, even if their body is a single
|
||||||
statement.
|
statement.
|
||||||
|
|
||||||
- `comments` (default `false`) -- pass `true` or `"all"` to preserve all
|
- `comments` (default `false`) -- pass `true` or `"all"` to preserve all
|
||||||
comments, `"some"` to preserve some comments, a regular expression string
|
comments, `"some"` to preserve multi-line comments that contain `@cc_on`,
|
||||||
(e.g. `/^!/`) or a function.
|
`@license`, or `@preserve` (case-insensitive), a regular expression string
|
||||||
- `indent_level` (default 4)
|
(e.g. `/^!/`), or a function which returns `boolean`, e.g.
|
||||||
- `indent_start` (default 0) -- prefix all lines by that many spaces
|
```js
|
||||||
- `inline_script` (default `false`) -- escape the slash in occurrences of
|
function(node, comment) {
|
||||||
`</script` in strings
|
return comment.value.indexOf("@type " + node.TYPE) >= 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- `indent_level` (default `4`)
|
||||||
|
|
||||||
|
- `indent_start` (default `0`) -- prefix all lines by that many spaces
|
||||||
|
|
||||||
|
- `inline_script` (default `true`) -- escape HTML comments and the slash in
|
||||||
|
occurrences of `</script>` in strings
|
||||||
|
|
||||||
- `keep_quoted_props` (default `false`) -- when turned on, prevents stripping
|
- `keep_quoted_props` (default `false`) -- when turned on, prevents stripping
|
||||||
quotes from property names in object literals.
|
quotes from property names in object literals.
|
||||||
|
|
||||||
- `max_line_len` (default `false`) -- maximum line length (for uglified code)
|
- `max_line_len` (default `false`) -- maximum line length (for uglified code)
|
||||||
|
|
||||||
- `preamble` (default `null`) -- when passed it must be a string and
|
- `preamble` (default `null`) -- when passed it must be a string and
|
||||||
it will be prepended to the output literally. The source map will
|
it will be prepended to the output literally. The source map will
|
||||||
adjust for this text. Can be used to insert a comment containing
|
adjust for this text. Can be used to insert a comment containing
|
||||||
licensing information, for example.
|
licensing information, for example.
|
||||||
- `preserve_line` (default `false`) -- pass `true` to preserve lines, but it
|
|
||||||
only works if `beautify` is set to `false`.
|
- `preserve_line` (default `false`) -- pass `true` to retain line numbering on
|
||||||
|
a best effort basis.
|
||||||
|
|
||||||
- `quote_keys` (default `false`) -- pass `true` to quote all keys in literal
|
- `quote_keys` (default `false`) -- pass `true` to quote all keys in literal
|
||||||
objects
|
objects
|
||||||
|
|
||||||
- `quote_style` (default `0`) -- preferred quote style for strings (affects
|
- `quote_style` (default `0`) -- preferred quote style for strings (affects
|
||||||
quoted property names and directives as well):
|
quoted property names and directives as well):
|
||||||
- `0` -- prefers double quotes, switches to single quotes when there are
|
- `0` -- prefers double quotes, switches to single quotes when there are
|
||||||
more double quotes in the string itself.
|
more double quotes in the string itself. `0` is best for gzip size.
|
||||||
- `1` -- always use single quotes
|
- `1` -- always use single quotes
|
||||||
- `2` -- always use double quotes
|
- `2` -- always use double quotes
|
||||||
- `3` -- always use the original quotes
|
- `3` -- always use the original quotes
|
||||||
|
|
||||||
- `semicolons` (default `true`) -- separate statements with semicolons. If
|
- `semicolons` (default `true`) -- separate statements with semicolons. If
|
||||||
you pass `false` then whenever possible we will use a newline instead of a
|
you pass `false` then whenever possible we will use a newline instead of a
|
||||||
semicolon, leading to more readable output of uglified code (size before
|
semicolon, leading to more readable output of uglified code (size before
|
||||||
gzip could be smaller; size after gzip insignificantly larger).
|
gzip could be smaller; size after gzip insignificantly larger).
|
||||||
|
|
||||||
- `shebang` (default `true`) -- preserve shebang `#!` in preamble (bash scripts)
|
- `shebang` (default `true`) -- preserve shebang `#!` in preamble (bash scripts)
|
||||||
- `width` (default 80) -- only takes effect when beautification is on, this
|
|
||||||
|
- `webkit` (default `false`) -- enable workarounds for WebKit bugs.
|
||||||
|
PhantomJS users should set this option to `true`.
|
||||||
|
|
||||||
|
- `width` (default `80`) -- only takes effect when beautification is on, this
|
||||||
specifies an (orientative) line width that the beautifier will try to
|
specifies an (orientative) line width that the beautifier will try to
|
||||||
obey. It refers to the width of the line text (excluding indentation).
|
obey. It refers to the width of the line text (excluding indentation).
|
||||||
It doesn't work very well currently, but it does make the code generated
|
It doesn't work very well currently, but it does make the code generated
|
||||||
by UglifyJS more readable.
|
by UglifyJS more readable.
|
||||||
|
|
||||||
- `wrap_iife` (default `false`) -- pass `true` to wrap immediately invoked
|
- `wrap_iife` (default `false`) -- pass `true` to wrap immediately invoked
|
||||||
function expressions. See
|
function expressions. See
|
||||||
[#640](https://github.com/mishoo/UglifyJS2/issues/640) for more details.
|
[#640](https://github.com/mishoo/UglifyJS/issues/640) for more details.
|
||||||
|
|
||||||
# Miscellaneous
|
# Miscellaneous
|
||||||
|
|
||||||
@@ -819,10 +957,6 @@ when this flag is on:
|
|||||||
- `new Object()` → `{}`
|
- `new Object()` → `{}`
|
||||||
- `String(exp)` or `exp.toString()` → `"" + exp`
|
- `String(exp)` or `exp.toString()` → `"" + exp`
|
||||||
- `new Object/RegExp/Function/Error/Array (...)` → we discard the `new`
|
- `new Object/RegExp/Function/Error/Array (...)` → we discard the `new`
|
||||||
- `typeof foo == "undefined"` → `foo === void 0`
|
|
||||||
- `void 0` → `undefined` (if there is a variable named "undefined" in
|
|
||||||
scope; we do it because the variable name will be mangled, typically
|
|
||||||
reduced to a single character)
|
|
||||||
|
|
||||||
### Conditional compilation
|
### Conditional compilation
|
||||||
|
|
||||||
@@ -939,8 +1073,9 @@ var result = UglifyJS.minify(ast, {
|
|||||||
### Working with Uglify AST
|
### Working with Uglify AST
|
||||||
|
|
||||||
Transversal and transformation of the native AST can be performed through
|
Transversal and transformation of the native AST can be performed through
|
||||||
[`TreeWalker`](http://lisperator.net/uglifyjs/walk) and
|
[`TreeWalker`](https://github.com/mishoo/UglifyJS/blob/master/lib/ast.js) and
|
||||||
[`TreeTransformer`](http://lisperator.net/uglifyjs/transform) respectively.
|
[`TreeTransformer`](https://github.com/mishoo/UglifyJS/blob/master/lib/transform.js)
|
||||||
|
respectively.
|
||||||
|
|
||||||
### ESTree / SpiderMonkey AST
|
### ESTree / SpiderMonkey AST
|
||||||
|
|
||||||
@@ -972,3 +1107,70 @@ in total it's a bit more than just using UglifyJS's own parser.
|
|||||||
|
|
||||||
[acorn]: https://github.com/ternjs/acorn
|
[acorn]: https://github.com/ternjs/acorn
|
||||||
[sm-spec]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k
|
[sm-spec]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k
|
||||||
|
|
||||||
|
### Uglify Fast Minify Mode
|
||||||
|
|
||||||
|
It's not well known, but whitespace removal and symbol mangling accounts
|
||||||
|
for 95% of the size reduction in minified code for most JavaScript - not
|
||||||
|
elaborate code transforms. One can simply disable `compress` to speed up
|
||||||
|
Uglify builds by 3 to 4 times. In this fast `mangle`-only mode Uglify has
|
||||||
|
comparable minify speeds and gzip sizes to
|
||||||
|
[`butternut`](https://www.npmjs.com/package/butternut):
|
||||||
|
|
||||||
|
| d3.js | minify size | gzip size | minify time (seconds) |
|
||||||
|
| --- | ---: | ---: | ---: |
|
||||||
|
| original | 451,131 | 108,733 | - |
|
||||||
|
| uglify-js@3.0.24 mangle=false, compress=false | 316,600 | 85,245 | 0.70 |
|
||||||
|
| uglify-js@3.0.24 mangle=true, compress=false | 220,216 | 72,730 | 1.13 |
|
||||||
|
| butternut@0.4.6 | 217,568 | 72,738 | 1.41 |
|
||||||
|
| uglify-js@3.0.24 mangle=true, compress=true | 212,511 | 71,560 | 3.36 |
|
||||||
|
| babili@0.1.4 | 210,713 | 72,140 | 12.64 |
|
||||||
|
|
||||||
|
To enable fast minify mode from the CLI use:
|
||||||
|
```
|
||||||
|
uglifyjs file.js -m
|
||||||
|
```
|
||||||
|
To enable fast minify mode with the API use:
|
||||||
|
```js
|
||||||
|
UglifyJS.minify(code, { compress: false, mangle: true });
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Source maps and debugging
|
||||||
|
|
||||||
|
Various `compress` transforms that simplify, rearrange, inline and remove code
|
||||||
|
are known to have an adverse effect on debugging with source maps. This is
|
||||||
|
expected as code is optimized and mappings are often simply not possible as
|
||||||
|
some code no longer exists. For highest fidelity in source map debugging
|
||||||
|
disable the Uglify `compress` option and just use `mangle`.
|
||||||
|
|
||||||
|
### Compiler assumptions
|
||||||
|
|
||||||
|
To allow for better optimizations, the compiler makes various assumptions:
|
||||||
|
|
||||||
|
- `.toString()` and `.valueOf()` don't have side effects, and for built-in
|
||||||
|
objects they have not been overridden.
|
||||||
|
- `undefined`, `NaN` and `Infinity` have not been externally redefined.
|
||||||
|
- `arguments.callee`, `arguments.caller` and `Function.prototype.caller` are not used.
|
||||||
|
- The code doesn't expect the contents of `Function.prototype.toString()` or
|
||||||
|
`Error.prototype.stack` to be anything in particular.
|
||||||
|
- Getting and setting properties on a plain object does not cause other side effects
|
||||||
|
(using `.watch()` or `Proxy`).
|
||||||
|
- Object properties can be added, removed and modified (not prevented with
|
||||||
|
`Object.defineProperty()`, `Object.defineProperties()`, `Object.freeze()`,
|
||||||
|
`Object.preventExtensions()` or `Object.seal()`).
|
||||||
|
- When `toplevel` is enabled, UglifyJS effectively assumes input code is wrapped
|
||||||
|
within `function(){ ... }`, thus forbids aliasing of declared global variables:
|
||||||
|
```js
|
||||||
|
A = "FAIL";
|
||||||
|
var B = "FAIL";
|
||||||
|
// can be `global`, `self`, `window` etc.
|
||||||
|
var top = function() {
|
||||||
|
return this;
|
||||||
|
}();
|
||||||
|
// "PASS"
|
||||||
|
top.A = "PASS";
|
||||||
|
console.log(A);
|
||||||
|
// "FAIL" after compress and/or mangle
|
||||||
|
top.B = "PASS";
|
||||||
|
console.log(B);
|
||||||
|
```
|
||||||
|
|||||||
24
appveyor.yml
24
appveyor.yml
@@ -1,24 +0,0 @@
|
|||||||
environment:
|
|
||||||
matrix:
|
|
||||||
- nodejs_version: "0.10"
|
|
||||||
- nodejs_version: "0.12"
|
|
||||||
- nodejs_version: "4.0"
|
|
||||||
- nodejs_version: "6.0"
|
|
||||||
|
|
||||||
matrix:
|
|
||||||
fast_finish: true
|
|
||||||
|
|
||||||
platform:
|
|
||||||
- x86
|
|
||||||
- x64
|
|
||||||
|
|
||||||
install:
|
|
||||||
- ps: Install-Product node $env:nodejs_version $env:platform
|
|
||||||
- npm install
|
|
||||||
|
|
||||||
test_script:
|
|
||||||
- node --version
|
|
||||||
- npm --version
|
|
||||||
- npm test
|
|
||||||
|
|
||||||
build: off
|
|
||||||
618
bin/uglifyjs
618
bin/uglifyjs
@@ -3,169 +3,257 @@
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
// workaround for tty output truncation upon process.exit()
|
require("../tools/exit");
|
||||||
[process.stdout, process.stderr].forEach(function(stream){
|
|
||||||
if (stream._handle && stream._handle.setBlocking)
|
|
||||||
stream._handle.setBlocking(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
var info = require("../package.json");
|
var info = require("../package.json");
|
||||||
var path = require("path");
|
var path = require("path");
|
||||||
var program = require("commander");
|
|
||||||
var UglifyJS = require("../tools/node");
|
var UglifyJS = require("../tools/node");
|
||||||
|
|
||||||
var skip_keys = [ "cname", "enclosed", "parent_scope", "scope", "thedef", "uses_eval", "uses_with" ];
|
var skip_keys = [ "cname", "inlined", "parent_scope", "scope", "uses_eval", "uses_with" ];
|
||||||
var files = {};
|
var files = {};
|
||||||
var options = {
|
var options = {};
|
||||||
compress: false,
|
var short_forms = {
|
||||||
mangle: false
|
b: "beautify",
|
||||||
|
c: "compress",
|
||||||
|
d: "define",
|
||||||
|
e: "enclose",
|
||||||
|
h: "help",
|
||||||
|
m: "mangle",
|
||||||
|
o: "output",
|
||||||
|
O: "output-opts",
|
||||||
|
p: "parse",
|
||||||
|
v: "version",
|
||||||
|
V: "version",
|
||||||
};
|
};
|
||||||
program.version(info.name + " " + info.version);
|
var args = process.argv.slice(2);
|
||||||
program.parseArgv = program.parse;
|
var paths = [];
|
||||||
program.parse = undefined;
|
var output, nameCache;
|
||||||
if (process.argv.indexOf("ast") >= 0) program.helpInformation = UglifyJS.describe_ast;
|
var specified = {};
|
||||||
else if (process.argv.indexOf("options") >= 0) program.helpInformation = function() {
|
while (args.length) {
|
||||||
var text = [];
|
var arg = args.shift();
|
||||||
var options = UglifyJS.default_options();
|
if (arg[0] != "-") {
|
||||||
for (var option in options) {
|
paths.push(arg);
|
||||||
text.push("--" + (option == "output" ? "beautify" : option == "sourceMap" ? "source-map" : option) + " options:");
|
} else if (arg == "--") {
|
||||||
var defs = options[option];
|
paths = paths.concat(args);
|
||||||
var padding = "";
|
break;
|
||||||
Object.keys(defs).map(function(name) {
|
} else if (arg[1] == "-") {
|
||||||
if (padding.length < name.length) padding = Array(name.length + 1).join(" ");
|
process_option(arg.slice(2));
|
||||||
return [ name, JSON.stringify(defs[name]) ];
|
} else [].forEach.call(arg.slice(1), function(letter, index, arg) {
|
||||||
}).forEach(function(tokens) {
|
if (!(letter in short_forms)) fatal("invalid option -" + letter);
|
||||||
text.push(" " + tokens[0] + padding.slice(tokens[0].length - 2) + tokens[1]);
|
process_option(short_forms[letter], index + 1 < arg.length);
|
||||||
});
|
});
|
||||||
text.push("");
|
|
||||||
}
|
|
||||||
return text.join("\n");
|
|
||||||
};
|
|
||||||
program.option("-p, --parse <options>", "Specify parser options.", parse_js("parse", true));
|
|
||||||
program.option("-c, --compress [options]", "Enable compressor/specify compressor options.", parse_js("compress", true));
|
|
||||||
program.option("-m, --mangle [options]", "Mangle names/specify mangler options.", parse_js("mangle", true));
|
|
||||||
program.option("--mangle-props [options]", "Mangle properties/specify mangler options.", parse_js("mangle-props", true));
|
|
||||||
program.option("-b, --beautify [options]", "Beautify output/specify output options.", parse_js("beautify", true));
|
|
||||||
program.option("-o, --output <file>", "Output file (default STDOUT).");
|
|
||||||
program.option("--comments [filter]", "Preserve copyright comments in the output.");
|
|
||||||
program.option("--config-file <file>", "Read minify() options from JSON file.");
|
|
||||||
program.option("-d, --define <expr>[=value]", "Global definitions.", parse_js("define"));
|
|
||||||
program.option("--ie8", "Support non-standard Internet Explorer 8.");
|
|
||||||
program.option("--keep-fnames", "Do not mangle/drop function names. Useful for code relying on Function.prototype.name.");
|
|
||||||
program.option("--name-cache <file>", "File to hold mangled name mappings.");
|
|
||||||
program.option("--self", "Build UglifyJS as a library (implies --wrap UglifyJS)");
|
|
||||||
program.option("--source-map [options]", "Enable source map/specify source map options.", parse_source_map());
|
|
||||||
program.option("--timings", "Display operations run time on STDERR.")
|
|
||||||
program.option("--toplevel", "Compress and/or mangle variables in toplevel scope.");
|
|
||||||
program.option("--verbose", "Print diagnostic messages.");
|
|
||||||
program.option("--warn", "Print warning messages.");
|
|
||||||
program.option("--wrap <name>", "Embed everything as a function with “exports” corresponding to “name” globally.");
|
|
||||||
program.arguments("[files...]").parseArgv(process.argv);
|
|
||||||
if (program.configFile) {
|
|
||||||
options = JSON.parse(read_file(program.configFile));
|
|
||||||
}
|
}
|
||||||
if (!program.output && program.sourceMap && program.sourceMap.url != "inline") {
|
|
||||||
fatal("ERROR: cannot write source map to STDOUT");
|
function process_option(name, no_value) {
|
||||||
}
|
specified[name] = true;
|
||||||
[
|
switch (name) {
|
||||||
"compress",
|
case "help":
|
||||||
"ie8",
|
switch (read_value()) {
|
||||||
"mangle",
|
case "ast":
|
||||||
"sourceMap",
|
print(UglifyJS.describe_ast());
|
||||||
"toplevel",
|
break;
|
||||||
"wrap"
|
case "options":
|
||||||
].forEach(function(name) {
|
var text = [];
|
||||||
if (name in program) {
|
var toplevels = [];
|
||||||
options[name] = program[name];
|
var padding = "";
|
||||||
}
|
var defaults = UglifyJS.default_options();
|
||||||
});
|
for (var name in defaults) {
|
||||||
if (program.beautify) {
|
var option = defaults[name];
|
||||||
options.output = typeof program.beautify == "object" ? program.beautify : {};
|
if (option && typeof option == "object") {
|
||||||
if (!("beautify" in options.output)) {
|
text.push("--" + ({
|
||||||
options.output.beautify = true;
|
output: "beautify",
|
||||||
}
|
sourceMap: "source-map",
|
||||||
}
|
}[name] || name) + " options:");
|
||||||
if (program.comments) {
|
text.push(format_object(option));
|
||||||
if (typeof options.output != "object") options.output = {};
|
text.push("");
|
||||||
options.output.comments = typeof program.comments == "string" ? program.comments : "some";
|
} else {
|
||||||
}
|
if (padding.length < name.length) padding = Array(name.length + 1).join(" ");
|
||||||
if (program.define) {
|
toplevels.push([ {
|
||||||
if (typeof options.compress != "object") options.compress = {};
|
keep_fnames: "keep-fnames",
|
||||||
if (typeof options.compress.global_defs != "object") options.compress.global_defs = {};
|
nameCache: "name-cache",
|
||||||
for (var expr in program.define) {
|
}[name] || name, option ]);
|
||||||
options.compress.global_defs[expr] = program.define[expr];
|
}
|
||||||
}
|
}
|
||||||
}
|
toplevels.forEach(function(tokens) {
|
||||||
if (program.keepFnames) {
|
text.push("--" + tokens[0] + padding.slice(tokens[0].length - 2) + tokens[1]);
|
||||||
options.keep_fnames = true;
|
});
|
||||||
}
|
print(text.join("\n"));
|
||||||
if (program.mangleProps) {
|
break;
|
||||||
if (program.mangleProps.domprops) {
|
default:
|
||||||
delete program.mangleProps.domprops;
|
print([
|
||||||
} else {
|
"Usage: uglifyjs [files...] [options]",
|
||||||
if (typeof program.mangleProps != "object") program.mangleProps = {};
|
"",
|
||||||
if (!Array.isArray(program.mangleProps.reserved)) program.mangleProps.reserved = [];
|
"Options:",
|
||||||
require("../tools/domprops").forEach(function(name) {
|
" -h, --help Print usage information.",
|
||||||
UglifyJS._push_uniq(program.mangleProps.reserved, name);
|
" `--help options` for details on available options.",
|
||||||
});
|
" -v, -V, --version Print version number.",
|
||||||
}
|
" -p, --parse <options> Specify parser options.",
|
||||||
if (typeof options.mangle != "object") options.mangle = {};
|
" -c, --compress [options] Enable compressor/specify compressor options.",
|
||||||
options.mangle.properties = program.mangleProps;
|
" -m, --mangle [options] Mangle names/specify mangler options.",
|
||||||
}
|
" --mangle-props [options] Mangle properties/specify mangler options.",
|
||||||
var cache;
|
" -b, --beautify [options] Beautify output/specify output options.",
|
||||||
if (program.nameCache) {
|
" -O, --output-opts <options> Output options (beautify disabled).",
|
||||||
cache = JSON.parse(read_file(program.nameCache, "{}"));
|
" -o, --output <file> Output file (default STDOUT).",
|
||||||
if (options.mangle) {
|
" --comments [filter] Preserve copyright comments in the output.",
|
||||||
if (typeof options.mangle != "object") options.mangle = {};
|
" --config-file <file> Read minify() options from JSON file.",
|
||||||
options.mangle.cache = to_cache("vars");
|
" -d, --define <expr>[=value] Global definitions.",
|
||||||
if (options.mangle.properties) {
|
" -e, --enclose [arg[,...][:value[,...]]] Embed everything in a big function, with configurable argument(s) & value(s).",
|
||||||
if (typeof options.mangle.properties != "object") options.mangle.properties = {};
|
" --ie8 Support non-standard Internet Explorer 8.",
|
||||||
options.mangle.properties.cache = to_cache("props");
|
" --keep-fnames Do not mangle/drop function names. Useful for code relying on Function.prototype.name.",
|
||||||
|
" --name-cache <file> File to hold mangled name mappings.",
|
||||||
|
" --rename Force symbol expansion.",
|
||||||
|
" --no-rename Disable symbol expansion.",
|
||||||
|
" --self Build UglifyJS as a library (implies --wrap UglifyJS)",
|
||||||
|
" --source-map [options] Enable source map/specify source map options.",
|
||||||
|
" --timings Display operations run time on STDERR.",
|
||||||
|
" --toplevel Compress and/or mangle variables in toplevel scope.",
|
||||||
|
" --validate Perform validation during AST manipulations.",
|
||||||
|
" --verbose Print diagnostic messages.",
|
||||||
|
" --warn Print warning messages.",
|
||||||
|
" --wrap <name> Embed everything as a function with “exports” corresponding to “name” globally.",
|
||||||
|
" --reduce-test Reduce a standalone test case (assumes cloned repository).",
|
||||||
|
].join("\n"));
|
||||||
}
|
}
|
||||||
|
process.exit();
|
||||||
|
case "version":
|
||||||
|
print(info.name + " " + info.version);
|
||||||
|
process.exit();
|
||||||
|
case "config-file":
|
||||||
|
var config = JSON.parse(read_file(read_value(true)));
|
||||||
|
if (config.mangle && config.mangle.properties && config.mangle.properties.regex) {
|
||||||
|
config.mangle.properties.regex = UglifyJS.parse(config.mangle.properties.regex, {
|
||||||
|
expression: true,
|
||||||
|
}).value;
|
||||||
|
}
|
||||||
|
for (var key in config) if (!(key in options)) options[key] = config[key];
|
||||||
|
break;
|
||||||
|
case "compress":
|
||||||
|
case "mangle":
|
||||||
|
options[name] = parse_js(read_value(), options[name]);
|
||||||
|
break;
|
||||||
|
case "source-map":
|
||||||
|
options.sourceMap = parse_js(read_value(), options.sourceMap);
|
||||||
|
break;
|
||||||
|
case "enclose":
|
||||||
|
options[name] = read_value();
|
||||||
|
break;
|
||||||
|
case "ie8":
|
||||||
|
case "timings":
|
||||||
|
case "toplevel":
|
||||||
|
case "validate":
|
||||||
|
options[name] = true;
|
||||||
|
break;
|
||||||
|
case "keep-fnames":
|
||||||
|
options.keep_fnames = true;
|
||||||
|
break;
|
||||||
|
case "wrap":
|
||||||
|
options[name] = read_value(true);
|
||||||
|
break;
|
||||||
|
case "verbose":
|
||||||
|
options.warnings = "verbose";
|
||||||
|
break;
|
||||||
|
case "warn":
|
||||||
|
if (!options.warnings) options.warnings = true;
|
||||||
|
break;
|
||||||
|
case "beautify":
|
||||||
|
options.output = parse_js(read_value(), options.output);
|
||||||
|
if (!("beautify" in options.output)) options.output.beautify = true;
|
||||||
|
break;
|
||||||
|
case "output-opts":
|
||||||
|
options.output = parse_js(read_value(true), options.output);
|
||||||
|
break;
|
||||||
|
case "comments":
|
||||||
|
if (typeof options.output != "object") options.output = {};
|
||||||
|
options.output.comments = read_value();
|
||||||
|
if (options.output.comments === true) options.output.comments = "some";
|
||||||
|
break;
|
||||||
|
case "define":
|
||||||
|
if (typeof options.compress != "object") options.compress = {};
|
||||||
|
options.compress.global_defs = parse_js(read_value(true), options.compress.global_defs, "define");
|
||||||
|
break;
|
||||||
|
case "mangle-props":
|
||||||
|
if (typeof options.mangle != "object") options.mangle = {};
|
||||||
|
options.mangle.properties = parse_js(read_value(), options.mangle.properties);
|
||||||
|
break;
|
||||||
|
case "name-cache":
|
||||||
|
nameCache = read_value(true);
|
||||||
|
options.nameCache = JSON.parse(read_file(nameCache, "{}"));
|
||||||
|
break;
|
||||||
|
case "output":
|
||||||
|
output = read_value(true);
|
||||||
|
break;
|
||||||
|
case "parse":
|
||||||
|
options.parse = parse_js(read_value(true), options.parse);
|
||||||
|
break;
|
||||||
|
case "rename":
|
||||||
|
options.rename = true;
|
||||||
|
break;
|
||||||
|
case "no-rename":
|
||||||
|
options.rename = false;
|
||||||
|
break;
|
||||||
|
case "reduce-test":
|
||||||
|
case "self":
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fatal("invalid option --" + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
function read_value(required) {
|
||||||
|
if (no_value || !args.length || args[0][0] == "-") {
|
||||||
|
if (required) fatal("missing option argument for --" + name);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return args.shift();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (program.output == "ast") {
|
if (!output && options.sourceMap && options.sourceMap.url != "inline") fatal("cannot write source map to STDOUT");
|
||||||
options.output = {
|
if (specified["beautify"] && specified["output-opts"]) fatal("--beautify cannot be used with --output-opts");
|
||||||
ast: true,
|
[ "compress", "mangle" ].forEach(function(name) {
|
||||||
code: false
|
if (!(name in options)) options[name] = false;
|
||||||
};
|
});
|
||||||
}
|
if (options.mangle && options.mangle.properties) {
|
||||||
if (program.parse) {
|
if (options.mangle.properties.domprops) {
|
||||||
if (!program.parse.acorn && !program.parse.spidermonkey) {
|
delete options.mangle.properties.domprops;
|
||||||
options.parse = program.parse;
|
} else {
|
||||||
} else if (program.sourceMap && program.sourceMap.content == "inline") {
|
if (typeof options.mangle.properties != "object") options.mangle.properties = {};
|
||||||
fatal("ERROR: inline source map only works with built-in parser");
|
if (!Array.isArray(options.mangle.properties.reserved)) options.mangle.properties.reserved = [];
|
||||||
|
require("../tools/domprops").forEach(function(name) {
|
||||||
|
UglifyJS.push_uniq(options.mangle.properties.reserved, name);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (output == "ast") options.output = {
|
||||||
|
ast: true,
|
||||||
|
code: false,
|
||||||
|
};
|
||||||
|
if (options.parse && (options.parse.acorn || options.parse.spidermonkey)
|
||||||
|
&& options.sourceMap && options.sourceMap.content == "inline") {
|
||||||
|
fatal("inline source map only works with built-in parser");
|
||||||
|
}
|
||||||
|
if (options.warnings) {
|
||||||
|
UglifyJS.AST_Node.log_function(print_error, options.warnings == "verbose");
|
||||||
|
delete options.warnings;
|
||||||
|
}
|
||||||
var convert_path = function(name) {
|
var convert_path = function(name) {
|
||||||
return name;
|
return name;
|
||||||
};
|
};
|
||||||
if (typeof program.sourceMap == "object" && "base" in program.sourceMap) {
|
if (typeof options.sourceMap == "object" && "base" in options.sourceMap) {
|
||||||
convert_path = function() {
|
convert_path = function() {
|
||||||
var base = program.sourceMap.base;
|
var base = options.sourceMap.base;
|
||||||
delete options.sourceMap.base;
|
delete options.sourceMap.base;
|
||||||
return function(name) {
|
return function(name) {
|
||||||
return path.relative(base, name);
|
return path.relative(base, name);
|
||||||
};
|
};
|
||||||
}();
|
}();
|
||||||
}
|
}
|
||||||
if (program.verbose) {
|
if (specified["self"]) {
|
||||||
options.warnings = "verbose";
|
if (paths.length) UglifyJS.AST_Node.warn("Ignoring input files since --self was passed");
|
||||||
} else if (program.warn) {
|
|
||||||
options.warnings = true;
|
|
||||||
}
|
|
||||||
if (program.self) {
|
|
||||||
if (program.args.length) {
|
|
||||||
console.error("WARN: Ignoring input files since --self was passed");
|
|
||||||
}
|
|
||||||
if (!options.wrap) options.wrap = "UglifyJS";
|
if (!options.wrap) options.wrap = "UglifyJS";
|
||||||
simple_glob(UglifyJS.FILES).forEach(function(name) {
|
paths = UglifyJS.FILES;
|
||||||
files[convert_path(name)] = read_file(name);
|
}
|
||||||
});
|
if (paths.length) {
|
||||||
run();
|
simple_glob(paths).forEach(function(name) {
|
||||||
} else if (program.args.length) {
|
|
||||||
simple_glob(program.args).forEach(function(name) {
|
|
||||||
files[convert_path(name)] = read_file(name);
|
files[convert_path(name)] = read_file(name);
|
||||||
});
|
});
|
||||||
run();
|
run();
|
||||||
@@ -186,13 +274,14 @@ function convert_ast(fn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function run() {
|
function run() {
|
||||||
UglifyJS.AST_Node.warn_function = function(msg) {
|
var content = options.sourceMap && options.sourceMap.content;
|
||||||
console.error("WARN:", msg);
|
if (content && content != "inline") {
|
||||||
};
|
UglifyJS.AST_Node.info("Using input source map: " + content);
|
||||||
if (program.timings) options.timings = true;
|
options.sourceMap.content = read_file(content, content);
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
if (program.parse) {
|
if (options.parse) {
|
||||||
if (program.parse.acorn) {
|
if (options.parse.acorn) {
|
||||||
files = convert_ast(function(toplevel, name) {
|
files = convert_ast(function(toplevel, name) {
|
||||||
return require("acorn").parse(files[name], {
|
return require("acorn").parse(files[name], {
|
||||||
locations: true,
|
locations: true,
|
||||||
@@ -200,7 +289,7 @@ function run() {
|
|||||||
sourceFile: name
|
sourceFile: name
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else if (program.parse.spidermonkey) {
|
} else if (options.parse.spidermonkey) {
|
||||||
files = convert_ast(function(toplevel, name) {
|
files = convert_ast(function(toplevel, name) {
|
||||||
var obj = JSON.parse(files[name]);
|
var obj = JSON.parse(files[name]);
|
||||||
if (!toplevel) return obj;
|
if (!toplevel) return obj;
|
||||||
@@ -212,34 +301,70 @@ function run() {
|
|||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
fatal(ex);
|
fatal(ex);
|
||||||
}
|
}
|
||||||
var result = UglifyJS.minify(files, options);
|
var result;
|
||||||
|
if (specified["reduce-test"]) {
|
||||||
|
// load on demand - assumes cloned repository
|
||||||
|
var reduce_test = require("../test/reduce");
|
||||||
|
if (Object.keys(files).length != 1) fatal("can only test on a single file");
|
||||||
|
result = reduce_test(files[Object.keys(files)[0]], options, {
|
||||||
|
log: print_error,
|
||||||
|
verbose: true,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
result = UglifyJS.minify(files, options);
|
||||||
|
}
|
||||||
if (result.error) {
|
if (result.error) {
|
||||||
var ex = result.error;
|
var ex = result.error;
|
||||||
if (ex.name == "SyntaxError") {
|
if (ex.name == "SyntaxError") {
|
||||||
console.error("Parse error at " + ex.filename + ":" + ex.line + "," + ex.col);
|
print_error("Parse error at " + ex.filename + ":" + ex.line + "," + ex.col);
|
||||||
var col = ex.col;
|
var file = files[ex.filename];
|
||||||
var lines = files[ex.filename].split(/\r?\n/);
|
if (file) {
|
||||||
var line = lines[ex.line - 1];
|
var col = ex.col;
|
||||||
if (!line && !col) {
|
var lines = file.split(/\r?\n/);
|
||||||
line = lines[ex.line - 2];
|
var line = lines[ex.line - 1];
|
||||||
col = line.length;
|
if (!line && !col) {
|
||||||
}
|
line = lines[ex.line - 2];
|
||||||
if (line) {
|
col = line.length;
|
||||||
if (col > 40) {
|
}
|
||||||
line = line.slice(col - 40);
|
if (line) {
|
||||||
col = 40;
|
var limit = 70;
|
||||||
|
if (col > limit) {
|
||||||
|
line = line.slice(col - limit);
|
||||||
|
col = limit;
|
||||||
|
}
|
||||||
|
print_error(line.slice(0, 80));
|
||||||
|
print_error(line.slice(0, col).replace(/\S/g, " ") + "^");
|
||||||
}
|
}
|
||||||
console.error(line.slice(0, 80));
|
|
||||||
console.error(line.slice(0, col).replace(/\S/g, " ") + "^");
|
|
||||||
}
|
}
|
||||||
}
|
} else if (ex.defs) {
|
||||||
if (ex.defs) {
|
print_error("Supported options:");
|
||||||
console.error("Supported options:");
|
print_error(format_object(ex.defs));
|
||||||
console.error(ex.defs);
|
|
||||||
}
|
}
|
||||||
fatal(ex);
|
fatal(ex);
|
||||||
} else if (program.output == "ast") {
|
} else if (output == "ast") {
|
||||||
console.log(JSON.stringify(result.ast, function(key, value) {
|
if (!options.compress && !options.mangle) {
|
||||||
|
var toplevel = result.ast;
|
||||||
|
if (!(toplevel instanceof UglifyJS.AST_Toplevel)) {
|
||||||
|
if (!(toplevel instanceof UglifyJS.AST_Statement)) toplevel = new UglifyJS.AST_SimpleStatement({
|
||||||
|
body: toplevel,
|
||||||
|
});
|
||||||
|
toplevel = new UglifyJS.AST_Toplevel({
|
||||||
|
body: [ toplevel ],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
toplevel.figure_out_scope({});
|
||||||
|
}
|
||||||
|
print(JSON.stringify(result.ast, function(key, value) {
|
||||||
|
if (value) switch (key) {
|
||||||
|
case "thedef":
|
||||||
|
return symdef(value);
|
||||||
|
case "enclosed":
|
||||||
|
return value.length ? value.map(symdef) : undefined;
|
||||||
|
case "variables":
|
||||||
|
case "functions":
|
||||||
|
case "globals":
|
||||||
|
return value.size() ? value.map(symdef) : undefined;
|
||||||
|
}
|
||||||
if (skip_key(key)) return;
|
if (skip_key(key)) return;
|
||||||
if (value instanceof UglifyJS.AST_Token) return;
|
if (value instanceof UglifyJS.AST_Token) return;
|
||||||
if (value instanceof UglifyJS.Dictionary) return;
|
if (value instanceof UglifyJS.Dictionary) return;
|
||||||
@@ -254,36 +379,34 @@ function run() {
|
|||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}, 2));
|
}, 2));
|
||||||
} else if (program.output == "spidermonkey") {
|
} else if (output == "spidermonkey") {
|
||||||
console.log(JSON.stringify(UglifyJS.minify(result.code, {
|
print(JSON.stringify(UglifyJS.minify(result.code, {
|
||||||
compress: false,
|
compress: false,
|
||||||
mangle: false,
|
mangle: false,
|
||||||
output: {
|
output: {
|
||||||
ast: true,
|
ast: true,
|
||||||
code: false
|
code: false
|
||||||
}
|
},
|
||||||
}).ast.to_mozilla_ast(), null, 2));
|
}).ast.to_mozilla_ast(), null, 2));
|
||||||
} else if (program.output) {
|
} else if (output) {
|
||||||
fs.writeFileSync(program.output, result.code);
|
fs.writeFileSync(output, result.code);
|
||||||
if (result.map) {
|
if (result.map) fs.writeFileSync(output + ".map", result.map);
|
||||||
fs.writeFileSync(program.output + ".map", result.map);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
console.log(result.code);
|
print(result.code);
|
||||||
}
|
|
||||||
if (program.nameCache) {
|
|
||||||
fs.writeFileSync(program.nameCache, JSON.stringify(cache, function(key, value) {
|
|
||||||
return value instanceof UglifyJS.Dictionary ? value.toObject() : value;
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
if (nameCache) fs.writeFileSync(nameCache, JSON.stringify(options.nameCache));
|
||||||
if (result.timings) for (var phase in result.timings) {
|
if (result.timings) for (var phase in result.timings) {
|
||||||
console.error("- " + phase + ": " + result.timings[phase].toFixed(3) + "s");
|
print_error("- " + phase + ": " + result.timings[phase].toFixed(3) + "s");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function fatal(message) {
|
function fatal(message) {
|
||||||
if (message instanceof Error) message = message.stack.replace(/^\S*?Error:/, "ERROR:")
|
if (message instanceof Error) {
|
||||||
console.error(message);
|
message = message.stack.replace(/^\S*?Error:/, "ERROR:")
|
||||||
|
} else {
|
||||||
|
message = "ERROR: " + message;
|
||||||
|
}
|
||||||
|
print_error(message);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,7 +430,7 @@ function simple_glob(glob) {
|
|||||||
.replace(/\?/g, "[^/\\\\]") + "$";
|
.replace(/\?/g, "[^/\\\\]") + "$";
|
||||||
var mod = process.platform === "win32" ? "i" : "";
|
var mod = process.platform === "win32" ? "i" : "";
|
||||||
var rx = new RegExp(pattern, mod);
|
var rx = new RegExp(pattern, mod);
|
||||||
var results = entries.filter(function(name) {
|
var results = entries.sort().filter(function(name) {
|
||||||
return rx.test(name);
|
return rx.test(name);
|
||||||
}).map(function(name) {
|
}).map(function(name) {
|
||||||
return path.join(dir, name);
|
return path.join(dir, name);
|
||||||
@@ -327,78 +450,75 @@ function read_file(path, default_value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function parse_js(flag, constants) {
|
function parse_js(value, options, flag) {
|
||||||
return function(value, options) {
|
if (!options || typeof options != "object") options = {};
|
||||||
options = options || {};
|
if (typeof value == "string") try {
|
||||||
try {
|
UglifyJS.parse(value, {
|
||||||
UglifyJS.minify(value, {
|
expression: true
|
||||||
parse: {
|
}).walk(new UglifyJS.TreeWalker(function(node) {
|
||||||
expression: true
|
if (node instanceof UglifyJS.AST_Assign) {
|
||||||
},
|
var name = node.left.print_to_string();
|
||||||
compress: false,
|
var value = node.right;
|
||||||
mangle: false,
|
if (flag) {
|
||||||
output: {
|
options[name] = value;
|
||||||
ast: true,
|
} else if (value instanceof UglifyJS.AST_Array) {
|
||||||
code: false
|
options[name] = value.elements.map(to_string);
|
||||||
|
} else {
|
||||||
|
options[name] = to_string(value);
|
||||||
}
|
}
|
||||||
}).ast.walk(new UglifyJS.TreeWalker(function(node) {
|
return true;
|
||||||
if (node instanceof UglifyJS.AST_Assign) {
|
}
|
||||||
var name = node.left.print_to_string();
|
if (node instanceof UglifyJS.AST_Symbol || node instanceof UglifyJS.AST_PropAccess) {
|
||||||
var value = node.right;
|
var name = node.print_to_string();
|
||||||
if (!constants) {
|
options[name] = true;
|
||||||
options[name] = value;
|
return true;
|
||||||
} else if (value instanceof UglifyJS.AST_Array) {
|
}
|
||||||
options[name] = value.elements.map(to_string);
|
if (!(node instanceof UglifyJS.AST_Sequence)) throw node;
|
||||||
} else {
|
|
||||||
options[name] = to_string(value);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (node instanceof UglifyJS.AST_Symbol || node instanceof UglifyJS.AST_PropAccess) {
|
|
||||||
var name = node.print_to_string();
|
|
||||||
options[name] = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (!(node instanceof UglifyJS.AST_Sequence)) throw node;
|
|
||||||
|
|
||||||
function to_string(value) {
|
function to_string(value) {
|
||||||
return value instanceof UglifyJS.AST_Constant ? value.getValue() : value.print_to_string({
|
return value instanceof UglifyJS.AST_Constant ? value.value : value.print_to_string({
|
||||||
quote_keys: true
|
quote_keys: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
} catch(ex) {
|
} catch (ex) {
|
||||||
|
if (flag) {
|
||||||
|
fatal("cannot parse arguments for '" + flag + "': " + value);
|
||||||
|
} else {
|
||||||
options[value] = null;
|
options[value] = null;
|
||||||
}
|
}
|
||||||
return options;
|
|
||||||
}
|
}
|
||||||
}
|
return options;
|
||||||
|
|
||||||
function parse_source_map() {
|
|
||||||
var parse = parse_js("sourceMap", true);
|
|
||||||
return function(value, options) {
|
|
||||||
var hasContent = options && options.sourceMap && "content" in options.sourceMap;
|
|
||||||
var settings = parse(value, options);
|
|
||||||
if (!hasContent && settings.content && settings.content != "inline") {
|
|
||||||
console.error("INFO: Using input source map:", settings.content);
|
|
||||||
settings.content = read_file(settings.content, settings.content);
|
|
||||||
}
|
|
||||||
return settings;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function to_cache(key) {
|
|
||||||
if (cache[key]) {
|
|
||||||
cache[key].props = UglifyJS.Dictionary.fromObject(cache[key].props);
|
|
||||||
} else {
|
|
||||||
cache[key] = {
|
|
||||||
cname: -1,
|
|
||||||
props: new UglifyJS.Dictionary()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return cache[key];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function skip_key(key) {
|
function skip_key(key) {
|
||||||
return skip_keys.indexOf(key) >= 0;
|
return skip_keys.indexOf(key) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function symdef(def) {
|
||||||
|
var ret = (1e6 + def.id) + " " + def.name;
|
||||||
|
if (def.mangled_name) ret += " " + def.mangled_name;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
function format_object(obj) {
|
||||||
|
var lines = [];
|
||||||
|
var padding = "";
|
||||||
|
Object.keys(obj).map(function(name) {
|
||||||
|
if (padding.length < name.length) padding = Array(name.length + 1).join(" ");
|
||||||
|
return [ name, JSON.stringify(obj[name]) ];
|
||||||
|
}).forEach(function(tokens) {
|
||||||
|
lines.push(" " + tokens[0] + padding.slice(tokens[0].length - 2) + tokens[1]);
|
||||||
|
});
|
||||||
|
return lines.join("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
function print_error(msg) {
|
||||||
|
process.stderr.write(msg);
|
||||||
|
process.stderr.write("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
function print(txt) {
|
||||||
|
process.stdout.write(txt);
|
||||||
|
process.stdout.write("\n");
|
||||||
|
}
|
||||||
|
|||||||
902
lib/ast.js
902
lib/ast.js
File diff suppressed because it is too large
Load Diff
10320
lib/compress.js
10320
lib/compress.js
File diff suppressed because it is too large
Load Diff
198
lib/minify.js
198
lib/minify.js
@@ -1,19 +1,47 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var to_ascii = typeof atob == "undefined" ? function(b64) {
|
var to_ascii, to_base64;
|
||||||
return new Buffer(b64, "base64").toString();
|
if (typeof Buffer == "undefined") {
|
||||||
} : atob;
|
to_ascii = atob;
|
||||||
var to_base64 = typeof btoa == "undefined" ? function(str) {
|
to_base64 = btoa;
|
||||||
return new Buffer(str).toString("base64");
|
} else if (typeof Buffer.alloc == "undefined") {
|
||||||
} : btoa;
|
to_ascii = function(b64) {
|
||||||
|
return new Buffer(b64, "base64").toString();
|
||||||
|
};
|
||||||
|
to_base64 = function(str) {
|
||||||
|
return new Buffer(str).toString("base64");
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
to_ascii = function(b64) {
|
||||||
|
return Buffer.from(b64, "base64").toString();
|
||||||
|
};
|
||||||
|
to_base64 = function(str) {
|
||||||
|
return Buffer.from(str).toString("base64");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function read_source_map(code) {
|
function read_source_map(name, toplevel) {
|
||||||
var match = /\n\/\/# sourceMappingURL=data:application\/json(;.*?)?;base64,(.*)/.exec(code);
|
var comments = toplevel.end.comments_after;
|
||||||
if (!match) {
|
for (var i = comments.length; --i >= 0;) {
|
||||||
AST_Node.warn("inline source map not found");
|
var comment = comments[i];
|
||||||
return null;
|
if (comment.type != "comment1") break;
|
||||||
|
var match = /^# ([^\s=]+)=(\S+)\s*$/.exec(comment.value);
|
||||||
|
if (!match) break;
|
||||||
|
if (match[1] == "sourceMappingURL") {
|
||||||
|
match = /^data:application\/json(;.*?)?;base64,(\S+)$/.exec(match[2]);
|
||||||
|
if (!match) break;
|
||||||
|
return to_ascii(match[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AST_Node.warn("inline source map not found: " + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
function parse_source_map(content) {
|
||||||
|
try {
|
||||||
|
return JSON.parse(content);
|
||||||
|
} catch (ex) {
|
||||||
|
throw new Error("invalid input source map: " + content);
|
||||||
}
|
}
|
||||||
return to_ascii(match[2]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function set_shorthand(name, options, keys) {
|
function set_shorthand(name, options, keys) {
|
||||||
@@ -27,32 +55,54 @@ function set_shorthand(name, options, keys) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function init_cache(cache) {
|
||||||
|
if (!cache) return;
|
||||||
|
if (!("props" in cache)) {
|
||||||
|
cache.props = new Dictionary();
|
||||||
|
} else if (!(cache.props instanceof Dictionary)) {
|
||||||
|
cache.props = Dictionary.fromObject(cache.props);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function to_json(cache) {
|
||||||
|
return {
|
||||||
|
props: cache.props.toObject()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function minify(files, options) {
|
function minify(files, options) {
|
||||||
var warn_function = AST_Node.warn_function;
|
|
||||||
try {
|
try {
|
||||||
options = defaults(options, {
|
options = defaults(options, {
|
||||||
compress: {},
|
compress: {},
|
||||||
|
enclose: false,
|
||||||
ie8: false,
|
ie8: false,
|
||||||
keep_fnames: false,
|
keep_fnames: false,
|
||||||
mangle: {},
|
mangle: {},
|
||||||
|
nameCache: null,
|
||||||
output: {},
|
output: {},
|
||||||
parse: {},
|
parse: {},
|
||||||
|
rename: undefined,
|
||||||
sourceMap: false,
|
sourceMap: false,
|
||||||
timings: false,
|
timings: false,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
|
validate: false,
|
||||||
warnings: false,
|
warnings: false,
|
||||||
wrap: false,
|
wrap: false,
|
||||||
}, true);
|
}, true);
|
||||||
|
if (options.validate) AST_Node.enable_validation();
|
||||||
var timings = options.timings && {
|
var timings = options.timings && {
|
||||||
start: Date.now()
|
start: Date.now()
|
||||||
};
|
};
|
||||||
|
if (options.rename === undefined) {
|
||||||
|
options.rename = options.compress && options.mangle;
|
||||||
|
}
|
||||||
set_shorthand("ie8", options, [ "compress", "mangle", "output" ]);
|
set_shorthand("ie8", options, [ "compress", "mangle", "output" ]);
|
||||||
set_shorthand("keep_fnames", options, [ "compress", "mangle" ]);
|
set_shorthand("keep_fnames", options, [ "compress", "mangle" ]);
|
||||||
set_shorthand("toplevel", options, [ "compress", "mangle" ]);
|
set_shorthand("toplevel", options, [ "compress", "mangle" ]);
|
||||||
set_shorthand("warnings", options, [ "compress" ]);
|
var quoted_props;
|
||||||
if (options.mangle) {
|
if (options.mangle) {
|
||||||
options.mangle = defaults(options.mangle, {
|
options.mangle = defaults(options.mangle, {
|
||||||
cache: null,
|
cache: options.nameCache && (options.nameCache.vars || {}),
|
||||||
eval: false,
|
eval: false,
|
||||||
ie8: false,
|
ie8: false,
|
||||||
keep_fnames: false,
|
keep_fnames: false,
|
||||||
@@ -60,22 +110,36 @@ function minify(files, options) {
|
|||||||
reserved: [],
|
reserved: [],
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
}, true);
|
}, true);
|
||||||
|
if (options.mangle.properties) {
|
||||||
|
if (typeof options.mangle.properties != "object") {
|
||||||
|
options.mangle.properties = {};
|
||||||
|
}
|
||||||
|
if (options.mangle.properties.keep_quoted) {
|
||||||
|
quoted_props = options.mangle.properties.reserved;
|
||||||
|
if (!Array.isArray(quoted_props)) quoted_props = [];
|
||||||
|
options.mangle.properties.reserved = quoted_props;
|
||||||
|
}
|
||||||
|
if (options.nameCache && !("cache" in options.mangle.properties)) {
|
||||||
|
options.mangle.properties.cache = options.nameCache.props || {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
init_cache(options.mangle.cache);
|
||||||
|
init_cache(options.mangle.properties.cache);
|
||||||
}
|
}
|
||||||
if (options.sourceMap) {
|
if (options.sourceMap) {
|
||||||
options.sourceMap = defaults(options.sourceMap, {
|
options.sourceMap = defaults(options.sourceMap, {
|
||||||
content: null,
|
content: null,
|
||||||
filename: null,
|
filename: null,
|
||||||
includeSources: false,
|
includeSources: false,
|
||||||
|
names: true,
|
||||||
root: null,
|
root: null,
|
||||||
url: null,
|
url: null,
|
||||||
}, true);
|
}, true);
|
||||||
}
|
}
|
||||||
var warnings = [];
|
var warnings = [];
|
||||||
if (options.warnings && !AST_Node.warn_function) {
|
if (options.warnings) AST_Node.log_function(function(warning) {
|
||||||
AST_Node.warn_function = function(warning) {
|
warnings.push(warning);
|
||||||
warnings.push(warning);
|
}, options.warnings == "verbose");
|
||||||
};
|
|
||||||
}
|
|
||||||
if (timings) timings.parse = Date.now();
|
if (timings) timings.parse = Date.now();
|
||||||
var toplevel;
|
var toplevel;
|
||||||
if (files instanceof AST_Toplevel) {
|
if (files instanceof AST_Toplevel) {
|
||||||
@@ -86,36 +150,54 @@ function minify(files, options) {
|
|||||||
}
|
}
|
||||||
options.parse = options.parse || {};
|
options.parse = options.parse || {};
|
||||||
options.parse.toplevel = null;
|
options.parse.toplevel = null;
|
||||||
for (var name in files) {
|
var source_map_content = options.sourceMap && options.sourceMap.content;
|
||||||
|
if (typeof source_map_content == "string" && source_map_content != "inline") {
|
||||||
|
source_map_content = parse_source_map(source_map_content);
|
||||||
|
}
|
||||||
|
if (source_map_content) options.sourceMap.orig = Object.create(null);
|
||||||
|
for (var name in files) if (HOP(files, name)) {
|
||||||
options.parse.filename = name;
|
options.parse.filename = name;
|
||||||
options.parse.toplevel = parse(files[name], options.parse);
|
options.parse.toplevel = toplevel = parse(files[name], options.parse);
|
||||||
if (options.sourceMap && options.sourceMap.content == "inline") {
|
if (source_map_content == "inline") {
|
||||||
if (Object.keys(files).length > 1)
|
var inlined_content = read_source_map(name, toplevel);
|
||||||
throw new Error("inline source map only works with singular input");
|
if (inlined_content) {
|
||||||
options.sourceMap.content = read_source_map(files[name]);
|
options.sourceMap.orig[name] = parse_source_map(inlined_content);
|
||||||
|
}
|
||||||
|
} else if (source_map_content) {
|
||||||
|
options.sourceMap.orig[name] = source_map_content;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
toplevel = options.parse.toplevel;
|
|
||||||
}
|
}
|
||||||
if (options.wrap) {
|
if (quoted_props) {
|
||||||
toplevel = toplevel.wrap_commonjs(options.wrap);
|
reserve_quoted_keys(toplevel, quoted_props);
|
||||||
|
}
|
||||||
|
[ "enclose", "wrap" ].forEach(function(action) {
|
||||||
|
var option = options[action];
|
||||||
|
if (!option) return;
|
||||||
|
var orig = toplevel.print_to_string().slice(0, -1);
|
||||||
|
toplevel = toplevel[action](option);
|
||||||
|
files[toplevel.start.file] = toplevel.print_to_string().replace(orig, "");
|
||||||
|
});
|
||||||
|
if (options.validate) toplevel.validate_ast();
|
||||||
|
if (timings) timings.rename = Date.now();
|
||||||
|
if (options.rename) {
|
||||||
|
toplevel.figure_out_scope(options.mangle);
|
||||||
|
toplevel.expand_names(options.mangle);
|
||||||
}
|
}
|
||||||
if (timings) timings.scope1 = Date.now();
|
|
||||||
if (options.compress) toplevel.figure_out_scope(options.mangle);
|
|
||||||
if (timings) timings.compress = Date.now();
|
if (timings) timings.compress = Date.now();
|
||||||
if (options.compress) toplevel = new Compressor(options.compress).compress(toplevel);
|
if (options.compress) {
|
||||||
if (timings) timings.scope2 = Date.now();
|
toplevel = new Compressor(options.compress).compress(toplevel);
|
||||||
|
if (options.validate) toplevel.validate_ast();
|
||||||
|
}
|
||||||
|
if (timings) timings.scope = Date.now();
|
||||||
if (options.mangle) toplevel.figure_out_scope(options.mangle);
|
if (options.mangle) toplevel.figure_out_scope(options.mangle);
|
||||||
if (timings) timings.mangle = Date.now();
|
if (timings) timings.mangle = Date.now();
|
||||||
if (options.mangle) {
|
if (options.mangle) {
|
||||||
base54.reset();
|
|
||||||
toplevel.compute_char_frequency(options.mangle);
|
toplevel.compute_char_frequency(options.mangle);
|
||||||
toplevel.mangle_names(options.mangle);
|
toplevel.mangle_names(options.mangle);
|
||||||
}
|
}
|
||||||
if (timings) timings.properties = Date.now();
|
if (timings) timings.properties = Date.now();
|
||||||
if (options.mangle && options.mangle.properties) {
|
if (options.mangle && options.mangle.properties) mangle_properties(toplevel, options.mangle.properties);
|
||||||
toplevel = mangle_properties(toplevel, options.mangle.properties);
|
|
||||||
}
|
|
||||||
if (timings) timings.output = Date.now();
|
if (timings) timings.output = Date.now();
|
||||||
var result = {};
|
var result = {};
|
||||||
if (options.output.ast) {
|
if (options.output.ast) {
|
||||||
@@ -123,19 +205,12 @@ function minify(files, options) {
|
|||||||
}
|
}
|
||||||
if (!HOP(options.output, "code") || options.output.code) {
|
if (!HOP(options.output, "code") || options.output.code) {
|
||||||
if (options.sourceMap) {
|
if (options.sourceMap) {
|
||||||
if (typeof options.sourceMap.content == "string") {
|
options.output.source_map = SourceMap(options.sourceMap);
|
||||||
options.sourceMap.content = JSON.parse(options.sourceMap.content);
|
|
||||||
}
|
|
||||||
options.output.source_map = SourceMap({
|
|
||||||
file: options.sourceMap.filename,
|
|
||||||
orig: options.sourceMap.content,
|
|
||||||
root: options.sourceMap.root
|
|
||||||
});
|
|
||||||
if (options.sourceMap.includeSources) {
|
if (options.sourceMap.includeSources) {
|
||||||
if (files instanceof AST_Toplevel) {
|
if (files instanceof AST_Toplevel) {
|
||||||
throw new Error("original source content unavailable");
|
throw new Error("original source content unavailable");
|
||||||
} else for (var name in files) {
|
} else for (var name in files) if (HOP(files, name)) {
|
||||||
options.output.source_map.get().setSourceContent(name, files[name]);
|
options.output.source_map.setSourceContent(name, files[name]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -146,24 +221,35 @@ function minify(files, options) {
|
|||||||
result.code = stream.get();
|
result.code = stream.get();
|
||||||
if (options.sourceMap) {
|
if (options.sourceMap) {
|
||||||
result.map = options.output.source_map.toString();
|
result.map = options.output.source_map.toString();
|
||||||
if (options.sourceMap.url == "inline") {
|
var url = options.sourceMap.url;
|
||||||
result.code += "\n//# sourceMappingURL=data:application/json;charset=utf-8;base64," + to_base64(result.map);
|
if (url) {
|
||||||
} else if (options.sourceMap.url) {
|
result.code = result.code.replace(/\n\/\/# sourceMappingURL=\S+\s*$/, "");
|
||||||
result.code += "\n//# sourceMappingURL=" + options.sourceMap.url;
|
if (url == "inline") {
|
||||||
|
result.code += "\n//# sourceMappingURL=data:application/json;charset=utf-8;base64," + to_base64(result.map);
|
||||||
|
} else {
|
||||||
|
result.code += "\n//# sourceMappingURL=" + url;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (options.nameCache && options.mangle) {
|
||||||
|
if (options.mangle.cache) options.nameCache.vars = to_json(options.mangle.cache);
|
||||||
|
if (options.mangle.properties && options.mangle.properties.cache) {
|
||||||
|
options.nameCache.props = to_json(options.mangle.properties.cache);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (timings) {
|
if (timings) {
|
||||||
timings.end = Date.now();
|
timings.end = Date.now();
|
||||||
result.timings = {
|
result.timings = {
|
||||||
parse: 1e-3 * (timings.scope1 - timings.parse),
|
parse: 1e-3 * (timings.rename - timings.parse),
|
||||||
scope: 1e-3 * (timings.compress - timings.scope1 + timings.mangle - timings.scope2),
|
rename: 1e-3 * (timings.compress - timings.rename),
|
||||||
compress: 1e-3 * (timings.scope2 - timings.compress),
|
compress: 1e-3 * (timings.scope - timings.compress),
|
||||||
|
scope: 1e-3 * (timings.mangle - timings.scope),
|
||||||
mangle: 1e-3 * (timings.properties - timings.mangle),
|
mangle: 1e-3 * (timings.properties - timings.mangle),
|
||||||
properties: 1e-3 * (timings.output - timings.properties),
|
properties: 1e-3 * (timings.output - timings.properties),
|
||||||
output: 1e-3 * (timings.end - timings.output),
|
output: 1e-3 * (timings.end - timings.output),
|
||||||
total: 1e-3 * (timings.end - timings.start)
|
total: 1e-3 * (timings.end - timings.start)
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
if (warnings.length) {
|
if (warnings.length) {
|
||||||
result.warnings = warnings;
|
result.warnings = warnings;
|
||||||
@@ -172,6 +258,6 @@ function minify(files, options) {
|
|||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
return { error: ex };
|
return { error: ex };
|
||||||
} finally {
|
} finally {
|
||||||
AST_Node.warn_function = warn_function;
|
AST_Node.disable_validation();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
|
||||||
A JavaScript tokenizer / parser / beautifier / compressor.
|
A JavaScript tokenizer / parser / beautifier / compressor.
|
||||||
https://github.com/mishoo/UglifyJS2
|
https://github.com/mishoo/UglifyJS
|
||||||
|
|
||||||
-------------------------------- (C) ---------------------------------
|
-------------------------------- (C) ---------------------------------
|
||||||
|
|
||||||
@@ -43,11 +43,9 @@
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
(function(){
|
(function() {
|
||||||
|
function normalize_directives(body) {
|
||||||
var normalize_directives = function(body) {
|
|
||||||
var in_directive = true;
|
var in_directive = true;
|
||||||
|
|
||||||
for (var i = 0; i < body.length; i++) {
|
for (var i = 0; i < body.length; i++) {
|
||||||
if (in_directive && body[i] instanceof AST_Statement && body[i].body instanceof AST_String) {
|
if (in_directive && body[i] instanceof AST_Statement && body[i].body instanceof AST_String) {
|
||||||
body[i] = new AST_Directive({
|
body[i] = new AST_Directive({
|
||||||
@@ -59,9 +57,8 @@
|
|||||||
in_directive = false;
|
in_directive = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return body;
|
return body;
|
||||||
};
|
}
|
||||||
|
|
||||||
var MOZ_TO_ME = {
|
var MOZ_TO_ME = {
|
||||||
Program: function(M) {
|
Program: function(M) {
|
||||||
@@ -114,7 +111,7 @@
|
|||||||
var args = {
|
var args = {
|
||||||
start : my_start_token(key),
|
start : my_start_token(key),
|
||||||
end : my_end_token(M.value),
|
end : my_end_token(M.value),
|
||||||
key : key.type == "Identifier" ? key.name : key.value,
|
key : "" + key[key.type == "Identifier" ? "name" : "value"],
|
||||||
value : from_moz(M.value)
|
value : from_moz(M.value)
|
||||||
};
|
};
|
||||||
if (M.kind == "init") return new AST_ObjectKeyVal(args);
|
if (M.kind == "init") return new AST_ObjectKeyVal(args);
|
||||||
@@ -129,7 +126,7 @@
|
|||||||
return new AST_Array({
|
return new AST_Array({
|
||||||
start : my_start_token(M),
|
start : my_start_token(M),
|
||||||
end : my_end_token(M),
|
end : my_end_token(M),
|
||||||
elements : M.elements.map(function(elem){
|
elements : M.elements.map(function(elem) {
|
||||||
return elem === null ? new AST_Hole() : from_moz(elem);
|
return elem === null ? new AST_Hole() : from_moz(elem);
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
@@ -138,7 +135,7 @@
|
|||||||
return new AST_Object({
|
return new AST_Object({
|
||||||
start : my_start_token(M),
|
start : my_start_token(M),
|
||||||
end : my_end_token(M),
|
end : my_end_token(M),
|
||||||
properties : M.properties.map(function(prop){
|
properties : M.properties.map(function(prop) {
|
||||||
prop.type = "Property";
|
prop.type = "Property";
|
||||||
return from_moz(prop)
|
return from_moz(prop)
|
||||||
})
|
})
|
||||||
@@ -180,6 +177,17 @@
|
|||||||
end : my_end_token(M)
|
end : my_end_token(M)
|
||||||
};
|
};
|
||||||
if (val === null) return new AST_Null(args);
|
if (val === null) return new AST_Null(args);
|
||||||
|
var rx = M.regex;
|
||||||
|
if (rx && rx.pattern) {
|
||||||
|
// RegExpLiteral as per ESTree AST spec
|
||||||
|
args.value = new RegExp(rx.pattern, rx.flags);
|
||||||
|
args.value.raw_source = rx.pattern;
|
||||||
|
return new AST_RegExp(args);
|
||||||
|
} else if (rx) {
|
||||||
|
// support legacy RegExp
|
||||||
|
args.value = M.regex && M.raw ? M.raw : val;
|
||||||
|
return new AST_RegExp(args);
|
||||||
|
}
|
||||||
switch (typeof val) {
|
switch (typeof val) {
|
||||||
case "string":
|
case "string":
|
||||||
args.value = val;
|
args.value = val;
|
||||||
@@ -189,16 +197,6 @@
|
|||||||
return new AST_Number(args);
|
return new AST_Number(args);
|
||||||
case "boolean":
|
case "boolean":
|
||||||
return new (val ? AST_True : AST_False)(args);
|
return new (val ? AST_True : AST_False)(args);
|
||||||
default:
|
|
||||||
var rx = M.regex;
|
|
||||||
if (rx && rx.pattern) {
|
|
||||||
// RegExpLiteral as per ESTree AST spec
|
|
||||||
args.value = new RegExp(rx.pattern, rx.flags).toString();
|
|
||||||
} else {
|
|
||||||
// support legacy RegExp
|
|
||||||
args.value = M.regex && M.raw ? M.raw : val;
|
|
||||||
}
|
|
||||||
return new AST_RegExp(args);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Identifier: function(M) {
|
Identifier: function(M) {
|
||||||
@@ -214,7 +212,14 @@
|
|||||||
end : my_end_token(M),
|
end : my_end_token(M),
|
||||||
name : M.name
|
name : M.name
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
|
ThisExpression: function(M) {
|
||||||
|
return new AST_This({
|
||||||
|
start : my_start_token(M),
|
||||||
|
end : my_end_token(M),
|
||||||
|
name : "this",
|
||||||
|
});
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
MOZ_TO_ME.UpdateExpression =
|
MOZ_TO_ME.UpdateExpression =
|
||||||
@@ -247,7 +252,6 @@
|
|||||||
map("VariableDeclarator", AST_VarDef, "id>name, init>value");
|
map("VariableDeclarator", AST_VarDef, "id>name, init>value");
|
||||||
map("CatchClause", AST_Catch, "param>argname, body%body");
|
map("CatchClause", AST_Catch, "param>argname, body%body");
|
||||||
|
|
||||||
map("ThisExpression", AST_This);
|
|
||||||
map("BinaryExpression", AST_Binary, "operator=operator, left>left, right>right");
|
map("BinaryExpression", AST_Binary, "operator=operator, left>left, right>right");
|
||||||
map("LogicalExpression", AST_Binary, "operator=operator, left>left, right>right");
|
map("LogicalExpression", AST_Binary, "operator=operator, left>left, right>right");
|
||||||
map("AssignmentExpression", AST_Assign, "operator=operator, left>left, right>right");
|
map("AssignmentExpression", AST_Assign, "operator=operator, left>left, right>right");
|
||||||
@@ -405,19 +409,24 @@
|
|||||||
var def = M.definition();
|
var def = M.definition();
|
||||||
return {
|
return {
|
||||||
type: "Identifier",
|
type: "Identifier",
|
||||||
name: def ? def.mangled_name || def.name : M.name
|
name: def && def.mangled_name || M.name
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
def_to_moz(AST_This, function To_Moz_ThisExpression() {
|
||||||
|
return { type: "ThisExpression" };
|
||||||
|
});
|
||||||
|
|
||||||
def_to_moz(AST_RegExp, function To_Moz_RegExpLiteral(M) {
|
def_to_moz(AST_RegExp, function To_Moz_RegExpLiteral(M) {
|
||||||
var value = M.value;
|
var flags = M.value.toString().match(/[gimuy]*$/)[0];
|
||||||
|
var value = "/" + M.value.raw_source + "/" + flags;
|
||||||
return {
|
return {
|
||||||
type: "Literal",
|
type: "Literal",
|
||||||
value: value,
|
value: value,
|
||||||
raw: value.toString(),
|
raw: value,
|
||||||
regex: {
|
regex: {
|
||||||
pattern: value.source,
|
pattern: M.value.raw_source,
|
||||||
flags: value.toString().match(/[gimuy]*$/)[0]
|
flags: flags
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@@ -478,7 +487,7 @@
|
|||||||
endpos : range ? range[0] : moznode.start,
|
endpos : range ? range[0] : moznode.start,
|
||||||
raw : raw_token(moznode),
|
raw : raw_token(moznode),
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
function my_end_token(moznode) {
|
function my_end_token(moznode) {
|
||||||
var loc = moznode.loc, end = loc && loc.end;
|
var loc = moznode.loc, end = loc && loc.end;
|
||||||
@@ -493,7 +502,7 @@
|
|||||||
endpos : range ? range[1] : moznode.end,
|
endpos : range ? range[1] : moznode.end,
|
||||||
raw : raw_token(moznode),
|
raw : raw_token(moznode),
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
function map(moztype, mytype, propmap) {
|
function map(moztype, mytype, propmap) {
|
||||||
var moz_to_me = "function From_Moz_" + moztype + "(M){\n";
|
var moz_to_me = "function From_Moz_" + moztype + "(M){\n";
|
||||||
@@ -505,7 +514,7 @@
|
|||||||
me_to_moz += "return {\n" +
|
me_to_moz += "return {\n" +
|
||||||
"type: " + JSON.stringify(moztype);
|
"type: " + JSON.stringify(moztype);
|
||||||
|
|
||||||
if (propmap) propmap.split(/\s*,\s*/).forEach(function(prop){
|
if (propmap) propmap.split(/\s*,\s*/).forEach(function(prop) {
|
||||||
var m = /([a-z0-9$_]+)(=|@|>|%)([a-z0-9$_]+)/i.exec(prop);
|
var m = /([a-z0-9$_]+)(=|@|>|%)([a-z0-9$_]+)/i.exec(prop);
|
||||||
if (!m) throw new Error("Can't understand property map: " + prop);
|
if (!m) throw new Error("Can't understand property map: " + prop);
|
||||||
var moz = m[1], how = m[2], my = m[3];
|
var moz = m[1], how = m[2], my = m[3];
|
||||||
@@ -548,7 +557,7 @@
|
|||||||
);
|
);
|
||||||
MOZ_TO_ME[moztype] = moz_to_me;
|
MOZ_TO_ME[moztype] = moz_to_me;
|
||||||
def_to_moz(mytype, me_to_moz);
|
def_to_moz(mytype, me_to_moz);
|
||||||
};
|
}
|
||||||
|
|
||||||
var FROM_MOZ_STACK = null;
|
var FROM_MOZ_STACK = null;
|
||||||
|
|
||||||
@@ -557,13 +566,28 @@
|
|||||||
var ret = node != null ? MOZ_TO_ME[node.type](node) : null;
|
var ret = node != null ? MOZ_TO_ME[node.type](node) : null;
|
||||||
FROM_MOZ_STACK.pop();
|
FROM_MOZ_STACK.pop();
|
||||||
return ret;
|
return ret;
|
||||||
};
|
}
|
||||||
|
|
||||||
AST_Node.from_mozilla_ast = function(node){
|
AST_Node.from_mozilla_ast = function(node) {
|
||||||
var save_stack = FROM_MOZ_STACK;
|
var save_stack = FROM_MOZ_STACK;
|
||||||
FROM_MOZ_STACK = [];
|
FROM_MOZ_STACK = [];
|
||||||
var ast = from_moz(node);
|
var ast = from_moz(node);
|
||||||
FROM_MOZ_STACK = save_stack;
|
FROM_MOZ_STACK = save_stack;
|
||||||
|
ast.walk(new TreeWalker(function(node) {
|
||||||
|
if (node instanceof AST_LabelRef) {
|
||||||
|
for (var level = 0, parent; parent = this.parent(level); level++) {
|
||||||
|
if (parent instanceof AST_Scope) break;
|
||||||
|
if (parent instanceof AST_LabeledStatement && parent.label.name == node.name) {
|
||||||
|
node.thedef = parent.label;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!node.thedef) {
|
||||||
|
var s = node.start;
|
||||||
|
js_error("Undefined label " + node.name, s.file, s.line, s.col, s.pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
return ast;
|
return ast;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -583,24 +607,24 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return moznode;
|
return moznode;
|
||||||
};
|
}
|
||||||
|
|
||||||
function def_to_moz(mytype, handler) {
|
function def_to_moz(mytype, handler) {
|
||||||
mytype.DEFMETHOD("to_mozilla_ast", function() {
|
mytype.DEFMETHOD("to_mozilla_ast", function() {
|
||||||
return set_moz_loc(this, handler(this));
|
return set_moz_loc(this, handler(this));
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
function to_moz(node) {
|
function to_moz(node) {
|
||||||
return node != null ? node.to_mozilla_ast() : null;
|
return node != null ? node.to_mozilla_ast() : null;
|
||||||
};
|
}
|
||||||
|
|
||||||
function to_moz_block(node) {
|
function to_moz_block(node) {
|
||||||
return {
|
return {
|
||||||
type: "BlockStatement",
|
type: "BlockStatement",
|
||||||
body: node.body.map(to_moz)
|
body: node.body.map(to_moz)
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
function to_moz_scope(type, node) {
|
function to_moz_scope(type, node) {
|
||||||
var body = node.body.map(to_moz);
|
var body = node.body.map(to_moz);
|
||||||
@@ -611,5 +635,5 @@
|
|||||||
type: type,
|
type: type,
|
||||||
body: body
|
body: body
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
})();
|
})();
|
||||||
|
|||||||
1361
lib/output.js
1361
lib/output.js
File diff suppressed because it is too large
Load Diff
628
lib/parse.js
628
lib/parse.js
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
|||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
|
||||||
A JavaScript tokenizer / parser / beautifier / compressor.
|
A JavaScript tokenizer / parser / beautifier / compressor.
|
||||||
https://github.com/mishoo/UglifyJS2
|
https://github.com/mishoo/UglifyJS
|
||||||
|
|
||||||
-------------------------------- (C) ---------------------------------
|
-------------------------------- (C) ---------------------------------
|
||||||
|
|
||||||
@@ -43,7 +43,8 @@
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
function find_builtins(reserved) {
|
var builtins = function() {
|
||||||
|
var names = [];
|
||||||
// NaN will be included due to Number.NaN
|
// NaN will be included due to Number.NaN
|
||||||
[
|
[
|
||||||
"null",
|
"null",
|
||||||
@@ -53,211 +54,207 @@ function find_builtins(reserved) {
|
|||||||
"-Infinity",
|
"-Infinity",
|
||||||
"undefined",
|
"undefined",
|
||||||
].forEach(add);
|
].forEach(add);
|
||||||
[ Object, Array, Function, Number,
|
[
|
||||||
String, Boolean, Error, Math,
|
Array,
|
||||||
Date, RegExp
|
Boolean,
|
||||||
].forEach(function(ctor){
|
Date,
|
||||||
|
Error,
|
||||||
|
Function,
|
||||||
|
Math,
|
||||||
|
Number,
|
||||||
|
Object,
|
||||||
|
RegExp,
|
||||||
|
String,
|
||||||
|
].forEach(function(ctor) {
|
||||||
Object.getOwnPropertyNames(ctor).map(add);
|
Object.getOwnPropertyNames(ctor).map(add);
|
||||||
if (ctor.prototype) {
|
if (ctor.prototype) {
|
||||||
|
Object.getOwnPropertyNames(new ctor()).map(add);
|
||||||
Object.getOwnPropertyNames(ctor.prototype).map(add);
|
Object.getOwnPropertyNames(ctor.prototype).map(add);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
return makePredicate(names);
|
||||||
|
|
||||||
|
function add(name) {
|
||||||
|
names.push(name);
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
|
||||||
|
function reserve_quoted_keys(ast, reserved) {
|
||||||
|
ast.walk(new TreeWalker(function(node) {
|
||||||
|
if (node instanceof AST_ObjectKeyVal) {
|
||||||
|
if (node.quote) add(node.key);
|
||||||
|
} else if (node instanceof AST_Sub) {
|
||||||
|
addStrings(node.property, add);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
function add(name) {
|
function add(name) {
|
||||||
push_uniq(reserved, name);
|
push_uniq(reserved, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function addStrings(node, add) {
|
||||||
|
if (node instanceof AST_Conditional) {
|
||||||
|
addStrings(node.consequent, add);
|
||||||
|
addStrings(node.alternative, add);
|
||||||
|
} else if (node instanceof AST_Sequence) {
|
||||||
|
addStrings(node.tail_node(), add);
|
||||||
|
} else if (node instanceof AST_String) {
|
||||||
|
add(node.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function mangle_properties(ast, options) {
|
function mangle_properties(ast, options) {
|
||||||
options = defaults(options, {
|
options = defaults(options, {
|
||||||
builtins: false,
|
builtins: false,
|
||||||
cache: null,
|
cache: null,
|
||||||
debug: false,
|
debug: false,
|
||||||
keep_quoted: false,
|
keep_quoted: false,
|
||||||
only_cache: false,
|
|
||||||
regex: null,
|
regex: null,
|
||||||
reserved: null,
|
reserved: null,
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
var reserved = Object.create(options.builtins ? null : builtins);
|
||||||
|
if (Array.isArray(options.reserved)) options.reserved.forEach(function(name) {
|
||||||
|
reserved[name] = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
var reserved = options.reserved || [];
|
var cname = -1;
|
||||||
if (!options.builtins) find_builtins(reserved);
|
var cache;
|
||||||
|
if (options.cache) {
|
||||||
var cache = options.cache;
|
cache = options.cache.props;
|
||||||
if (cache == null) {
|
cache.each(function(name) {
|
||||||
cache = {
|
reserved[name] = true;
|
||||||
cname: -1,
|
});
|
||||||
props: new Dictionary()
|
} else {
|
||||||
};
|
cache = new Dictionary();
|
||||||
}
|
}
|
||||||
|
|
||||||
var regex = options.regex;
|
var regex = options.regex;
|
||||||
var keep_quoted = options.keep_quoted;
|
|
||||||
|
|
||||||
// note debug is either false (disabled), or a string of the debug suffix to use (enabled).
|
// note debug is either false (disabled), or a string of the debug suffix to use (enabled).
|
||||||
// note debug may be enabled as an empty string, which is falsey. Also treat passing 'true'
|
// note debug may be enabled as an empty string, which is falsey. Also treat passing 'true'
|
||||||
// the same as passing an empty string.
|
// the same as passing an empty string.
|
||||||
var debug = options.debug !== false;
|
var debug = options.debug !== false;
|
||||||
var debug_name_suffix;
|
var debug_suffix;
|
||||||
if (debug) {
|
if (debug) debug_suffix = options.debug === true ? "" : options.debug;
|
||||||
debug_name_suffix = (options.debug === true ? "" : options.debug);
|
|
||||||
}
|
|
||||||
|
|
||||||
var names_to_mangle = [];
|
var names_to_mangle = Object.create(null);
|
||||||
var unmangleable = [];
|
var unmangleable = Object.create(reserved);
|
||||||
var to_keep = {};
|
|
||||||
|
|
||||||
// step 1: find candidates to mangle
|
// step 1: find candidates to mangle
|
||||||
ast.walk(new TreeWalker(function(node){
|
ast.walk(new TreeWalker(function(node) {
|
||||||
if (node instanceof AST_ObjectKeyVal) {
|
if (node instanceof AST_Binary) {
|
||||||
add(node.key, keep_quoted && node.quote);
|
if (node.operator == "in") addStrings(node.left, add);
|
||||||
}
|
} else if (node.TYPE == "Call") {
|
||||||
else if (node instanceof AST_ObjectProperty) {
|
var exp = node.expression;
|
||||||
|
if (exp instanceof AST_Dot) switch (exp.property) {
|
||||||
|
case "defineProperty":
|
||||||
|
case "getOwnPropertyDescriptor":
|
||||||
|
if (node.args.length < 2) break;
|
||||||
|
exp = exp.expression;
|
||||||
|
if (!(exp instanceof AST_SymbolRef)) break;
|
||||||
|
if (exp.name != "Object") break;
|
||||||
|
if (!exp.definition().undeclared) break;
|
||||||
|
addStrings(node.args[1], add);
|
||||||
|
break;
|
||||||
|
case "hasOwnProperty":
|
||||||
|
if (node.args.length < 1) break;
|
||||||
|
addStrings(node.args[0], add);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (node instanceof AST_Dot) {
|
||||||
|
add(node.property);
|
||||||
|
} else if (node instanceof AST_ObjectKeyVal) {
|
||||||
|
add(node.key);
|
||||||
|
} else if (node instanceof AST_ObjectProperty) {
|
||||||
// setter or getter, since KeyVal is handled above
|
// setter or getter, since KeyVal is handled above
|
||||||
add(node.key.name);
|
add(node.key.name);
|
||||||
}
|
} else if (node instanceof AST_Sub) {
|
||||||
else if (node instanceof AST_Dot) {
|
addStrings(node.property, add);
|
||||||
add(node.property);
|
|
||||||
}
|
|
||||||
else if (node instanceof AST_Sub) {
|
|
||||||
addStrings(node.property, keep_quoted);
|
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// step 2: transform the tree, renaming properties
|
// step 2: renaming properties
|
||||||
return ast.transform(new TreeTransformer(function(node){
|
ast.walk(new TreeWalker(function(node) {
|
||||||
if (node instanceof AST_ObjectKeyVal) {
|
if (node instanceof AST_Binary) {
|
||||||
if (!(keep_quoted && node.quote))
|
if (node.operator == "in") mangleStrings(node.left);
|
||||||
node.key = mangle(node.key);
|
} else if (node.TYPE == "Call") {
|
||||||
}
|
var exp = node.expression;
|
||||||
else if (node instanceof AST_ObjectProperty) {
|
if (exp instanceof AST_Dot) switch (exp.property) {
|
||||||
|
case "defineProperty":
|
||||||
|
case "getOwnPropertyDescriptor":
|
||||||
|
if (node.args.length < 2) break;
|
||||||
|
exp = exp.expression;
|
||||||
|
if (!(exp instanceof AST_SymbolRef)) break;
|
||||||
|
if (exp.name != "Object") break;
|
||||||
|
if (!exp.definition().undeclared) break;
|
||||||
|
mangleStrings(node.args[1]);
|
||||||
|
break;
|
||||||
|
case "hasOwnProperty":
|
||||||
|
if (node.args.length < 1) break;
|
||||||
|
mangleStrings(node.args[0]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (node instanceof AST_Dot) {
|
||||||
|
node.property = mangle(node.property);
|
||||||
|
} else if (node instanceof AST_ObjectKeyVal) {
|
||||||
|
node.key = mangle(node.key);
|
||||||
|
} else if (node instanceof AST_ObjectProperty) {
|
||||||
// setter or getter
|
// setter or getter
|
||||||
node.key.name = mangle(node.key.name);
|
node.key.name = mangle(node.key.name);
|
||||||
|
} else if (node instanceof AST_Sub) {
|
||||||
|
if (!options.keep_quoted) mangleStrings(node.property);
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_Dot) {
|
|
||||||
node.property = mangle(node.property);
|
|
||||||
}
|
|
||||||
else if (node instanceof AST_Sub) {
|
|
||||||
if (!keep_quoted)
|
|
||||||
node.property = mangleStrings(node.property);
|
|
||||||
}
|
|
||||||
// else if (node instanceof AST_String) {
|
|
||||||
// if (should_mangle(node.value)) {
|
|
||||||
// AST_Node.warn(
|
|
||||||
// "Found \"{prop}\" property candidate for mangling in an arbitrary string [{file}:{line},{col}]", {
|
|
||||||
// file : node.start.file,
|
|
||||||
// line : node.start.line,
|
|
||||||
// col : node.start.col,
|
|
||||||
// prop : node.value
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// only function declarations after this line
|
// only function declarations after this line
|
||||||
|
|
||||||
function can_mangle(name) {
|
function can_mangle(name) {
|
||||||
if (unmangleable.indexOf(name) >= 0) return false;
|
if (unmangleable[name]) return false;
|
||||||
if (reserved.indexOf(name) >= 0) return false;
|
|
||||||
if (options.only_cache) {
|
|
||||||
return cache.props.has(name);
|
|
||||||
}
|
|
||||||
if (/^-?[0-9]+(\.[0-9]+)?(e[+-][0-9]+)?$/.test(name)) return false;
|
if (/^-?[0-9]+(\.[0-9]+)?(e[+-][0-9]+)?$/.test(name)) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function should_mangle(name) {
|
function should_mangle(name) {
|
||||||
if (keep_quoted && name in to_keep) return false;
|
if (reserved[name]) return false;
|
||||||
if (regex && !regex.test(name)) return false;
|
if (regex && !regex.test(name)) return false;
|
||||||
if (reserved.indexOf(name) >= 0) return false;
|
return cache.has(name) || names_to_mangle[name];
|
||||||
return cache.props.has(name)
|
|
||||||
|| names_to_mangle.indexOf(name) >= 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function add(name, keep) {
|
function add(name) {
|
||||||
if (keep) {
|
if (can_mangle(name)) names_to_mangle[name] = true;
|
||||||
to_keep[name] = true;
|
if (!should_mangle(name)) unmangleable[name] = true;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (can_mangle(name))
|
|
||||||
push_uniq(names_to_mangle, name);
|
|
||||||
|
|
||||||
if (!should_mangle(name)) {
|
|
||||||
push_uniq(unmangleable, name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function mangle(name) {
|
function mangle(name) {
|
||||||
if (!should_mangle(name)) {
|
if (!should_mangle(name)) {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
var mangled = cache.get(name);
|
||||||
var mangled = cache.props.get(name);
|
|
||||||
if (!mangled) {
|
if (!mangled) {
|
||||||
if (debug) {
|
if (debug) {
|
||||||
// debug mode: use a prefix and suffix to preserve readability, e.g. o.foo -> o._$foo$NNN_.
|
// debug mode: use a prefix and suffix to preserve readability, e.g. o.foo -> o._$foo$NNN_.
|
||||||
var debug_mangled = "_$" + name + "$" + debug_name_suffix + "_";
|
var debug_mangled = "_$" + name + "$" + debug_suffix + "_";
|
||||||
|
if (can_mangle(debug_mangled)) mangled = debug_mangled;
|
||||||
if (can_mangle(debug_mangled) && !(keep_quoted && debug_mangled in to_keep)) {
|
|
||||||
mangled = debug_mangled;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// either debug mode is off, or it is on and we could not use the mangled name
|
// either debug mode is off, or it is on and we could not use the mangled name
|
||||||
if (!mangled) {
|
if (!mangled) do {
|
||||||
// Note: `can_mangle()` does not check if the name collides with the `to_keep` set
|
mangled = base54(++cname);
|
||||||
// (filled with quoted properties when `keep_quoted` is set). Make sure we add this
|
} while (!can_mangle(mangled));
|
||||||
// check so we don't collide with a quoted name.
|
cache.set(name, mangled);
|
||||||
do {
|
|
||||||
mangled = base54(++cache.cname);
|
|
||||||
} while (!can_mangle(mangled) || keep_quoted && mangled in to_keep);
|
|
||||||
}
|
|
||||||
|
|
||||||
cache.props.set(name, mangled);
|
|
||||||
}
|
}
|
||||||
return mangled;
|
return mangled;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addStrings(node, keep) {
|
function mangleStrings(node) {
|
||||||
var out = {};
|
if (node instanceof AST_Sequence) {
|
||||||
try {
|
mangleStrings(node.expressions.tail_node());
|
||||||
(function walk(node){
|
} else if (node instanceof AST_String) {
|
||||||
node.walk(new TreeWalker(function(node){
|
node.value = mangle(node.value);
|
||||||
if (node instanceof AST_Sequence) {
|
} else if (node instanceof AST_Conditional) {
|
||||||
walk(node.expressions[node.expressions.length - 1]);
|
mangleStrings(node.consequent);
|
||||||
return true;
|
mangleStrings(node.alternative);
|
||||||
}
|
|
||||||
if (node instanceof AST_String) {
|
|
||||||
add(node.value, keep);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (node instanceof AST_Conditional) {
|
|
||||||
walk(node.consequent);
|
|
||||||
walk(node.alternative);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
throw out;
|
|
||||||
}));
|
|
||||||
})(node);
|
|
||||||
} catch(ex) {
|
|
||||||
if (ex !== out) throw ex;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function mangleStrings(node) {
|
|
||||||
return node.transform(new TreeTransformer(function(node){
|
|
||||||
if (node instanceof AST_Sequence) {
|
|
||||||
var last = node.expressions.length - 1;
|
|
||||||
node.expressions[last] = mangleStrings(node.expressions[last]);
|
|
||||||
}
|
|
||||||
else if (node instanceof AST_String) {
|
|
||||||
node.value = mangle(node.value);
|
|
||||||
}
|
|
||||||
else if (node instanceof AST_Conditional) {
|
|
||||||
node.consequent = mangleStrings(node.consequent);
|
|
||||||
node.alternative = mangleStrings(node.alternative);
|
|
||||||
}
|
|
||||||
return node;
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
758
lib/scope.js
758
lib/scope.js
@@ -1,7 +1,7 @@
|
|||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
|
||||||
A JavaScript tokenizer / parser / beautifier / compressor.
|
A JavaScript tokenizer / parser / beautifier / compressor.
|
||||||
https://github.com/mishoo/UglifyJS2
|
https://github.com/mishoo/UglifyJS
|
||||||
|
|
||||||
-------------------------------- (C) ---------------------------------
|
-------------------------------- (C) ---------------------------------
|
||||||
|
|
||||||
@@ -43,54 +43,64 @@
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
function SymbolDef(scope, index, orig) {
|
function SymbolDef(id, scope, orig, init) {
|
||||||
|
this.eliminated = 0;
|
||||||
|
this.global = false;
|
||||||
|
this.id = id;
|
||||||
|
this.init = init;
|
||||||
|
this.lambda = orig instanceof AST_SymbolLambda;
|
||||||
|
this.mangled_name = null;
|
||||||
this.name = orig.name;
|
this.name = orig.name;
|
||||||
this.orig = [ orig ];
|
this.orig = [ orig ];
|
||||||
this.scope = scope;
|
|
||||||
this.references = [];
|
this.references = [];
|
||||||
this.global = false;
|
this.replaced = 0;
|
||||||
this.mangled_name = null;
|
this.scope = scope;
|
||||||
this.undeclared = false;
|
this.undeclared = false;
|
||||||
this.index = index;
|
}
|
||||||
this.id = SymbolDef.next_id++;
|
|
||||||
};
|
|
||||||
|
|
||||||
SymbolDef.next_id = 1;
|
|
||||||
|
|
||||||
SymbolDef.prototype = {
|
SymbolDef.prototype = {
|
||||||
unmangleable: function(options) {
|
forEach: function(fn) {
|
||||||
if (!options) options = {};
|
this.orig.forEach(fn);
|
||||||
|
this.references.forEach(fn);
|
||||||
return (this.global && !options.toplevel)
|
|
||||||
|| this.undeclared
|
|
||||||
|| (!options.eval && (this.scope.uses_eval || this.scope.uses_with))
|
|
||||||
|| (options.keep_fnames
|
|
||||||
&& (this.orig[0] instanceof AST_SymbolLambda
|
|
||||||
|| this.orig[0] instanceof AST_SymbolDefun));
|
|
||||||
},
|
},
|
||||||
mangle: function(options) {
|
mangle: function(options) {
|
||||||
var cache = options.cache && options.cache.props;
|
var cache = options.cache && options.cache.props;
|
||||||
if (this.global && cache && cache.has(this.name)) {
|
if (this.global && cache && cache.has(this.name)) {
|
||||||
this.mangled_name = cache.get(this.name);
|
this.mangled_name = cache.get(this.name);
|
||||||
}
|
} else if (!this.mangled_name && !this.unmangleable(options)) {
|
||||||
else if (!this.mangled_name && !this.unmangleable(options)) {
|
var def = this.redefined();
|
||||||
var s = this.scope;
|
if (def) {
|
||||||
var sym = this.orig[0];
|
|
||||||
if (options.ie8 && sym instanceof AST_SymbolLambda)
|
|
||||||
s = s.parent_scope;
|
|
||||||
var def;
|
|
||||||
if (this.defun && (def = this.defun.variables.get(this.name))) {
|
|
||||||
this.mangled_name = def.mangled_name || def.name;
|
this.mangled_name = def.mangled_name || def.name;
|
||||||
} else
|
} else {
|
||||||
this.mangled_name = s.next_mangled(options, this);
|
this.mangled_name = next_mangled_name(this.scope, options, this);
|
||||||
|
}
|
||||||
if (this.global && cache) {
|
if (this.global && cache) {
|
||||||
cache.set(this.name, this.mangled_name);
|
cache.set(this.name, this.mangled_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
redefined: function() {
|
||||||
|
var scope = this.defun;
|
||||||
|
if (!scope) return;
|
||||||
|
var name = this.name;
|
||||||
|
var def = scope.variables.get(name)
|
||||||
|
|| scope instanceof AST_Toplevel && scope.globals.get(name)
|
||||||
|
|| this.orig[0] instanceof AST_SymbolConst && find_if(function(def) {
|
||||||
|
return def.name == name;
|
||||||
|
}, scope.enclosed);
|
||||||
|
if (def && def !== this) return def.redefined() || def;
|
||||||
|
},
|
||||||
|
unmangleable: function(options) {
|
||||||
|
return this.global && !options.toplevel
|
||||||
|
|| this.undeclared
|
||||||
|
|| !options.eval && this.scope.pinned()
|
||||||
|
|| options.keep_fnames
|
||||||
|
&& (this.orig[0] instanceof AST_SymbolLambda
|
||||||
|
|| this.orig[0] instanceof AST_SymbolDefun);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
||||||
options = defaults(options, {
|
options = defaults(options, {
|
||||||
cache: null,
|
cache: null,
|
||||||
ie8: false,
|
ie8: false,
|
||||||
@@ -98,45 +108,46 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
|
|
||||||
// pass 1: setup scope chaining and handle definitions
|
// pass 1: setup scope chaining and handle definitions
|
||||||
var self = this;
|
var self = this;
|
||||||
var scope = self.parent_scope = null;
|
|
||||||
var labels = new Dictionary();
|
|
||||||
var defun = null;
|
var defun = null;
|
||||||
var tw = new TreeWalker(function(node, descend){
|
var next_def_id = 0;
|
||||||
if (node instanceof AST_Catch) {
|
var scope = self.parent_scope = null;
|
||||||
var save_scope = scope;
|
var tw = new TreeWalker(function(node, descend) {
|
||||||
scope = new AST_Scope(node);
|
if (node instanceof AST_Defun) {
|
||||||
scope.init_scope_vars(save_scope);
|
node.name.walk(tw);
|
||||||
descend();
|
walk_scope(function() {
|
||||||
scope = save_scope;
|
node.argnames.forEach(function(argname) {
|
||||||
|
argname.walk(tw);
|
||||||
|
});
|
||||||
|
walk_body(node, tw);
|
||||||
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (node instanceof AST_Scope) {
|
if (node instanceof AST_SwitchBranch) {
|
||||||
node.init_scope_vars(scope);
|
node.init_vars(scope);
|
||||||
var save_scope = scope;
|
|
||||||
var save_defun = defun;
|
|
||||||
var save_labels = labels;
|
|
||||||
defun = scope = node;
|
|
||||||
labels = new Dictionary();
|
|
||||||
descend();
|
descend();
|
||||||
scope = save_scope;
|
return true;
|
||||||
defun = save_defun;
|
|
||||||
labels = save_labels;
|
|
||||||
return true; // don't descend again in TreeWalker
|
|
||||||
}
|
}
|
||||||
if (node instanceof AST_LabeledStatement) {
|
if (node instanceof AST_Try) {
|
||||||
var l = node.label;
|
walk_scope(function() {
|
||||||
if (labels.has(l.name)) {
|
walk_body(node, tw);
|
||||||
throw new Error(string_template("Label {name} defined twice", l));
|
});
|
||||||
}
|
if (node.bcatch) node.bcatch.walk(tw);
|
||||||
labels.set(l.name, l);
|
if (node.bfinally) node.bfinally.walk(tw);
|
||||||
descend();
|
return true;
|
||||||
labels.del(l.name);
|
|
||||||
return true; // no descend again
|
|
||||||
}
|
}
|
||||||
if (node instanceof AST_With) {
|
if (node instanceof AST_With) {
|
||||||
for (var s = scope; s; s = s.parent_scope)
|
var s = scope;
|
||||||
|
do {
|
||||||
|
s = s.resolve();
|
||||||
|
if (s.uses_with) break;
|
||||||
s.uses_with = true;
|
s.uses_with = true;
|
||||||
return;
|
} while (s = s.parent_scope);
|
||||||
|
walk_scope(descend);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (node instanceof AST_BlockScope) {
|
||||||
|
walk_scope(descend);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
if (node instanceof AST_Symbol) {
|
if (node instanceof AST_Symbol) {
|
||||||
node.scope = scope;
|
node.scope = scope;
|
||||||
@@ -145,100 +156,154 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
node.thedef = node;
|
node.thedef = node;
|
||||||
node.references = [];
|
node.references = [];
|
||||||
}
|
}
|
||||||
if (node instanceof AST_SymbolLambda) {
|
if (node instanceof AST_SymbolCatch) {
|
||||||
defun.def_function(node);
|
|
||||||
}
|
|
||||||
else if (node instanceof AST_SymbolDefun) {
|
|
||||||
// Careful here, the scope where this should be defined is
|
|
||||||
// the parent scope. The reason is that we enter a new
|
|
||||||
// scope when we encounter the AST_Defun node (which is
|
|
||||||
// instanceof AST_Scope) but we get to the symbol a bit
|
|
||||||
// later.
|
|
||||||
(node.scope = defun.parent_scope).def_function(node);
|
|
||||||
}
|
|
||||||
else if (node instanceof AST_SymbolVar) {
|
|
||||||
defun.def_variable(node);
|
|
||||||
if (defun !== scope) {
|
|
||||||
node.mark_enclosed(options);
|
|
||||||
var def = scope.find_variable(node);
|
|
||||||
if (node.thedef !== def) {
|
|
||||||
node.thedef = def;
|
|
||||||
node.reference(options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (node instanceof AST_SymbolCatch) {
|
|
||||||
scope.def_variable(node).defun = defun;
|
scope.def_variable(node).defun = defun;
|
||||||
|
} else if (node instanceof AST_SymbolConst) {
|
||||||
|
scope.def_variable(node).defun = defun;
|
||||||
|
} else if (node instanceof AST_SymbolDefun) {
|
||||||
|
defun.def_function(node, tw.parent());
|
||||||
|
entangle(defun, scope);
|
||||||
|
} else if (node instanceof AST_SymbolFunarg) {
|
||||||
|
defun.def_variable(node);
|
||||||
|
entangle(defun, scope);
|
||||||
|
} else if (node instanceof AST_SymbolLambda) {
|
||||||
|
var def = defun.def_function(node, node.name == "arguments" ? undefined : defun);
|
||||||
|
if (options.ie8) def.defun = defun.parent_scope.resolve();
|
||||||
|
} else if (node instanceof AST_SymbolVar) {
|
||||||
|
defun.def_variable(node, null);
|
||||||
|
entangle(defun, scope);
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_LabelRef) {
|
|
||||||
var sym = labels.get(node.name);
|
function walk_scope(descend) {
|
||||||
if (!sym) throw new Error(string_template("Undefined label {name} [{line},{col}]", {
|
node.init_vars(scope);
|
||||||
name: node.name,
|
var save_defun = defun;
|
||||||
line: node.start.line,
|
var save_scope = scope;
|
||||||
col: node.start.col
|
if (node instanceof AST_Scope) defun = node;
|
||||||
}));
|
scope = node;
|
||||||
node.thedef = sym;
|
descend();
|
||||||
|
scope = save_scope;
|
||||||
|
defun = save_defun;
|
||||||
|
}
|
||||||
|
|
||||||
|
function entangle(defun, scope) {
|
||||||
|
if (defun === scope) return;
|
||||||
|
node.mark_enclosed(options);
|
||||||
|
var def = scope.find_variable(node);
|
||||||
|
if (node.thedef === def) return;
|
||||||
|
node.thedef = def;
|
||||||
|
def.orig.push(node);
|
||||||
|
node.mark_enclosed(options);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
self.make_def = function(orig, init) {
|
||||||
|
return new SymbolDef(++next_def_id, this, orig, init);
|
||||||
|
};
|
||||||
self.walk(tw);
|
self.walk(tw);
|
||||||
|
|
||||||
// pass 2: find back references and eval
|
// pass 2: find back references and eval
|
||||||
self.globals = new Dictionary();
|
self.globals = new Dictionary();
|
||||||
var tw = new TreeWalker(function(node, descend){
|
var tw = new TreeWalker(function(node) {
|
||||||
if (node instanceof AST_LoopControl && node.label) {
|
if (node instanceof AST_LoopControl) {
|
||||||
node.label.thedef.references.push(node);
|
if (node.label) node.label.thedef.references.push(node);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (node instanceof AST_SymbolRef) {
|
if (node instanceof AST_SymbolRef) {
|
||||||
var name = node.name;
|
var name = node.name;
|
||||||
if (name == "eval" && tw.parent() instanceof AST_Call) {
|
|
||||||
for (var s = node.scope; s && !s.uses_eval; s = s.parent_scope) {
|
|
||||||
s.uses_eval = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var sym = node.scope.find_variable(name);
|
var sym = node.scope.find_variable(name);
|
||||||
if (node.scope instanceof AST_Lambda && name == "arguments") {
|
|
||||||
node.scope.uses_arguments = true;
|
|
||||||
}
|
|
||||||
if (!sym) {
|
if (!sym) {
|
||||||
sym = self.def_global(node);
|
sym = self.def_global(node);
|
||||||
|
} else if (name == "arguments" && sym.scope instanceof AST_Lambda) {
|
||||||
|
sym.scope.uses_arguments = true;
|
||||||
|
}
|
||||||
|
if (name == "eval") {
|
||||||
|
var parent = tw.parent();
|
||||||
|
if (parent.TYPE == "Call" && parent.expression === node) {
|
||||||
|
var s = node.scope;
|
||||||
|
do {
|
||||||
|
s = s.resolve();
|
||||||
|
if (s.uses_eval) break;
|
||||||
|
s.uses_eval = true;
|
||||||
|
} while (s = s.parent_scope);
|
||||||
|
} else if (sym.undeclared) {
|
||||||
|
self.uses_eval = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
node.thedef = sym;
|
node.thedef = sym;
|
||||||
node.reference(options);
|
node.reference(options);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
// ensure mangling works if `catch` reuses a scope variable
|
||||||
|
if (node instanceof AST_SymbolCatch) {
|
||||||
|
var def = node.definition().redefined();
|
||||||
|
if (def) for (var s = node.scope; s; s = s.parent_scope) {
|
||||||
|
push_uniq(s.enclosed, def);
|
||||||
|
if (s === def.scope) break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// ensure compression works if `const` reuses a scope variable
|
||||||
|
if (node instanceof AST_SymbolConst) {
|
||||||
|
var redef = node.definition().redefined();
|
||||||
|
if (redef) redef.const_redefs = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
self.walk(tw);
|
self.walk(tw);
|
||||||
|
|
||||||
// pass 3: fix up any scoping issue with IE8
|
// pass 3: fix up any scoping issue with IE8
|
||||||
if (options.ie8) {
|
if (options.ie8) self.walk(new TreeWalker(function(node) {
|
||||||
self.walk(new TreeWalker(function(node, descend) {
|
if (node instanceof AST_SymbolCatch) {
|
||||||
if (node instanceof AST_SymbolCatch) {
|
var scope = node.thedef.defun;
|
||||||
var name = node.name;
|
if (scope.name instanceof AST_SymbolLambda && scope.name.name == node.name) {
|
||||||
var refs = node.thedef.references;
|
scope = scope.parent_scope.resolve();
|
||||||
var scope = node.thedef.defun;
|
|
||||||
var def = scope.find_variable(name) || self.globals.get(name) || scope.def_variable(node);
|
|
||||||
refs.forEach(function(ref) {
|
|
||||||
ref.thedef = def;
|
|
||||||
ref.reference(options);
|
|
||||||
});
|
|
||||||
node.thedef = def;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}));
|
redefine(node, scope);
|
||||||
}
|
return true;
|
||||||
|
}
|
||||||
|
if (node instanceof AST_SymbolLambda) {
|
||||||
|
var def = node.thedef;
|
||||||
|
redefine(node, node.scope.parent_scope.resolve());
|
||||||
|
if (typeof node.thedef.init !== "undefined") {
|
||||||
|
node.thedef.init = false;
|
||||||
|
} else if (def.init) {
|
||||||
|
node.thedef.init = def.init;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
if (options.cache) {
|
function redefine(node, scope) {
|
||||||
this.cname = options.cache.cname;
|
var name = node.name;
|
||||||
|
var old_def = node.thedef;
|
||||||
|
var new_def = scope.find_variable(name);
|
||||||
|
if (new_def) {
|
||||||
|
var redef = new_def.redefined();
|
||||||
|
if (redef) new_def = redef;
|
||||||
|
} else {
|
||||||
|
new_def = self.globals.get(name);
|
||||||
|
}
|
||||||
|
if (new_def) {
|
||||||
|
new_def.orig.push(node);
|
||||||
|
} else {
|
||||||
|
new_def = scope.def_variable(node);
|
||||||
|
}
|
||||||
|
old_def.defun = new_def.scope;
|
||||||
|
old_def.forEach(function(node) {
|
||||||
|
node.redef = true;
|
||||||
|
node.thedef = new_def;
|
||||||
|
node.reference(options);
|
||||||
|
});
|
||||||
|
if (old_def.lambda) new_def.lambda = true;
|
||||||
|
if (new_def.undeclared) self.variables.set(name, new_def);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Toplevel.DEFMETHOD("def_global", function(node){
|
AST_Toplevel.DEFMETHOD("def_global", function(node) {
|
||||||
var globals = this.globals, name = node.name;
|
var globals = this.globals, name = node.name;
|
||||||
if (globals.has(name)) {
|
if (globals.has(name)) {
|
||||||
return globals.get(name);
|
return globals.get(name);
|
||||||
} else {
|
} else {
|
||||||
var g = new SymbolDef(this, globals.size(), node);
|
var g = this.make_def(node);
|
||||||
g.undeclared = true;
|
g.undeclared = true;
|
||||||
g.global = true;
|
g.global = true;
|
||||||
globals.set(name, g);
|
globals.set(name, g);
|
||||||
@@ -246,30 +311,40 @@ AST_Toplevel.DEFMETHOD("def_global", function(node){
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Scope.DEFMETHOD("init_scope_vars", function(parent_scope){
|
function init_block_vars(scope, parent) {
|
||||||
this.variables = new Dictionary(); // map name to AST_SymbolVar (variables defined in this scope; includes functions)
|
scope.enclosed = []; // variables from this or outer scope(s) that are referenced from this or inner scopes
|
||||||
this.functions = new Dictionary(); // map name to AST_SymbolDefun (functions defined in this scope)
|
scope.parent_scope = parent; // the parent scope (null if this is the top level)
|
||||||
this.uses_with = false; // will be set to true if this or some nested scope uses the `with` statement
|
scope.functions = new Dictionary(); // map name to AST_SymbolDefun (functions defined in this scope)
|
||||||
this.uses_eval = false; // will be set to true if this or nested scope uses the global `eval`
|
scope.variables = new Dictionary(); // map name to AST_SymbolVar (variables defined in this scope; includes functions)
|
||||||
this.parent_scope = parent_scope; // the parent scope
|
if (parent) scope.make_def = parent.make_def; // top-level tracking of SymbolDef instances
|
||||||
this.enclosed = []; // a list of variables from this or outer scope(s) that are referenced from this or inner scopes
|
}
|
||||||
this.cname = -1; // the current index for mangling functions/variables
|
|
||||||
});
|
|
||||||
|
|
||||||
AST_Lambda.DEFMETHOD("init_scope_vars", function(){
|
function init_scope_vars(scope, parent) {
|
||||||
AST_Scope.prototype.init_scope_vars.apply(this, arguments);
|
init_block_vars(scope, parent);
|
||||||
|
scope.uses_eval = false; // will be set to true if this or nested scope uses the global `eval`
|
||||||
|
scope.uses_with = false; // will be set to true if this or some nested scope uses the `with` statement
|
||||||
|
}
|
||||||
|
|
||||||
|
AST_BlockScope.DEFMETHOD("init_vars", function(parent_scope) {
|
||||||
|
init_block_vars(this, parent_scope);
|
||||||
|
});
|
||||||
|
AST_Scope.DEFMETHOD("init_vars", function(parent_scope) {
|
||||||
|
init_scope_vars(this, parent_scope);
|
||||||
|
});
|
||||||
|
AST_Lambda.DEFMETHOD("init_vars", function(parent_scope) {
|
||||||
|
init_scope_vars(this, parent_scope);
|
||||||
this.uses_arguments = false;
|
this.uses_arguments = false;
|
||||||
this.def_variable(new AST_SymbolFunarg({
|
this.def_variable(new AST_SymbolFunarg({
|
||||||
name: "arguments",
|
name: "arguments",
|
||||||
start: this.start,
|
start: this.start,
|
||||||
end: this.end
|
end: this.end,
|
||||||
}));
|
}));
|
||||||
|
return this;
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Symbol.DEFMETHOD("mark_enclosed", function(options) {
|
AST_Symbol.DEFMETHOD("mark_enclosed", function(options) {
|
||||||
var def = this.definition();
|
var def = this.definition();
|
||||||
var s = this.scope;
|
for (var s = this.scope; s; s = s.parent_scope) {
|
||||||
while (s) {
|
|
||||||
push_uniq(s.enclosed, def);
|
push_uniq(s.enclosed, def);
|
||||||
if (options.keep_fnames) {
|
if (options.keep_fnames) {
|
||||||
s.functions.each(function(d) {
|
s.functions.each(function(d) {
|
||||||
@@ -277,7 +352,6 @@ AST_Symbol.DEFMETHOD("mark_enclosed", function(options) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (s === def.scope) break;
|
if (s === def.scope) break;
|
||||||
s = s.parent_scope;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -286,267 +360,321 @@ AST_Symbol.DEFMETHOD("reference", function(options) {
|
|||||||
this.mark_enclosed(options);
|
this.mark_enclosed(options);
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Scope.DEFMETHOD("find_variable", function(name){
|
AST_BlockScope.DEFMETHOD("find_variable", function(name) {
|
||||||
if (name instanceof AST_Symbol) name = name.name;
|
if (name instanceof AST_Symbol) name = name.name;
|
||||||
return this.variables.get(name)
|
return this.variables.get(name)
|
||||||
|| (this.parent_scope && this.parent_scope.find_variable(name));
|
|| (this.parent_scope && this.parent_scope.find_variable(name));
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Scope.DEFMETHOD("def_function", function(symbol){
|
AST_BlockScope.DEFMETHOD("def_function", function(symbol, init) {
|
||||||
this.functions.set(symbol.name, this.def_variable(symbol));
|
var def = this.def_variable(symbol, init);
|
||||||
|
if (!def.init || def.init instanceof AST_Defun) def.init = init;
|
||||||
|
this.functions.set(symbol.name, def);
|
||||||
|
return def;
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Scope.DEFMETHOD("def_variable", function(symbol){
|
AST_BlockScope.DEFMETHOD("def_variable", function(symbol, init) {
|
||||||
var def;
|
var def = this.variables.get(symbol.name);
|
||||||
if (!this.variables.has(symbol.name)) {
|
if (def) {
|
||||||
def = new SymbolDef(this, this.variables.size(), symbol);
|
def.orig.push(symbol);
|
||||||
|
if (def.init instanceof AST_Function) def.init = init;
|
||||||
|
} else {
|
||||||
|
def = this.make_def(symbol, init);
|
||||||
this.variables.set(symbol.name, def);
|
this.variables.set(symbol.name, def);
|
||||||
def.global = !this.parent_scope;
|
def.global = !this.parent_scope;
|
||||||
} else {
|
|
||||||
def = this.variables.get(symbol.name);
|
|
||||||
def.orig.push(symbol);
|
|
||||||
}
|
}
|
||||||
return symbol.thedef = def;
|
return symbol.thedef = def;
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Scope.DEFMETHOD("next_mangled", function(options){
|
function names_in_use(scope, options) {
|
||||||
var ext = this.enclosed;
|
var names = scope.names_in_use;
|
||||||
out: while (true) {
|
if (!names) {
|
||||||
var m = base54(++this.cname);
|
scope.cname = -1;
|
||||||
if (!is_identifier(m)) continue; // skip over "do"
|
scope.cname_holes = [];
|
||||||
|
scope.names_in_use = names = Object.create(null);
|
||||||
// https://github.com/mishoo/UglifyJS2/issues/242 -- do not
|
var cache = options.cache && options.cache.props;
|
||||||
// shadow a name reserved from mangling.
|
scope.enclosed.forEach(function(def) {
|
||||||
if (options.reserved.indexOf(m) >= 0) continue;
|
if (def.unmangleable(options)) names[def.name] = true;
|
||||||
|
if (def.global && cache && cache.has(def.name)) {
|
||||||
// we must ensure that the mangled name does not shadow a name
|
names[cache.get(def.name)] = true;
|
||||||
// from some parent scope that is referenced in this or in
|
}
|
||||||
// inner scopes.
|
});
|
||||||
for (var i = ext.length; --i >= 0;) {
|
|
||||||
var sym = ext[i];
|
|
||||||
var name = sym.mangled_name || (sym.unmangleable(options) && sym.name);
|
|
||||||
if (m == name) continue out;
|
|
||||||
}
|
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
});
|
return names;
|
||||||
|
}
|
||||||
AST_Function.DEFMETHOD("next_mangled", function(options, def){
|
|
||||||
// #179, #326
|
|
||||||
// in Safari strict mode, something like (function x(x){...}) is a syntax error;
|
|
||||||
// a function expression's argument cannot shadow the function expression's name
|
|
||||||
|
|
||||||
var tricky_def = def.orig[0] instanceof AST_SymbolFunarg && this.name && this.name.definition();
|
|
||||||
|
|
||||||
// the function's mangled_name is null when keep_fnames is true
|
|
||||||
var tricky_name = tricky_def ? tricky_def.mangled_name || tricky_def.name : null;
|
|
||||||
|
|
||||||
|
function next_mangled_name(scope, options, def) {
|
||||||
|
var in_use = names_in_use(scope, options);
|
||||||
|
var holes = scope.cname_holes;
|
||||||
|
var names = Object.create(null);
|
||||||
|
var scopes = [ scope ];
|
||||||
|
def.forEach(function(sym) {
|
||||||
|
var scope = sym.scope;
|
||||||
|
do {
|
||||||
|
if (scopes.indexOf(scope) < 0) {
|
||||||
|
for (var name in names_in_use(scope, options)) {
|
||||||
|
names[name] = true;
|
||||||
|
}
|
||||||
|
scopes.push(scope);
|
||||||
|
} else break;
|
||||||
|
} while (scope = scope.parent_scope);
|
||||||
|
});
|
||||||
|
var name;
|
||||||
|
for (var i = 0; i < holes.length; i++) {
|
||||||
|
name = base54(holes[i]);
|
||||||
|
if (names[name]) continue;
|
||||||
|
holes.splice(i, 1);
|
||||||
|
in_use[name] = true;
|
||||||
|
return name;
|
||||||
|
}
|
||||||
while (true) {
|
while (true) {
|
||||||
var name = AST_Lambda.prototype.next_mangled.call(this, options, def);
|
name = base54(++scope.cname);
|
||||||
if (!tricky_name || tricky_name != name)
|
if (in_use[name] || RESERVED_WORDS[name] || options.reserved.has[name]) continue;
|
||||||
return name;
|
if (!names[name]) break;
|
||||||
|
holes.push(scope.cname);
|
||||||
}
|
}
|
||||||
});
|
in_use[name] = true;
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
AST_Symbol.DEFMETHOD("unmangleable", function(options){
|
AST_Symbol.DEFMETHOD("unmangleable", function(options) {
|
||||||
return this.definition().unmangleable(options);
|
var def = this.definition();
|
||||||
|
return !def || def.unmangleable(options);
|
||||||
});
|
});
|
||||||
|
|
||||||
// labels are always mangleable
|
// labels are always mangleable
|
||||||
AST_Label.DEFMETHOD("unmangleable", return_false);
|
AST_Label.DEFMETHOD("unmangleable", return_false);
|
||||||
|
|
||||||
AST_Symbol.DEFMETHOD("unreferenced", function(){
|
AST_Symbol.DEFMETHOD("definition", function() {
|
||||||
return this.definition().references.length == 0
|
|
||||||
&& !(this.scope.uses_eval || this.scope.uses_with);
|
|
||||||
});
|
|
||||||
|
|
||||||
AST_Symbol.DEFMETHOD("undeclared", function(){
|
|
||||||
return this.definition().undeclared;
|
|
||||||
});
|
|
||||||
|
|
||||||
AST_LabelRef.DEFMETHOD("undeclared", return_false);
|
|
||||||
|
|
||||||
AST_Label.DEFMETHOD("undeclared", return_false);
|
|
||||||
|
|
||||||
AST_Symbol.DEFMETHOD("definition", function(){
|
|
||||||
return this.thedef;
|
return this.thedef;
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Symbol.DEFMETHOD("global", function(){
|
function _default_mangler_options(options) {
|
||||||
return this.definition().global;
|
options = defaults(options, {
|
||||||
});
|
|
||||||
|
|
||||||
AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options){
|
|
||||||
return defaults(options, {
|
|
||||||
eval : false,
|
eval : false,
|
||||||
ie8 : false,
|
ie8 : false,
|
||||||
keep_fnames : false,
|
keep_fnames : false,
|
||||||
reserved : [],
|
reserved : [],
|
||||||
toplevel : false,
|
toplevel : false,
|
||||||
});
|
});
|
||||||
});
|
if (!Array.isArray(options.reserved)) options.reserved = [];
|
||||||
|
|
||||||
AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
|
||||||
options = this._default_mangler_options(options);
|
|
||||||
|
|
||||||
// Never mangle arguments
|
// Never mangle arguments
|
||||||
options.reserved.push('arguments');
|
push_uniq(options.reserved, "arguments");
|
||||||
|
options.reserved.has = makePredicate(options.reserved);
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
|
||||||
|
options = _default_mangler_options(options);
|
||||||
|
|
||||||
// We only need to mangle declaration nodes. Special logic wired
|
// We only need to mangle declaration nodes. Special logic wired
|
||||||
// into the code generator will display the mangled name if it's
|
// into the code generator will display the mangled name if it's
|
||||||
// present (and for AST_SymbolRef-s it'll use the mangled name of
|
// present (and for AST_SymbolRef-s it'll use the mangled name of
|
||||||
// the AST_SymbolDeclaration that it points to).
|
// the AST_SymbolDeclaration that it points to).
|
||||||
var lname = -1;
|
var lname = -1;
|
||||||
var to_mangle = [];
|
|
||||||
|
|
||||||
if (options.cache) {
|
if (options.cache && options.cache.props) {
|
||||||
this.globals.each(function(symbol){
|
var mangled_names = names_in_use(this, options);
|
||||||
if (options.reserved.indexOf(symbol.name) < 0) {
|
options.cache.props.each(function(mangled_name) {
|
||||||
to_mangle.push(symbol);
|
mangled_names[mangled_name] = true;
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var tw = new TreeWalker(function(node, descend){
|
var redefined = [];
|
||||||
|
var tw = new TreeWalker(function(node, descend) {
|
||||||
if (node instanceof AST_LabeledStatement) {
|
if (node instanceof AST_LabeledStatement) {
|
||||||
// lname is incremented when we get to the AST_Label
|
// lname is incremented when we get to the AST_Label
|
||||||
var save_nesting = lname;
|
var save_nesting = lname;
|
||||||
descend();
|
descend();
|
||||||
lname = save_nesting;
|
lname = save_nesting;
|
||||||
return true; // don't descend again in TreeWalker
|
return true;
|
||||||
}
|
}
|
||||||
if (node instanceof AST_Scope) {
|
if (node instanceof AST_BlockScope) {
|
||||||
var p = tw.parent(), a = [];
|
var to_mangle = [];
|
||||||
node.variables.each(function(symbol){
|
node.variables.each(function(def) {
|
||||||
if (options.reserved.indexOf(symbol.name) < 0) {
|
if (!defer_redef(def)) to_mangle.push(def);
|
||||||
a.push(symbol);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
to_mangle.push.apply(to_mangle, a);
|
descend();
|
||||||
return;
|
if (options.cache && node instanceof AST_Toplevel) {
|
||||||
|
node.globals.each(mangle);
|
||||||
|
}
|
||||||
|
if (node instanceof AST_Defun && tw.has_directive("use asm")) {
|
||||||
|
var sym = new AST_SymbolRef(node.name);
|
||||||
|
sym.scope = node;
|
||||||
|
sym.reference(options);
|
||||||
|
}
|
||||||
|
to_mangle.forEach(mangle);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
if (node instanceof AST_Label) {
|
if (node instanceof AST_Label) {
|
||||||
var name;
|
var name;
|
||||||
do name = base54(++lname); while (!is_identifier(name));
|
do {
|
||||||
|
name = base54(++lname);
|
||||||
|
} while (RESERVED_WORDS[name]);
|
||||||
node.mangled_name = name;
|
node.mangled_name = name;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!options.ie8 && node instanceof AST_SymbolCatch) {
|
|
||||||
to_mangle.push(node.definition());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
this.walk(tw);
|
this.walk(tw);
|
||||||
to_mangle.forEach(function(def){ def.mangle(options) });
|
redefined.forEach(mangle);
|
||||||
|
|
||||||
if (options.cache) {
|
function mangle(def) {
|
||||||
options.cache.cname = this.cname;
|
if (options.reserved.has[def.name]) return;
|
||||||
|
def.mangle(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
function defer_redef(def, node) {
|
||||||
|
var redef = def.redefined();
|
||||||
|
if (!redef) return false;
|
||||||
|
redefined.push(def);
|
||||||
|
def.references.forEach(reference);
|
||||||
|
var node = def.orig[0];
|
||||||
|
if (node instanceof AST_SymbolCatch || node instanceof AST_SymbolConst) reference(node);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
function reference(sym) {
|
||||||
|
sym.thedef = redef;
|
||||||
|
sym.reference(options);
|
||||||
|
sym.thedef = def;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options){
|
AST_Toplevel.DEFMETHOD("find_colliding_names", function(options) {
|
||||||
options = this._default_mangler_options(options);
|
var cache = options.cache && options.cache.props;
|
||||||
var tw = new TreeWalker(function(node){
|
var avoid = Object.create(RESERVED_WORDS);
|
||||||
if (node instanceof AST_Constant)
|
options.reserved.forEach(to_avoid);
|
||||||
base54.consider(node.print_to_string());
|
this.globals.each(add_def);
|
||||||
else if (node instanceof AST_Return)
|
this.walk(new TreeWalker(function(node) {
|
||||||
base54.consider("return");
|
if (node instanceof AST_BlockScope) node.variables.each(add_def);
|
||||||
else if (node instanceof AST_Throw)
|
}));
|
||||||
base54.consider("throw");
|
return avoid;
|
||||||
else if (node instanceof AST_Continue)
|
|
||||||
base54.consider("continue");
|
function to_avoid(name) {
|
||||||
else if (node instanceof AST_Break)
|
avoid[name] = true;
|
||||||
base54.consider("break");
|
}
|
||||||
else if (node instanceof AST_Debugger)
|
|
||||||
base54.consider("debugger");
|
function add_def(def) {
|
||||||
else if (node instanceof AST_Directive)
|
var name = def.name;
|
||||||
base54.consider(node.value);
|
if (def.global && cache && cache.has(name)) name = cache.get(name);
|
||||||
else if (node instanceof AST_While)
|
else if (!def.unmangleable(options)) return;
|
||||||
base54.consider("while");
|
to_avoid(name);
|
||||||
else if (node instanceof AST_Do)
|
}
|
||||||
base54.consider("do while");
|
});
|
||||||
else if (node instanceof AST_If) {
|
|
||||||
base54.consider("if");
|
AST_Toplevel.DEFMETHOD("expand_names", function(options) {
|
||||||
if (node.alternative) base54.consider("else");
|
base54.reset();
|
||||||
}
|
|
||||||
else if (node instanceof AST_Var)
|
|
||||||
base54.consider("var");
|
|
||||||
else if (node instanceof AST_Lambda)
|
|
||||||
base54.consider("function");
|
|
||||||
else if (node instanceof AST_For)
|
|
||||||
base54.consider("for");
|
|
||||||
else if (node instanceof AST_ForIn)
|
|
||||||
base54.consider("for in");
|
|
||||||
else if (node instanceof AST_Switch)
|
|
||||||
base54.consider("switch");
|
|
||||||
else if (node instanceof AST_Case)
|
|
||||||
base54.consider("case");
|
|
||||||
else if (node instanceof AST_Default)
|
|
||||||
base54.consider("default");
|
|
||||||
else if (node instanceof AST_With)
|
|
||||||
base54.consider("with");
|
|
||||||
else if (node instanceof AST_ObjectSetter)
|
|
||||||
base54.consider("set" + node.key);
|
|
||||||
else if (node instanceof AST_ObjectGetter)
|
|
||||||
base54.consider("get" + node.key);
|
|
||||||
else if (node instanceof AST_ObjectKeyVal)
|
|
||||||
base54.consider(node.key);
|
|
||||||
else if (node instanceof AST_New)
|
|
||||||
base54.consider("new");
|
|
||||||
else if (node instanceof AST_This)
|
|
||||||
base54.consider("this");
|
|
||||||
else if (node instanceof AST_Try)
|
|
||||||
base54.consider("try");
|
|
||||||
else if (node instanceof AST_Catch)
|
|
||||||
base54.consider("catch");
|
|
||||||
else if (node instanceof AST_Finally)
|
|
||||||
base54.consider("finally");
|
|
||||||
else if (node instanceof AST_Symbol && node.unmangleable(options))
|
|
||||||
base54.consider(node.name);
|
|
||||||
else if (node instanceof AST_Unary || node instanceof AST_Binary)
|
|
||||||
base54.consider(node.operator);
|
|
||||||
else if (node instanceof AST_Dot)
|
|
||||||
base54.consider(node.property);
|
|
||||||
});
|
|
||||||
this.walk(tw);
|
|
||||||
base54.sort();
|
base54.sort();
|
||||||
|
options = _default_mangler_options(options);
|
||||||
|
var avoid = this.find_colliding_names(options);
|
||||||
|
var cname = 0;
|
||||||
|
this.globals.each(rename);
|
||||||
|
this.walk(new TreeWalker(function(node) {
|
||||||
|
if (node instanceof AST_BlockScope) node.variables.each(rename);
|
||||||
|
}));
|
||||||
|
|
||||||
|
function next_name() {
|
||||||
|
var name;
|
||||||
|
do {
|
||||||
|
name = base54(cname++);
|
||||||
|
} while (avoid[name]);
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
function rename(def) {
|
||||||
|
if (def.global && options.cache) return;
|
||||||
|
if (def.unmangleable(options)) return;
|
||||||
|
if (options.reserved.has[def.name]) return;
|
||||||
|
var redef = def.redefined();
|
||||||
|
var name = redef ? redef.rename || redef.name : next_name();
|
||||||
|
def.rename = name;
|
||||||
|
def.forEach(function(sym) {
|
||||||
|
if (sym.definition() === def) sym.name = name;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
AST_Node.DEFMETHOD("tail_node", return_this);
|
||||||
|
AST_Sequence.DEFMETHOD("tail_node", function() {
|
||||||
|
return this.expressions[this.expressions.length - 1];
|
||||||
|
});
|
||||||
|
|
||||||
|
AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options) {
|
||||||
|
options = _default_mangler_options(options);
|
||||||
|
base54.reset();
|
||||||
|
var fn = AST_Symbol.prototype.add_source_map;
|
||||||
|
try {
|
||||||
|
AST_Symbol.prototype.add_source_map = function() {
|
||||||
|
if (!this.unmangleable(options)) base54.consider(this.name, -1);
|
||||||
|
};
|
||||||
|
if (options.properties) {
|
||||||
|
AST_Dot.prototype.add_source_map = function() {
|
||||||
|
base54.consider(this.property, -1);
|
||||||
|
};
|
||||||
|
AST_Sub.prototype.add_source_map = function() {
|
||||||
|
skip_string(this.property);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
base54.consider(this.print_to_string(), 1);
|
||||||
|
} finally {
|
||||||
|
AST_Symbol.prototype.add_source_map = fn;
|
||||||
|
delete AST_Dot.prototype.add_source_map;
|
||||||
|
delete AST_Sub.prototype.add_source_map;
|
||||||
|
}
|
||||||
|
base54.sort();
|
||||||
|
|
||||||
|
function skip_string(node) {
|
||||||
|
if (node instanceof AST_String) {
|
||||||
|
base54.consider(node.value, -1);
|
||||||
|
} else if (node instanceof AST_Conditional) {
|
||||||
|
skip_string(node.consequent);
|
||||||
|
skip_string(node.alternative);
|
||||||
|
} else if (node instanceof AST_Sequence) {
|
||||||
|
skip_string(node.tail_node());
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var base54 = (function() {
|
var base54 = (function() {
|
||||||
var string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_0123456789";
|
var freq = Object.create(null);
|
||||||
|
function init(chars) {
|
||||||
|
var array = [];
|
||||||
|
for (var i = 0; i < chars.length; i++) {
|
||||||
|
var ch = chars[i];
|
||||||
|
array.push(ch);
|
||||||
|
freq[ch] = -1e-2 * i;
|
||||||
|
}
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
var digits = init("0123456789");
|
||||||
|
var leading = init("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_");
|
||||||
var chars, frequency;
|
var chars, frequency;
|
||||||
function reset() {
|
function reset() {
|
||||||
frequency = Object.create(null);
|
frequency = Object.create(freq);
|
||||||
chars = string.split("").map(function(ch){ return ch.charCodeAt(0) });
|
|
||||||
chars.forEach(function(ch){ frequency[ch] = 0 });
|
|
||||||
}
|
}
|
||||||
base54.consider = function(str){
|
base54.consider = function(str, delta) {
|
||||||
for (var i = str.length; --i >= 0;) {
|
for (var i = str.length; --i >= 0;) {
|
||||||
var code = str.charCodeAt(i);
|
frequency[str[i]] += delta;
|
||||||
if (code in frequency) ++frequency[code];
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
function compare(a, b) {
|
||||||
|
return frequency[b] - frequency[a];
|
||||||
|
}
|
||||||
base54.sort = function() {
|
base54.sort = function() {
|
||||||
chars = mergeSort(chars, function(a, b){
|
chars = leading.sort(compare).concat(digits.sort(compare));
|
||||||
if (is_digit(a) && !is_digit(b)) return 1;
|
|
||||||
if (is_digit(b) && !is_digit(a)) return -1;
|
|
||||||
return frequency[b] - frequency[a];
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
base54.reset = reset;
|
base54.reset = reset;
|
||||||
reset();
|
reset();
|
||||||
base54.get = function(){ return chars };
|
|
||||||
base54.freq = function(){ return frequency };
|
|
||||||
function base54(num) {
|
function base54(num) {
|
||||||
var ret = "", base = 54;
|
var ret = "", base = 54;
|
||||||
num++;
|
num++;
|
||||||
do {
|
do {
|
||||||
num--;
|
num--;
|
||||||
ret += String.fromCharCode(chars[num % base]);
|
ret += chars[num % base];
|
||||||
num = Math.floor(num / base);
|
num = Math.floor(num / base);
|
||||||
base = 64;
|
base = 64;
|
||||||
} while (num > 0);
|
} while (num > 0);
|
||||||
return ret;
|
return ret;
|
||||||
};
|
}
|
||||||
return base54;
|
return base54;
|
||||||
})();
|
})();
|
||||||
|
|||||||
190
lib/sourcemap.js
190
lib/sourcemap.js
@@ -1,7 +1,7 @@
|
|||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
|
||||||
A JavaScript tokenizer / parser / beautifier / compressor.
|
A JavaScript tokenizer / parser / beautifier / compressor.
|
||||||
https://github.com/mishoo/UglifyJS2
|
https://github.com/mishoo/UglifyJS
|
||||||
|
|
||||||
-------------------------------- (C) ---------------------------------
|
-------------------------------- (C) ---------------------------------
|
||||||
|
|
||||||
@@ -43,55 +43,149 @@
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
// a small wrapper around fitzgen's source-map library
|
var vlq_char = characters("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
|
||||||
function SourceMap(options) {
|
var vlq_bits = vlq_char.reduce(function(map, ch, bits) {
|
||||||
options = defaults(options, {
|
map[ch] = bits;
|
||||||
file : null,
|
return map;
|
||||||
root : null,
|
}, Object.create(null));
|
||||||
orig : null,
|
|
||||||
|
|
||||||
orig_line_diff : 0,
|
function vlq_decode(indices, str) {
|
||||||
dest_line_diff : 0,
|
var value = 0;
|
||||||
});
|
var shift = 0;
|
||||||
var generator = new MOZ_SourceMap.SourceMapGenerator({
|
for (var i = 0, j = 0; i < str.length; i++) {
|
||||||
file : options.file,
|
var bits = vlq_bits[str[i]];
|
||||||
sourceRoot : options.root
|
value += (bits & 31) << shift;
|
||||||
});
|
if (bits & 32) {
|
||||||
var orig_map = options.orig && new MOZ_SourceMap.SourceMapConsumer(options.orig);
|
shift += 5;
|
||||||
|
} else {
|
||||||
if (orig_map && Array.isArray(options.orig.sources)) {
|
indices[j++] += value & 1 ? 0x80000000 | -(value >> 1) : value >> 1;
|
||||||
orig_map._sources.toArray().forEach(function(source) {
|
value = shift = 0;
|
||||||
var sourceContent = orig_map.sourceContentFor(source, true);
|
}
|
||||||
if (sourceContent) {
|
|
||||||
generator.setSourceContent(source, sourceContent);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
function vlq_encode(num) {
|
||||||
|
var result = "";
|
||||||
|
num = Math.abs(num) << 1 | num >>> 31;
|
||||||
|
do {
|
||||||
|
var bits = num & 31;
|
||||||
|
if (num >>>= 5) bits |= 32;
|
||||||
|
result += vlq_char[bits];
|
||||||
|
} while (num);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function create_array_map() {
|
||||||
|
var map = Object.create(null);
|
||||||
|
var array = [];
|
||||||
|
array.index = function(name) {
|
||||||
|
if (!HOP(map, name)) {
|
||||||
|
map[name] = array.length;
|
||||||
|
array.push(name);
|
||||||
|
}
|
||||||
|
return map[name];
|
||||||
|
};
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
function SourceMap(options) {
|
||||||
|
var sources = create_array_map();
|
||||||
|
var sources_content = options.includeSources && Object.create(null);
|
||||||
|
var names = create_array_map();
|
||||||
|
var mappings = "";
|
||||||
|
if (options.orig) Object.keys(options.orig).forEach(function(name) {
|
||||||
|
var map = options.orig[name];
|
||||||
|
var indices = [ 0, 0, 1, 0, 0 ];
|
||||||
|
options.orig[name] = {
|
||||||
|
names: map.names,
|
||||||
|
mappings: map.mappings.split(/;/).map(function(line) {
|
||||||
|
indices[0] = 0;
|
||||||
|
return line.split(/,/).map(function(segment) {
|
||||||
|
return indices.slice(0, vlq_decode(indices, segment));
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
sources: map.sources,
|
||||||
|
};
|
||||||
|
if (!sources_content || !map.sourcesContent) return;
|
||||||
|
for (var i = 0; i < map.sources.length; i++) {
|
||||||
|
var content = map.sourcesContent[i];
|
||||||
|
if (content) sources_content[map.sources[i]] = content;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var prev_source;
|
||||||
|
var generated_line = 1;
|
||||||
|
var generated_column = 0;
|
||||||
|
var source_index = 0;
|
||||||
|
var original_line = 1;
|
||||||
|
var original_column = 0;
|
||||||
|
var name_index = 0;
|
||||||
|
return {
|
||||||
|
add: options.orig ? function(source, gen_line, gen_col, orig_line, orig_col, name) {
|
||||||
|
var map = options.orig[source];
|
||||||
|
if (map) {
|
||||||
|
var segments = map.mappings[orig_line - 1];
|
||||||
|
if (!segments) return;
|
||||||
|
var indices;
|
||||||
|
for (var i = 0; i < segments.length; i++) {
|
||||||
|
var col = segments[i][0];
|
||||||
|
if (orig_col >= col) indices = segments[i];
|
||||||
|
if (orig_col <= col) break;
|
||||||
|
}
|
||||||
|
if (!indices || indices.length < 4) {
|
||||||
|
source = null;
|
||||||
|
} else {
|
||||||
|
source = map.sources[indices[1]];
|
||||||
|
orig_line = indices[2];
|
||||||
|
orig_col = indices[3];
|
||||||
|
if (indices.length > 4) name = map.names[indices[4]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
add(source, gen_line, gen_col, orig_line, orig_col, name);
|
||||||
|
} : add,
|
||||||
|
setSourceContent: sources_content ? function(source, content) {
|
||||||
|
sources_content[source] = content;
|
||||||
|
} : noop,
|
||||||
|
toString: function() {
|
||||||
|
return JSON.stringify({
|
||||||
|
version: 3,
|
||||||
|
file: options.filename || undefined,
|
||||||
|
sourceRoot: options.root || undefined,
|
||||||
|
sources: sources,
|
||||||
|
sourcesContent: sources_content ? sources.map(function(source) {
|
||||||
|
return sources_content[source] || null;
|
||||||
|
}) : undefined,
|
||||||
|
names: names,
|
||||||
|
mappings: mappings,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
function add(source, gen_line, gen_col, orig_line, orig_col, name) {
|
function add(source, gen_line, gen_col, orig_line, orig_col, name) {
|
||||||
if (orig_map) {
|
if (prev_source == null && source == null) return;
|
||||||
var info = orig_map.originalPositionFor({
|
prev_source = source;
|
||||||
line: orig_line,
|
if (generated_line < gen_line) {
|
||||||
column: orig_col
|
generated_column = 0;
|
||||||
});
|
do {
|
||||||
if (info.source === null) {
|
mappings += ";";
|
||||||
return;
|
} while (++generated_line < gen_line);
|
||||||
}
|
} else if (mappings) {
|
||||||
source = info.source;
|
mappings += ",";
|
||||||
orig_line = info.line;
|
|
||||||
orig_col = info.column;
|
|
||||||
name = info.name || name;
|
|
||||||
}
|
}
|
||||||
generator.addMapping({
|
mappings += vlq_encode(gen_col - generated_column);
|
||||||
generated : { line: gen_line + options.dest_line_diff, column: gen_col },
|
generated_column = gen_col;
|
||||||
original : { line: orig_line + options.orig_line_diff, column: orig_col },
|
if (source == null) return;
|
||||||
source : source,
|
var src_idx = sources.index(source);
|
||||||
name : name
|
mappings += vlq_encode(src_idx - source_index);
|
||||||
});
|
source_index = src_idx;
|
||||||
};
|
mappings += vlq_encode(orig_line - original_line);
|
||||||
return {
|
original_line = orig_line;
|
||||||
add : add,
|
mappings += vlq_encode(orig_col - original_column);
|
||||||
get : function() { return generator },
|
original_column = orig_col;
|
||||||
toString : function() { return JSON.stringify(generator.toJSON()); }
|
if (options.names && name != null) {
|
||||||
};
|
var name_idx = names.index(name);
|
||||||
};
|
mappings += vlq_encode(name_idx - name_index);
|
||||||
|
name_index = name_idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
140
lib/transform.js
140
lib/transform.js
@@ -1,7 +1,7 @@
|
|||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
|
||||||
A JavaScript tokenizer / parser / beautifier / compressor.
|
A JavaScript tokenizer / parser / beautifier / compressor.
|
||||||
https://github.com/mishoo/UglifyJS2
|
https://github.com/mishoo/UglifyJS
|
||||||
|
|
||||||
-------------------------------- (C) ---------------------------------
|
-------------------------------- (C) ---------------------------------
|
||||||
|
|
||||||
@@ -43,8 +43,6 @@
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
// Tree transformer helpers.
|
|
||||||
|
|
||||||
function TreeTransformer(before, after) {
|
function TreeTransformer(before, after) {
|
||||||
TreeWalker.call(this);
|
TreeWalker.call(this);
|
||||||
this.before = before;
|
this.before = before;
|
||||||
@@ -52,166 +50,136 @@ function TreeTransformer(before, after) {
|
|||||||
}
|
}
|
||||||
TreeTransformer.prototype = new TreeWalker;
|
TreeTransformer.prototype = new TreeWalker;
|
||||||
|
|
||||||
(function(undefined){
|
(function(DEF) {
|
||||||
|
|
||||||
function _(node, descend) {
|
|
||||||
node.DEFMETHOD("transform", function(tw, in_list){
|
|
||||||
var x, y;
|
|
||||||
tw.push(this);
|
|
||||||
if (tw.before) x = tw.before(this, descend, in_list);
|
|
||||||
if (x === undefined) {
|
|
||||||
if (!tw.after) {
|
|
||||||
x = this;
|
|
||||||
descend(x, tw);
|
|
||||||
} else {
|
|
||||||
tw.stack[tw.stack.length - 1] = x = this;
|
|
||||||
descend(x, tw);
|
|
||||||
y = tw.after(x, in_list);
|
|
||||||
if (y !== undefined) x = y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tw.pop(this);
|
|
||||||
return x;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
function do_list(list, tw) {
|
function do_list(list, tw) {
|
||||||
return MAP(list, function(node){
|
return List(list, function(node) {
|
||||||
return node.transform(tw, true);
|
return node.transform(tw, true);
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
_(AST_Node, noop);
|
DEF(AST_Node, noop);
|
||||||
|
DEF(AST_LabeledStatement, function(self, tw) {
|
||||||
_(AST_LabeledStatement, function(self, tw){
|
|
||||||
self.label = self.label.transform(tw);
|
self.label = self.label.transform(tw);
|
||||||
self.body = self.body.transform(tw);
|
self.body = self.body.transform(tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_SimpleStatement, function(self, tw) {
|
||||||
_(AST_SimpleStatement, function(self, tw){
|
|
||||||
self.body = self.body.transform(tw);
|
self.body = self.body.transform(tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Block, function(self, tw) {
|
||||||
_(AST_Block, function(self, tw){
|
|
||||||
self.body = do_list(self.body, tw);
|
self.body = do_list(self.body, tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Do, function(self, tw) {
|
||||||
_(AST_DWLoop, function(self, tw){
|
self.body = self.body.transform(tw);
|
||||||
|
self.condition = self.condition.transform(tw);
|
||||||
|
});
|
||||||
|
DEF(AST_While, function(self, tw) {
|
||||||
self.condition = self.condition.transform(tw);
|
self.condition = self.condition.transform(tw);
|
||||||
self.body = self.body.transform(tw);
|
self.body = self.body.transform(tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_For, function(self, tw) {
|
||||||
_(AST_For, function(self, tw){
|
|
||||||
if (self.init) self.init = self.init.transform(tw);
|
if (self.init) self.init = self.init.transform(tw);
|
||||||
if (self.condition) self.condition = self.condition.transform(tw);
|
if (self.condition) self.condition = self.condition.transform(tw);
|
||||||
if (self.step) self.step = self.step.transform(tw);
|
if (self.step) self.step = self.step.transform(tw);
|
||||||
self.body = self.body.transform(tw);
|
self.body = self.body.transform(tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_ForIn, function(self, tw) {
|
||||||
_(AST_ForIn, function(self, tw){
|
|
||||||
self.init = self.init.transform(tw);
|
self.init = self.init.transform(tw);
|
||||||
self.object = self.object.transform(tw);
|
self.object = self.object.transform(tw);
|
||||||
self.body = self.body.transform(tw);
|
self.body = self.body.transform(tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_With, function(self, tw) {
|
||||||
_(AST_With, function(self, tw){
|
|
||||||
self.expression = self.expression.transform(tw);
|
self.expression = self.expression.transform(tw);
|
||||||
self.body = self.body.transform(tw);
|
self.body = self.body.transform(tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Exit, function(self, tw) {
|
||||||
_(AST_Exit, function(self, tw){
|
|
||||||
if (self.value) self.value = self.value.transform(tw);
|
if (self.value) self.value = self.value.transform(tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_LoopControl, function(self, tw) {
|
||||||
_(AST_LoopControl, function(self, tw){
|
|
||||||
if (self.label) self.label = self.label.transform(tw);
|
if (self.label) self.label = self.label.transform(tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_If, function(self, tw) {
|
||||||
_(AST_If, function(self, tw){
|
|
||||||
self.condition = self.condition.transform(tw);
|
self.condition = self.condition.transform(tw);
|
||||||
self.body = self.body.transform(tw);
|
self.body = self.body.transform(tw);
|
||||||
if (self.alternative) self.alternative = self.alternative.transform(tw);
|
if (self.alternative) self.alternative = self.alternative.transform(tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Switch, function(self, tw) {
|
||||||
_(AST_Switch, function(self, tw){
|
|
||||||
self.expression = self.expression.transform(tw);
|
self.expression = self.expression.transform(tw);
|
||||||
self.body = do_list(self.body, tw);
|
self.body = do_list(self.body, tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Case, function(self, tw) {
|
||||||
_(AST_Case, function(self, tw){
|
|
||||||
self.expression = self.expression.transform(tw);
|
self.expression = self.expression.transform(tw);
|
||||||
self.body = do_list(self.body, tw);
|
self.body = do_list(self.body, tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Try, function(self, tw) {
|
||||||
_(AST_Try, function(self, tw){
|
|
||||||
self.body = do_list(self.body, tw);
|
self.body = do_list(self.body, tw);
|
||||||
if (self.bcatch) self.bcatch = self.bcatch.transform(tw);
|
if (self.bcatch) self.bcatch = self.bcatch.transform(tw);
|
||||||
if (self.bfinally) self.bfinally = self.bfinally.transform(tw);
|
if (self.bfinally) self.bfinally = self.bfinally.transform(tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Catch, function(self, tw) {
|
||||||
_(AST_Catch, function(self, tw){
|
if (self.argname) self.argname = self.argname.transform(tw);
|
||||||
self.argname = self.argname.transform(tw);
|
|
||||||
self.body = do_list(self.body, tw);
|
self.body = do_list(self.body, tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Definitions, function(self, tw) {
|
||||||
_(AST_Definitions, function(self, tw){
|
|
||||||
self.definitions = do_list(self.definitions, tw);
|
self.definitions = do_list(self.definitions, tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_VarDef, function(self, tw) {
|
||||||
_(AST_VarDef, function(self, tw){
|
|
||||||
self.name = self.name.transform(tw);
|
self.name = self.name.transform(tw);
|
||||||
if (self.value) self.value = self.value.transform(tw);
|
if (self.value) self.value = self.value.transform(tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Lambda, function(self, tw) {
|
||||||
_(AST_Lambda, function(self, tw){
|
|
||||||
if (self.name) self.name = self.name.transform(tw);
|
if (self.name) self.name = self.name.transform(tw);
|
||||||
self.argnames = do_list(self.argnames, tw);
|
self.argnames = do_list(self.argnames, tw);
|
||||||
self.body = do_list(self.body, tw);
|
self.body = do_list(self.body, tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Call, function(self, tw) {
|
||||||
_(AST_Call, function(self, tw){
|
|
||||||
self.expression = self.expression.transform(tw);
|
self.expression = self.expression.transform(tw);
|
||||||
self.args = do_list(self.args, tw);
|
self.args = do_list(self.args, tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Sequence, function(self, tw) {
|
||||||
_(AST_Sequence, function(self, tw){
|
|
||||||
self.expressions = do_list(self.expressions, tw);
|
self.expressions = do_list(self.expressions, tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Dot, function(self, tw) {
|
||||||
_(AST_Dot, function(self, tw){
|
|
||||||
self.expression = self.expression.transform(tw);
|
self.expression = self.expression.transform(tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Sub, function(self, tw) {
|
||||||
_(AST_Sub, function(self, tw){
|
|
||||||
self.expression = self.expression.transform(tw);
|
self.expression = self.expression.transform(tw);
|
||||||
self.property = self.property.transform(tw);
|
self.property = self.property.transform(tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Unary, function(self, tw) {
|
||||||
_(AST_Unary, function(self, tw){
|
|
||||||
self.expression = self.expression.transform(tw);
|
self.expression = self.expression.transform(tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Binary, function(self, tw) {
|
||||||
_(AST_Binary, function(self, tw){
|
|
||||||
self.left = self.left.transform(tw);
|
self.left = self.left.transform(tw);
|
||||||
self.right = self.right.transform(tw);
|
self.right = self.right.transform(tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Conditional, function(self, tw) {
|
||||||
_(AST_Conditional, function(self, tw){
|
|
||||||
self.condition = self.condition.transform(tw);
|
self.condition = self.condition.transform(tw);
|
||||||
self.consequent = self.consequent.transform(tw);
|
self.consequent = self.consequent.transform(tw);
|
||||||
self.alternative = self.alternative.transform(tw);
|
self.alternative = self.alternative.transform(tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Array, function(self, tw) {
|
||||||
_(AST_Array, function(self, tw){
|
|
||||||
self.elements = do_list(self.elements, tw);
|
self.elements = do_list(self.elements, tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Object, function(self, tw) {
|
||||||
_(AST_Object, function(self, tw){
|
|
||||||
self.properties = do_list(self.properties, tw);
|
self.properties = do_list(self.properties, tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_ObjectProperty, function(self, tw) {
|
||||||
_(AST_ObjectProperty, function(self, tw){
|
|
||||||
self.value = self.value.transform(tw);
|
self.value = self.value.transform(tw);
|
||||||
});
|
});
|
||||||
|
})(function(node, descend) {
|
||||||
})();
|
node.DEFMETHOD("transform", function(tw, in_list) {
|
||||||
|
var x, y;
|
||||||
|
tw.push(this);
|
||||||
|
if (tw.before) x = tw.before(this, descend, in_list);
|
||||||
|
if (typeof x === "undefined") {
|
||||||
|
x = this;
|
||||||
|
descend(x, tw);
|
||||||
|
if (tw.after) {
|
||||||
|
y = tw.after(x, in_list);
|
||||||
|
if (typeof y !== "undefined") x = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tw.pop();
|
||||||
|
return x;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
268
lib/utils.js
268
lib/utils.js
@@ -1,7 +1,7 @@
|
|||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
|
||||||
A JavaScript tokenizer / parser / beautifier / compressor.
|
A JavaScript tokenizer / parser / beautifier / compressor.
|
||||||
https://github.com/mishoo/UglifyJS2
|
https://github.com/mishoo/UglifyJS
|
||||||
|
|
||||||
-------------------------------- (C) ---------------------------------
|
-------------------------------- (C) ---------------------------------
|
||||||
|
|
||||||
@@ -43,40 +43,25 @@
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
function array_to_hash(a) {
|
|
||||||
var ret = Object.create(null);
|
|
||||||
for (var i = 0; i < a.length; ++i)
|
|
||||||
ret[a[i]] = true;
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
|
|
||||||
function slice(a, start) {
|
|
||||||
return Array.prototype.slice.call(a, start || 0);
|
|
||||||
};
|
|
||||||
|
|
||||||
function characters(str) {
|
function characters(str) {
|
||||||
return str.split("");
|
return str.split("");
|
||||||
};
|
}
|
||||||
|
|
||||||
function member(name, array) {
|
function member(name, array) {
|
||||||
return array.indexOf(name) >= 0;
|
return array.indexOf(name) >= 0;
|
||||||
};
|
}
|
||||||
|
|
||||||
function find_if(func, array) {
|
function find_if(func, array) {
|
||||||
for (var i = 0, n = array.length; i < n; ++i) {
|
for (var i = array.length; --i >= 0;) if (func(array[i])) return array[i];
|
||||||
if (func(array[i]))
|
}
|
||||||
return array[i];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function repeat_string(str, i) {
|
function repeat_string(str, i) {
|
||||||
if (i <= 0) return "";
|
if (i <= 0) return "";
|
||||||
if (i == 1) return str;
|
if (i == 1) return str;
|
||||||
var d = repeat_string(str, i >> 1);
|
var d = repeat_string(str, i >> 1);
|
||||||
d += d;
|
d += d;
|
||||||
if (i & 1) d += str;
|
return i & 1 ? d + str : d;
|
||||||
return d;
|
}
|
||||||
};
|
|
||||||
|
|
||||||
function configure_error_stack(fn) {
|
function configure_error_stack(fn) {
|
||||||
Object.defineProperty(fn.prototype, "stack", {
|
Object.defineProperty(fn.prototype, "stack", {
|
||||||
@@ -85,7 +70,7 @@ function configure_error_stack(fn) {
|
|||||||
err.name = this.name;
|
err.name = this.name;
|
||||||
try {
|
try {
|
||||||
throw err;
|
throw err;
|
||||||
} catch(e) {
|
} catch (e) {
|
||||||
return e.stack;
|
return e.stack;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -95,27 +80,21 @@ function configure_error_stack(fn) {
|
|||||||
function DefaultsError(msg, defs) {
|
function DefaultsError(msg, defs) {
|
||||||
this.message = msg;
|
this.message = msg;
|
||||||
this.defs = defs;
|
this.defs = defs;
|
||||||
};
|
}
|
||||||
DefaultsError.prototype = Object.create(Error.prototype);
|
DefaultsError.prototype = Object.create(Error.prototype);
|
||||||
DefaultsError.prototype.constructor = DefaultsError;
|
DefaultsError.prototype.constructor = DefaultsError;
|
||||||
DefaultsError.prototype.name = "DefaultsError";
|
DefaultsError.prototype.name = "DefaultsError";
|
||||||
configure_error_stack(DefaultsError);
|
configure_error_stack(DefaultsError);
|
||||||
|
|
||||||
DefaultsError.croak = function(msg, defs) {
|
|
||||||
throw new DefaultsError(msg, defs);
|
|
||||||
};
|
|
||||||
|
|
||||||
function defaults(args, defs, croak) {
|
function defaults(args, defs, croak) {
|
||||||
if (args === true)
|
if (croak) for (var i in args) {
|
||||||
args = {};
|
if (HOP(args, i) && !HOP(defs, i)) throw new DefaultsError("`" + i + "` is not a supported option", defs);
|
||||||
var ret = args || {};
|
|
||||||
if (croak) for (var i in ret) if (HOP(ret, i) && !HOP(defs, i))
|
|
||||||
DefaultsError.croak("`" + i + "` is not a supported option", defs);
|
|
||||||
for (var i in defs) if (HOP(defs, i)) {
|
|
||||||
ret[i] = (args && HOP(args, i)) ? args[i] : defs[i];
|
|
||||||
}
|
}
|
||||||
return ret;
|
for (var i in args) {
|
||||||
};
|
if (HOP(args, i)) defs[i] = args[i];
|
||||||
|
}
|
||||||
|
return defs;
|
||||||
|
}
|
||||||
|
|
||||||
function merge(obj, ext) {
|
function merge(obj, ext) {
|
||||||
var count = 0;
|
var count = 0;
|
||||||
@@ -124,7 +103,7 @@ function merge(obj, ext) {
|
|||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
};
|
}
|
||||||
|
|
||||||
function noop() {}
|
function noop() {}
|
||||||
function return_false() { return false; }
|
function return_false() { return false; }
|
||||||
@@ -132,164 +111,68 @@ function return_true() { return true; }
|
|||||||
function return_this() { return this; }
|
function return_this() { return this; }
|
||||||
function return_null() { return null; }
|
function return_null() { return null; }
|
||||||
|
|
||||||
var MAP = (function(){
|
var List = (function() {
|
||||||
function MAP(a, f, backwards) {
|
function List(a, f) {
|
||||||
var ret = [], top = [], i;
|
var ret = [];
|
||||||
function doit() {
|
for (var i = 0; i < a.length; i++) {
|
||||||
var val = f(a[i], i);
|
var val = f(a[i], i);
|
||||||
var is_last = val instanceof Last;
|
if (val === skip) continue;
|
||||||
if (is_last) val = val.v;
|
if (val instanceof Splice) {
|
||||||
if (val instanceof AtTop) {
|
ret.push.apply(ret, val.v);
|
||||||
val = val.v;
|
|
||||||
if (val instanceof Splice) {
|
|
||||||
top.push.apply(top, backwards ? val.v.slice().reverse() : val.v);
|
|
||||||
} else {
|
|
||||||
top.push(val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (val !== skip) {
|
|
||||||
if (val instanceof Splice) {
|
|
||||||
ret.push.apply(ret, backwards ? val.v.slice().reverse() : val.v);
|
|
||||||
} else {
|
|
||||||
ret.push(val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return is_last;
|
|
||||||
};
|
|
||||||
if (a instanceof Array) {
|
|
||||||
if (backwards) {
|
|
||||||
for (i = a.length; --i >= 0;) if (doit()) break;
|
|
||||||
ret.reverse();
|
|
||||||
top.reverse();
|
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < a.length; ++i) if (doit()) break;
|
ret.push(val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
return ret;
|
||||||
for (i in a) if (HOP(a, i)) if (doit()) break;
|
}
|
||||||
}
|
List.is_op = function(val) {
|
||||||
return top.concat(ret);
|
return val === skip || val instanceof Splice;
|
||||||
};
|
};
|
||||||
MAP.at_top = function(val) { return new AtTop(val) };
|
List.splice = function(val) {
|
||||||
MAP.splice = function(val) { return new Splice(val) };
|
return new Splice(val);
|
||||||
MAP.last = function(val) { return new Last(val) };
|
};
|
||||||
var skip = MAP.skip = {};
|
var skip = List.skip = {};
|
||||||
function AtTop(val) { this.v = val };
|
function Splice(val) {
|
||||||
function Splice(val) { this.v = val };
|
this.v = val;
|
||||||
function Last(val) { this.v = val };
|
}
|
||||||
return MAP;
|
return List;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
function push_uniq(array, el) {
|
function push_uniq(array, el) {
|
||||||
if (array.indexOf(el) < 0)
|
if (array.indexOf(el) < 0) return array.push(el);
|
||||||
array.push(el);
|
}
|
||||||
};
|
|
||||||
|
|
||||||
function string_template(text, props) {
|
function string_template(text, props) {
|
||||||
return text.replace(/\{(.+?)\}/g, function(str, p){
|
return text.replace(/\{(.+?)\}/g, function(str, p) {
|
||||||
return props && props[p];
|
return props && props[p];
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
function remove(array, el) {
|
function remove(array, el) {
|
||||||
for (var i = array.length; --i >= 0;) {
|
var index = array.indexOf(el);
|
||||||
if (array[i] === el) array.splice(i, 1);
|
if (index >= 0) array.splice(index, 1);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
function mergeSort(array, cmp) {
|
|
||||||
if (array.length < 2) return array.slice();
|
|
||||||
function merge(a, b) {
|
|
||||||
var r = [], ai = 0, bi = 0, i = 0;
|
|
||||||
while (ai < a.length && bi < b.length) {
|
|
||||||
cmp(a[ai], b[bi]) <= 0
|
|
||||||
? r[i++] = a[ai++]
|
|
||||||
: r[i++] = b[bi++];
|
|
||||||
}
|
|
||||||
if (ai < a.length) r.push.apply(r, a.slice(ai));
|
|
||||||
if (bi < b.length) r.push.apply(r, b.slice(bi));
|
|
||||||
return r;
|
|
||||||
};
|
|
||||||
function _ms(a) {
|
|
||||||
if (a.length <= 1)
|
|
||||||
return a;
|
|
||||||
var m = Math.floor(a.length / 2), left = a.slice(0, m), right = a.slice(m);
|
|
||||||
left = _ms(left);
|
|
||||||
right = _ms(right);
|
|
||||||
return merge(left, right);
|
|
||||||
};
|
|
||||||
return _ms(array);
|
|
||||||
};
|
|
||||||
|
|
||||||
function set_difference(a, b) {
|
|
||||||
return a.filter(function(el){
|
|
||||||
return b.indexOf(el) < 0;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
function set_intersection(a, b) {
|
|
||||||
return a.filter(function(el){
|
|
||||||
return b.indexOf(el) >= 0;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// this function is taken from Acorn [1], written by Marijn Haverbeke
|
|
||||||
// [1] https://github.com/marijnh/acorn
|
|
||||||
function makePredicate(words) {
|
function makePredicate(words) {
|
||||||
if (!(words instanceof Array)) words = words.split(" ");
|
if (!Array.isArray(words)) words = words.split(" ");
|
||||||
var f = "", cats = [];
|
var map = Object.create(null);
|
||||||
out: for (var i = 0; i < words.length; ++i) {
|
words.forEach(function(word) {
|
||||||
for (var j = 0; j < cats.length; ++j)
|
map[word] = true;
|
||||||
if (cats[j][0].length == words[i].length) {
|
});
|
||||||
cats[j].push(words[i]);
|
return map;
|
||||||
continue out;
|
}
|
||||||
}
|
|
||||||
cats.push([words[i]]);
|
|
||||||
}
|
|
||||||
function quote(word) {
|
|
||||||
return JSON.stringify(word).replace(/[\u2028\u2029]/g, function(s) {
|
|
||||||
switch (s) {
|
|
||||||
case "\u2028": return "\\u2028";
|
|
||||||
case "\u2029": return "\\u2029";
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function compareTo(arr) {
|
|
||||||
if (arr.length == 1) return f += "return str === " + quote(arr[0]) + ";";
|
|
||||||
f += "switch(str){";
|
|
||||||
for (var i = 0; i < arr.length; ++i) f += "case " + quote(arr[i]) + ":";
|
|
||||||
f += "return true}return false;";
|
|
||||||
}
|
|
||||||
// When there are more than three length categories, an outer
|
|
||||||
// switch first dispatches on the lengths, to save on comparisons.
|
|
||||||
if (cats.length > 3) {
|
|
||||||
cats.sort(function(a, b) {return b.length - a.length;});
|
|
||||||
f += "switch(str.length){";
|
|
||||||
for (var i = 0; i < cats.length; ++i) {
|
|
||||||
var cat = cats[i];
|
|
||||||
f += "case " + cat[0].length + ":";
|
|
||||||
compareTo(cat);
|
|
||||||
}
|
|
||||||
f += "}";
|
|
||||||
// Otherwise, simply generate a flat `switch` statement.
|
|
||||||
} else {
|
|
||||||
compareTo(words);
|
|
||||||
}
|
|
||||||
return new Function("str", f);
|
|
||||||
};
|
|
||||||
|
|
||||||
function all(array, predicate) {
|
function all(array, predicate) {
|
||||||
for (var i = array.length; --i >= 0;)
|
for (var i = array.length; --i >= 0;)
|
||||||
if (!predicate(array[i]))
|
if (!predicate(array[i], i))
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
};
|
}
|
||||||
|
|
||||||
function Dictionary() {
|
function Dictionary() {
|
||||||
this._values = Object.create(null);
|
this._values = Object.create(null);
|
||||||
this._size = 0;
|
this._size = 0;
|
||||||
};
|
}
|
||||||
Dictionary.prototype = {
|
Dictionary.prototype = {
|
||||||
set: function(key, val) {
|
set: function(key, val) {
|
||||||
if (!this.has(key)) ++this._size;
|
if (!this.has(key)) ++this._size;
|
||||||
@@ -313,6 +196,12 @@ Dictionary.prototype = {
|
|||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
has: function(key) { return ("$" + key) in this._values },
|
has: function(key) { return ("$" + key) in this._values },
|
||||||
|
all: function(predicate) {
|
||||||
|
for (var i in this._values)
|
||||||
|
if (!predicate(this._values[i], i.substr(1)))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
},
|
||||||
each: function(f) {
|
each: function(f) {
|
||||||
for (var i in this._values)
|
for (var i in this._values)
|
||||||
f(this._values[i], i.substr(1));
|
f(this._values[i], i.substr(1));
|
||||||
@@ -326,6 +215,13 @@ Dictionary.prototype = {
|
|||||||
ret.push(f(this._values[i], i.substr(1)));
|
ret.push(f(this._values[i], i.substr(1)));
|
||||||
return ret;
|
return ret;
|
||||||
},
|
},
|
||||||
|
clone: function() {
|
||||||
|
var ret = new Dictionary();
|
||||||
|
for (var i in this._values)
|
||||||
|
ret._values[i] = this._values[i];
|
||||||
|
ret._size = this._size;
|
||||||
|
return ret;
|
||||||
|
},
|
||||||
toObject: function() { return this._values }
|
toObject: function() { return this._values }
|
||||||
};
|
};
|
||||||
Dictionary.fromObject = function(obj) {
|
Dictionary.fromObject = function(obj) {
|
||||||
@@ -343,20 +239,22 @@ function HOP(obj, prop) {
|
|||||||
// a statement.
|
// a statement.
|
||||||
function first_in_statement(stack) {
|
function first_in_statement(stack) {
|
||||||
var node = stack.parent(-1);
|
var node = stack.parent(-1);
|
||||||
for (var i = 0, p; p = stack.parent(i); i++) {
|
for (var i = 0, p; p = stack.parent(i++); node = p) {
|
||||||
if (p instanceof AST_Statement && p.body === node)
|
if (p.TYPE == "Call") {
|
||||||
return true;
|
if (p.expression === node) continue;
|
||||||
if ((p instanceof AST_Sequence && p.expressions[0] === node) ||
|
} else if (p instanceof AST_Binary) {
|
||||||
(p instanceof AST_Call && p.expression === node && !(p instanceof AST_New) ) ||
|
if (p.left === node) continue;
|
||||||
(p instanceof AST_Dot && p.expression === node ) ||
|
} else if (p instanceof AST_Conditional) {
|
||||||
(p instanceof AST_Sub && p.expression === node ) ||
|
if (p.condition === node) continue;
|
||||||
(p instanceof AST_Conditional && p.condition === node ) ||
|
} else if (p instanceof AST_PropAccess) {
|
||||||
(p instanceof AST_Binary && p.left === node ) ||
|
if (p.expression === node) continue;
|
||||||
(p instanceof AST_UnaryPostfix && p.expression === node ))
|
} else if (p instanceof AST_Sequence) {
|
||||||
{
|
if (p.expressions[0] === node) continue;
|
||||||
node = p;
|
} else if (p instanceof AST_Statement) {
|
||||||
} else {
|
return p.body === node;
|
||||||
return false;
|
} else if (p instanceof AST_UnaryPostfix) {
|
||||||
|
if (p.expression === node) continue;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
48
package.json
48
package.json
@@ -1,23 +1,17 @@
|
|||||||
{
|
{
|
||||||
"name": "uglify-js",
|
"name": "uglify-js",
|
||||||
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
||||||
"homepage": "http://lisperator.net/uglifyjs",
|
|
||||||
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"version": "3.0.13",
|
"version": "3.11.3",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.8.0"
|
"node": ">=0.8.0"
|
||||||
},
|
},
|
||||||
"maintainers": [
|
"maintainers": [
|
||||||
|
"Alex Lam <alexlamsl@gmail.com>",
|
||||||
"Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)"
|
"Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)"
|
||||||
],
|
],
|
||||||
"repository": {
|
"repository": "mishoo/UglifyJS",
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/mishoo/UglifyJS2.git"
|
|
||||||
},
|
|
||||||
"bugs": {
|
|
||||||
"url": "https://github.com/mishoo/UglifyJS2/issues"
|
|
||||||
},
|
|
||||||
"main": "tools/node.js",
|
"main": "tools/node.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
"uglifyjs": "bin/uglifyjs"
|
"uglifyjs": "bin/uglifyjs"
|
||||||
@@ -28,17 +22,35 @@
|
|||||||
"tools",
|
"tools",
|
||||||
"LICENSE"
|
"LICENSE"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
|
||||||
"commander": "~2.9.0",
|
|
||||||
"source-map": "~0.5.1"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"acorn": "~5.0.3",
|
"acorn": "~7.1.0",
|
||||||
"mocha": "~2.3.4",
|
"semver": "~6.3.0"
|
||||||
"semver": "~5.3.0"
|
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "node test/run-tests.js"
|
"test": "node test/compress.js && node test/mocha.js"
|
||||||
},
|
},
|
||||||
"keywords": ["uglify", "uglify-js", "minify", "minifier", "es5"]
|
"keywords": [
|
||||||
|
"cli",
|
||||||
|
"compress",
|
||||||
|
"compressor",
|
||||||
|
"ecma",
|
||||||
|
"ecmascript",
|
||||||
|
"es",
|
||||||
|
"es5",
|
||||||
|
"javascript",
|
||||||
|
"js",
|
||||||
|
"jsmin",
|
||||||
|
"min",
|
||||||
|
"minification",
|
||||||
|
"minifier",
|
||||||
|
"minify",
|
||||||
|
"optimize",
|
||||||
|
"optimizer",
|
||||||
|
"pack",
|
||||||
|
"packer",
|
||||||
|
"parse",
|
||||||
|
"parser",
|
||||||
|
"uglifier",
|
||||||
|
"uglify"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,27 +4,30 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var createHash = require("crypto").createHash;
|
var createHash = require("crypto").createHash;
|
||||||
var fork = require("child_process").fork;
|
var fetch = require("./fetch");
|
||||||
|
var spawn = require("child_process").spawn;
|
||||||
|
var zlib = require("zlib");
|
||||||
var args = process.argv.slice(2);
|
var args = process.argv.slice(2);
|
||||||
if (!args.length) {
|
if (!args.length) args.push("-mc");
|
||||||
args.push("-mc");
|
args.unshift("bin/uglifyjs");
|
||||||
}
|
|
||||||
args.push("--timings");
|
args.push("--timings");
|
||||||
var urls = [
|
var urls = [
|
||||||
"https://code.jquery.com/jquery-3.2.1.js",
|
"https://code.jquery.com/jquery-3.4.1.js",
|
||||||
"https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.4/angular.js",
|
"https://code.angularjs.org/1.7.8/angular.js",
|
||||||
"https://cdnjs.cloudflare.com/ajax/libs/mathjs/3.9.0/math.js",
|
"https://unpkg.com/mathjs@6.2.3/dist/math.js",
|
||||||
"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.js",
|
|
||||||
"https://unpkg.com/react@15.3.2/dist/react.js",
|
"https://unpkg.com/react@15.3.2/dist/react.js",
|
||||||
"http://builds.emberjs.com/tags/v2.11.0/ember.prod.js",
|
"https://cdnjs.cloudflare.com/ajax/libs/d3/5.12.0/d3.js",
|
||||||
"https://cdn.jsdelivr.net/lodash/4.17.4/lodash.js",
|
"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.js",
|
||||||
"https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.js",
|
"https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js",
|
||||||
|
"https://cdnjs.cloudflare.com/ajax/libs/ember.js/2.12.2/ember.prod.js",
|
||||||
|
"https://raw.githubusercontent.com/kangax/html-minifier/v4.0.0/dist/htmlminifier.js",
|
||||||
];
|
];
|
||||||
var results = {};
|
var results = {};
|
||||||
var remaining = 2 * urls.length;
|
var remaining = 2 * urls.length;
|
||||||
function done() {
|
function done() {
|
||||||
if (!--remaining) {
|
if (!--remaining) {
|
||||||
var failures = [];
|
var failures = [];
|
||||||
|
var sum = { input: 0, output: 0, gzip: 0 };
|
||||||
urls.forEach(function(url) {
|
urls.forEach(function(url) {
|
||||||
var info = results[url];
|
var info = results[url];
|
||||||
console.log();
|
console.log();
|
||||||
@@ -32,10 +35,14 @@ function done() {
|
|||||||
console.log(info.log);
|
console.log(info.log);
|
||||||
console.log("Original:", info.input, "bytes");
|
console.log("Original:", info.input, "bytes");
|
||||||
console.log("Uglified:", info.output, "bytes");
|
console.log("Uglified:", info.output, "bytes");
|
||||||
|
console.log("GZipped: ", info.gzip, "bytes");
|
||||||
console.log("SHA1 sum:", info.sha1);
|
console.log("SHA1 sum:", info.sha1);
|
||||||
if (info.code) {
|
if (info.code) {
|
||||||
failures.push(url);
|
failures.push(url);
|
||||||
}
|
}
|
||||||
|
sum.input += info.input;
|
||||||
|
sum.output += info.output;
|
||||||
|
sum.gzip += info.gzip;
|
||||||
});
|
});
|
||||||
if (failures.length) {
|
if (failures.length) {
|
||||||
console.error("Benchmark failed:");
|
console.error("Benchmark failed:");
|
||||||
@@ -43,6 +50,13 @@ function done() {
|
|||||||
console.error(url);
|
console.error(url);
|
||||||
});
|
});
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
|
} else {
|
||||||
|
console.log();
|
||||||
|
console.log("Subtotal");
|
||||||
|
console.log();
|
||||||
|
console.log("Original:", sum.input, "bytes");
|
||||||
|
console.log("Uglified:", sum.output, "bytes");
|
||||||
|
console.log("GZipped: ", sum.gzip, "bytes");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -50,17 +64,25 @@ urls.forEach(function(url) {
|
|||||||
results[url] = {
|
results[url] = {
|
||||||
input: 0,
|
input: 0,
|
||||||
output: 0,
|
output: 0,
|
||||||
|
gzip: 0,
|
||||||
log: ""
|
log: ""
|
||||||
};
|
};
|
||||||
require(url.slice(0, url.indexOf(":"))).get(url, function(res) {
|
fetch(url, function(err, res) {
|
||||||
var uglifyjs = fork("bin/uglifyjs", args, { silent: true });
|
if (err) throw err;
|
||||||
|
var uglifyjs = spawn(process.argv[0], args, { silent: true });
|
||||||
res.on("data", function(data) {
|
res.on("data", function(data) {
|
||||||
results[url].input += data.length;
|
results[url].input += data.length;
|
||||||
}).pipe(uglifyjs.stdin);
|
}).pipe(uglifyjs.stdin);
|
||||||
|
var sha1 = createHash("sha1");
|
||||||
uglifyjs.stdout.on("data", function(data) {
|
uglifyjs.stdout.on("data", function(data) {
|
||||||
results[url].output += data.length;
|
results[url].output += data.length;
|
||||||
}).pipe(createHash("sha1")).on("data", function(data) {
|
}).pipe(zlib.createGzip({
|
||||||
results[url].sha1 = data.toString("hex");
|
level: zlib.Z_BEST_COMPRESSION
|
||||||
|
})).on("data", function(data) {
|
||||||
|
results[url].gzip += data.length;
|
||||||
|
sha1.update(data);
|
||||||
|
}).on("end", function() {
|
||||||
|
results[url].sha1 = sha1.digest("hex");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
uglifyjs.stderr.setEncoding("utf8");
|
uglifyjs.stderr.setEncoding("utf8");
|
||||||
|
|||||||
460
test/compress.js
Normal file
460
test/compress.js
Normal file
@@ -0,0 +1,460 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
require("../tools/exit");
|
||||||
|
|
||||||
|
var assert = require("assert");
|
||||||
|
var child_process = require("child_process");
|
||||||
|
var fs = require("fs");
|
||||||
|
var path = require("path");
|
||||||
|
var sandbox = require("./sandbox");
|
||||||
|
var semver = require("semver");
|
||||||
|
var U = require("./node");
|
||||||
|
|
||||||
|
var file = process.argv[2];
|
||||||
|
var dir = path.resolve(path.dirname(module.filename), "compress");
|
||||||
|
if (file) {
|
||||||
|
var minify_options = require("./ufuzz/options.json").map(JSON.stringify);
|
||||||
|
log("--- {file}", { file: file });
|
||||||
|
var tests = parse_test(path.resolve(dir, file));
|
||||||
|
process.exit(Object.keys(tests).filter(function(name) {
|
||||||
|
return !test_case(tests[name]);
|
||||||
|
}).length);
|
||||||
|
} else {
|
||||||
|
var files = fs.readdirSync(dir).filter(function(name) {
|
||||||
|
return /\.js$/i.test(name);
|
||||||
|
});
|
||||||
|
var failures = 0;
|
||||||
|
var failed_files = Object.create(null);
|
||||||
|
(function next() {
|
||||||
|
var file = files.shift();
|
||||||
|
if (file) {
|
||||||
|
child_process.spawn(process.argv[0], [ process.argv[1], file ], {
|
||||||
|
stdio: [ "ignore", 1, 2 ]
|
||||||
|
}).on("exit", function(code) {
|
||||||
|
if (code) {
|
||||||
|
failures += code;
|
||||||
|
failed_files[file] = code;
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
} else if (failures) {
|
||||||
|
console.error();
|
||||||
|
console.error("!!! Failed " + failures + " test case(s).");
|
||||||
|
console.error("!!! " + Object.keys(failed_files).join(", "));
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
|
||||||
|
function evaluate(code) {
|
||||||
|
if (code instanceof U.AST_Node) code = make_code(code, { beautify: true });
|
||||||
|
return new Function("return(" + code + ")")();
|
||||||
|
}
|
||||||
|
|
||||||
|
function log() {
|
||||||
|
console.log("%s", tmpl.apply(null, arguments));
|
||||||
|
}
|
||||||
|
|
||||||
|
function make_code(ast, options) {
|
||||||
|
var stream = U.OutputStream(options);
|
||||||
|
ast.print(stream);
|
||||||
|
return stream.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
function parse_test(file) {
|
||||||
|
var script = fs.readFileSync(file, "utf8");
|
||||||
|
// TODO try/catch can be removed after fixing https://github.com/mishoo/UglifyJS/issues/348
|
||||||
|
try {
|
||||||
|
var ast = U.parse(script, {
|
||||||
|
filename: file
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Caught error while parsing tests in " + file);
|
||||||
|
console.error(e);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
var tests = Object.create(null);
|
||||||
|
var tw = new U.TreeWalker(function(node, descend) {
|
||||||
|
if (node instanceof U.AST_LabeledStatement
|
||||||
|
&& tw.parent() instanceof U.AST_Toplevel) {
|
||||||
|
var name = node.label.name;
|
||||||
|
if (name in tests) {
|
||||||
|
throw new Error('Duplicated test name "' + name + '" in ' + file);
|
||||||
|
}
|
||||||
|
tests[name] = get_one_test(name, node.body);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(node instanceof U.AST_Toplevel)) croak(node);
|
||||||
|
});
|
||||||
|
ast.walk(tw);
|
||||||
|
return tests;
|
||||||
|
|
||||||
|
function croak(node) {
|
||||||
|
throw new Error(tmpl("Can't understand test file {file} [{line},{col}]\n{code}", {
|
||||||
|
file: file,
|
||||||
|
line: node.start.line,
|
||||||
|
col: node.start.col,
|
||||||
|
code: make_code(node, { beautify: false })
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
function read_string(stat) {
|
||||||
|
if (stat.TYPE == "SimpleStatement") {
|
||||||
|
var body = stat.body;
|
||||||
|
switch(body.TYPE) {
|
||||||
|
case "String":
|
||||||
|
return body.value;
|
||||||
|
case "Array":
|
||||||
|
return body.elements.map(function(element) {
|
||||||
|
if (element.TYPE !== "String")
|
||||||
|
throw new Error("Should be array of strings");
|
||||||
|
return element.value;
|
||||||
|
}).join("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new Error("Should be string or array of strings");
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_one_test(name, block) {
|
||||||
|
var test = { name: name, options: {} };
|
||||||
|
var tw = new U.TreeWalker(function(node, descend) {
|
||||||
|
if (node instanceof U.AST_Assign) {
|
||||||
|
if (!(node.left instanceof U.AST_SymbolRef)) {
|
||||||
|
croak(node);
|
||||||
|
}
|
||||||
|
var name = node.left.name;
|
||||||
|
test[name] = evaluate(node.right);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (node instanceof U.AST_LabeledStatement) {
|
||||||
|
var label = node.label;
|
||||||
|
assert.ok([
|
||||||
|
"input",
|
||||||
|
"expect",
|
||||||
|
"expect_exact",
|
||||||
|
"expect_warnings",
|
||||||
|
"expect_stdout",
|
||||||
|
"node_version",
|
||||||
|
].indexOf(label.name) >= 0, tmpl("Unsupported label {name} [{line},{col}]", {
|
||||||
|
name: label.name,
|
||||||
|
line: label.start.line,
|
||||||
|
col: label.start.col
|
||||||
|
}));
|
||||||
|
var stat = node.body;
|
||||||
|
if (label.name == "expect_exact" || label.name == "node_version") {
|
||||||
|
test[label.name] = read_string(stat);
|
||||||
|
} else if (label.name == "expect_stdout") {
|
||||||
|
var body = stat.body;
|
||||||
|
if (body instanceof U.AST_Boolean) {
|
||||||
|
test[label.name] = body.value;
|
||||||
|
} else if (body instanceof U.AST_Call) {
|
||||||
|
var ctor = global[body.expression.name];
|
||||||
|
assert.ok(ctor === Error || ctor.prototype instanceof Error, tmpl("Unsupported expect_stdout format [{line},{col}]", {
|
||||||
|
line: label.start.line,
|
||||||
|
col: label.start.col
|
||||||
|
}));
|
||||||
|
test[label.name] = ctor.apply(null, body.args.map(function(node) {
|
||||||
|
assert.ok(node instanceof U.AST_Constant, tmpl("Unsupported expect_stdout format [{line},{col}]", {
|
||||||
|
line: label.start.line,
|
||||||
|
col: label.start.col
|
||||||
|
}));
|
||||||
|
return node.value;
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
test[label.name] = read_string(stat) + "\n";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
test[label.name] = stat;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
block.walk(tw);
|
||||||
|
return test;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to reminify original input with standard options
|
||||||
|
// to see if it matches expect_stdout.
|
||||||
|
function reminify(orig_options, input_code, input_formatted, stdout) {
|
||||||
|
for (var i = 0; i < minify_options.length; i++) {
|
||||||
|
var options = JSON.parse(minify_options[i]);
|
||||||
|
if (options.compress) [
|
||||||
|
"keep_fargs",
|
||||||
|
"keep_fnames",
|
||||||
|
].forEach(function(name) {
|
||||||
|
if (name in orig_options) {
|
||||||
|
options.compress[name] = orig_options[name];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var options_formatted = JSON.stringify(options, null, 4);
|
||||||
|
options.validate = true;
|
||||||
|
var result = U.minify(input_code, options);
|
||||||
|
if (result.error) {
|
||||||
|
log([
|
||||||
|
"!!! failed input reminify",
|
||||||
|
"---INPUT---",
|
||||||
|
"{input}",
|
||||||
|
"---OPTIONS---",
|
||||||
|
"{options}",
|
||||||
|
"--ERROR---",
|
||||||
|
"{error}",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
].join("\n"), {
|
||||||
|
input: input_formatted,
|
||||||
|
options: options_formatted,
|
||||||
|
error: result.error,
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
var toplevel = sandbox.has_toplevel(options);
|
||||||
|
var expected = stdout[toplevel ? 1 : 0];
|
||||||
|
var actual = run_code(result.code, toplevel);
|
||||||
|
if (typeof expected != "string" && typeof actual != "string" && expected.name == actual.name) {
|
||||||
|
actual = expected;
|
||||||
|
}
|
||||||
|
if (!sandbox.same_stdout(expected, actual)) {
|
||||||
|
log([
|
||||||
|
"!!! failed running reminified input",
|
||||||
|
"---INPUT---",
|
||||||
|
"{input}",
|
||||||
|
"---OPTIONS---",
|
||||||
|
"{options}",
|
||||||
|
"---OUTPUT---",
|
||||||
|
"{output}",
|
||||||
|
"---EXPECTED {expected_type}---",
|
||||||
|
"{expected}",
|
||||||
|
"---ACTUAL {actual_type}---",
|
||||||
|
"{actual}",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
].join("\n"), {
|
||||||
|
input: input_formatted,
|
||||||
|
options: options_formatted,
|
||||||
|
output: result.code,
|
||||||
|
expected_type: typeof expected == "string" ? "STDOUT" : "ERROR",
|
||||||
|
expected: expected,
|
||||||
|
actual_type: typeof actual == "string" ? "STDOUT" : "ERROR",
|
||||||
|
actual: actual,
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_code(code, toplevel) {
|
||||||
|
var result = sandbox.run_code(code, toplevel);
|
||||||
|
return typeof result == "string" ? result.replace(/\u001b\[\d+m/g, "") : result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_case(test) {
|
||||||
|
log(" Running test [{name}]", { name: test.name });
|
||||||
|
U.AST_Node.enable_validation();
|
||||||
|
var output_options = test.beautify || {};
|
||||||
|
var expect;
|
||||||
|
if (test.expect) {
|
||||||
|
expect = make_code(to_toplevel(test.expect, test.mangle), output_options);
|
||||||
|
} else {
|
||||||
|
expect = test.expect_exact;
|
||||||
|
}
|
||||||
|
var input = to_toplevel(test.input, test.mangle);
|
||||||
|
var input_code = make_code(input);
|
||||||
|
var input_formatted = make_code(test.input, {
|
||||||
|
beautify: true,
|
||||||
|
comments: "all",
|
||||||
|
keep_quoted_props: true,
|
||||||
|
quote_style: 3,
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
input.validate_ast();
|
||||||
|
U.parse(input_code);
|
||||||
|
} catch (ex) {
|
||||||
|
log([
|
||||||
|
"!!! Cannot parse input",
|
||||||
|
"---INPUT---",
|
||||||
|
"{input}",
|
||||||
|
"--PARSE ERROR--",
|
||||||
|
"{error}",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
].join("\n"), {
|
||||||
|
input: input_formatted,
|
||||||
|
error: ex,
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var warnings_emitted = [];
|
||||||
|
if (test.expect_warnings) {
|
||||||
|
var expected_warnings = make_code(test.expect_warnings, {
|
||||||
|
beautify: false,
|
||||||
|
quote_style: 2, // force double quote to match JSON
|
||||||
|
});
|
||||||
|
U.AST_Node.log_function(function(text) {
|
||||||
|
warnings_emitted.push(text);
|
||||||
|
}, /"INFO: /.test(expected_warnings));
|
||||||
|
}
|
||||||
|
if (test.mangle && test.mangle.properties && test.mangle.properties.keep_quoted) {
|
||||||
|
var quoted_props = test.mangle.properties.reserved;
|
||||||
|
if (!Array.isArray(quoted_props)) quoted_props = [];
|
||||||
|
test.mangle.properties.reserved = quoted_props;
|
||||||
|
U.reserve_quoted_keys(input, quoted_props);
|
||||||
|
}
|
||||||
|
if (test.rename) {
|
||||||
|
input.figure_out_scope(test.mangle);
|
||||||
|
input.expand_names(test.mangle);
|
||||||
|
}
|
||||||
|
var cmp = new U.Compressor(test.options, true);
|
||||||
|
var output = cmp.compress(input);
|
||||||
|
output.figure_out_scope(test.mangle);
|
||||||
|
if (test.mangle) {
|
||||||
|
output.compute_char_frequency(test.mangle);
|
||||||
|
output.mangle_names(test.mangle);
|
||||||
|
if (test.mangle.properties) U.mangle_properties(output, test.mangle.properties);
|
||||||
|
}
|
||||||
|
var output_code = make_code(output, output_options);
|
||||||
|
if (expect != output_code) {
|
||||||
|
log([
|
||||||
|
"!!! failed",
|
||||||
|
"---INPUT---",
|
||||||
|
"{input}",
|
||||||
|
"---OUTPUT---",
|
||||||
|
"{output}",
|
||||||
|
"---EXPECTED---",
|
||||||
|
"{expected}",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
].join("\n"), {
|
||||||
|
input: input_formatted,
|
||||||
|
output: output_code,
|
||||||
|
expected: expect
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// expect == output
|
||||||
|
try {
|
||||||
|
output.validate_ast();
|
||||||
|
U.parse(output_code);
|
||||||
|
} catch (ex) {
|
||||||
|
log([
|
||||||
|
"!!! Test matched expected result but cannot parse output",
|
||||||
|
"---INPUT---",
|
||||||
|
"{input}",
|
||||||
|
"---OUTPUT---",
|
||||||
|
"{output}",
|
||||||
|
"--REPARSE ERROR--",
|
||||||
|
"{error}",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
].join("\n"), {
|
||||||
|
input: input_formatted,
|
||||||
|
output: output_code,
|
||||||
|
error: ex,
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (test.expect_warnings) {
|
||||||
|
warnings_emitted = warnings_emitted.map(function(input) {
|
||||||
|
return input.split(process.cwd() + path.sep).join("").split(path.sep).join("/");
|
||||||
|
});
|
||||||
|
var actual_warnings = JSON.stringify(warnings_emitted);
|
||||||
|
if (expected_warnings != actual_warnings) {
|
||||||
|
log([
|
||||||
|
"!!! failed",
|
||||||
|
"---INPUT---",
|
||||||
|
"{input}",
|
||||||
|
"---EXPECTED WARNINGS---",
|
||||||
|
"{expected_warnings}",
|
||||||
|
"---ACTUAL WARNINGS---",
|
||||||
|
"{actual_warnings}",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
].join("\n"), {
|
||||||
|
input: input_formatted,
|
||||||
|
expected_warnings: expected_warnings,
|
||||||
|
actual_warnings: actual_warnings,
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (test.expect_stdout && (!test.node_version || semver.satisfies(process.version, test.node_version))) {
|
||||||
|
var stdout = [ run_code(input_code), run_code(input_code, true) ];
|
||||||
|
var toplevel = sandbox.has_toplevel({
|
||||||
|
compress: test.options,
|
||||||
|
mangle: test.mangle
|
||||||
|
});
|
||||||
|
var actual = stdout[toplevel ? 1 : 0];
|
||||||
|
if (test.expect_stdout === true) {
|
||||||
|
test.expect_stdout = actual;
|
||||||
|
}
|
||||||
|
if (!sandbox.same_stdout(test.expect_stdout, actual)) {
|
||||||
|
log([
|
||||||
|
"!!! Invalid input or expected stdout",
|
||||||
|
"---INPUT---",
|
||||||
|
"{input}",
|
||||||
|
"---EXPECTED {expected_type}---",
|
||||||
|
"{expected}",
|
||||||
|
"---ACTUAL {actual_type}---",
|
||||||
|
"{actual}",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
].join("\n"), {
|
||||||
|
input: input_formatted,
|
||||||
|
expected_type: typeof test.expect_stdout == "string" ? "STDOUT" : "ERROR",
|
||||||
|
expected: test.expect_stdout,
|
||||||
|
actual_type: typeof actual == "string" ? "STDOUT" : "ERROR",
|
||||||
|
actual: actual,
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
actual = run_code(output_code, toplevel);
|
||||||
|
if (!sandbox.same_stdout(test.expect_stdout, actual)) {
|
||||||
|
log([
|
||||||
|
"!!! failed",
|
||||||
|
"---INPUT---",
|
||||||
|
"{input}",
|
||||||
|
"---EXPECTED {expected_type}---",
|
||||||
|
"{expected}",
|
||||||
|
"---ACTUAL {actual_type}---",
|
||||||
|
"{actual}",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
].join("\n"), {
|
||||||
|
input: input_formatted,
|
||||||
|
expected_type: typeof test.expect_stdout == "string" ? "STDOUT" : "ERROR",
|
||||||
|
expected: test.expect_stdout,
|
||||||
|
actual_type: typeof actual == "string" ? "STDOUT" : "ERROR",
|
||||||
|
actual: actual,
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!reminify(test.options, input_code, input_formatted, stdout)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function tmpl() {
|
||||||
|
return U.string_template.apply(null, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
function to_toplevel(input, mangle_options) {
|
||||||
|
if (!(input instanceof U.AST_BlockStatement)) throw new Error("Unsupported input syntax");
|
||||||
|
var directive = true;
|
||||||
|
var offset = input.start.line;
|
||||||
|
var tokens = [];
|
||||||
|
var toplevel = new U.AST_Toplevel(input.transform(new U.TreeTransformer(function(node) {
|
||||||
|
if (U.push_uniq(tokens, node.start)) node.start.line -= offset;
|
||||||
|
if (!directive || node === input) return;
|
||||||
|
if (node instanceof U.AST_SimpleStatement && node.body instanceof U.AST_String) {
|
||||||
|
return new U.AST_Directive(node.body);
|
||||||
|
} else {
|
||||||
|
directive = false;
|
||||||
|
}
|
||||||
|
})));
|
||||||
|
toplevel.figure_out_scope(mangle_options);
|
||||||
|
return toplevel;
|
||||||
|
}
|
||||||
809
test/compress/arguments.js
Normal file
809
test/compress/arguments.js
Normal file
@@ -0,0 +1,809 @@
|
|||||||
|
replace_index: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
evaluate: true,
|
||||||
|
properties: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var arguments = [];
|
||||||
|
console.log(arguments[0]);
|
||||||
|
(function() {
|
||||||
|
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||||
|
})("bar", 42);
|
||||||
|
(function(a, b) {
|
||||||
|
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||||
|
})("bar", 42);
|
||||||
|
(function(arguments) {
|
||||||
|
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||||
|
})("bar", 42);
|
||||||
|
(function() {
|
||||||
|
var arguments;
|
||||||
|
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||||
|
})("bar", 42);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var arguments = [];
|
||||||
|
console.log(arguments[0]);
|
||||||
|
(function() {
|
||||||
|
console.log(arguments[1], arguments[1], arguments.foo);
|
||||||
|
})("bar", 42);
|
||||||
|
(function(a, b) {
|
||||||
|
console.log(b, b, arguments.foo);
|
||||||
|
})("bar", 42);
|
||||||
|
(function(arguments) {
|
||||||
|
console.log(arguments[1], arguments[1], arguments.foo);
|
||||||
|
})("bar", 42);
|
||||||
|
(function() {
|
||||||
|
var arguments;
|
||||||
|
console.log(arguments[1], arguments[1], arguments.foo);
|
||||||
|
})("bar", 42);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"undefined",
|
||||||
|
"42 42 undefined",
|
||||||
|
"42 42 undefined",
|
||||||
|
"a a undefined",
|
||||||
|
"42 42 undefined",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
replace_index_strict: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
evaluate: true,
|
||||||
|
properties: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
(function() {
|
||||||
|
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||||
|
})("bar", 42);
|
||||||
|
(function(a, b) {
|
||||||
|
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||||
|
})("bar", 42);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
(function() {
|
||||||
|
console.log(arguments[1], arguments[1], arguments.foo);
|
||||||
|
})("bar", 42);
|
||||||
|
(function(a, b) {
|
||||||
|
console.log(b, b, arguments.foo);
|
||||||
|
})("bar", 42);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"42 42 undefined",
|
||||||
|
"42 42 undefined",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
replace_index_keep_fargs: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
evaluate: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
properties: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var arguments = [];
|
||||||
|
console.log(arguments[0]);
|
||||||
|
(function() {
|
||||||
|
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||||
|
})("bar", 42);
|
||||||
|
(function(a, b) {
|
||||||
|
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||||
|
})("bar", 42);
|
||||||
|
(function(arguments) {
|
||||||
|
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||||
|
})("bar", 42);
|
||||||
|
(function() {
|
||||||
|
var arguments;
|
||||||
|
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||||
|
})("bar", 42);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var arguments = [];
|
||||||
|
console.log(arguments[0]);
|
||||||
|
(function(argument_0, argument_1) {
|
||||||
|
console.log(argument_1, argument_1, arguments.foo);
|
||||||
|
})("bar", 42);
|
||||||
|
(function(a, b) {
|
||||||
|
console.log(b, b, arguments.foo);
|
||||||
|
})("bar", 42);
|
||||||
|
(function(arguments) {
|
||||||
|
console.log(arguments[1], arguments[1], arguments.foo);
|
||||||
|
})("bar", 42);
|
||||||
|
(function() {
|
||||||
|
var arguments;
|
||||||
|
console.log(arguments[1], arguments[1], arguments.foo);
|
||||||
|
})("bar", 42);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"undefined",
|
||||||
|
"42 42 undefined",
|
||||||
|
"42 42 undefined",
|
||||||
|
"a a undefined",
|
||||||
|
"42 42 undefined",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
replace_index_keep_fargs_strict: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
evaluate: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
properties: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
(function() {
|
||||||
|
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||||
|
})("bar", 42);
|
||||||
|
(function(a, b) {
|
||||||
|
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||||
|
})("bar", 42);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
(function(argument_0, argument_1) {
|
||||||
|
console.log(argument_1, argument_1, arguments.foo);
|
||||||
|
})("bar", 42);
|
||||||
|
(function(a, b) {
|
||||||
|
console.log(b, b, arguments.foo);
|
||||||
|
})("bar", 42);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"42 42 undefined",
|
||||||
|
"42 42 undefined",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
modified: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a, b) {
|
||||||
|
var c = arguments[0];
|
||||||
|
var d = arguments[1];
|
||||||
|
var a = "foo";
|
||||||
|
b++;
|
||||||
|
arguments[0] = "moo";
|
||||||
|
arguments[1] *= 2;
|
||||||
|
console.log(a, b, c, d, arguments[0], arguments[1]);
|
||||||
|
})("bar", 42);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a, b) {
|
||||||
|
var c = a;
|
||||||
|
var d = b;
|
||||||
|
var a = "foo";
|
||||||
|
b++;
|
||||||
|
a = "moo";
|
||||||
|
b *= 2;
|
||||||
|
console.log(a, b, c, d, a, b);
|
||||||
|
})("bar", 42);
|
||||||
|
}
|
||||||
|
expect_stdout: "moo 86 bar 42 moo 86"
|
||||||
|
}
|
||||||
|
|
||||||
|
modified_strict: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
(function(a, b) {
|
||||||
|
var c = arguments[0];
|
||||||
|
var d = arguments[1];
|
||||||
|
var a = "foo";
|
||||||
|
b++;
|
||||||
|
arguments[0] = "moo";
|
||||||
|
arguments[1] *= 2;
|
||||||
|
console.log(a, b, c, d, arguments[0], arguments[1]);
|
||||||
|
})("bar", 42);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
(function(a, b) {
|
||||||
|
var c = arguments[0];
|
||||||
|
var d = arguments[1];
|
||||||
|
var a = "foo";
|
||||||
|
b++;
|
||||||
|
arguments[0] = "moo";
|
||||||
|
arguments[1] *= 2;
|
||||||
|
console.log(a, b, c, d, arguments[0], arguments[1]);
|
||||||
|
})("bar", 42);
|
||||||
|
}
|
||||||
|
expect_stdout: "foo 43 bar 42 moo 84"
|
||||||
|
}
|
||||||
|
|
||||||
|
duplicate_argname: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a, b, a) {
|
||||||
|
console.log(a, b, arguments[0], arguments[1], arguments[2]);
|
||||||
|
})("foo", 42, "bar");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a, b, a) {
|
||||||
|
console.log(a, b, arguments[0], b, a);
|
||||||
|
})("foo", 42, "bar");
|
||||||
|
}
|
||||||
|
expect_stdout: "bar 42 foo 42 bar"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3273: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a) {
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
arguments[0]++;
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
})(0);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a) {
|
||||||
|
console.log(a, a);
|
||||||
|
a++;
|
||||||
|
console.log(a, a);
|
||||||
|
})(0);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"0 0",
|
||||||
|
"1 1",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3273_no_call_arg: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a) {
|
||||||
|
arguments[0] = "FAIL";
|
||||||
|
console.log(a);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a) {
|
||||||
|
arguments[0] = "FAIL";
|
||||||
|
console.log(a);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3273_reduce_vars: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a) {
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
arguments[0]++;
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
})(0);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a) {
|
||||||
|
console.log(a, a);
|
||||||
|
a++;
|
||||||
|
console.log(a, a);
|
||||||
|
})(0);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"0 0",
|
||||||
|
"1 1",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3273_local_strict: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a) {
|
||||||
|
"use strict";
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
arguments[0]++;
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
})(0);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a) {
|
||||||
|
"use strict";
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
arguments[0]++;
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
})(0);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"0 0",
|
||||||
|
"1 0",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3273_local_strict_reduce_vars: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a) {
|
||||||
|
"use strict";
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
arguments[0]++;
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
})(0);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a) {
|
||||||
|
"use strict";
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
arguments[0]++;
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
})(0);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"0 0",
|
||||||
|
"1 0",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3273_global_strict: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
(function(a) {
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
arguments[0]++;
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
})(0);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
(function(a) {
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
arguments[0]++;
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
})(0);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"0 0",
|
||||||
|
"1 0",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3273_global_strict_reduce_vars: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
(function(a) {
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
arguments[0]++;
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
})(0);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
(function(a) {
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
arguments[0]++;
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
})(0);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"0 0",
|
||||||
|
"1 0",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3273_keep_fargs_false: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
"use strict";
|
||||||
|
arguments[0]++;
|
||||||
|
console.log(arguments[0]);
|
||||||
|
})(0);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(argument_0) {
|
||||||
|
"use strict";
|
||||||
|
argument_0++;
|
||||||
|
console.log(argument_0);
|
||||||
|
})(0);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3273_keep_fargs_strict: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
keep_fargs: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
"use strict";
|
||||||
|
arguments[0]++;
|
||||||
|
console.log(arguments[0]);
|
||||||
|
})(0);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(argument_0) {
|
||||||
|
"use strict";
|
||||||
|
argument_0++;
|
||||||
|
console.log(argument_0);
|
||||||
|
})(0);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3282_1: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(t) {
|
||||||
|
return function() {
|
||||||
|
t();
|
||||||
|
};
|
||||||
|
})(function() {
|
||||||
|
'use strict';
|
||||||
|
function e() {
|
||||||
|
return arguments[0];
|
||||||
|
}
|
||||||
|
e();
|
||||||
|
e();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
return function() {
|
||||||
|
(function() {
|
||||||
|
"use strict";
|
||||||
|
function e() {
|
||||||
|
return arguments[0];
|
||||||
|
}
|
||||||
|
e();
|
||||||
|
e();
|
||||||
|
})();
|
||||||
|
};
|
||||||
|
})()();
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3282_1_passes: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
passes: 2,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(t) {
|
||||||
|
return function() {
|
||||||
|
t();
|
||||||
|
};
|
||||||
|
})(function() {
|
||||||
|
'use strict';
|
||||||
|
function e() {
|
||||||
|
return arguments[0];
|
||||||
|
}
|
||||||
|
e();
|
||||||
|
e();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
return function() {
|
||||||
|
(function() {
|
||||||
|
"use strict";
|
||||||
|
function e(argument_0) {
|
||||||
|
return argument_0;
|
||||||
|
}
|
||||||
|
e();
|
||||||
|
e();
|
||||||
|
})();
|
||||||
|
};
|
||||||
|
})()();
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3282_2: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(f) {
|
||||||
|
f();
|
||||||
|
})(function() {
|
||||||
|
return (function(t) {
|
||||||
|
return function() {
|
||||||
|
t();
|
||||||
|
};
|
||||||
|
})(function() {
|
||||||
|
'use strict';
|
||||||
|
function e() {
|
||||||
|
return arguments[0];
|
||||||
|
}
|
||||||
|
e();
|
||||||
|
e();
|
||||||
|
})();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
(function() {
|
||||||
|
return function(t) {
|
||||||
|
return function() {
|
||||||
|
t();
|
||||||
|
};
|
||||||
|
}(function() {
|
||||||
|
"use strict";
|
||||||
|
function e() {
|
||||||
|
return arguments[0];
|
||||||
|
}
|
||||||
|
e();
|
||||||
|
e();
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3282_2_passes: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
passes: 2,
|
||||||
|
reduce_vars: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(f) {
|
||||||
|
f();
|
||||||
|
})(function() {
|
||||||
|
return (function(t) {
|
||||||
|
return function() {
|
||||||
|
t();
|
||||||
|
};
|
||||||
|
})(function() {
|
||||||
|
'use strict';
|
||||||
|
function e() {
|
||||||
|
return arguments[0];
|
||||||
|
}
|
||||||
|
e();
|
||||||
|
e();
|
||||||
|
})();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
(function() {
|
||||||
|
return function(t) {
|
||||||
|
return function() {
|
||||||
|
t();
|
||||||
|
};
|
||||||
|
}(function() {
|
||||||
|
"use strict";
|
||||||
|
function e(argument_0) {
|
||||||
|
return argument_0;
|
||||||
|
}
|
||||||
|
e();
|
||||||
|
e();
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3420_1: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
keep_fargs: "strict",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
return function() {
|
||||||
|
return arguments[0];
|
||||||
|
};
|
||||||
|
}().length);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
return function() {
|
||||||
|
return arguments[0];
|
||||||
|
};
|
||||||
|
}().length);
|
||||||
|
}
|
||||||
|
expect_stdout: "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3420_2: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
keep_fargs: "strict",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var foo = function() {
|
||||||
|
delete arguments[0];
|
||||||
|
};
|
||||||
|
foo();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var foo = function() {
|
||||||
|
delete arguments[0];
|
||||||
|
};
|
||||||
|
foo();
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3420_3: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
keep_fargs: "strict",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
var foo = function() {
|
||||||
|
delete arguments[0];
|
||||||
|
};
|
||||||
|
foo();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
var foo = function() {
|
||||||
|
delete arguments[0];
|
||||||
|
};
|
||||||
|
foo();
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3420_4: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
keep_fargs: "strict",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
!function() {
|
||||||
|
console.log(arguments[0]);
|
||||||
|
delete arguments[0];
|
||||||
|
console.log(arguments[0]);
|
||||||
|
}(42);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function(argument_0) {
|
||||||
|
console.log(argument_0);
|
||||||
|
delete arguments[0];
|
||||||
|
console.log(arguments[0]);
|
||||||
|
}(42);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"42",
|
||||||
|
"undefined",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3420_5: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
keep_fargs: "strict",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
!function() {
|
||||||
|
console.log(arguments[0]);
|
||||||
|
delete arguments[0];
|
||||||
|
console.log(arguments[0]);
|
||||||
|
}(42);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
!function(argument_0) {
|
||||||
|
console.log(argument_0);
|
||||||
|
delete arguments[0];
|
||||||
|
console.log(arguments[0]);
|
||||||
|
}(42);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"42",
|
||||||
|
"undefined",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3420_6: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
keep_fargs: "strict",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
return delete arguments[0];
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
return delete arguments[0];
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "true"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3420_7: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
keep_fargs: "strict",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
console.log(function() {
|
||||||
|
return delete arguments[0];
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
console.log(function() {
|
||||||
|
return delete arguments[0];
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "true"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4200: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
get p() {
|
||||||
|
return arguments[0];
|
||||||
|
},
|
||||||
|
};
|
||||||
|
console.log(o.p);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
get p() {
|
||||||
|
return arguments[0];
|
||||||
|
},
|
||||||
|
};
|
||||||
|
console.log(o.p);
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
@@ -15,9 +15,10 @@ holes_and_undefined: {
|
|||||||
|
|
||||||
constant_join: {
|
constant_join: {
|
||||||
options = {
|
options = {
|
||||||
unsafe : true,
|
evaluate: true,
|
||||||
evaluate : true
|
strings: true,
|
||||||
};
|
unsafe: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = [ "foo", "bar", "baz" ].join("");
|
var a = [ "foo", "bar", "baz" ].join("");
|
||||||
var a1 = [ "foo", "bar", "baz" ].join();
|
var a1 = [ "foo", "bar", "baz" ].join();
|
||||||
@@ -64,9 +65,10 @@ constant_join: {
|
|||||||
|
|
||||||
constant_join_2: {
|
constant_join_2: {
|
||||||
options = {
|
options = {
|
||||||
unsafe : true,
|
evaluate: true,
|
||||||
evaluate : true
|
strings: true,
|
||||||
};
|
unsafe: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = [ "foo", "bar", boo(), "baz", "x", "y" ].join("");
|
var a = [ "foo", "bar", boo(), "baz", "x", "y" ].join("");
|
||||||
var b = [ "foo", "bar", boo(), "baz", "x", "y" ].join("-");
|
var b = [ "foo", "bar", boo(), "baz", "x", "y" ].join("-");
|
||||||
@@ -93,10 +95,12 @@ constant_join_2: {
|
|||||||
|
|
||||||
constant_join_3: {
|
constant_join_3: {
|
||||||
options = {
|
options = {
|
||||||
unsafe: true,
|
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
};
|
strings: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
|
var foo, bar, baz;
|
||||||
var a = [ null ].join();
|
var a = [ null ].join();
|
||||||
var b = [ , ].join();
|
var b = [ , ].join();
|
||||||
var c = [ , 1, , 3 ].join();
|
var c = [ , 1, , 3 ].join();
|
||||||
@@ -111,6 +115,7 @@ constant_join_3: {
|
|||||||
var l = [ foo, bar + "baz" ].join("");
|
var l = [ foo, bar + "baz" ].join("");
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
|
var foo, bar, baz;
|
||||||
var a = "";
|
var a = "";
|
||||||
var b = "";
|
var b = "";
|
||||||
var c = ",1,,3";
|
var c = ",1,,3";
|
||||||
@@ -128,50 +133,224 @@ constant_join_3: {
|
|||||||
|
|
||||||
for_loop: {
|
for_loop: {
|
||||||
options = {
|
options = {
|
||||||
unsafe : true,
|
evaluate: true,
|
||||||
unused : true,
|
reduce_funcs: true,
|
||||||
evaluate : true,
|
reduce_vars: true,
|
||||||
reduce_vars : true
|
unsafe: true,
|
||||||
};
|
unused: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
function f0() {
|
function f0() {
|
||||||
var a = [1, 2, 3];
|
var a = [1, 2, 3];
|
||||||
for (var i = 0; i < a.length; i++) {
|
var b = 0;
|
||||||
console.log(a[i]);
|
for (var i = 0; i < a.length; i++)
|
||||||
}
|
b += a[i];
|
||||||
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
function f1() {
|
function f1() {
|
||||||
var a = [1, 2, 3];
|
var a = [1, 2, 3];
|
||||||
for (var i = 0, len = a.length; i < len; i++) {
|
var b = 0;
|
||||||
console.log(a[i]);
|
for (var i = 0, len = a.length; i < len; i++)
|
||||||
}
|
b += a[i];
|
||||||
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
function f2() {
|
|
||||||
var a = [1, 2, 3];
|
|
||||||
for (var i = 0; i < a.length; i++) {
|
|
||||||
a[i]++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
function f0() {
|
|
||||||
var a = [1, 2, 3];
|
|
||||||
for (var i = 0; i < 3; i++)
|
|
||||||
console.log(a[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
function f1() {
|
|
||||||
var a = [1, 2, 3];
|
|
||||||
for (var i = 0; i < 3; i++)
|
|
||||||
console.log(a[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
function f2() {
|
function f2() {
|
||||||
var a = [1, 2, 3];
|
var a = [1, 2, 3];
|
||||||
for (var i = 0; i < a.length; i++)
|
for (var i = 0; i < a.length; i++)
|
||||||
a[i]++;
|
a[i]++;
|
||||||
|
return a[2];
|
||||||
|
}
|
||||||
|
console.log(f0(), f1(), f2());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f0() {
|
||||||
|
var a = [1, 2, 3];
|
||||||
|
var b = 0;
|
||||||
|
for (var i = 0; i < 3; i++)
|
||||||
|
b += a[i];
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
function f1() {
|
||||||
|
var a = [1, 2, 3];
|
||||||
|
var b = 0;
|
||||||
|
for (var i = 0; i < 3; i++)
|
||||||
|
b += a[i];
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
function f2() {
|
||||||
|
var a = [1, 2, 3];
|
||||||
|
for (var i = 0; i < a.length; i++)
|
||||||
|
a[i]++;
|
||||||
|
return a[2];
|
||||||
|
}
|
||||||
|
console.log(f0(), f1(), f2());
|
||||||
|
}
|
||||||
|
expect_stdout: "6 6 4"
|
||||||
|
}
|
||||||
|
|
||||||
|
index: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unsafe: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = [ 1, 2 ];
|
||||||
|
console.log(a[0], a[1]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(1, 2);
|
||||||
|
}
|
||||||
|
expect_stdout: "1 2"
|
||||||
|
}
|
||||||
|
|
||||||
|
length: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unsafe: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = [ 1, 2 ];
|
||||||
|
console.log(a.length);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(2);
|
||||||
|
}
|
||||||
|
expect_stdout: "2"
|
||||||
|
}
|
||||||
|
|
||||||
|
index_length: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unsafe: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = [ 1, 2 ];
|
||||||
|
console.log(a[0], a.length);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(1, 2);
|
||||||
|
}
|
||||||
|
expect_stdout: "1 2"
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor_bad: {
|
||||||
|
options = {
|
||||||
|
unsafe: true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
Array(NaN);
|
||||||
|
console.log("FAIL1");
|
||||||
|
} catch (ex) {
|
||||||
|
try {
|
||||||
|
new Array(NaN);
|
||||||
|
console.log("FAIL2");
|
||||||
|
} catch (ex) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Array(3.14);
|
||||||
|
console.log("FAIL1");
|
||||||
|
} catch (ex) {
|
||||||
|
try {
|
||||||
|
new Array(3.14);
|
||||||
|
console.log("FAIL2");
|
||||||
|
} catch (ex) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
Array(NaN);
|
||||||
|
console.log("FAIL1");
|
||||||
|
} catch (ex) {
|
||||||
|
try {
|
||||||
|
Array(NaN);
|
||||||
|
console.log("FAIL2");
|
||||||
|
} catch (ex) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Array(3.14);
|
||||||
|
console.log("FAIL1");
|
||||||
|
} catch (ex) {
|
||||||
|
try {
|
||||||
|
Array(3.14);
|
||||||
|
console.log("FAIL2");
|
||||||
|
} catch (ex) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"PASS",
|
||||||
|
"PASS",
|
||||||
|
]
|
||||||
|
expect_warnings: [
|
||||||
|
"WARN: Invalid array length: 3.14 [test/compress/arrays.js:13,12]",
|
||||||
|
"WARN: Invalid array length: 3.14 [test/compress/arrays.js:17,16]",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor_good: {
|
||||||
|
options = {
|
||||||
|
unsafe: true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(Array());
|
||||||
|
console.log(Array(0));
|
||||||
|
console.log(Array(1));
|
||||||
|
console.log(Array(6));
|
||||||
|
console.log(Array(7));
|
||||||
|
console.log(Array(1, 2));
|
||||||
|
console.log(Array(false));
|
||||||
|
console.log(Array("foo"));
|
||||||
|
console.log(Array(Array));
|
||||||
|
console.log(new Array());
|
||||||
|
console.log(new Array(0));
|
||||||
|
console.log(new Array(1));
|
||||||
|
console.log(new Array(6));
|
||||||
|
console.log(new Array(7));
|
||||||
|
console.log(new Array(1, 2));
|
||||||
|
console.log(new Array(false));
|
||||||
|
console.log(new Array("foo"));
|
||||||
|
console.log(new Array(Array));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log([]);
|
||||||
|
console.log([]);
|
||||||
|
console.log([,]);
|
||||||
|
console.log([,,,,,,]);
|
||||||
|
console.log(Array(7));
|
||||||
|
console.log([ 1, 2 ]);
|
||||||
|
console.log([ false ]);
|
||||||
|
console.log([ "foo" ]);
|
||||||
|
console.log(Array(Array));
|
||||||
|
console.log([]);
|
||||||
|
console.log([]);
|
||||||
|
console.log([,]);
|
||||||
|
console.log([,,,,,,]);
|
||||||
|
console.log(Array(7));
|
||||||
|
console.log([ 1, 2 ]);
|
||||||
|
console.log([ false ]);
|
||||||
|
console.log([ "foo" ]);
|
||||||
|
console.log(Array(Array));
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
expect_warnings: []
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ ascii_only_true: {
|
|||||||
"\x20\x21\x22\x23 ... \x7d\x7e\x7f\x80\x81 ... \xfe\xff\u0fff\uffff";
|
"\x20\x21\x22\x23 ... \x7d\x7e\x7f\x80\x81 ... \xfe\xff\u0fff\uffff";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect_exact: 'function f(){return"\\x000\\x001\\x007\\08\\0"+"\\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\b\\t\\n\\v\\f\\r\\x0e\\x0f"+"\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f"+\' !"# ... }~\\x7f\\x80\\x81 ... \\xfe\\xff\\u0fff\\uffff\'}'
|
expect_exact: 'function f(){return"\\x000\\x001\\x007\\x008\\0"+"\\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\b\\t\\n\\v\\f\\r\\x0e\\x0f"+"\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f"+\' !"# ... }~\\x7f\\x80\\x81 ... \\xfe\\xff\\u0fff\\uffff\'}'
|
||||||
}
|
}
|
||||||
|
|
||||||
ascii_only_false: {
|
ascii_only_false: {
|
||||||
@@ -31,5 +31,5 @@ ascii_only_false: {
|
|||||||
"\x20\x21\x22\x23 ... \x7d\x7e\x7f\x80\x81 ... \xfe\xff\u0fff\uffff";
|
"\x20\x21\x22\x23 ... \x7d\x7e\x7f\x80\x81 ... \xfe\xff\u0fff\uffff";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect_exact: 'function f(){return"\\x000\\x001\\x007\\08\\0"+"\\0\x01\x02\x03\x04\x05\x06\x07\\b\\t\\n\\v\\f\\r\x0e\x0f"+"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"+\' !"# ... }~\x7f\x80\x81 ... \xfe\xff\u0fff\uffff\'}'
|
expect_exact: 'function f(){return"\\x000\\x001\\x007\\x008\\0"+"\\0\x01\x02\x03\x04\x05\x06\x07\\b\\t\\n\\v\\f\\r\x0e\x0f"+"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"+\' !"# ... }~\x7f\x80\x81 ... \xfe\xff\u0fff\uffff\'}'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,25 +1,25 @@
|
|||||||
asm_mixed: {
|
asm_mixed: {
|
||||||
options = {
|
options = {
|
||||||
sequences : true,
|
assignments: true,
|
||||||
properties : true,
|
booleans: true,
|
||||||
dead_code : true,
|
comparisons: true,
|
||||||
drop_debugger : true,
|
conditionals: true,
|
||||||
conditionals : true,
|
dead_code: true,
|
||||||
comparisons : true,
|
drop_debugger: true,
|
||||||
evaluate : true,
|
evaluate: true,
|
||||||
booleans : true,
|
hoist_funs: true,
|
||||||
loops : true,
|
hoist_vars: true,
|
||||||
unused : true,
|
if_return: true,
|
||||||
hoist_funs : true,
|
join_vars: true,
|
||||||
keep_fargs : true,
|
keep_fargs: true,
|
||||||
keep_fnames : false,
|
keep_fnames: false,
|
||||||
hoist_vars : true,
|
loops: true,
|
||||||
if_return : true,
|
negate_iife: true,
|
||||||
join_vars : true,
|
properties: true,
|
||||||
cascade : true,
|
sequences: true,
|
||||||
side_effects : true,
|
side_effects: true,
|
||||||
negate_iife : true
|
unused: true,
|
||||||
};
|
}
|
||||||
input: {
|
input: {
|
||||||
// adapted from http://asmjs.org/spec/latest/
|
// adapted from http://asmjs.org/spec/latest/
|
||||||
function asm_GeometricMean(stdlib, foreign, buffer) {
|
function asm_GeometricMean(stdlib, foreign, buffer) {
|
||||||
@@ -76,9 +76,8 @@ asm_mixed: {
|
|||||||
start = start | 0;
|
start = start | 0;
|
||||||
end = end | 0;
|
end = end | 0;
|
||||||
var sum = 0.0, p = 0, q = 0;
|
var sum = 0.0, p = 0, q = 0;
|
||||||
for (p = start << 3, q = end << 3; (p | 0) < (q | 0); p = p + 8 | 0) {
|
for (p = start << 3, q = end << 3; (p | 0) < (q | 0); p = p + 8 | 0)
|
||||||
sum = sum + +log(values[p >> 3]);
|
sum = sum + +log(values[p >> 3]);
|
||||||
}
|
|
||||||
return +sum;
|
return +sum;
|
||||||
}
|
}
|
||||||
function geometricMean(start, end) {
|
function geometricMean(start, end) {
|
||||||
@@ -91,12 +90,12 @@ asm_mixed: {
|
|||||||
function no_asm_GeometricMean(stdlib, foreign, buffer) {
|
function no_asm_GeometricMean(stdlib, foreign, buffer) {
|
||||||
function logSum(start, end) {
|
function logSum(start, end) {
|
||||||
start |= 0, end |= 0;
|
start |= 0, end |= 0;
|
||||||
var sum = 0, p = 0, q = 0;
|
for (var sum = 0, p = 0, q = 0, p = start << 3, q = end << 3; (0 | p) < (0 | q); p = p + 8 | 0)
|
||||||
for (p = start << 3, q = end << 3; (0 | p) < (0 | q); p = p + 8 | 0) sum += +log(values[p >> 3]);
|
sum += +log(values[p >> 3]);
|
||||||
return +sum;
|
return +sum;
|
||||||
}
|
}
|
||||||
function geometricMean(start, end) {
|
function geometricMean(start, end) {
|
||||||
return start |= 0, end |= 0, +exp(+logSum(start, end) / +(end - start | 0));
|
return start |= 0, end |= 0, +exp(+logSum(start, end) / (end - start | 0));
|
||||||
}
|
}
|
||||||
var exp = stdlib.Math.exp, log = stdlib.Math.log, values = new stdlib.Float64Array(buffer);
|
var exp = stdlib.Math.exp, log = stdlib.Math.log, values = new stdlib.Float64Array(buffer);
|
||||||
return { geometricMean: geometricMean };
|
return { geometricMean: geometricMean };
|
||||||
@@ -104,3 +103,131 @@ asm_mixed: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
asm_toplevel: {
|
||||||
|
options = {}
|
||||||
|
input: {
|
||||||
|
"use asm";
|
||||||
|
0.0;
|
||||||
|
function f() {
|
||||||
|
0.0;
|
||||||
|
(function(){
|
||||||
|
0.0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
expect_exact: '"use asm";0.0;function f(){0.0;(function(){0.0})}0.0;'
|
||||||
|
}
|
||||||
|
|
||||||
|
asm_function_expression: {
|
||||||
|
options = {}
|
||||||
|
input: {
|
||||||
|
0.0;
|
||||||
|
var a = function() {
|
||||||
|
"use asm";
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
function f() {
|
||||||
|
0.0;
|
||||||
|
return function(){
|
||||||
|
"use asm";
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
expect_exact: '0;var a=function(){"use asm";0.0};function f(){0;return function(){"use asm";0.0};0}0;'
|
||||||
|
}
|
||||||
|
|
||||||
|
asm_nested_functions: {
|
||||||
|
options = {}
|
||||||
|
input: {
|
||||||
|
0.0;
|
||||||
|
function a() {
|
||||||
|
"use asm";
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
0.0;
|
||||||
|
function b() {
|
||||||
|
0.0;
|
||||||
|
function c(){
|
||||||
|
"use asm";
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
0.0;
|
||||||
|
function d(){
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
expect_exact: '0;function a(){"use asm";0.0}0;function b(){0;function c(){"use asm";0.0}0;function d(){0}0}0;'
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3636_1: {
|
||||||
|
mangle = {}
|
||||||
|
input: {
|
||||||
|
function n(stdlib, foreign, buffer) {
|
||||||
|
"use asm";
|
||||||
|
function add(x, y) {
|
||||||
|
x = x | 0;
|
||||||
|
y = y | 0;
|
||||||
|
return x + y | 0;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
add: add
|
||||||
|
};
|
||||||
|
}
|
||||||
|
console.log(new n().add("foo", 42));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function n(o, e, u) {
|
||||||
|
"use asm";
|
||||||
|
function d(n, o) {
|
||||||
|
n = n | 0;
|
||||||
|
o = o | 0;
|
||||||
|
return n + o | 0;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
add: d
|
||||||
|
};
|
||||||
|
}
|
||||||
|
console.log(new n().add("foo", 42));
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3636_2: {
|
||||||
|
mangle = {}
|
||||||
|
input: {
|
||||||
|
var n = function(stdlib, foreign, buffer) {
|
||||||
|
"use asm";
|
||||||
|
function add(x, y) {
|
||||||
|
x = x | 0;
|
||||||
|
y = y | 0;
|
||||||
|
return x + y | 0;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
add: add
|
||||||
|
};
|
||||||
|
};
|
||||||
|
console.log(new n().add("foo", 42));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var n = function(n, o, e) {
|
||||||
|
"use asm";
|
||||||
|
function r(n, o) {
|
||||||
|
n = n | 0;
|
||||||
|
o = o | 0;
|
||||||
|
return n + o | 0;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
add: r
|
||||||
|
};
|
||||||
|
};
|
||||||
|
console.log(new n().add("foo", 42));
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
op_equals_left_local_var: {
|
op_equals_left_local_var: {
|
||||||
options = {
|
options = {
|
||||||
|
assignments: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -60,6 +61,7 @@ op_equals_left_local_var: {
|
|||||||
|
|
||||||
op_equals_right_local_var: {
|
op_equals_right_local_var: {
|
||||||
options = {
|
options = {
|
||||||
|
assignments: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -123,6 +125,7 @@ op_equals_right_local_var: {
|
|||||||
}
|
}
|
||||||
op_equals_left_global_var: {
|
op_equals_left_global_var: {
|
||||||
options = {
|
options = {
|
||||||
|
assignments: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -179,6 +182,7 @@ op_equals_left_global_var: {
|
|||||||
|
|
||||||
op_equals_right_global_var: {
|
op_equals_right_global_var: {
|
||||||
options = {
|
options = {
|
||||||
|
assignments: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -236,3 +240,224 @@ op_equals_right_global_var: {
|
|||||||
x = g() & x;
|
x = g() & x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
increment_decrement_1: {
|
||||||
|
options = {
|
||||||
|
assignments: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a) {
|
||||||
|
a += 1;
|
||||||
|
a -= 1;
|
||||||
|
return a;
|
||||||
|
}(42));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a){
|
||||||
|
++a;
|
||||||
|
--a;
|
||||||
|
return a;
|
||||||
|
}(42));
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
increment_decrement_2: {
|
||||||
|
options = {
|
||||||
|
assignments: true,
|
||||||
|
passes: 2,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a) {
|
||||||
|
a = a + 1;
|
||||||
|
a = a - 1;
|
||||||
|
a += 1;
|
||||||
|
a -= 1;
|
||||||
|
return a;
|
||||||
|
}(42));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a){
|
||||||
|
++a;
|
||||||
|
--a;
|
||||||
|
++a;
|
||||||
|
--a;
|
||||||
|
return a;
|
||||||
|
}(42));
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3375_1: {
|
||||||
|
options = {
|
||||||
|
assignments: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function p(o) {
|
||||||
|
console.log(typeof o, o);
|
||||||
|
}
|
||||||
|
p(function(b) {
|
||||||
|
var a = b += 1;
|
||||||
|
--b;
|
||||||
|
return a;
|
||||||
|
}("object"));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function p(o) {
|
||||||
|
console.log(typeof o, o);
|
||||||
|
}
|
||||||
|
p(function(b) {
|
||||||
|
var a = b += 1;
|
||||||
|
--b;
|
||||||
|
return a;
|
||||||
|
}("object"));
|
||||||
|
}
|
||||||
|
expect_stdout: "string object1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3375_2: {
|
||||||
|
options = {
|
||||||
|
assignments: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function p(o) {
|
||||||
|
console.log(typeof o, o);
|
||||||
|
}
|
||||||
|
p(function(b) {
|
||||||
|
var a = b -= 1;
|
||||||
|
--b;
|
||||||
|
return a;
|
||||||
|
}("object"));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function p(o) {
|
||||||
|
console.log(typeof o, o);
|
||||||
|
}
|
||||||
|
p(function(b) {
|
||||||
|
var a = --b;
|
||||||
|
--b;
|
||||||
|
return a;
|
||||||
|
}("object"));
|
||||||
|
}
|
||||||
|
expect_stdout: "number NaN"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3427: {
|
||||||
|
options = {
|
||||||
|
assignments: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
var a;
|
||||||
|
a || (a = {});
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3429_1: {
|
||||||
|
options = {
|
||||||
|
assignments: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS";
|
||||||
|
(function(b) {
|
||||||
|
b && (b = a = "FAIL");
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "PASS";
|
||||||
|
(function(b) {
|
||||||
|
b = b && (a = "FAIL");
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3429_2: {
|
||||||
|
options = {
|
||||||
|
assignments: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
(function(b) {
|
||||||
|
b || (b = a = "FAIL");
|
||||||
|
})(42);
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
(function(b) {
|
||||||
|
b = b || (a = "FAIL");
|
||||||
|
})(42);
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3949_1: {
|
||||||
|
options = {
|
||||||
|
assignments: true,
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 42;
|
||||||
|
function f() {
|
||||||
|
var b = a;
|
||||||
|
b = b >> 2;
|
||||||
|
return 100 + b;
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 42;
|
||||||
|
function f() {
|
||||||
|
var b = a;
|
||||||
|
b >>= 2;
|
||||||
|
return 100 + b;
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
}
|
||||||
|
expect_stdout: "110"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3949_2: {
|
||||||
|
options = {
|
||||||
|
assignments: true,
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 42;
|
||||||
|
function f() {
|
||||||
|
var b = a;
|
||||||
|
b = 5 & b;
|
||||||
|
return 100 + b;
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 42;
|
||||||
|
function f() {
|
||||||
|
var b = a;
|
||||||
|
b &= 5;
|
||||||
|
return 100 + b;
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
}
|
||||||
|
expect_stdout: "100"
|
||||||
|
}
|
||||||
155
test/compress/booleans.js
Normal file
155
test/compress/booleans.js
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
iife_boolean_context: {
|
||||||
|
options = {
|
||||||
|
booleans: true,
|
||||||
|
evaluate: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
return Object(1) || false;
|
||||||
|
}() ? "PASS" : "FAIL");
|
||||||
|
console.log(function() {
|
||||||
|
return [].length || true;
|
||||||
|
}() ? "PASS" : "FAIL");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
return Object(1);
|
||||||
|
}() ? "PASS" : "FAIL");
|
||||||
|
console.log(function() {
|
||||||
|
return [].length, 1;
|
||||||
|
}() ? "PASS" : "FAIL");
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"PASS",
|
||||||
|
"PASS",
|
||||||
|
]
|
||||||
|
expect_warnings: [
|
||||||
|
"WARN: Dropping side-effect-free || [test/compress/booleans.js:2,19]",
|
||||||
|
"WARN: Boolean || always true [test/compress/booleans.js:5,19]",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3465_1: {
|
||||||
|
options = {
|
||||||
|
booleans: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a) {
|
||||||
|
return typeof a;
|
||||||
|
}() ? "PASS" : "FAIL");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a) {
|
||||||
|
return 1;
|
||||||
|
}() ? "PASS" : "FAIL");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3465_2: {
|
||||||
|
options = {
|
||||||
|
booleans: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function f(a) {
|
||||||
|
if (!a) console.log(f(42));
|
||||||
|
return typeof a;
|
||||||
|
}() ? "PASS" : "FAIL");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function f(a) {
|
||||||
|
if (!a) console.log(f(42));
|
||||||
|
return typeof a;
|
||||||
|
}() ? "PASS" : "FAIL");
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"number",
|
||||||
|
"PASS",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3465_3: {
|
||||||
|
options = {
|
||||||
|
booleans: true,
|
||||||
|
passes: 2,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function f(a) {
|
||||||
|
return typeof a;
|
||||||
|
}() ? "PASS" : "FAIL");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a) {
|
||||||
|
return 1;
|
||||||
|
}() ? "PASS" : "FAIL");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2737_2: {
|
||||||
|
options = {
|
||||||
|
booleans: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(bar) {
|
||||||
|
for (;bar();) break;
|
||||||
|
})(function qux() {
|
||||||
|
return console.log("PASS"), qux;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(bar) {
|
||||||
|
for (;bar();) break;
|
||||||
|
})(function() {
|
||||||
|
return console.log("PASS"), 1;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3658: {
|
||||||
|
options = {
|
||||||
|
booleans: true,
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function f() {
|
||||||
|
console || f();
|
||||||
|
return "PASS";
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function f() {
|
||||||
|
console || f();
|
||||||
|
return "PASS";
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3690: {
|
||||||
|
options = {
|
||||||
|
booleans: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a) {
|
||||||
|
return function() {
|
||||||
|
return a = [ this ];
|
||||||
|
}() ? "PASS" : "FAIL";
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a) {
|
||||||
|
return function() {
|
||||||
|
return 1;
|
||||||
|
}() ? "PASS" : "FAIL";
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,76 +0,0 @@
|
|||||||
keep_comparisons: {
|
|
||||||
options = {
|
|
||||||
comparisons: true,
|
|
||||||
unsafe_comps: false
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var obj1 = {
|
|
||||||
valueOf: function() {triggeredFirst();}
|
|
||||||
}
|
|
||||||
var obj2 = {
|
|
||||||
valueOf: function() {triggeredSecond();}
|
|
||||||
}
|
|
||||||
var result1 = obj1 <= obj2;
|
|
||||||
var result2 = obj1 < obj2;
|
|
||||||
var result3 = obj1 >= obj2;
|
|
||||||
var result4 = obj1 > obj2;
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var obj1 = {
|
|
||||||
valueOf: function() {triggeredFirst();}
|
|
||||||
}
|
|
||||||
var obj2 = {
|
|
||||||
valueOf: function() {triggeredSecond();}
|
|
||||||
}
|
|
||||||
var result1 = obj1 <= obj2;
|
|
||||||
var result2 = obj1 < obj2;
|
|
||||||
var result3 = obj1 >= obj2;
|
|
||||||
var result4 = obj1 > obj2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
keep_comparisons_with_unsafe_comps: {
|
|
||||||
options = {
|
|
||||||
comparisons: true,
|
|
||||||
unsafe_comps: true
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var obj1 = {
|
|
||||||
valueOf: function() {triggeredFirst();}
|
|
||||||
}
|
|
||||||
var obj2 = {
|
|
||||||
valueOf: function() {triggeredSecond();}
|
|
||||||
}
|
|
||||||
var result1 = obj1 <= obj2;
|
|
||||||
var result2 = obj1 < obj2;
|
|
||||||
var result3 = obj1 >= obj2;
|
|
||||||
var result4 = obj1 > obj2;
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var obj1 = {
|
|
||||||
valueOf: function() {triggeredFirst();}
|
|
||||||
}
|
|
||||||
var obj2 = {
|
|
||||||
valueOf: function() {triggeredSecond();}
|
|
||||||
}
|
|
||||||
var result1 = obj2 >= obj1;
|
|
||||||
var result2 = obj2 > obj1;
|
|
||||||
var result3 = obj1 >= obj2;
|
|
||||||
var result4 = obj1 > obj2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dont_change_in_or_instanceof_expressions: {
|
|
||||||
input: {
|
|
||||||
1 in 1;
|
|
||||||
null in null;
|
|
||||||
1 instanceof 1;
|
|
||||||
null instanceof null;
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
1 in 1;
|
|
||||||
null in null;
|
|
||||||
1 instanceof 1;
|
|
||||||
null instanceof null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
495
test/compress/comparisons.js
Normal file
495
test/compress/comparisons.js
Normal file
@@ -0,0 +1,495 @@
|
|||||||
|
comparisons: {
|
||||||
|
options = {
|
||||||
|
comparisons: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var obj1, obj2;
|
||||||
|
var result1 = obj1 <= obj2;
|
||||||
|
var result2 = obj1 < obj2;
|
||||||
|
var result3 = obj1 >= obj2;
|
||||||
|
var result4 = obj1 > obj2;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var obj1, obj2;
|
||||||
|
var result1 = obj1 <= obj2;
|
||||||
|
var result2 = obj1 < obj2;
|
||||||
|
var result3 = obj2 <= obj1;
|
||||||
|
var result4 = obj2 < obj1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe_comps: {
|
||||||
|
options = {
|
||||||
|
comparisons: true,
|
||||||
|
conditionals: true,
|
||||||
|
unsafe_comps: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var obj1, obj2;
|
||||||
|
obj1 <= obj2 ? f1() : g1();
|
||||||
|
obj1 < obj2 ? f2() : g2();
|
||||||
|
obj1 >= obj2 ? f3() : g3();
|
||||||
|
obj1 > obj2 ? f4() : g4();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var obj1, obj2;
|
||||||
|
(obj2 < obj1 ? g1 : f1)();
|
||||||
|
(obj1 < obj2 ? f2 : g2)();
|
||||||
|
(obj1 < obj2 ? g3 : f3)();
|
||||||
|
(obj2 < obj1 ? f4 : g4)();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dont_change_in_or_instanceof_expressions: {
|
||||||
|
input: {
|
||||||
|
1 in 1;
|
||||||
|
null in null;
|
||||||
|
1 instanceof 1;
|
||||||
|
null instanceof null;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
1 in 1;
|
||||||
|
null in null;
|
||||||
|
1 instanceof 1;
|
||||||
|
null instanceof null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self_comparison_1: {
|
||||||
|
options = {
|
||||||
|
comparisons: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
a === a;
|
||||||
|
a !== b;
|
||||||
|
b.c === a.c;
|
||||||
|
b.c !== b.c;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
a == a;
|
||||||
|
a !== b;
|
||||||
|
b.c === a.c;
|
||||||
|
b.c != b.c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self_comparison_2: {
|
||||||
|
options = {
|
||||||
|
comparisons: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {}
|
||||||
|
var o = {};
|
||||||
|
console.log(f != f, o === o);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {}
|
||||||
|
var o = {};
|
||||||
|
console.log(false, true);
|
||||||
|
}
|
||||||
|
expect_stdout: "false true"
|
||||||
|
}
|
||||||
|
|
||||||
|
self_comparison_3: {
|
||||||
|
options = {
|
||||||
|
comparisons: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
function f() {
|
||||||
|
var b = a;
|
||||||
|
a = null;
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
for (var i = 0; i < 2; i++)
|
||||||
|
console.log(f() === f());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
function f() {
|
||||||
|
var b = a;
|
||||||
|
a = null;
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
for (var i = 0; i < 2; i++)
|
||||||
|
console.log(f() === f());
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"false",
|
||||||
|
"true",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
self_comparison_4: {
|
||||||
|
options = {
|
||||||
|
booleans: true,
|
||||||
|
comparisons: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {};
|
||||||
|
console.log(o == o, o != o);
|
||||||
|
console.log(o === o, o !== o);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(!0, !1);
|
||||||
|
console.log(!0, !1);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"true false",
|
||||||
|
"true false",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2857_1: {
|
||||||
|
options = {
|
||||||
|
comparisons: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f1(a) {
|
||||||
|
a === undefined || a === null;
|
||||||
|
a === undefined || a !== null;
|
||||||
|
a !== undefined || a === null;
|
||||||
|
a !== undefined || a !== null;
|
||||||
|
a === undefined && a === null;
|
||||||
|
a === undefined && a !== null;
|
||||||
|
a !== undefined && a === null;
|
||||||
|
a !== undefined && a !== null;
|
||||||
|
}
|
||||||
|
function f2(a) {
|
||||||
|
a === null || a === undefined;
|
||||||
|
a === null || a !== undefined;
|
||||||
|
a !== null || a === undefined;
|
||||||
|
a !== null || a !== undefined;
|
||||||
|
a === null && a === undefined;
|
||||||
|
a === null && a !== undefined;
|
||||||
|
a !== null && a === undefined;
|
||||||
|
a !== null && a !== undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f1(a) {
|
||||||
|
null == a;
|
||||||
|
void 0 === a || null !== a;
|
||||||
|
void 0 !== a || null === a;
|
||||||
|
void 0 !== a || null !== a;
|
||||||
|
void 0 === a && null === a;
|
||||||
|
void 0 === a && null !== a;
|
||||||
|
void 0 !== a && null === a;
|
||||||
|
null != a;
|
||||||
|
}
|
||||||
|
function f2(a) {
|
||||||
|
null == a;
|
||||||
|
null === a || void 0 !== a;
|
||||||
|
null !== a || void 0 === a;
|
||||||
|
null !== a || void 0 !== a;
|
||||||
|
null === a && void 0 === a;
|
||||||
|
null === a && void 0 !== a;
|
||||||
|
null !== a && void 0 === a;
|
||||||
|
null != a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2857_2: {
|
||||||
|
options = {
|
||||||
|
comparisons: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a, p) {
|
||||||
|
a === undefined || a === null || p;
|
||||||
|
a === undefined || a !== null || p;
|
||||||
|
a !== undefined || a === null || p;
|
||||||
|
a !== undefined || a !== null || p;
|
||||||
|
a === undefined && a === null || p;
|
||||||
|
a === undefined && a !== null || p;
|
||||||
|
a !== undefined && a === null || p;
|
||||||
|
a !== undefined && a !== null || p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a, p) {
|
||||||
|
null == a || p;
|
||||||
|
void 0 === a || null !== a || p;
|
||||||
|
void 0 !== a || null === a || p;
|
||||||
|
void 0 !== a || null !== a || p;
|
||||||
|
void 0 === a && null === a || p;
|
||||||
|
void 0 === a && null !== a || p;
|
||||||
|
void 0 !== a && null === a || p;
|
||||||
|
null != a || p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2857_3: {
|
||||||
|
options = {
|
||||||
|
comparisons: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a, p) {
|
||||||
|
a === undefined || a === null && p;
|
||||||
|
a === undefined || a !== null && p;
|
||||||
|
a !== undefined || a === null && p;
|
||||||
|
a !== undefined || a !== null && p;
|
||||||
|
a === undefined && a === null && p;
|
||||||
|
a === undefined && a !== null && p;
|
||||||
|
a !== undefined && a === null && p;
|
||||||
|
a !== undefined && a !== null && p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a, p) {
|
||||||
|
void 0 === a || null === a && p;
|
||||||
|
void 0 === a || null !== a && p;
|
||||||
|
void 0 !== a || null === a && p;
|
||||||
|
void 0 !== a || null !== a && p;
|
||||||
|
void 0 === a && null === a && p;
|
||||||
|
void 0 === a && null !== a && p;
|
||||||
|
void 0 !== a && null === a && p;
|
||||||
|
null != a && p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2857_4: {
|
||||||
|
options = {
|
||||||
|
comparisons: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a, p) {
|
||||||
|
p || a === undefined || a === null;
|
||||||
|
p || a === undefined || a !== null;
|
||||||
|
p || a !== undefined || a === null;
|
||||||
|
p || a !== undefined || a !== null;
|
||||||
|
p || a === undefined && a === null;
|
||||||
|
p || a === undefined && a !== null;
|
||||||
|
p || a !== undefined && a === null;
|
||||||
|
p || a !== undefined && a !== null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a, p) {
|
||||||
|
p || null == a;
|
||||||
|
p || void 0 === a || null !== a;
|
||||||
|
p || void 0 !== a || null === a;
|
||||||
|
p || void 0 !== a || null !== a;
|
||||||
|
p || void 0 === a && null === a;
|
||||||
|
p || void 0 === a && null !== a;
|
||||||
|
p || void 0 !== a && null === a;
|
||||||
|
p || null != a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2857_5: {
|
||||||
|
options = {
|
||||||
|
comparisons: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a, p) {
|
||||||
|
p && a === undefined || a === null;
|
||||||
|
p && a === undefined || a !== null;
|
||||||
|
p && a !== undefined || a === null;
|
||||||
|
p && a !== undefined || a !== null;
|
||||||
|
p && a === undefined && a === null;
|
||||||
|
p && a === undefined && a !== null;
|
||||||
|
p && a !== undefined && a === null;
|
||||||
|
p && a !== undefined && a !== null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a, p) {
|
||||||
|
p && void 0 === a || null === a;
|
||||||
|
p && void 0 === a || null !== a;
|
||||||
|
p && void 0 !== a || null === a;
|
||||||
|
p && void 0 !== a || null !== a;
|
||||||
|
p && void 0 === a && null === a;
|
||||||
|
p && void 0 === a && null !== a;
|
||||||
|
p && void 0 !== a && null === a;
|
||||||
|
p && null != a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2857_6: {
|
||||||
|
options = {
|
||||||
|
comparisons: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
if (({}).b === undefined || {}.b === null)
|
||||||
|
return a.b !== undefined && a.b !== null;
|
||||||
|
}
|
||||||
|
console.log(f({
|
||||||
|
a: [ null ],
|
||||||
|
get b() {
|
||||||
|
return this.a.shift();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
if (null == {}.b)
|
||||||
|
return void 0 !== a.b && null !== a.b;
|
||||||
|
}
|
||||||
|
console.log(f({
|
||||||
|
a: [ null ],
|
||||||
|
get b() {
|
||||||
|
return this.a.shift();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
expect_stdout: "true"
|
||||||
|
}
|
||||||
|
|
||||||
|
is_boolean_unsafe: {
|
||||||
|
options = {
|
||||||
|
comparisons: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(/foo/.test("bar") === [].isPrototypeOf({}));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(/foo/.test("bar") == [].isPrototypeOf({}));
|
||||||
|
}
|
||||||
|
expect_stdout: "true"
|
||||||
|
}
|
||||||
|
|
||||||
|
is_number_unsafe: {
|
||||||
|
options = {
|
||||||
|
comparisons: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(Math.acos(42) !== "foo".charCodeAt(4));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(Math.acos(42) != "foo".charCodeAt(4));
|
||||||
|
}
|
||||||
|
expect_stdout: "true"
|
||||||
|
}
|
||||||
|
|
||||||
|
is_boolean_var: {
|
||||||
|
options = {
|
||||||
|
comparisons: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a, b) {
|
||||||
|
for (var i = 0, c = !b; i < a.length; i++)
|
||||||
|
if (!a[i] === c)
|
||||||
|
return i;
|
||||||
|
}([ false, true ], 42));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a, b) {
|
||||||
|
for (var i = 0, c = !b; i < a.length; i++)
|
||||||
|
if (!a[i] == c)
|
||||||
|
return i;
|
||||||
|
}([ false, true ], 42));
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
is_defined: {
|
||||||
|
options = {
|
||||||
|
comparisons: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function a() {
|
||||||
|
return void 0 === a;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function a() {
|
||||||
|
return a, false;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "false"
|
||||||
|
expect_warnings: [
|
||||||
|
"WARN: Expression always defined [test/compress/comparisons.js:2,19]",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe_indexOf: {
|
||||||
|
options = {
|
||||||
|
booleans: true,
|
||||||
|
comparisons: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = Object.keys({ foo: 42 });
|
||||||
|
if (a.indexOf("bar") < 0) console.log("PASS");
|
||||||
|
if (0 > a.indexOf("bar")) console.log("PASS");
|
||||||
|
if (a.indexOf("foo") >= 0) console.log("PASS");
|
||||||
|
if (0 <= a.indexOf("foo")) console.log("PASS");
|
||||||
|
if (a.indexOf("foo") > -1) console.log("PASS");
|
||||||
|
if (-1 < a.indexOf("foo")) console.log("PASS");
|
||||||
|
if (a.indexOf("bar") == -1) console.log("PASS");
|
||||||
|
if (-1 == a.indexOf("bar")) console.log("PASS");
|
||||||
|
if (a.indexOf("bar") === -1) console.log("PASS");
|
||||||
|
if (-1 === a.indexOf("bar")) console.log("PASS");
|
||||||
|
if (a.indexOf("foo") != -1) console.log("PASS");
|
||||||
|
if (-1 != a.indexOf("foo")) console.log("PASS");
|
||||||
|
if (a.indexOf("foo") !== -1) console.log("PASS");
|
||||||
|
if (-1 !== a.indexOf("foo")) console.log("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = Object.keys({ foo: 42 });
|
||||||
|
if (!~a.indexOf("bar")) console.log("PASS");
|
||||||
|
if (!~a.indexOf("bar")) console.log("PASS");
|
||||||
|
if (~a.indexOf("foo")) console.log("PASS");
|
||||||
|
if (~a.indexOf("foo")) console.log("PASS");
|
||||||
|
if (~a.indexOf("foo")) console.log("PASS");
|
||||||
|
if (~a.indexOf("foo")) console.log("PASS");
|
||||||
|
if (!~a.indexOf("bar")) console.log("PASS");
|
||||||
|
if (!~a.indexOf("bar")) console.log("PASS");
|
||||||
|
if (!~a.indexOf("bar")) console.log("PASS");
|
||||||
|
if (!~a.indexOf("bar")) console.log("PASS");
|
||||||
|
if (~a.indexOf("foo")) console.log("PASS");
|
||||||
|
if (~a.indexOf("foo")) console.log("PASS");
|
||||||
|
if (~a.indexOf("foo")) console.log("PASS");
|
||||||
|
if (~a.indexOf("foo")) console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"PASS",
|
||||||
|
"PASS",
|
||||||
|
"PASS",
|
||||||
|
"PASS",
|
||||||
|
"PASS",
|
||||||
|
"PASS",
|
||||||
|
"PASS",
|
||||||
|
"PASS",
|
||||||
|
"PASS",
|
||||||
|
"PASS",
|
||||||
|
"PASS",
|
||||||
|
"PASS",
|
||||||
|
"PASS",
|
||||||
|
"PASS",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3413: {
|
||||||
|
options = {
|
||||||
|
comparisons: true,
|
||||||
|
evaluate: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var b;
|
||||||
|
void 0 !== ("" < b || void 0) || console.log("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var b;
|
||||||
|
void 0 !== ("" < b || void 0) || console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
concat_1: {
|
concat_1: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true
|
evaluate: true,
|
||||||
};
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = "foo" + "bar" + x() + "moo" + "foo" + y() + "x" + "y" + "z" + q();
|
var a = "foo" + "bar" + x() + "moo" + "foo" + y() + "x" + "y" + "z" + q();
|
||||||
var b = "foo" + 1 + x() + 2 + "boo";
|
var b = "foo" + 1 + x() + 2 + "boo";
|
||||||
@@ -21,12 +21,14 @@ concat_1: {
|
|||||||
var c = 1 + x() + 2 + "boo";
|
var c = 1 + x() + 2 + "boo";
|
||||||
var d = 1 + x() + 2 + 3 + "boo";
|
var d = 1 + x() + 2 + 3 + "boo";
|
||||||
var e = 1 + x() + 2 + "X3boo";
|
var e = 1 + x() + 2 + "X3boo";
|
||||||
var f = "\x00360\08\0";
|
var f = "\x00360\x008\0";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
concat_2: {
|
concat_2: {
|
||||||
options = {};
|
options = {
|
||||||
|
strings: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
console.log(
|
console.log(
|
||||||
1 + (2 + 3),
|
1 + (2 + 3),
|
||||||
@@ -55,7 +57,9 @@ concat_2: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
concat_3: {
|
concat_3: {
|
||||||
options = {};
|
options = {
|
||||||
|
strings: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
console.log(
|
console.log(
|
||||||
1 + 2 + (3 + 4 + 5),
|
1 + 2 + (3 + 4 + 5),
|
||||||
@@ -84,7 +88,9 @@ concat_3: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
concat_4: {
|
concat_4: {
|
||||||
options = {};
|
options = {
|
||||||
|
strings: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
console.log(
|
console.log(
|
||||||
1 + "2" + (3 + 4 + 5),
|
1 + "2" + (3 + 4 + 5),
|
||||||
@@ -113,7 +119,9 @@ concat_4: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
concat_5: {
|
concat_5: {
|
||||||
options = {};
|
options = {
|
||||||
|
strings: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
console.log(
|
console.log(
|
||||||
"1" + 2 + (3 + 4 + 5),
|
"1" + 2 + (3 + 4 + 5),
|
||||||
@@ -142,7 +150,9 @@ concat_5: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
concat_6: {
|
concat_6: {
|
||||||
options = {};
|
options = {
|
||||||
|
strings: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
console.log(
|
console.log(
|
||||||
"1" + "2" + (3 + 4 + 5),
|
"1" + "2" + (3 + 4 + 5),
|
||||||
@@ -171,6 +181,9 @@ concat_6: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
concat_7: {
|
concat_7: {
|
||||||
|
options = {
|
||||||
|
strings: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
console.log(
|
console.log(
|
||||||
"" + 1,
|
"" + 1,
|
||||||
@@ -197,6 +210,9 @@ concat_7: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
concat_8: {
|
concat_8: {
|
||||||
|
options = {
|
||||||
|
strings: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
console.log(
|
console.log(
|
||||||
1 + "",
|
1 + "",
|
||||||
@@ -221,3 +237,55 @@ concat_8: {
|
|||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
concat_9: {
|
||||||
|
options = {
|
||||||
|
booleans: true,
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
strings: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "foo";
|
||||||
|
console.log(
|
||||||
|
12 + (34 + a),
|
||||||
|
null + (34 + a),
|
||||||
|
12 + (null + a),
|
||||||
|
false + (34 + a),
|
||||||
|
12 + (false + a),
|
||||||
|
"bar" + (34 + a),
|
||||||
|
12 + ("bar" + a)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "foo";
|
||||||
|
console.log(
|
||||||
|
"1234" + a,
|
||||||
|
"null34" + a,
|
||||||
|
"12null" + a,
|
||||||
|
!1 + (34 + a),
|
||||||
|
12 + (!1 + a),
|
||||||
|
"bar34" + a,
|
||||||
|
"12bar" + a
|
||||||
|
);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3689: {
|
||||||
|
options = {
|
||||||
|
strings: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a) {
|
||||||
|
return a + ("" + (a[0] = 0));
|
||||||
|
}([]));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a) {
|
||||||
|
return a + ("" + (a[0] = 0));
|
||||||
|
}([]));
|
||||||
|
}
|
||||||
|
expect_stdout: "00"
|
||||||
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
1153
test/compress/const.js
Normal file
1153
test/compress/const.js
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
|||||||
keep_debugger: {
|
keep_debugger: {
|
||||||
options = {
|
options = {
|
||||||
drop_debugger: false
|
drop_debugger: false,
|
||||||
};
|
}
|
||||||
input: {
|
input: {
|
||||||
debugger;
|
debugger;
|
||||||
}
|
}
|
||||||
@@ -12,8 +12,8 @@ keep_debugger: {
|
|||||||
|
|
||||||
drop_debugger: {
|
drop_debugger: {
|
||||||
options = {
|
options = {
|
||||||
drop_debugger: true
|
drop_debugger: true,
|
||||||
};
|
}
|
||||||
input: {
|
input: {
|
||||||
debugger;
|
debugger;
|
||||||
if (foo) debugger;
|
if (foo) debugger;
|
||||||
|
|||||||
131
test/compress/directives.js
Normal file
131
test/compress/directives.js
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
simple_statement_is_not_a_directive: {
|
||||||
|
input: {
|
||||||
|
"use strict"
|
||||||
|
.split(" ")
|
||||||
|
.forEach(function(s) {
|
||||||
|
console.log(s);
|
||||||
|
});
|
||||||
|
console.log(!this); // is strict mode?
|
||||||
|
(function() {
|
||||||
|
"directive"
|
||||||
|
""
|
||||||
|
"use strict"
|
||||||
|
"hello world"
|
||||||
|
.split(" ")
|
||||||
|
.forEach(function(s) {
|
||||||
|
console.log(s);
|
||||||
|
});
|
||||||
|
console.log(!this); // is strict mode?
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict".split(" ").forEach(function(s) {
|
||||||
|
console.log(s);
|
||||||
|
});
|
||||||
|
console.log(!this);
|
||||||
|
(function() {
|
||||||
|
"directive";
|
||||||
|
"";
|
||||||
|
"use strict";
|
||||||
|
"hello world".split(" ").forEach(function(s) {
|
||||||
|
console.log(s);
|
||||||
|
});
|
||||||
|
console.log(!this);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"use",
|
||||||
|
"strict",
|
||||||
|
"false",
|
||||||
|
"hello",
|
||||||
|
"world",
|
||||||
|
"true",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_lone_use_strict: {
|
||||||
|
options = {
|
||||||
|
directives: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f1() {
|
||||||
|
"use strict";
|
||||||
|
}
|
||||||
|
function f2() {
|
||||||
|
"use strict";
|
||||||
|
function f3() {
|
||||||
|
"use strict";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(function f4() {
|
||||||
|
"use strict";
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f1() {
|
||||||
|
}
|
||||||
|
function f2() {
|
||||||
|
}
|
||||||
|
(function() {})();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3166: {
|
||||||
|
options = {
|
||||||
|
directives: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"foo";
|
||||||
|
"use strict";
|
||||||
|
function f() {
|
||||||
|
"use strict";
|
||||||
|
"bar";
|
||||||
|
"use asm";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
function f() {
|
||||||
|
"use asm";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
valid_after_invalid_1: {
|
||||||
|
input: {
|
||||||
|
console.log(typeof function() {
|
||||||
|
"use\x20strict";
|
||||||
|
"use strict";
|
||||||
|
return this;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(typeof function() {
|
||||||
|
"use\x20strict";
|
||||||
|
"use strict";
|
||||||
|
return this;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
valid_after_invalid_2: {
|
||||||
|
options = {
|
||||||
|
directives: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(typeof function() {
|
||||||
|
"use\x20strict";
|
||||||
|
"use strict";
|
||||||
|
return this;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(typeof function() {
|
||||||
|
"use strict";
|
||||||
|
return this;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
drop_console_1: {
|
drop_console_1: {
|
||||||
options = {};
|
options = {}
|
||||||
input: {
|
input: {
|
||||||
console.log('foo');
|
console.log('foo');
|
||||||
console.log.apply(console, arguments);
|
console.log.apply(console, arguments);
|
||||||
@@ -11,7 +11,9 @@ drop_console_1: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
drop_console_2: {
|
drop_console_2: {
|
||||||
options = { drop_console: true };
|
options = {
|
||||||
|
drop_console: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
console.log('foo');
|
console.log('foo');
|
||||||
console.log.apply(console, arguments);
|
console.log.apply(console, arguments);
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@ must_replace: {
|
|||||||
options = {
|
options = {
|
||||||
global_defs: {
|
global_defs: {
|
||||||
D: "foo bar",
|
D: "foo bar",
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
console.log(D);
|
console.log(D);
|
||||||
@@ -12,6 +12,20 @@ must_replace: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
repeated_nodes: {
|
||||||
|
options = {
|
||||||
|
global_defs: {
|
||||||
|
"@N": "rand()",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(N, N);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(rand(), rand());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
keyword: {
|
keyword: {
|
||||||
options = {
|
options = {
|
||||||
global_defs: {
|
global_defs: {
|
||||||
@@ -37,6 +51,7 @@ object: {
|
|||||||
VALUE: 42,
|
VALUE: 42,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
side_effects: true,
|
||||||
unsafe: true,
|
unsafe: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -140,9 +155,8 @@ mixed: {
|
|||||||
console.log(CONFIG);
|
console.log(CONFIG);
|
||||||
}
|
}
|
||||||
expect_warnings: [
|
expect_warnings: [
|
||||||
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:126,22]',
|
"WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:4,22]",
|
||||||
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:127,22]',
|
"WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:7,8]",
|
||||||
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:129,8]',
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,3 +188,45 @@ issue_1986: {
|
|||||||
console.log(42);
|
console.log(42);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2167: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
global_defs: {
|
||||||
|
"@isDevMode": "function(){}",
|
||||||
|
},
|
||||||
|
passes: 2,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
if (isDevMode()) {
|
||||||
|
greetOverlord();
|
||||||
|
}
|
||||||
|
doWork();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
doWork();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3217: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
global_defs: {
|
||||||
|
"@o": "{fn:function(){var a=42;console.log(a)}}",
|
||||||
|
},
|
||||||
|
inline: true,
|
||||||
|
properties: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
o.fn();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(42);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
1043
test/compress/hoist_props.js
Normal file
1043
test/compress/hoist_props.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -88,3 +88,24 @@ sequences_funs: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2295: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
hoist_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function foo(o) {
|
||||||
|
var a = o.a;
|
||||||
|
if (a) return a;
|
||||||
|
var a = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function foo(o) {
|
||||||
|
var a = o.a;
|
||||||
|
if (a) return a;
|
||||||
|
a = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,55 +1,107 @@
|
|||||||
html_comment_in_expression: {
|
html_comment_in_expression: {
|
||||||
input: {
|
input: {
|
||||||
function f(a, b, x, y) { return a < !--b && x-- > y; }
|
(function(a, b) {
|
||||||
|
console.log(a < !--b && a-- > b, a, b);
|
||||||
|
})(1, 2);
|
||||||
}
|
}
|
||||||
expect_exact: "function f(a,b,x,y){return a< !--b&&x-- >y}";
|
expect_exact: "(function(a,b){console.log(a<! --b&&a-- >b,a,b)})(1,2);"
|
||||||
|
expect_stdout: "false 1 1"
|
||||||
}
|
}
|
||||||
|
|
||||||
html_comment_in_less_than: {
|
html_comment_in_less_than: {
|
||||||
input: {
|
input: {
|
||||||
function f(a, b) { return a < !--b; }
|
(function(a, b, c) {
|
||||||
|
console.log(
|
||||||
|
a < !--b,
|
||||||
|
a < !--b + c,
|
||||||
|
a + b < !--c,
|
||||||
|
a, b, c
|
||||||
|
);
|
||||||
|
})(1, 2, 3);
|
||||||
}
|
}
|
||||||
expect_exact: "function f(a,b){return a< !--b}";
|
expect_exact: "(function(a,b,c){console.log(a<! --b,a<! --b+c,a+b<! --c,a,b,c)})(1,2,3);"
|
||||||
|
expect_stdout: "false true false 1 0 2"
|
||||||
}
|
}
|
||||||
|
|
||||||
html_comment_in_left_shift: {
|
html_comment_in_left_shift: {
|
||||||
input: {
|
input: {
|
||||||
function f(a, b) { return a << !--b; }
|
(function(a, b, c) {
|
||||||
|
console.log(
|
||||||
|
a << !--b,
|
||||||
|
a << !--b + c,
|
||||||
|
a + b << !--c,
|
||||||
|
a, b, c
|
||||||
|
);
|
||||||
|
})(1, 2, 3);
|
||||||
}
|
}
|
||||||
expect_exact: "function f(a,b){return a<< !--b}";
|
expect_exact: "(function(a,b,c){console.log(a<<! --b,a<<! --b+c,a+b<<! --c,a,b,c)})(1,2,3);"
|
||||||
}
|
expect_stdout: "1 16 1 1 0 2"
|
||||||
|
|
||||||
html_comment_in_right_shift: {
|
|
||||||
input: {
|
|
||||||
function f(a, b) { return a-- >> b; }
|
|
||||||
}
|
|
||||||
expect_exact: "function f(a,b){return a-- >>b}";
|
|
||||||
}
|
|
||||||
|
|
||||||
html_comment_in_zero_fill_right_shift: {
|
|
||||||
input: {
|
|
||||||
function f(a, b) { return a-- >>> b; }
|
|
||||||
}
|
|
||||||
expect_exact: "function f(a,b){return a-- >>>b}";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
html_comment_in_greater_than: {
|
html_comment_in_greater_than: {
|
||||||
input: {
|
input: {
|
||||||
function f(a, b) { return a-- > b; }
|
(function(a, b, c) {
|
||||||
|
console.log(
|
||||||
|
a-- > b,
|
||||||
|
a-- > b + c,
|
||||||
|
a + b-- > c,
|
||||||
|
a, b, c
|
||||||
|
);
|
||||||
|
})(1, 2, 3);
|
||||||
}
|
}
|
||||||
expect_exact: "function f(a,b){return a-- >b}";
|
expect_exact: "(function(a,b,c){console.log(a-- >b,a-- >b+c,a+b-- >c,a,b,c)})(1,2,3);"
|
||||||
|
expect_stdout: "false false false -1 1 3"
|
||||||
}
|
}
|
||||||
|
|
||||||
html_comment_in_greater_than_or_equal: {
|
html_comment_in_greater_than_or_equal: {
|
||||||
input: {
|
input: {
|
||||||
function f(a, b) { return a-- >= b; }
|
(function(a, b, c) {
|
||||||
|
console.log(
|
||||||
|
a-- >= b,
|
||||||
|
a-- >= b + c,
|
||||||
|
a + b-- >= c,
|
||||||
|
a, b, c
|
||||||
|
);
|
||||||
|
})(1, 2, 3);
|
||||||
}
|
}
|
||||||
expect_exact: "function f(a,b){return a-- >=b}";
|
expect_exact: "(function(a,b,c){console.log(a-- >=b,a-- >=b+c,a+b-- >=c,a,b,c)})(1,2,3);"
|
||||||
|
expect_stdout: "false false false -1 1 3"
|
||||||
|
}
|
||||||
|
|
||||||
|
html_comment_in_right_shift: {
|
||||||
|
input: {
|
||||||
|
(function(a, b, c) {
|
||||||
|
console.log(
|
||||||
|
a-- >> b,
|
||||||
|
a-- >> b + c,
|
||||||
|
a + b-- >> c,
|
||||||
|
a, b, c
|
||||||
|
);
|
||||||
|
})(1, 2, 3);
|
||||||
|
}
|
||||||
|
expect_exact: "(function(a,b,c){console.log(a-- >>b,a-- >>b+c,a+b-- >>c,a,b,c)})(1,2,3);"
|
||||||
|
expect_stdout: "0 0 0 -1 1 3"
|
||||||
|
}
|
||||||
|
|
||||||
|
html_comment_in_zero_fill_right_shift: {
|
||||||
|
input: {
|
||||||
|
(function(a, b, c) {
|
||||||
|
console.log(
|
||||||
|
a-- >>> b,
|
||||||
|
a-- >>> b + c,
|
||||||
|
a + b-- >>> c,
|
||||||
|
a, b, c
|
||||||
|
);
|
||||||
|
})(1, 2, 3);
|
||||||
|
}
|
||||||
|
expect_exact: "(function(a,b,c){console.log(a-- >>>b,a-- >>>b+c,a+b-- >>>c,a,b,c)})(1,2,3);"
|
||||||
|
expect_stdout: "0 0 0 -1 1 3"
|
||||||
}
|
}
|
||||||
|
|
||||||
html_comment_in_string_literal: {
|
html_comment_in_string_literal: {
|
||||||
input: {
|
input: {
|
||||||
function f() { return "<!--HTML-->comment in<!--string literal-->"; }
|
console.log("<!--HTML-->comment in<!--string literal-->".length);
|
||||||
}
|
}
|
||||||
expect_exact: 'function f(){return"\\x3c!--HTML--\\x3ecomment in\\x3c!--string literal--\\x3e"}';
|
expect_exact: 'console.log("\\x3c!--HTML--\\x3ecomment in\\x3c!--string literal--\\x3e".length);'
|
||||||
|
expect_stdout: "42"
|
||||||
}
|
}
|
||||||
|
|||||||
2861
test/compress/ie8.js
Normal file
2861
test/compress/ie8.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,14 +1,14 @@
|
|||||||
if_return_1: {
|
if_return_1: {
|
||||||
options = {
|
options = {
|
||||||
if_return : true,
|
booleans: true,
|
||||||
sequences : true,
|
comparisons: true,
|
||||||
conditionals : true,
|
conditionals: true,
|
||||||
comparisons : true,
|
dead_code: true,
|
||||||
evaluate : true,
|
evaluate: true,
|
||||||
booleans : true,
|
if_return: true,
|
||||||
unused : true,
|
sequences: true,
|
||||||
side_effects : true,
|
side_effects: true,
|
||||||
dead_code : true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f(x) {
|
function f(x) {
|
||||||
@@ -24,15 +24,15 @@ if_return_1: {
|
|||||||
|
|
||||||
if_return_2: {
|
if_return_2: {
|
||||||
options = {
|
options = {
|
||||||
if_return : true,
|
booleans: true,
|
||||||
sequences : true,
|
comparisons: true,
|
||||||
conditionals : true,
|
conditionals: true,
|
||||||
comparisons : true,
|
dead_code: true,
|
||||||
evaluate : true,
|
evaluate: true,
|
||||||
booleans : true,
|
if_return: true,
|
||||||
unused : true,
|
sequences: true,
|
||||||
side_effects : true,
|
side_effects: true,
|
||||||
dead_code : true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f(x, y) {
|
function f(x, y) {
|
||||||
@@ -49,15 +49,15 @@ if_return_2: {
|
|||||||
|
|
||||||
if_return_3: {
|
if_return_3: {
|
||||||
options = {
|
options = {
|
||||||
if_return : true,
|
booleans: true,
|
||||||
sequences : true,
|
comparisons: true,
|
||||||
conditionals : true,
|
conditionals: true,
|
||||||
comparisons : true,
|
dead_code: true,
|
||||||
evaluate : true,
|
evaluate: true,
|
||||||
booleans : true,
|
if_return: true,
|
||||||
unused : true,
|
sequences: true,
|
||||||
side_effects : true,
|
side_effects: true,
|
||||||
dead_code : true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f(x) {
|
function f(x) {
|
||||||
@@ -75,15 +75,15 @@ if_return_3: {
|
|||||||
|
|
||||||
if_return_4: {
|
if_return_4: {
|
||||||
options = {
|
options = {
|
||||||
if_return : true,
|
booleans: true,
|
||||||
sequences : true,
|
comparisons: true,
|
||||||
conditionals : true,
|
conditionals: true,
|
||||||
comparisons : true,
|
dead_code: true,
|
||||||
evaluate : true,
|
evaluate: true,
|
||||||
booleans : true,
|
if_return: true,
|
||||||
unused : true,
|
sequences: true,
|
||||||
side_effects : true,
|
side_effects: true,
|
||||||
dead_code : true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f(x, y) {
|
function f(x, y) {
|
||||||
@@ -100,15 +100,15 @@ if_return_4: {
|
|||||||
|
|
||||||
if_return_5: {
|
if_return_5: {
|
||||||
options = {
|
options = {
|
||||||
if_return : true,
|
booleans: true,
|
||||||
sequences : true,
|
comparisons: true,
|
||||||
conditionals : true,
|
conditionals: true,
|
||||||
comparisons : true,
|
dead_code: true,
|
||||||
evaluate : true,
|
evaluate: true,
|
||||||
booleans : true,
|
if_return: true,
|
||||||
unused : true,
|
sequences: true,
|
||||||
side_effects : true,
|
side_effects: true,
|
||||||
dead_code : true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f() {
|
function f() {
|
||||||
@@ -126,15 +126,15 @@ if_return_5: {
|
|||||||
|
|
||||||
if_return_6: {
|
if_return_6: {
|
||||||
options = {
|
options = {
|
||||||
if_return : true,
|
booleans: true,
|
||||||
sequences : true,
|
comparisons: true,
|
||||||
conditionals : true,
|
conditionals: true,
|
||||||
comparisons : true,
|
dead_code: true,
|
||||||
evaluate : true,
|
evaluate: true,
|
||||||
booleans : true,
|
if_return: true,
|
||||||
unused : true,
|
sequences: true,
|
||||||
side_effects : true,
|
side_effects: true,
|
||||||
dead_code : true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f(x) {
|
function f(x) {
|
||||||
@@ -150,15 +150,15 @@ if_return_6: {
|
|||||||
|
|
||||||
if_return_7: {
|
if_return_7: {
|
||||||
options = {
|
options = {
|
||||||
if_return : true,
|
booleans: true,
|
||||||
sequences : true,
|
comparisons: true,
|
||||||
conditionals : true,
|
conditionals: true,
|
||||||
comparisons : true,
|
dead_code: true,
|
||||||
evaluate : true,
|
evaluate: true,
|
||||||
booleans : true,
|
if_return: true,
|
||||||
unused : true,
|
sequences: true,
|
||||||
side_effects : true,
|
side_effects: true,
|
||||||
dead_code : true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f(x) {
|
function f(x) {
|
||||||
@@ -176,10 +176,10 @@ if_return_7: {
|
|||||||
|
|
||||||
if_return_8: {
|
if_return_8: {
|
||||||
options = {
|
options = {
|
||||||
if_return: true,
|
conditionals: true,
|
||||||
sequences: true,
|
if_return: true,
|
||||||
conditionals: true,
|
sequences: true,
|
||||||
side_effects : true,
|
side_effects: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f(e) {
|
function f(e) {
|
||||||
@@ -220,15 +220,15 @@ if_return_8: {
|
|||||||
|
|
||||||
issue_1089: {
|
issue_1089: {
|
||||||
options = {
|
options = {
|
||||||
if_return : true,
|
booleans: true,
|
||||||
sequences : true,
|
comparisons: true,
|
||||||
conditionals : true,
|
conditionals: true,
|
||||||
comparisons : true,
|
dead_code: true,
|
||||||
evaluate : true,
|
evaluate: true,
|
||||||
booleans : true,
|
if_return: true,
|
||||||
unused : true,
|
sequences: true,
|
||||||
side_effects : true,
|
side_effects: true,
|
||||||
dead_code : true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function x() {
|
function x() {
|
||||||
@@ -243,7 +243,7 @@ issue_1089: {
|
|||||||
expect: {
|
expect: {
|
||||||
function x() {
|
function x() {
|
||||||
var f = document.getElementById("fname");
|
var f = document.getElementById("fname");
|
||||||
if (f.files[0].size > 12345)
|
if (12345 < f.files[0].size)
|
||||||
return alert("alert"), f.focus(), !1;
|
return alert("alert"), f.focus(), !1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -251,9 +251,9 @@ issue_1089: {
|
|||||||
|
|
||||||
issue_1437: {
|
issue_1437: {
|
||||||
options = {
|
options = {
|
||||||
if_return : true,
|
conditionals: false,
|
||||||
sequences : true,
|
if_return: true,
|
||||||
conditionals : false
|
sequences: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function x() {
|
function x() {
|
||||||
@@ -281,9 +281,9 @@ issue_1437: {
|
|||||||
|
|
||||||
issue_1437_conditionals: {
|
issue_1437_conditionals: {
|
||||||
options = {
|
options = {
|
||||||
conditionals : true,
|
conditionals: true,
|
||||||
if_return : true,
|
if_return: true,
|
||||||
sequences : true
|
sequences: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function x() {
|
function x() {
|
||||||
@@ -326,3 +326,425 @@ issue_512: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if_var_return: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
if_return: true,
|
||||||
|
join_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
var a;
|
||||||
|
return;
|
||||||
|
var b;
|
||||||
|
}
|
||||||
|
function g() {
|
||||||
|
var a;
|
||||||
|
if (u()) {
|
||||||
|
var b;
|
||||||
|
return v();
|
||||||
|
var c;
|
||||||
|
}
|
||||||
|
var d;
|
||||||
|
if (w()) {
|
||||||
|
var e;
|
||||||
|
return x();
|
||||||
|
var f;
|
||||||
|
} else {
|
||||||
|
var g;
|
||||||
|
y();
|
||||||
|
var h;
|
||||||
|
}
|
||||||
|
var i;
|
||||||
|
z();
|
||||||
|
var j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
var a, b;
|
||||||
|
}
|
||||||
|
function g() {
|
||||||
|
var a, b, c, d, e, f, g, h, i, j;
|
||||||
|
return u() ? v() : w() ? x() : (y(), z(), void 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if_if_return_return: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a, b) {
|
||||||
|
if (a) {
|
||||||
|
if (b)
|
||||||
|
return b;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
g();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a, b) {
|
||||||
|
if (a)
|
||||||
|
return b || void 0;
|
||||||
|
g();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if_body_return_1: {
|
||||||
|
options = {
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var c = "PASS";
|
||||||
|
function f(a, b) {
|
||||||
|
if (a) {
|
||||||
|
if (b) throw new Error(c);
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
console.log(f(0, 0));
|
||||||
|
console.log(f(0, 1));
|
||||||
|
console.log(f(1, 0));
|
||||||
|
try {
|
||||||
|
f(1, 1);
|
||||||
|
console.log("FAIL");
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c = "PASS";
|
||||||
|
function f(a, b) {
|
||||||
|
if (a) {
|
||||||
|
if (b) throw new Error(c);
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
console.log(f(0, 0));
|
||||||
|
console.log(f(0, 1));
|
||||||
|
console.log(f(1, 0));
|
||||||
|
try {
|
||||||
|
f(1, 1);
|
||||||
|
console.log("FAIL");
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"true",
|
||||||
|
"true",
|
||||||
|
"42",
|
||||||
|
"PASS",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
if_body_return_2: {
|
||||||
|
options = {
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var c = "PASS";
|
||||||
|
function f(a, b) {
|
||||||
|
if (0 + a) {
|
||||||
|
if (b) throw new Error(c);
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
console.log(f(0, 0));
|
||||||
|
console.log(f(0, 1));
|
||||||
|
console.log(f(1, 0));
|
||||||
|
try {
|
||||||
|
f(1, 1);
|
||||||
|
console.log("FAIL");
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c = "PASS";
|
||||||
|
function f(a, b) {
|
||||||
|
if (0 + a) {
|
||||||
|
if (b) throw new Error(c);
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
console.log(f(0, 0));
|
||||||
|
console.log(f(0, 1));
|
||||||
|
console.log(f(1, 0));
|
||||||
|
try {
|
||||||
|
f(1, 1);
|
||||||
|
console.log("FAIL");
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"true",
|
||||||
|
"true",
|
||||||
|
"42",
|
||||||
|
"PASS",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
if_body_return_3: {
|
||||||
|
options = {
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var c = "PASS";
|
||||||
|
function f(a, b) {
|
||||||
|
if (1 == a) {
|
||||||
|
if (b) throw new Error(c);
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
console.log(f(0, 0));
|
||||||
|
console.log(f(0, 1));
|
||||||
|
console.log(f(1, 0));
|
||||||
|
try {
|
||||||
|
f(1, 1);
|
||||||
|
console.log("FAIL");
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c = "PASS";
|
||||||
|
function f(a, b) {
|
||||||
|
if (1 != a) return true;
|
||||||
|
if (b) throw new Error(c);
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
console.log(f(0, 0));
|
||||||
|
console.log(f(0, 1));
|
||||||
|
console.log(f(1, 0));
|
||||||
|
try {
|
||||||
|
f(1, 1);
|
||||||
|
console.log("FAIL");
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"true",
|
||||||
|
"true",
|
||||||
|
"42",
|
||||||
|
"PASS",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3600: {
|
||||||
|
options = {
|
||||||
|
if_return: true,
|
||||||
|
inline: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var c = 0;
|
||||||
|
(function() {
|
||||||
|
if ([ ][c++]); else return;
|
||||||
|
return void function() {
|
||||||
|
var b = --b, a = c = 42;
|
||||||
|
return c;
|
||||||
|
}();
|
||||||
|
})();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c = 0;
|
||||||
|
(function() {
|
||||||
|
if ([][c++]) b = --b, c = 42;
|
||||||
|
var b;
|
||||||
|
})();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
iife_if_return_simple: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
if_return: true,
|
||||||
|
inline: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
if (console)
|
||||||
|
return console.log("PASS");
|
||||||
|
console.log("FAIL");
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console ? console.log("PASS") : console.log("FAIL");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
nested_if_break: {
|
||||||
|
options = {
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
for (var i = 0; i < 3; i++)
|
||||||
|
L1: if ("number" == typeof i) {
|
||||||
|
if (0 === i) break L1;
|
||||||
|
console.log(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
for (var i = 0; i < 3; i++)
|
||||||
|
L1: if ("number" == typeof i)
|
||||||
|
if (0 !== i) console.log(i);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
nested_if_continue: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
if_return: true,
|
||||||
|
join_vars: true,
|
||||||
|
loops: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(n) {
|
||||||
|
var i = 0;
|
||||||
|
do {
|
||||||
|
if ("number" == typeof n) {
|
||||||
|
if (0 === n) {
|
||||||
|
console.log("even", i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (1 === n) {
|
||||||
|
console.log("odd", i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
} while (0 <= (n -= 2));
|
||||||
|
}
|
||||||
|
f(37);
|
||||||
|
f(42);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(n) {
|
||||||
|
for (var i = 0;
|
||||||
|
"number" == typeof n
|
||||||
|
&& (0 !== n
|
||||||
|
? 1 !== n
|
||||||
|
? i++
|
||||||
|
: console.log("odd", i)
|
||||||
|
: console.log("even", i)),
|
||||||
|
0 <= (n -= 2););
|
||||||
|
}
|
||||||
|
f(37);
|
||||||
|
f(42);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"odd 18",
|
||||||
|
"even 21",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
nested_if_return: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
if (A) {
|
||||||
|
if (B)
|
||||||
|
return B;
|
||||||
|
if (C)
|
||||||
|
return D;
|
||||||
|
if (E)
|
||||||
|
return F;
|
||||||
|
if (G)
|
||||||
|
return H;
|
||||||
|
if (I) {
|
||||||
|
if (J)
|
||||||
|
return K;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (L) {
|
||||||
|
if (M)
|
||||||
|
return;
|
||||||
|
return N;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
if (A)
|
||||||
|
return B || (C ? D : E ? F : G ? H : I ? J ? K : void 0 : L && !M ? N : void 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_866_1: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
if_return: true,
|
||||||
|
sequences: false,
|
||||||
|
};
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
if (a)
|
||||||
|
return "";
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
if (a)
|
||||||
|
return "";
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_866_2: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
if_return: true,
|
||||||
|
sequences: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
if (a)
|
||||||
|
if (b)
|
||||||
|
c;
|
||||||
|
else
|
||||||
|
return d;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
if (a) {
|
||||||
|
if (!b)
|
||||||
|
return d;
|
||||||
|
c;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,8 +1,17 @@
|
|||||||
non_hoisted_function_after_return: {
|
non_hoisted_function_after_return: {
|
||||||
options = {
|
options = {
|
||||||
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
|
booleans: true,
|
||||||
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
|
comparisons: true,
|
||||||
if_return: true, join_vars: true, cascade: true, side_effects: true
|
conditionals: true,
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
hoist_funs: false,
|
||||||
|
if_return: true,
|
||||||
|
join_vars: true,
|
||||||
|
keep_fargs: true,
|
||||||
|
loops: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function foo(x) {
|
function foo(x) {
|
||||||
@@ -21,25 +30,35 @@ non_hoisted_function_after_return: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function foo(x) {
|
function foo(x) {
|
||||||
return x ? bar() : baz();
|
return (x ? bar : baz)();
|
||||||
function bar() { return 7 }
|
function bar() { return 7 }
|
||||||
function baz() { return 8 }
|
function baz() { return 8 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect_warnings: [
|
expect_warnings: [
|
||||||
'WARN: Dropping unreachable code [test/compress/issue-1034.js:11,16]',
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:4,16]",
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:14,16]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:7,16]",
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:17,12]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:10,12]",
|
||||||
"WARN: Dropping unused function UnusedFunction [test/compress/issue-1034.js:18,21]"
|
"WARN: Dropping unused function UnusedFunction [test/compress/issue-1034.js:11,21]"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
non_hoisted_function_after_return_2a: {
|
non_hoisted_function_after_return_2a: {
|
||||||
options = {
|
options = {
|
||||||
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
|
booleans: true,
|
||||||
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
|
collapse_vars: false,
|
||||||
if_return: true, join_vars: true, cascade: true, side_effects: true,
|
comparisons: true,
|
||||||
collapse_vars: false, passes: 2, warnings: "verbose"
|
conditionals: true,
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
hoist_funs: false,
|
||||||
|
if_return: true,
|
||||||
|
join_vars: true,
|
||||||
|
keep_fargs: true,
|
||||||
|
loops: true,
|
||||||
|
passes: 2,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function foo(x) {
|
function foo(x) {
|
||||||
@@ -65,26 +84,37 @@ non_hoisted_function_after_return_2a: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect_warnings: [
|
expect_warnings: [
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:48,16]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:4,16]",
|
||||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:48,16]",
|
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:4,16]",
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:51,16]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:7,16]",
|
||||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:51,16]",
|
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:7,16]",
|
||||||
"WARN: Dropping unused variable a [test/compress/issue-1034.js:48,20]",
|
"WARN: Dropping unused variable a [test/compress/issue-1034.js:4,20]",
|
||||||
"WARN: Dropping unused function nope [test/compress/issue-1034.js:55,21]",
|
"WARN: Dropping unused function nope [test/compress/issue-1034.js:11,21]",
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:53,12]",
|
"INFO: pass 0: last_count: Infinity, count: 35",
|
||||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:53,12]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:9,12]",
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:56,12]",
|
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:9,12]",
|
||||||
"WARN: Dropping unused variable b [test/compress/issue-1034.js:51,20]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:12,12]",
|
||||||
"WARN: Dropping unused variable c [test/compress/issue-1034.js:53,16]",
|
"INFO: Dropping unused variable b [test/compress/issue-1034.js:7,20]",
|
||||||
|
"INFO: Dropping unused variable c [test/compress/issue-1034.js:9,16]",
|
||||||
|
"INFO: pass 1: last_count: 35, count: 18",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
non_hoisted_function_after_return_2b: {
|
non_hoisted_function_after_return_2b: {
|
||||||
options = {
|
options = {
|
||||||
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
|
booleans: true,
|
||||||
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
|
collapse_vars: false,
|
||||||
if_return: true, join_vars: true, cascade: true, side_effects: true,
|
comparisons: true,
|
||||||
collapse_vars: false
|
conditionals: true,
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
hoist_funs: false,
|
||||||
|
if_return: true,
|
||||||
|
join_vars: true,
|
||||||
|
keep_fargs: true,
|
||||||
|
loops: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function foo(x) {
|
function foo(x) {
|
||||||
@@ -108,20 +138,28 @@ non_hoisted_function_after_return_2b: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect_warnings: [
|
expect_warnings: [
|
||||||
// duplicate warnings no longer emitted
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:6,16]",
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:95,16]",
|
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:6,16]",
|
||||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:95,16]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:8,12]",
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:97,12]",
|
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:8,12]",
|
||||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:97,12]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:12,12]",
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:101,12]",
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
non_hoisted_function_after_return_strict: {
|
non_hoisted_function_after_return_strict: {
|
||||||
options = {
|
options = {
|
||||||
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
|
booleans: true,
|
||||||
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
|
comparisons: true,
|
||||||
if_return: true, join_vars: true, cascade: true, side_effects: true
|
conditionals: true,
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
hoist_funs: false,
|
||||||
|
if_return: true,
|
||||||
|
join_vars: true,
|
||||||
|
keep_fargs: true,
|
||||||
|
loops: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
"use strict";
|
"use strict";
|
||||||
@@ -143,7 +181,7 @@ non_hoisted_function_after_return_strict: {
|
|||||||
expect: {
|
expect: {
|
||||||
"use strict";
|
"use strict";
|
||||||
function foo(x) {
|
function foo(x) {
|
||||||
return x ? bar() : baz();
|
return (x ? bar : baz)();
|
||||||
function bar() { return 7 }
|
function bar() { return 7 }
|
||||||
function baz() { return 8 }
|
function baz() { return 8 }
|
||||||
}
|
}
|
||||||
@@ -151,19 +189,29 @@ non_hoisted_function_after_return_strict: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "8 7"
|
expect_stdout: "8 7"
|
||||||
expect_warnings: [
|
expect_warnings: [
|
||||||
'WARN: Dropping unreachable code [test/compress/issue-1034.js:131,16]',
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:5,16]",
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:134,16]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:8,16]",
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:137,12]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:11,12]",
|
||||||
"WARN: Dropping unused function UnusedFunction [test/compress/issue-1034.js:138,21]"
|
"WARN: Dropping unused function UnusedFunction [test/compress/issue-1034.js:12,21]",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
non_hoisted_function_after_return_2a_strict: {
|
non_hoisted_function_after_return_2a_strict: {
|
||||||
options = {
|
options = {
|
||||||
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
|
booleans: true,
|
||||||
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
|
collapse_vars: false,
|
||||||
if_return: true, join_vars: true, cascade: true, side_effects: true,
|
comparisons: true,
|
||||||
collapse_vars: false, passes: 2, warnings: "verbose"
|
conditionals: true,
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
hoist_funs: false,
|
||||||
|
if_return: true,
|
||||||
|
join_vars: true,
|
||||||
|
keep_fargs: true,
|
||||||
|
loops: true,
|
||||||
|
passes: 2,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
"use strict";
|
"use strict";
|
||||||
@@ -194,26 +242,37 @@ non_hoisted_function_after_return_2a_strict: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "5 6"
|
expect_stdout: "5 6"
|
||||||
expect_warnings: [
|
expect_warnings: [
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:173,16]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:5,16]",
|
||||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:173,16]",
|
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:5,16]",
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:176,16]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:8,16]",
|
||||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:176,16]",
|
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:8,16]",
|
||||||
"WARN: Dropping unused variable a [test/compress/issue-1034.js:173,20]",
|
"WARN: Dropping unused variable a [test/compress/issue-1034.js:5,20]",
|
||||||
"WARN: Dropping unused function nope [test/compress/issue-1034.js:180,21]",
|
"WARN: Dropping unused function nope [test/compress/issue-1034.js:12,21]",
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:178,12]",
|
"INFO: pass 0: last_count: Infinity, count: 46",
|
||||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:178,12]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:10,12]",
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:181,12]",
|
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:10,12]",
|
||||||
"WARN: Dropping unused variable b [test/compress/issue-1034.js:176,20]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:13,12]",
|
||||||
"WARN: Dropping unused variable c [test/compress/issue-1034.js:178,16]",
|
"INFO: Dropping unused variable b [test/compress/issue-1034.js:8,20]",
|
||||||
|
"INFO: Dropping unused variable c [test/compress/issue-1034.js:10,16]",
|
||||||
|
"INFO: pass 1: last_count: 46, count: 29",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
non_hoisted_function_after_return_2b_strict: {
|
non_hoisted_function_after_return_2b_strict: {
|
||||||
options = {
|
options = {
|
||||||
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
|
booleans: true,
|
||||||
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
|
collapse_vars: false,
|
||||||
if_return: true, join_vars: true, cascade: true, side_effects: true,
|
comparisons: true,
|
||||||
collapse_vars: false
|
conditionals: true,
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
hoist_funs: false,
|
||||||
|
if_return: true,
|
||||||
|
join_vars: true,
|
||||||
|
keep_fargs: true,
|
||||||
|
loops: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
"use strict";
|
"use strict";
|
||||||
@@ -242,11 +301,10 @@ non_hoisted_function_after_return_2b_strict: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "5 6"
|
expect_stdout: "5 6"
|
||||||
expect_warnings: [
|
expect_warnings: [
|
||||||
// duplicate warnings no longer emitted
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:7,16]",
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:225,16]",
|
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:7,16]",
|
||||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:225,16]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:9,12]",
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:227,12]",
|
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:9,12]",
|
||||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:227,12]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:13,12]",
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:231,12]",
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
const_pragma: {
|
const_pragma: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
};
|
}
|
||||||
|
|
||||||
input: {
|
input: {
|
||||||
/** @const */ var goog = goog || {};
|
/** @const */ var goog = goog || {};
|
||||||
@@ -16,8 +17,9 @@ const_pragma: {
|
|||||||
not_const: {
|
not_const: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
};
|
}
|
||||||
|
|
||||||
input: {
|
input: {
|
||||||
var goog = goog || {};
|
var goog = goog || {};
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ multiple_functions: {
|
|||||||
( function() {
|
( function() {
|
||||||
// NOTE: other compression steps will reduce this
|
// NOTE: other compression steps will reduce this
|
||||||
// down to just `window`.
|
// down to just `window`.
|
||||||
if ( window );
|
if ( !window );
|
||||||
function f() {}
|
function f() {}
|
||||||
function g() {}
|
function g() {}
|
||||||
} )();
|
} )();
|
||||||
@@ -38,7 +38,7 @@ single_function: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
( function() {
|
( function() {
|
||||||
if ( window );
|
if ( !window );
|
||||||
function f() {}
|
function f() {}
|
||||||
} )();
|
} )();
|
||||||
}
|
}
|
||||||
@@ -67,7 +67,7 @@ deeply_nested: {
|
|||||||
// NOTE: other compression steps will reduce this
|
// NOTE: other compression steps will reduce this
|
||||||
// down to just `window`.
|
// down to just `window`.
|
||||||
if ( window )
|
if ( window )
|
||||||
if (document);
|
if ( !document );
|
||||||
function f() {}
|
function f() {}
|
||||||
function g() {}
|
function g() {}
|
||||||
function h() {}
|
function h() {}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
with_in_global_scope: {
|
with_in_global_scope: {
|
||||||
options = {
|
options = {
|
||||||
unused: true
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var o = 42;
|
var o = 42;
|
||||||
@@ -18,7 +18,7 @@ with_in_global_scope: {
|
|||||||
}
|
}
|
||||||
with_in_function_scope: {
|
with_in_function_scope: {
|
||||||
options = {
|
options = {
|
||||||
unused: true
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function foo() {
|
function foo() {
|
||||||
@@ -40,7 +40,7 @@ with_in_function_scope: {
|
|||||||
}
|
}
|
||||||
compress_with_with_in_other_scope: {
|
compress_with_with_in_other_scope: {
|
||||||
options = {
|
options = {
|
||||||
unused: true
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function foo() {
|
function foo() {
|
||||||
@@ -69,7 +69,7 @@ compress_with_with_in_other_scope: {
|
|||||||
}
|
}
|
||||||
with_using_existing_variable_outside_scope: {
|
with_using_existing_variable_outside_scope: {
|
||||||
options = {
|
options = {
|
||||||
unused: true
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f() {
|
function f() {
|
||||||
@@ -99,7 +99,7 @@ with_using_existing_variable_outside_scope: {
|
|||||||
}
|
}
|
||||||
check_drop_unused_in_peer_function: {
|
check_drop_unused_in_peer_function: {
|
||||||
options = {
|
options = {
|
||||||
unused: true
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function outer() {
|
function outer() {
|
||||||
@@ -148,52 +148,57 @@ check_drop_unused_in_peer_function: {
|
|||||||
|
|
||||||
Infinity_not_in_with_scope: {
|
Infinity_not_in_with_scope: {
|
||||||
options = {
|
options = {
|
||||||
unused: true
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var o = { Infinity: 'oInfinity' };
|
var o = { Infinity: "FAIL" };
|
||||||
var vInfinity = "Infinity";
|
var vInfinity = "Infinity";
|
||||||
vInfinity = Infinity;
|
vInfinity = Infinity;
|
||||||
|
console.log(vInfinity);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var o = { Infinity: 'oInfinity' }
|
var o = { Infinity: "FAIL" };
|
||||||
var vInfinity = "Infinity"
|
var vInfinity = "Infinity";
|
||||||
vInfinity = 1/0
|
vInfinity = 1/0;
|
||||||
|
console.log(vInfinity);
|
||||||
}
|
}
|
||||||
|
expect_stdout: "Infinity"
|
||||||
}
|
}
|
||||||
|
|
||||||
Infinity_in_with_scope: {
|
Infinity_in_with_scope: {
|
||||||
options = {
|
options = {
|
||||||
unused: true
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var o = { Infinity: 'oInfinity' };
|
var o = { Infinity: "PASS" };
|
||||||
var vInfinity = "Infinity";
|
var vInfinity = "Infinity";
|
||||||
with (o) { vInfinity = Infinity; }
|
with (o) { vInfinity = Infinity; }
|
||||||
|
console.log(vInfinity);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var o = { Infinity: 'oInfinity' }
|
var o = { Infinity: "PASS" };
|
||||||
var vInfinity = "Infinity"
|
var vInfinity = "Infinity";
|
||||||
with (o) vInfinity = Infinity
|
with (o) vInfinity = Infinity;
|
||||||
|
console.log(vInfinity);
|
||||||
}
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
assorted_Infinity_NaN_undefined_in_with_scope: {
|
assorted_Infinity_NaN_undefined_in_with_scope: {
|
||||||
options = {
|
options = {
|
||||||
unused: true,
|
booleans: true,
|
||||||
evaluate: true,
|
comparisons: true,
|
||||||
dead_code: true,
|
conditionals: true,
|
||||||
conditionals: true,
|
dead_code: true,
|
||||||
comparisons: true,
|
evaluate: true,
|
||||||
booleans: true,
|
hoist_funs: true,
|
||||||
hoist_funs: true,
|
if_return: true,
|
||||||
keep_fargs: true,
|
join_vars: true,
|
||||||
if_return: true,
|
keep_fargs: true,
|
||||||
join_vars: true,
|
|
||||||
cascade: true,
|
|
||||||
side_effects: true,
|
|
||||||
sequences: false,
|
|
||||||
keep_infinity: false,
|
keep_infinity: false,
|
||||||
|
sequences: false,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var f = console.log;
|
var f = console.log;
|
||||||
@@ -243,20 +248,19 @@ assorted_Infinity_NaN_undefined_in_with_scope: {
|
|||||||
|
|
||||||
assorted_Infinity_NaN_undefined_in_with_scope_keep_infinity: {
|
assorted_Infinity_NaN_undefined_in_with_scope_keep_infinity: {
|
||||||
options = {
|
options = {
|
||||||
unused: true,
|
booleans: true,
|
||||||
evaluate: true,
|
comparisons: true,
|
||||||
dead_code: true,
|
conditionals: true,
|
||||||
conditionals: true,
|
dead_code: true,
|
||||||
comparisons: true,
|
evaluate: true,
|
||||||
booleans: true,
|
hoist_funs: true,
|
||||||
hoist_funs: true,
|
if_return: true,
|
||||||
keep_fargs: true,
|
join_vars: true,
|
||||||
if_return: true,
|
keep_fargs: true,
|
||||||
join_vars: true,
|
|
||||||
cascade: true,
|
|
||||||
side_effects: true,
|
|
||||||
sequences: false,
|
|
||||||
keep_infinity: true,
|
keep_infinity: true,
|
||||||
|
sequences: false,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var f = console.log;
|
var f = console.log;
|
||||||
|
|||||||
@@ -1,11 +1,15 @@
|
|||||||
keep_name_of_getter: {
|
keep_name_of_getter: {
|
||||||
options = { unused: true };
|
options = {
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
input: { a = { get foo () {} } }
|
input: { a = { get foo () {} } }
|
||||||
expect: { a = { get foo () {} } }
|
expect: { a = { get foo () {} } }
|
||||||
}
|
}
|
||||||
|
|
||||||
keep_name_of_setter: {
|
keep_name_of_setter: {
|
||||||
options = { unused: true };
|
options = {
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
input: { a = { set foo () {} } }
|
input: { a = { set foo () {} } }
|
||||||
expect: { a = { set foo () {} } }
|
expect: { a = { set foo () {} } }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
mangle_keep_fnames_false: {
|
mangle_keep_fnames_false: {
|
||||||
options = {
|
options = {
|
||||||
keep_fnames : true,
|
keep_fargs: true,
|
||||||
keep_fargs : true,
|
keep_fnames: true,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
keep_fnames : false,
|
keep_fnames : false,
|
||||||
@@ -26,8 +26,8 @@ mangle_keep_fnames_false: {
|
|||||||
|
|
||||||
mangle_keep_fnames_true: {
|
mangle_keep_fnames_true: {
|
||||||
options = {
|
options = {
|
||||||
keep_fnames : true,
|
keep_fargs: true,
|
||||||
keep_fargs : true,
|
keep_fnames: true,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
keep_fnames : true,
|
keep_fnames : true,
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
pure_function_calls: {
|
pure_function_calls: {
|
||||||
options = {
|
options = {
|
||||||
evaluate : true,
|
booleans: true,
|
||||||
conditionals : true,
|
comparisons: true,
|
||||||
comparisons : true,
|
conditionals: true,
|
||||||
side_effects : true,
|
evaluate: true,
|
||||||
booleans : true,
|
if_return: true,
|
||||||
unused : true,
|
join_vars: true,
|
||||||
if_return : true,
|
negate_iife: true,
|
||||||
join_vars : true,
|
side_effects: true,
|
||||||
cascade : true,
|
unused: true,
|
||||||
negate_iife : true,
|
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
// pure top-level IIFE will be dropped
|
// pure top-level IIFE will be dropped
|
||||||
@@ -49,29 +48,28 @@ pure_function_calls: {
|
|||||||
a.b(), f.g();
|
a.b(), f.g();
|
||||||
}
|
}
|
||||||
expect_warnings: [
|
expect_warnings: [
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:17,8]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:3,8]",
|
||||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:17,8]",
|
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:3,8]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:30,37]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:16,37]",
|
||||||
"WARN: Dropping unused variable iife2 [test/compress/issue-1261.js:30,16]",
|
"WARN: Dropping unused variable iife2 [test/compress/issue-1261.js:16,16]",
|
||||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:28,8]",
|
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:14,8]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:38,8]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:24,8]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:39,31]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:25,31]",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
pure_function_calls_toplevel: {
|
pure_function_calls_toplevel: {
|
||||||
options = {
|
options = {
|
||||||
evaluate : true,
|
booleans: true,
|
||||||
conditionals : true,
|
comparisons: true,
|
||||||
comparisons : true,
|
conditionals: true,
|
||||||
side_effects : true,
|
evaluate: true,
|
||||||
booleans : true,
|
if_return: true,
|
||||||
unused : true,
|
join_vars: true,
|
||||||
if_return : true,
|
negate_iife: true,
|
||||||
join_vars : true,
|
side_effects: true,
|
||||||
cascade : true,
|
toplevel: true,
|
||||||
negate_iife : true,
|
unused: true,
|
||||||
toplevel : true,
|
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
// pure top-level IIFE will be dropped
|
// pure top-level IIFE will be dropped
|
||||||
@@ -96,6 +94,13 @@ pure_function_calls_toplevel: {
|
|||||||
})();
|
})();
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
// pure top-level calls will be dropped regardless of the leading comments position
|
||||||
|
var MyClass = /*#__PURE__*//*@class*/(function(){
|
||||||
|
function MyClass() {}
|
||||||
|
MyClass.prototype.method = function() {};
|
||||||
|
return MyClass;
|
||||||
|
})();
|
||||||
|
|
||||||
// comment #__PURE__ comment
|
// comment #__PURE__ comment
|
||||||
bar(), baz(), quux();
|
bar(), baz(), quux();
|
||||||
a.b(), /* @__PURE__ */ c.d.e(), f.g();
|
a.b(), /* @__PURE__ */ c.d.e(), f.g();
|
||||||
@@ -105,15 +110,17 @@ pure_function_calls_toplevel: {
|
|||||||
a.b(), f.g();
|
a.b(), f.g();
|
||||||
}
|
}
|
||||||
expect_warnings: [
|
expect_warnings: [
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:79,8]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:3,8]",
|
||||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:79,8]",
|
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:3,8]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:92,37]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:16,37]",
|
||||||
"WARN: Dropping unused variable iife2 [test/compress/issue-1261.js:92,16]",
|
"WARN: Dropping unused variable iife2 [test/compress/issue-1261.js:16,16]",
|
||||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:90,8]",
|
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:14,8]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:100,8]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:31,8]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:101,31]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:32,31]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:84,33]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:8,33]",
|
||||||
"WARN: Dropping unused variable iife1 [test/compress/issue-1261.js:84,12]",
|
"WARN: Dropping unused variable iife1 [test/compress/issue-1261.js:8,12]",
|
||||||
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:24,45]",
|
||||||
|
"WARN: Dropping unused variable MyClass [test/compress/issue-1261.js:24,12]",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,29 +155,29 @@ should_warn: {
|
|||||||
baz();
|
baz();
|
||||||
}
|
}
|
||||||
expect_warnings: [
|
expect_warnings: [
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:128,61]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:1,61]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:128,23]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:1,23]",
|
||||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:128,23]",
|
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:1,23]",
|
||||||
"WARN: Boolean || always true [test/compress/issue-1261.js:129,23]",
|
"WARN: Boolean || always true [test/compress/issue-1261.js:2,23]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:129,23]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:2,23]",
|
||||||
"WARN: Condition always true [test/compress/issue-1261.js:129,23]",
|
"WARN: Condition always true [test/compress/issue-1261.js:2,23]",
|
||||||
"WARN: Condition left of || always true [test/compress/issue-1261.js:130,8]",
|
"WARN: Condition left of || always true [test/compress/issue-1261.js:3,8]",
|
||||||
"WARN: Condition always true [test/compress/issue-1261.js:130,8]",
|
"WARN: Condition always true [test/compress/issue-1261.js:3,8]",
|
||||||
"WARN: Boolean && always false [test/compress/issue-1261.js:131,23]",
|
"WARN: Boolean && always false [test/compress/issue-1261.js:4,23]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:131,23]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:4,23]",
|
||||||
"WARN: Condition always false [test/compress/issue-1261.js:131,23]",
|
"WARN: Condition always false [test/compress/issue-1261.js:4,23]",
|
||||||
"WARN: Condition left of && always false [test/compress/issue-1261.js:132,8]",
|
"WARN: Condition left of && always false [test/compress/issue-1261.js:5,8]",
|
||||||
"WARN: Condition always false [test/compress/issue-1261.js:132,8]",
|
"WARN: Condition always false [test/compress/issue-1261.js:5,8]",
|
||||||
"WARN: + in boolean context always true [test/compress/issue-1261.js:133,23]",
|
"WARN: + in boolean context always true [test/compress/issue-1261.js:6,23]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:133,23]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:6,23]",
|
||||||
"WARN: Condition always true [test/compress/issue-1261.js:133,23]",
|
"WARN: Condition always true [test/compress/issue-1261.js:6,23]",
|
||||||
"WARN: + in boolean context always true [test/compress/issue-1261.js:134,8]",
|
"WARN: + in boolean context always true [test/compress/issue-1261.js:7,8]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:134,31]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:7,31]",
|
||||||
"WARN: Condition always true [test/compress/issue-1261.js:134,8]",
|
"WARN: Condition always true [test/compress/issue-1261.js:7,8]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:135,23]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:8,23]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:136,24]",
|
"WARN: Condition always true [test/compress/issue-1261.js:9,8]",
|
||||||
"WARN: Condition always true [test/compress/issue-1261.js:136,8]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:9,24]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:137,31]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:10,31]",
|
||||||
"WARN: Condition always false [test/compress/issue-1261.js:137,8]",
|
"WARN: Condition always false [test/compress/issue-1261.js:10,8]",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,16 @@
|
|||||||
string_plus_optimization: {
|
string_plus_optimization: {
|
||||||
options = {
|
options = {
|
||||||
side_effects : true,
|
booleans: true,
|
||||||
evaluate : true,
|
comparisons: true,
|
||||||
conditionals : true,
|
conditionals: true,
|
||||||
comparisons : true,
|
dead_code: true,
|
||||||
dead_code : true,
|
evaluate: true,
|
||||||
booleans : true,
|
hoist_funs: true,
|
||||||
unused : true,
|
if_return: true,
|
||||||
if_return : true,
|
join_vars: true,
|
||||||
join_vars : true,
|
side_effects: true,
|
||||||
cascade : true,
|
unused: true,
|
||||||
hoist_funs : true,
|
}
|
||||||
};
|
|
||||||
input: {
|
input: {
|
||||||
function foo(anything) {
|
function foo(anything) {
|
||||||
function throwing_function() {
|
function throwing_function() {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
issue_1321_no_debug: {
|
issue_1321_no_debug: {
|
||||||
mangle_props = {
|
mangle = {
|
||||||
keep_quoted: true
|
properties: {
|
||||||
|
keep_quoted: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var x = {};
|
var x = {};
|
||||||
@@ -10,17 +12,19 @@ issue_1321_no_debug: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var x = {};
|
var x = {};
|
||||||
x.b = 1;
|
x.x = 1;
|
||||||
x["a"] = 2 * x.b;
|
x["a"] = 2 * x.x;
|
||||||
console.log(x.b, x["a"]);
|
console.log(x.x, x["a"]);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_1321_debug: {
|
issue_1321_debug: {
|
||||||
mangle_props = {
|
mangle = {
|
||||||
keep_quoted: true,
|
properties: {
|
||||||
debug: ""
|
debug: "",
|
||||||
|
keep_quoted: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var x = {};
|
var x = {};
|
||||||
@@ -30,16 +34,18 @@ issue_1321_debug: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var x = {};
|
var x = {};
|
||||||
x.a = 1;
|
x.x = 1;
|
||||||
x["_$foo$_"] = 2 * x.a;
|
x["_$foo$_"] = 2 * x.x;
|
||||||
console.log(x.a, x["_$foo$_"]);
|
console.log(x.x, x["_$foo$_"]);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_1321_with_quoted: {
|
issue_1321_with_quoted: {
|
||||||
mangle_props = {
|
mangle = {
|
||||||
keep_quoted: false
|
properties: {
|
||||||
|
keep_quoted: false,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var x = {};
|
var x = {};
|
||||||
@@ -49,9 +55,9 @@ issue_1321_with_quoted: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var x = {};
|
var x = {};
|
||||||
x.a = 1;
|
x.x = 1;
|
||||||
x["b"] = 2 * x.a;
|
x["o"] = 2 * x.x;
|
||||||
console.log(x.a, x["b"]);
|
console.log(x.x, x["o"]);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
tranformation_sort_order_equal: {
|
tranformation_sort_order_equal: {
|
||||||
options = {
|
options = {
|
||||||
comparisons: true,
|
comparisons: true,
|
||||||
};
|
}
|
||||||
|
|
||||||
input: { (a = parseInt('100')) == a }
|
input: { (a = parseInt('100')) == a }
|
||||||
expect: { (a = parseInt('100')) == a }
|
expect: { (a = parseInt('100')) == a }
|
||||||
@@ -24,7 +24,7 @@ tranformation_sort_order_equal: {
|
|||||||
tranformation_sort_order_unequal: {
|
tranformation_sort_order_unequal: {
|
||||||
options = {
|
options = {
|
||||||
comparisons: true,
|
comparisons: true,
|
||||||
};
|
}
|
||||||
|
|
||||||
input: { (a = parseInt('100')) != a }
|
input: { (a = parseInt('100')) != a }
|
||||||
expect: { (a = parseInt('100')) != a }
|
expect: { (a = parseInt('100')) != a }
|
||||||
@@ -33,7 +33,7 @@ tranformation_sort_order_unequal: {
|
|||||||
tranformation_sort_order_lesser_or_equal: {
|
tranformation_sort_order_lesser_or_equal: {
|
||||||
options = {
|
options = {
|
||||||
comparisons: true,
|
comparisons: true,
|
||||||
};
|
}
|
||||||
|
|
||||||
input: { (a = parseInt('100')) <= a }
|
input: { (a = parseInt('100')) <= a }
|
||||||
expect: { (a = parseInt('100')) <= a }
|
expect: { (a = parseInt('100')) <= a }
|
||||||
@@ -41,7 +41,7 @@ tranformation_sort_order_lesser_or_equal: {
|
|||||||
tranformation_sort_order_greater_or_equal: {
|
tranformation_sort_order_greater_or_equal: {
|
||||||
options = {
|
options = {
|
||||||
comparisons: true,
|
comparisons: true,
|
||||||
};
|
}
|
||||||
|
|
||||||
input: { (a = parseInt('100')) >= a }
|
input: { (a = parseInt('100')) >= a }
|
||||||
expect: { (a = parseInt('100')) >= a }
|
expect: { (a = parseInt('100')) >= a }
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
level_zero: {
|
level_zero: {
|
||||||
options = {
|
options = {
|
||||||
keep_fnames: true
|
keep_fnames: true,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
keep_fnames: true
|
keep_fnames: true
|
||||||
@@ -29,7 +29,7 @@ level_zero: {
|
|||||||
|
|
||||||
level_one: {
|
level_one: {
|
||||||
options = {
|
options = {
|
||||||
keep_fnames: true
|
keep_fnames: true,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
keep_fnames: true
|
keep_fnames: true
|
||||||
@@ -58,7 +58,7 @@ level_one: {
|
|||||||
|
|
||||||
level_two: {
|
level_two: {
|
||||||
options = {
|
options = {
|
||||||
keep_fnames: true
|
keep_fnames: true,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
keep_fnames: true
|
keep_fnames: true
|
||||||
@@ -97,7 +97,7 @@ level_two: {
|
|||||||
|
|
||||||
level_three: {
|
level_three: {
|
||||||
options = {
|
options = {
|
||||||
keep_fnames: true
|
keep_fnames: true,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
keep_fnames: true
|
keep_fnames: true
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ unsafe_undefined: {
|
|||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
if_return: true,
|
if_return: true,
|
||||||
unsafe: true
|
unsafe_undefined: true,
|
||||||
}
|
}
|
||||||
mangle = {}
|
mangle = {}
|
||||||
input: {
|
input: {
|
||||||
@@ -30,7 +30,7 @@ keep_fnames: {
|
|||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
if_return: true,
|
if_return: true,
|
||||||
unsafe: true
|
unsafe_undefined: true,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
keep_fnames: true
|
keep_fnames: true
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
typeof_eq_undefined: {
|
typeof_eq_undefined: {
|
||||||
options = {
|
options = {
|
||||||
comparisons: true
|
comparisons: true,
|
||||||
|
typeofs: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = typeof b != "undefined";
|
var a = typeof b != "undefined";
|
||||||
@@ -24,6 +25,7 @@ typeof_eq_undefined_ie8: {
|
|||||||
options = {
|
options = {
|
||||||
comparisons: true,
|
comparisons: true,
|
||||||
ie8: true,
|
ie8: true,
|
||||||
|
typeofs: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = typeof b != "undefined";
|
var a = typeof b != "undefined";
|
||||||
@@ -45,7 +47,8 @@ typeof_eq_undefined_ie8: {
|
|||||||
|
|
||||||
undefined_redefined: {
|
undefined_redefined: {
|
||||||
options = {
|
options = {
|
||||||
comparisons: true
|
comparisons: true,
|
||||||
|
typeofs: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f(undefined) {
|
function f(undefined) {
|
||||||
@@ -58,7 +61,8 @@ undefined_redefined: {
|
|||||||
|
|
||||||
undefined_redefined_mangle: {
|
undefined_redefined_mangle: {
|
||||||
options = {
|
options = {
|
||||||
comparisons: true
|
comparisons: true,
|
||||||
|
typeofs: true,
|
||||||
}
|
}
|
||||||
mangle = {}
|
mangle = {}
|
||||||
input: {
|
input: {
|
||||||
|
|||||||
@@ -22,18 +22,17 @@ else_with_empty_statement: {
|
|||||||
|
|
||||||
conditional_false_stray_else_in_loop: {
|
conditional_false_stray_else_in_loop: {
|
||||||
options = {
|
options = {
|
||||||
evaluate : true,
|
booleans: true,
|
||||||
comparisons : true,
|
comparisons: true,
|
||||||
booleans : true,
|
conditionals: false,
|
||||||
unused : true,
|
dead_code: true,
|
||||||
loops : true,
|
evaluate: true,
|
||||||
side_effects : true,
|
hoist_vars: true,
|
||||||
dead_code : true,
|
if_return: true,
|
||||||
hoist_vars : true,
|
join_vars: true,
|
||||||
join_vars : true,
|
loops: true,
|
||||||
if_return : true,
|
side_effects: true,
|
||||||
cascade : true,
|
unused: true,
|
||||||
conditionals : false,
|
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
for (var i = 1; i <= 4; ++i) {
|
for (var i = 1; i <= 4; ++i) {
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ unsafe_undefined: {
|
|||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
if_return: true,
|
if_return: true,
|
||||||
unsafe: true,
|
unsafe_undefined: true,
|
||||||
}
|
}
|
||||||
mangle = {}
|
mangle = {}
|
||||||
input: {
|
input: {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ chained_evaluation_1: {
|
|||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
@@ -28,6 +29,7 @@ chained_evaluation_2: {
|
|||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
@@ -50,3 +52,30 @@ chained_evaluation_2: {
|
|||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chained_evaluation_3: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: 10,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
var a = "long piece of string";
|
||||||
|
(function() {
|
||||||
|
var b = a, c;
|
||||||
|
c = f(b);
|
||||||
|
c.bar = b;
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
(function() {
|
||||||
|
f("long piece of string").bar = "long piece of string";
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
|
|
||||||
issue_1639_1: {
|
issue_1639_1: {
|
||||||
options = {
|
options = {
|
||||||
booleans: true,
|
booleans: true,
|
||||||
cascade: true,
|
collapse_vars: true,
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
join_vars: true,
|
join_vars: true,
|
||||||
@@ -12,7 +11,6 @@ issue_1639_1: {
|
|||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = 100, b = 10;
|
var a = 100, b = 10;
|
||||||
|
|
||||||
var L1 = 5;
|
var L1 = 5;
|
||||||
while (--L1 > 0) {
|
while (--L1 > 0) {
|
||||||
if ((--b), false) {
|
if ((--b), false) {
|
||||||
@@ -21,21 +19,21 @@ issue_1639_1: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(a, b);
|
console.log(a, b);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
for (var a = 100, b = 10, L1 = 5; --L1 > 0;)
|
for (var a = 100, b = 10, L1 = 5, ignore; --L1 > 0;) {
|
||||||
if (--b, !1) var ignore = 0;
|
--b;
|
||||||
|
}
|
||||||
console.log(a, b);
|
console.log(a, b);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: "100 6"
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_1639_2: {
|
issue_1639_2: {
|
||||||
options = {
|
options = {
|
||||||
booleans: true,
|
booleans: true,
|
||||||
cascade: true,
|
collapse_vars: true,
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
join_vars: true,
|
join_vars: true,
|
||||||
@@ -44,14 +42,12 @@ issue_1639_2: {
|
|||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = 100, b = 10;
|
var a = 100, b = 10;
|
||||||
|
|
||||||
function f19() {
|
function f19() {
|
||||||
if (++a, false)
|
if (++a, false)
|
||||||
if (a)
|
if (a)
|
||||||
if (++a);
|
if (++a);
|
||||||
}
|
}
|
||||||
f19();
|
f19();
|
||||||
|
|
||||||
console.log(a, b);
|
console.log(a, b);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
@@ -62,13 +58,13 @@ issue_1639_2: {
|
|||||||
f19(),
|
f19(),
|
||||||
console.log(a, b);
|
console.log(a, b);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: "101 10"
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_1639_3: {
|
issue_1639_3: {
|
||||||
options = {
|
options = {
|
||||||
booleans: true,
|
booleans: true,
|
||||||
cascade: true,
|
collapse_vars: true,
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
sequences: true,
|
sequences: true,
|
||||||
@@ -84,5 +80,5 @@ issue_1639_3: {
|
|||||||
a++,
|
a++,
|
||||||
console.log(a, b);
|
console.log(a, b);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: "101 10"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
f7: {
|
f7: {
|
||||||
options = {
|
options = {
|
||||||
booleans: true,
|
booleans: true,
|
||||||
cascade: true,
|
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
comparisons: true,
|
comparisons: true,
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
@@ -15,6 +14,7 @@ f7: {
|
|||||||
negate_iife: true,
|
negate_iife: true,
|
||||||
passes: 3,
|
passes: 3,
|
||||||
properties: true,
|
properties: true,
|
||||||
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
sequences: true,
|
sequences: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
@@ -35,11 +35,7 @@ f7: {
|
|||||||
console.log(a, b);
|
console.log(a, b);
|
||||||
}
|
}
|
||||||
expect_exact: [
|
expect_exact: [
|
||||||
"var b = 10;",
|
"console.log(100, 100);",
|
||||||
"",
|
|
||||||
"!function() {",
|
|
||||||
" for (;b = 100, !1; ) ;",
|
|
||||||
"}(), console.log(100, b);",
|
|
||||||
]
|
]
|
||||||
expect_stdout: true
|
expect_stdout: "100 100"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
side_effects_catch: {
|
side_effects_catch: {
|
||||||
options = {
|
options = {
|
||||||
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -34,6 +35,7 @@ side_effects_catch: {
|
|||||||
|
|
||||||
side_effects_else: {
|
side_effects_else: {
|
||||||
options = {
|
options = {
|
||||||
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -62,6 +64,7 @@ side_effects_else: {
|
|||||||
|
|
||||||
side_effects_finally: {
|
side_effects_finally: {
|
||||||
options = {
|
options = {
|
||||||
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -98,6 +101,7 @@ side_effects_finally: {
|
|||||||
|
|
||||||
side_effects_label: {
|
side_effects_label: {
|
||||||
options = {
|
options = {
|
||||||
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -130,6 +134,7 @@ side_effects_label: {
|
|||||||
|
|
||||||
side_effects_switch: {
|
side_effects_switch: {
|
||||||
options = {
|
options = {
|
||||||
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ mangle_catch_toplevel: {
|
|||||||
}
|
}
|
||||||
console.log(a);
|
console.log(a);
|
||||||
}
|
}
|
||||||
expect_exact: 'var o="FAIL";try{throw 1}catch(c){o="PASS"}console.log(o);'
|
expect_exact: 'var c="FAIL";try{throw 1}catch(o){c="PASS"}console.log(c);'
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,7 +148,7 @@ mangle_catch_var_toplevel: {
|
|||||||
}
|
}
|
||||||
console.log(a);
|
console.log(a);
|
||||||
}
|
}
|
||||||
expect_exact: 'var o="FAIL";try{throw 1}catch(r){var o="PASS"}console.log(o);'
|
expect_exact: 'var r="FAIL";try{throw 1}catch(o){var r="PASS"}console.log(r);'
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,3 +345,95 @@ mangle_catch_redef_2_ie8_toplevel: {
|
|||||||
expect_exact: 'try{throw"FAIL1"}catch(o){var o="FAIL2"}console.log(o);'
|
expect_exact: 'try{throw"FAIL1"}catch(o){var o="FAIL2"}console.log(o);'
|
||||||
expect_stdout: "undefined"
|
expect_stdout: "undefined"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mangle_catch_redef_3: {
|
||||||
|
mangle = {
|
||||||
|
ie8: false,
|
||||||
|
toplevel: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = "PASS";
|
||||||
|
try {
|
||||||
|
throw 0;
|
||||||
|
} catch (o) {
|
||||||
|
(function() {
|
||||||
|
function f() {
|
||||||
|
o = "FAIL";
|
||||||
|
}
|
||||||
|
f(), f();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
console.log(o);
|
||||||
|
}
|
||||||
|
expect_exact: 'var o="PASS";try{throw 0}catch(o){(function(){function c(){o="FAIL"}c(),c()})()}console.log(o);'
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
mangle_catch_redef_3_toplevel: {
|
||||||
|
mangle = {
|
||||||
|
ie8: false,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = "PASS";
|
||||||
|
try {
|
||||||
|
throw 0;
|
||||||
|
} catch (o) {
|
||||||
|
(function() {
|
||||||
|
function f() {
|
||||||
|
o = "FAIL";
|
||||||
|
}
|
||||||
|
f(), f();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
console.log(o);
|
||||||
|
}
|
||||||
|
expect_exact: 'var c="PASS";try{throw 0}catch(c){(function(){function o(){c="FAIL"}o(),o()})()}console.log(c);'
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
mangle_catch_redef_3_ie8: {
|
||||||
|
mangle = {
|
||||||
|
ie8: true,
|
||||||
|
toplevel: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = "PASS";
|
||||||
|
try {
|
||||||
|
throw 0;
|
||||||
|
} catch (o) {
|
||||||
|
(function() {
|
||||||
|
function f() {
|
||||||
|
o = "FAIL";
|
||||||
|
}
|
||||||
|
f(), f();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
console.log(o);
|
||||||
|
}
|
||||||
|
expect_exact: 'var o="PASS";try{throw 0}catch(o){(function(){function c(){o="FAIL"}c(),c()})()}console.log(o);'
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
mangle_catch_redef_3_ie8_toplevel: {
|
||||||
|
mangle = {
|
||||||
|
ie8: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = "PASS";
|
||||||
|
try {
|
||||||
|
throw 0;
|
||||||
|
} catch (o) {
|
||||||
|
(function() {
|
||||||
|
function f() {
|
||||||
|
o = "FAIL";
|
||||||
|
}
|
||||||
|
f(), f();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
console.log(o);
|
||||||
|
}
|
||||||
|
expect_exact: 'var c="PASS";try{throw 0}catch(c){(function(){function o(){c="FAIL"}o(),o()})()}console.log(c);'
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ function_iife_catch: {
|
|||||||
}
|
}
|
||||||
f();
|
f();
|
||||||
}
|
}
|
||||||
expect_exact: "function f(o){!function(){try{throw 0}catch(c){var o=1;console.log(c,o)}}()}f();"
|
expect_exact: "function f(o){!function(){try{throw 0}catch(o){var c=1;console.log(o,c)}}()}f();"
|
||||||
expect_stdout: "0 1"
|
expect_stdout: "0 1"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ function_iife_catch_ie8: {
|
|||||||
}
|
}
|
||||||
f();
|
f();
|
||||||
}
|
}
|
||||||
expect_exact: "function f(o){!function(){try{throw 0}catch(o){var c=1;console.log(o,c)}}()}f();"
|
expect_exact: "function f(c){!function(){try{throw 0}catch(c){var o=1;console.log(c,o)}}()}f();"
|
||||||
expect_stdout: "0 1"
|
expect_stdout: "0 1"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ function_catch_catch: {
|
|||||||
}
|
}
|
||||||
f();
|
f();
|
||||||
}
|
}
|
||||||
expect_exact: "var o=0;function f(){try{throw 1}catch(c){try{throw 2}catch(o){var o=3;console.log(o)}}console.log(o)}f();"
|
expect_exact: "var o=0;function f(){try{throw 1}catch(o){try{throw 2}catch(c){var c=3;console.log(c)}}console.log(c)}f();"
|
||||||
expect_stdout: [
|
expect_stdout: [
|
||||||
"3",
|
"3",
|
||||||
"undefined",
|
"undefined",
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ case_1: {
|
|||||||
input: {
|
input: {
|
||||||
var a = 0, b = 1;
|
var a = 0, b = 1;
|
||||||
switch (true) {
|
switch (true) {
|
||||||
case a, true:
|
case a || true:
|
||||||
default:
|
default:
|
||||||
b = 2;
|
b = 2;
|
||||||
case true:
|
case true:
|
||||||
@@ -17,7 +17,7 @@ case_1: {
|
|||||||
expect: {
|
expect: {
|
||||||
var a = 0, b = 1;
|
var a = 0, b = 1;
|
||||||
switch (true) {
|
switch (true) {
|
||||||
case a, true:
|
case a || true:
|
||||||
b = 2;
|
b = 2;
|
||||||
}
|
}
|
||||||
console.log(a, b);
|
console.log(a, b);
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
mangle_props: {
|
mangle_props: {
|
||||||
mangle_props = {}
|
mangle = {
|
||||||
|
properties: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
var obj = {
|
var obj = {
|
||||||
undefined: 1,
|
undefined: 1,
|
||||||
@@ -44,7 +46,7 @@ mangle_props: {
|
|||||||
obj[1/0],
|
obj[1/0],
|
||||||
obj["Infinity"],
|
obj["Infinity"],
|
||||||
obj[-1/0],
|
obj[-1/0],
|
||||||
obj[-1/0],
|
obj[-(1/0)],
|
||||||
obj["-Infinity"],
|
obj["-Infinity"],
|
||||||
obj[null],
|
obj[null],
|
||||||
obj["null"]
|
obj["null"]
|
||||||
@@ -54,10 +56,12 @@ mangle_props: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
numeric_literal: {
|
numeric_literal: {
|
||||||
|
mangle = {
|
||||||
|
properties: true,
|
||||||
|
}
|
||||||
beautify = {
|
beautify = {
|
||||||
beautify: true,
|
beautify: true,
|
||||||
}
|
}
|
||||||
mangle_props = {}
|
|
||||||
input: {
|
input: {
|
||||||
var obj = {
|
var obj = {
|
||||||
0: 0,
|
0: 0,
|
||||||
@@ -80,19 +84,19 @@ numeric_literal: {
|
|||||||
' 0: 0,',
|
' 0: 0,',
|
||||||
' "-0": 1,',
|
' "-0": 1,',
|
||||||
' 42: 2,',
|
' 42: 2,',
|
||||||
' "42": 3,',
|
' 42: 3,',
|
||||||
' 37: 4,',
|
' 37: 4,',
|
||||||
' a: 5,',
|
' o: 5,',
|
||||||
' 1e42: 6,',
|
' 1e42: 6,',
|
||||||
' b: 7,',
|
' b: 7,',
|
||||||
' "1e+42": 8',
|
' 1e42: 8',
|
||||||
'};',
|
'};',
|
||||||
'',
|
'',
|
||||||
'console.log(obj[-0], obj[-""], obj["-0"]);',
|
'console.log(obj[-0], obj[-""], obj["-0"]);',
|
||||||
'',
|
'',
|
||||||
'console.log(obj[42], obj["42"]);',
|
'console.log(obj[42], obj["42"]);',
|
||||||
'',
|
'',
|
||||||
'console.log(obj[37], obj["a"], obj[37], obj["37"]);',
|
'console.log(obj[37], obj["o"], obj[37], obj["37"]);',
|
||||||
'',
|
'',
|
||||||
'console.log(obj[1e42], obj["b"], obj["1e+42"]);',
|
'console.log(obj[1e42], obj["b"], obj["1e+42"]);',
|
||||||
]
|
]
|
||||||
@@ -105,7 +109,9 @@ numeric_literal: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
identifier: {
|
identifier: {
|
||||||
mangle_props = {}
|
mangle = {
|
||||||
|
properties: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
var obj = {
|
var obj = {
|
||||||
abstract: 1,
|
abstract: 1,
|
||||||
@@ -173,32 +179,32 @@ identifier: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var obj = {
|
var obj = {
|
||||||
a: 1,
|
e: 1,
|
||||||
b: 2,
|
t: 2,
|
||||||
c: 3,
|
n: 3,
|
||||||
d: 4,
|
a: 4,
|
||||||
e: 5,
|
i: 5,
|
||||||
f: 6,
|
o: 6,
|
||||||
g: 7,
|
r: 7,
|
||||||
h: 8,
|
l: 8,
|
||||||
i: 9,
|
s: 9,
|
||||||
j: 10,
|
c: 10,
|
||||||
k: 11,
|
f: 11,
|
||||||
l: 12,
|
u: 12,
|
||||||
m: 13,
|
d: 13,
|
||||||
n: 14,
|
h: 14,
|
||||||
o: 15,
|
p: 15,
|
||||||
p: 16,
|
b: 16,
|
||||||
q: 17,
|
v: 17,
|
||||||
r: 18,
|
w: 18,
|
||||||
s: 19,
|
y: 19,
|
||||||
t: 20,
|
g: 20,
|
||||||
u: 21,
|
m: 21,
|
||||||
v: 22,
|
k: 22,
|
||||||
w: 23,
|
x: 23,
|
||||||
x: 24,
|
j: 24,
|
||||||
y: 25,
|
z: 25,
|
||||||
z: 26,
|
q: 26,
|
||||||
A: 27,
|
A: 27,
|
||||||
B: 28,
|
B: 28,
|
||||||
C: 29,
|
C: 29,
|
||||||
@@ -229,11 +235,11 @@ identifier: {
|
|||||||
Z: 54,
|
Z: 54,
|
||||||
$: 55,
|
$: 55,
|
||||||
_: 56,
|
_: 56,
|
||||||
aa: 57,
|
ee: 57,
|
||||||
ba: 58,
|
te: 58,
|
||||||
ca: 59,
|
ne: 59,
|
||||||
da: 60,
|
ae: 60,
|
||||||
ea: 61,
|
ie: 61,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
unary_prefix: {
|
unary_prefix: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
iife_for: {
|
iife_for: {
|
||||||
options = {
|
options = {
|
||||||
negate_iife: true,
|
negate_iife: true,
|
||||||
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -26,6 +27,7 @@ iife_for: {
|
|||||||
iife_for_in: {
|
iife_for_in: {
|
||||||
options = {
|
options = {
|
||||||
negate_iife: true,
|
negate_iife: true,
|
||||||
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -51,6 +53,7 @@ iife_for_in: {
|
|||||||
iife_do: {
|
iife_do: {
|
||||||
options = {
|
options = {
|
||||||
negate_iife: true,
|
negate_iife: true,
|
||||||
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -80,6 +83,7 @@ iife_do: {
|
|||||||
iife_while: {
|
iife_while: {
|
||||||
options = {
|
options = {
|
||||||
negate_iife: true,
|
negate_iife: true,
|
||||||
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -121,8 +125,8 @@ label_do: {
|
|||||||
|
|
||||||
label_while: {
|
label_while: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
loops: true,
|
loops: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -130,5 +134,5 @@ label_while: {
|
|||||||
L: while (0) continue L;
|
L: while (0) continue L;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect_exact: "function f(){L:;}"
|
expect_exact: "function f(){L:0}"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
do_not_update_lhs: {
|
do_not_update_lhs: {
|
||||||
options = {
|
options = {
|
||||||
global_defs: { DEBUG: 0 }
|
global_defs: {
|
||||||
|
DEBUG: 0,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
DEBUG++;
|
DEBUG++;
|
||||||
@@ -16,7 +18,9 @@ do_not_update_lhs: {
|
|||||||
|
|
||||||
do_update_rhs: {
|
do_update_rhs: {
|
||||||
options = {
|
options = {
|
||||||
global_defs: { DEBUG: 0 }
|
global_defs: {
|
||||||
|
DEBUG: 0,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
MY_DEBUG = DEBUG;
|
MY_DEBUG = DEBUG;
|
||||||
@@ -35,7 +39,7 @@ mixed: {
|
|||||||
DEBUG: 0,
|
DEBUG: 0,
|
||||||
ENV: 1,
|
ENV: 1,
|
||||||
FOO: 2,
|
FOO: 2,
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var ENV = 3;
|
var ENV = 3;
|
||||||
@@ -60,11 +64,11 @@ mixed: {
|
|||||||
x = 0;
|
x = 0;
|
||||||
}
|
}
|
||||||
expect_warnings: [
|
expect_warnings: [
|
||||||
'WARN: global_defs ENV redefined [test/compress/issue-208.js:41,12]',
|
"WARN: global_defs ENV redefined [test/compress/issue-208.js:1,12]",
|
||||||
'WARN: global_defs FOO redefined [test/compress/issue-208.js:42,12]',
|
"WARN: global_defs FOO redefined [test/compress/issue-208.js:2,12]",
|
||||||
'WARN: global_defs FOO redefined [test/compress/issue-208.js:44,10]',
|
"WARN: global_defs FOO redefined [test/compress/issue-208.js:4,10]",
|
||||||
'WARN: global_defs DEBUG redefined [test/compress/issue-208.js:45,8]',
|
"WARN: global_defs DEBUG redefined [test/compress/issue-208.js:5,8]",
|
||||||
'WARN: global_defs DEBUG redefined [test/compress/issue-208.js:46,8]',
|
"WARN: global_defs DEBUG redefined [test/compress/issue-208.js:6,8]",
|
||||||
'WARN: global_defs DEBUG redefined [test/compress/issue-208.js:47,8]',
|
"WARN: global_defs DEBUG redefined [test/compress/issue-208.js:7,8]",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
return_with_no_value_in_if_body: {
|
return_with_no_value_in_if_body: {
|
||||||
options = { conditionals: true };
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
function foo(bar) {
|
function foo(bar) {
|
||||||
if (bar) {
|
if (bar) {
|
||||||
|
|||||||
33
test/compress/issue-2652.js
Normal file
33
test/compress/issue-2652.js
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
insert_semicolon: {
|
||||||
|
beautify = {
|
||||||
|
beautify: true,
|
||||||
|
comments: "all",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a
|
||||||
|
/* foo */ var b
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"var a",
|
||||||
|
"/* foo */;",
|
||||||
|
"",
|
||||||
|
"var b;",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
unary_postfix: {
|
||||||
|
beautify = {
|
||||||
|
beautify: true,
|
||||||
|
comments: "all",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
a
|
||||||
|
/* foo */++b
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"a",
|
||||||
|
"/* foo */;",
|
||||||
|
"",
|
||||||
|
"++b;",
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
issue_267: {
|
issue_267: {
|
||||||
options = { comparisons: true };
|
options = {
|
||||||
|
comparisons: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
x = a % b / b * c * 2;
|
x = a % b / b * c * 2;
|
||||||
x = a % b * 2
|
x = a % b * 2
|
||||||
|
|||||||
@@ -1,66 +1,111 @@
|
|||||||
issue_269_1: {
|
issue_269_1: {
|
||||||
options = {unsafe: true};
|
options = {
|
||||||
input: {
|
unsafe: true,
|
||||||
f(
|
}
|
||||||
String(x),
|
input: {
|
||||||
Number(x),
|
var x = {};
|
||||||
Boolean(x),
|
console.log(
|
||||||
|
String(x),
|
||||||
|
Number(x),
|
||||||
|
Boolean(x),
|
||||||
|
|
||||||
String(),
|
String(),
|
||||||
Number(),
|
Number(),
|
||||||
Boolean()
|
Boolean()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
f(
|
var x = {};
|
||||||
x + '', +x, !!x,
|
console.log(
|
||||||
'', 0, false
|
x + "", +x, !!x,
|
||||||
);
|
"", 0, false
|
||||||
}
|
);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_269_dangers: {
|
issue_269_dangers: {
|
||||||
options = {unsafe: true};
|
options = {
|
||||||
input: {
|
unsafe: true,
|
||||||
f(
|
}
|
||||||
String(x, x),
|
input: {
|
||||||
Number(x, x),
|
var x = {};
|
||||||
Boolean(x, x)
|
console.log(
|
||||||
);
|
String(x, x),
|
||||||
}
|
Number(x, x),
|
||||||
expect: {
|
Boolean(x, x)
|
||||||
f(String(x, x), Number(x, x), Boolean(x, x));
|
);
|
||||||
}
|
}
|
||||||
|
expect: {
|
||||||
|
var x = {};
|
||||||
|
console.log(String(x, x), Number(x, x), Boolean(x, x));
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_269_in_scope: {
|
issue_269_in_scope: {
|
||||||
options = {unsafe: true};
|
options = {
|
||||||
input: {
|
unsafe: true,
|
||||||
var String, Number, Boolean;
|
}
|
||||||
f(
|
input: {
|
||||||
String(x),
|
var String, Number, Boolean;
|
||||||
Number(x, x),
|
var x = {};
|
||||||
Boolean(x)
|
console.log(
|
||||||
);
|
String(x),
|
||||||
}
|
Number(x, x),
|
||||||
expect: {
|
Boolean(x)
|
||||||
var String, Number, Boolean;
|
);
|
||||||
f(String(x), Number(x, x), Boolean(x));
|
}
|
||||||
}
|
expect: {
|
||||||
|
var String, Number, Boolean;
|
||||||
|
var x = {};
|
||||||
|
console.log(String(x), Number(x, x), Boolean(x));
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
strings_concat: {
|
strings_concat: {
|
||||||
options = {unsafe: true};
|
options = {
|
||||||
input: {
|
strings: true,
|
||||||
f(
|
unsafe: true,
|
||||||
String(x + 'str'),
|
}
|
||||||
String('str' + x)
|
input: {
|
||||||
);
|
var x = {};
|
||||||
}
|
console.log(
|
||||||
expect: {
|
String(x + "str"),
|
||||||
f(
|
String("str" + x)
|
||||||
x + 'str',
|
);
|
||||||
'str' + x
|
}
|
||||||
);
|
expect: {
|
||||||
}
|
var x = {};
|
||||||
|
console.log(
|
||||||
|
x + "str",
|
||||||
|
"str" + x
|
||||||
|
);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
regexp: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
RegExp("foo");
|
||||||
|
RegExp("bar", "ig");
|
||||||
|
RegExp(foo);
|
||||||
|
RegExp("bar", ig);
|
||||||
|
RegExp("should", "fail");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
/foo/;
|
||||||
|
/bar/ig;
|
||||||
|
RegExp(foo);
|
||||||
|
RegExp("bar", ig);
|
||||||
|
RegExp("should", "fail");
|
||||||
|
}
|
||||||
|
expect_warnings: [
|
||||||
|
'WARN: Error converting RegExp("should","fail") [test/compress/issue-269.js:5,8]',
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
32
test/compress/issue-2719.js
Normal file
32
test/compress/issue-2719.js
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
warn: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
passes: 2,
|
||||||
|
properties: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
return g();
|
||||||
|
}
|
||||||
|
function g() {
|
||||||
|
return g["call" + "er"].arguments;
|
||||||
|
}
|
||||||
|
// 3
|
||||||
|
console.log(f(1, 2, 3).length);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
// TypeError: Cannot read property 'arguments' of null
|
||||||
|
console.log(function g() {
|
||||||
|
return g.caller.arguments;
|
||||||
|
}().length);
|
||||||
|
}
|
||||||
|
expect_warnings: [
|
||||||
|
"WARN: Function.prototype.arguments not supported [test/compress/issue-2719.js:5,19]",
|
||||||
|
"WARN: Function.prototype.caller not supported [test/compress/issue-2719.js:5,19]",
|
||||||
|
]
|
||||||
|
}
|
||||||
498
test/compress/issue-281.js
Normal file
498
test/compress/issue-281.js
Normal file
@@ -0,0 +1,498 @@
|
|||||||
|
collapse_vars_constants: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f1(x) {
|
||||||
|
var a = 4, b = x.prop, c = 5, d = sideeffect1(), e = sideeffect2();
|
||||||
|
return b + (function() { return d - a * e - c; })();
|
||||||
|
}
|
||||||
|
function f2(x) {
|
||||||
|
var a = 4, b = x.prop, c = 5, not_used = sideeffect1(), e = sideeffect2();
|
||||||
|
return b + (function() { return -a * e - c; })();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f1(x) {
|
||||||
|
var b = x.prop, d = sideeffect1(), e = sideeffect2();
|
||||||
|
return b + (d - 4 * e - 5);
|
||||||
|
}
|
||||||
|
function f2(x) {
|
||||||
|
var b = x.prop;
|
||||||
|
sideeffect1();
|
||||||
|
return b + (-4 * sideeffect2() - 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
modified: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f5(b) {
|
||||||
|
var a = function() {
|
||||||
|
return b;
|
||||||
|
}();
|
||||||
|
return b++ + a;
|
||||||
|
}
|
||||||
|
console.log(f5(1));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f5(b) {
|
||||||
|
var a = b;
|
||||||
|
return b++ + a;
|
||||||
|
}
|
||||||
|
console.log(f5(1));
|
||||||
|
}
|
||||||
|
expect_stdout: "2"
|
||||||
|
}
|
||||||
|
|
||||||
|
ref_scope: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
var a = 1, b = 2, c = 3;
|
||||||
|
var a = c++, b = b /= a;
|
||||||
|
return function() {
|
||||||
|
return a;
|
||||||
|
}() + b;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
var a = 1, b = 2, c = 3;
|
||||||
|
b = b /= a = c++;
|
||||||
|
return a + b;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
safe_undefined: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
if_return: true,
|
||||||
|
inline: true,
|
||||||
|
unsafe: false,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
mangle = {}
|
||||||
|
input: {
|
||||||
|
var a, c;
|
||||||
|
console.log(function(undefined) {
|
||||||
|
return function() {
|
||||||
|
if (a)
|
||||||
|
return b;
|
||||||
|
if (c)
|
||||||
|
return d;
|
||||||
|
};
|
||||||
|
}(1)());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a, c;
|
||||||
|
console.log(a ? b : c ? d : void 0);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
negate_iife_3: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
expression: true,
|
||||||
|
inline: true,
|
||||||
|
negate_iife: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
t ? console.log(true) : console.log(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
negate_iife_3_off: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
expression: true,
|
||||||
|
inline: true,
|
||||||
|
negate_iife: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
t ? console.log(true) : console.log(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
negate_iife_4: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
expression: true,
|
||||||
|
inline: true,
|
||||||
|
negate_iife: true,
|
||||||
|
sequences: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||||
|
(function(){
|
||||||
|
console.log("something");
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
t ? console.log(true) : console.log(false), void console.log("something");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
negate_iife_5: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
expression: true,
|
||||||
|
inline: true,
|
||||||
|
negate_iife: true,
|
||||||
|
sequences: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
if ((function(){ return t })()) {
|
||||||
|
foo(true);
|
||||||
|
} else {
|
||||||
|
bar(false);
|
||||||
|
}
|
||||||
|
(function(){
|
||||||
|
console.log("something");
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
t ? foo(true) : bar(false), void console.log("something");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
negate_iife_5_off: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
expression: true,
|
||||||
|
inline: true,
|
||||||
|
negate_iife: false,
|
||||||
|
sequences: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
if ((function(){ return t })()) {
|
||||||
|
foo(true);
|
||||||
|
} else {
|
||||||
|
bar(false);
|
||||||
|
}
|
||||||
|
(function(){
|
||||||
|
console.log("something");
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
t ? foo(true) : bar(false), void console.log("something");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1254_negate_iife_true: {
|
||||||
|
options = {
|
||||||
|
expression: true,
|
||||||
|
inline: true,
|
||||||
|
negate_iife: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
return function() {
|
||||||
|
console.log('test')
|
||||||
|
};
|
||||||
|
})()();
|
||||||
|
}
|
||||||
|
expect_exact: 'void console.log("test");'
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1254_negate_iife_nested: {
|
||||||
|
options = {
|
||||||
|
expression: true,
|
||||||
|
inline: true,
|
||||||
|
negate_iife: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
return function() {
|
||||||
|
console.log('test')
|
||||||
|
};
|
||||||
|
})()()()()();
|
||||||
|
}
|
||||||
|
expect_exact: '(void console.log("test"))()()();'
|
||||||
|
}
|
||||||
|
|
||||||
|
negate_iife_issue_1073: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
negate_iife: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
new (function(a) {
|
||||||
|
return function Foo() {
|
||||||
|
this.x = a;
|
||||||
|
console.log(this);
|
||||||
|
};
|
||||||
|
}(7))();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
new function() {
|
||||||
|
this.x = 7,
|
||||||
|
console.log(this);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1288_side_effects: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
negate_iife: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
if (w) ;
|
||||||
|
else {
|
||||||
|
(function f() {})();
|
||||||
|
}
|
||||||
|
if (!x) {
|
||||||
|
(function() {
|
||||||
|
x = {};
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
if (y)
|
||||||
|
(function() {})();
|
||||||
|
else
|
||||||
|
(function(z) {
|
||||||
|
return z;
|
||||||
|
})(0);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
w;
|
||||||
|
x || (x = {});
|
||||||
|
y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inner_var_for_in_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
var a = 1, b = 2;
|
||||||
|
for (b in (function() {
|
||||||
|
return x(a, b, c);
|
||||||
|
})()) {
|
||||||
|
var c = 3, d = 4;
|
||||||
|
x(a, b, c, d);
|
||||||
|
}
|
||||||
|
x(a, b, c, d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
var a = 1, b = 2;
|
||||||
|
for (b in x(1, b, c)) {
|
||||||
|
var c = 3, d = 4;
|
||||||
|
x(1, b, c, d);
|
||||||
|
}
|
||||||
|
x(1, b, c, d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1595_3: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
passes: 2,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function f(a) {
|
||||||
|
return g(a + 1);
|
||||||
|
})(2);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
g(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1758: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(c) {
|
||||||
|
var undefined = 42;
|
||||||
|
return function() {
|
||||||
|
c--;
|
||||||
|
c--, c.toString();
|
||||||
|
return;
|
||||||
|
}();
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(c) {
|
||||||
|
var undefined = 42;
|
||||||
|
return c--, c--, void c.toString();
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
wrap_iife: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
negate_iife: false,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
wrap_iife: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
return function() {
|
||||||
|
console.log('test')
|
||||||
|
};
|
||||||
|
})()();
|
||||||
|
}
|
||||||
|
expect_exact: 'void console.log("test");'
|
||||||
|
}
|
||||||
|
|
||||||
|
wrap_iife_in_expression: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
negate_iife: false,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
wrap_iife: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
foo = (function() {
|
||||||
|
return bar();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_exact: 'foo=bar();'
|
||||||
|
}
|
||||||
|
|
||||||
|
wrap_iife_in_return_call: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
negate_iife: false,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
wrap_iife: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
return (function() {
|
||||||
|
console.log('test')
|
||||||
|
})();
|
||||||
|
})()();
|
||||||
|
}
|
||||||
|
expect_exact: '(void console.log("test"))();'
|
||||||
|
}
|
||||||
|
|
||||||
|
pure_annotation_1: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
/*@__PURE__*/(function() {
|
||||||
|
console.log("hello");
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_exact: ""
|
||||||
|
}
|
||||||
|
|
||||||
|
pure_annotation_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
/*@__PURE__*/(function(n) {
|
||||||
|
console.log("hello", n);
|
||||||
|
}(42));
|
||||||
|
}
|
||||||
|
expect_exact: ""
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_fargs: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 1;
|
||||||
|
!function(a_1) {
|
||||||
|
a++;
|
||||||
|
}(a++ + (a && a.var));
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 1;
|
||||||
|
++a && a.var, a++;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "3"
|
||||||
|
}
|
||||||
|
|
||||||
|
keep_fargs: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
keep_fargs: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 1;
|
||||||
|
!function(a_1) {
|
||||||
|
a++;
|
||||||
|
}(a++ + (a && a.var));
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 1;
|
||||||
|
++a && a.var, a++;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "3"
|
||||||
|
}
|
||||||
37
test/compress/issue-2871.js
Normal file
37
test/compress/issue-2871.js
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
comparison_with_undefined: {
|
||||||
|
options = {
|
||||||
|
comparisons: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
a == undefined;
|
||||||
|
a != undefined;
|
||||||
|
a === undefined;
|
||||||
|
a !== undefined;
|
||||||
|
|
||||||
|
undefined == a;
|
||||||
|
undefined != a;
|
||||||
|
undefined === a;
|
||||||
|
undefined !== a;
|
||||||
|
|
||||||
|
void 0 == a;
|
||||||
|
void 0 != a;
|
||||||
|
void 0 === a;
|
||||||
|
void 0 !== a;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
null == a;
|
||||||
|
null != a;
|
||||||
|
void 0 === a;
|
||||||
|
void 0 !== a;
|
||||||
|
|
||||||
|
null == a;
|
||||||
|
null != a;
|
||||||
|
void 0 === a;
|
||||||
|
void 0 !== a;
|
||||||
|
|
||||||
|
null == a;
|
||||||
|
null != a;
|
||||||
|
void 0 === a;
|
||||||
|
void 0 !== a;
|
||||||
|
}
|
||||||
|
}
|
||||||
21
test/compress/issue-2989.js
Normal file
21
test/compress/issue-2989.js
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
inline_script_off: {
|
||||||
|
beautify = {
|
||||||
|
inline_script: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log("</sCrIpT>");
|
||||||
|
}
|
||||||
|
expect_exact: 'console.log("</sCrIpT>");'
|
||||||
|
expect_stdout: "</sCrIpT>"
|
||||||
|
}
|
||||||
|
|
||||||
|
inline_script_on: {
|
||||||
|
beautify = {
|
||||||
|
inline_script: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log("</sCrIpT>");
|
||||||
|
}
|
||||||
|
expect_exact: 'console.log("<\\/sCrIpT>");'
|
||||||
|
expect_stdout: "</sCrIpT>"
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
collapse: {
|
collapse: {
|
||||||
options = {
|
options = {
|
||||||
cascade: true,
|
collapse_vars: true,
|
||||||
sequences: true,
|
sequences: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -41,7 +41,7 @@ collapse: {
|
|||||||
return void 0 !== ('function' === typeof b ? b() : b) && c();
|
return void 0 !== ('function' === typeof b ? b() : b) && c();
|
||||||
}
|
}
|
||||||
function f2(b) {
|
function f2(b) {
|
||||||
return b = c(), 'stirng' == typeof ('function' === typeof b ? b() : b) && d();
|
return 'stirng' == typeof ('function' === typeof (b = c()) ? b() : b) && d();
|
||||||
}
|
}
|
||||||
function f3(c) {
|
function f3(c) {
|
||||||
var a;
|
var a;
|
||||||
|
|||||||
128
test/compress/issue-3768.js
Normal file
128
test/compress/issue-3768.js
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
mangle: {
|
||||||
|
mangle = {
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var e = eval, x = 42;
|
||||||
|
(function() {
|
||||||
|
console.log(e("typeof x"));
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var e = eval, x = 42;
|
||||||
|
(function() {
|
||||||
|
console.log(e("typeof x"));
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
compress: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
var a = 42;
|
||||||
|
return eval("typeof a");
|
||||||
|
}(), function(e) {
|
||||||
|
var a = null;
|
||||||
|
return e("typeof a");
|
||||||
|
}(eval), function(eval) {
|
||||||
|
var a = false;
|
||||||
|
return eval("typeof a");
|
||||||
|
}(eval), function(f) {
|
||||||
|
var a = "STRING";
|
||||||
|
var eval = f;
|
||||||
|
return eval("typeof a");
|
||||||
|
}(eval), function(g) {
|
||||||
|
var a = eval;
|
||||||
|
function eval() {
|
||||||
|
return g;
|
||||||
|
}
|
||||||
|
return eval()("typeof a");
|
||||||
|
}(eval));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
var a = 42;
|
||||||
|
return eval("typeof a");
|
||||||
|
}(), (0, eval)("typeof a"), function(eval) {
|
||||||
|
var a = false;
|
||||||
|
return eval("typeof a");
|
||||||
|
}(eval), function(f) {
|
||||||
|
var a = "STRING";
|
||||||
|
var eval = f;
|
||||||
|
return eval("typeof a");
|
||||||
|
}(eval), function(g) {
|
||||||
|
var a = eval;
|
||||||
|
function eval() {
|
||||||
|
return g;
|
||||||
|
}
|
||||||
|
return eval()("typeof a");
|
||||||
|
}(eval));
|
||||||
|
}
|
||||||
|
expect_stdout: "number undefined boolean string undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
call_arg_1: {
|
||||||
|
mangle = {
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var z = "foo";
|
||||||
|
(function() {
|
||||||
|
var z = false;
|
||||||
|
(function(e) {
|
||||||
|
var z = 42;
|
||||||
|
e("console.log(typeof z)");
|
||||||
|
})(eval);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var z = "foo";
|
||||||
|
(function() {
|
||||||
|
var o = false;
|
||||||
|
(function(o) {
|
||||||
|
var a = 42;
|
||||||
|
o("console.log(typeof z)");
|
||||||
|
})(eval);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
call_arg_2: {
|
||||||
|
mangle = {
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function eval() {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
var z = "foo";
|
||||||
|
(function() {
|
||||||
|
var z = false;
|
||||||
|
(function(e) {
|
||||||
|
var z = 42;
|
||||||
|
e("console.log(typeof z)");
|
||||||
|
})(eval);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function n() {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
var o = "foo";
|
||||||
|
(function() {
|
||||||
|
var o = false;
|
||||||
|
(function(o) {
|
||||||
|
var n = 42;
|
||||||
|
o("console.log(typeof z)");
|
||||||
|
})(n);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
issue_44_valid_ast_1: {
|
issue_44_valid_ast_1: {
|
||||||
options = { unused: true };
|
options = {
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
function a(b) {
|
function a(b) {
|
||||||
for (var i = 0, e = b.qoo(); ; i++) {}
|
for (var i = 0, e = b.qoo(); ; i++) {}
|
||||||
@@ -14,7 +16,9 @@ issue_44_valid_ast_1: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
issue_44_valid_ast_2: {
|
issue_44_valid_ast_2: {
|
||||||
options = { unused: true };
|
options = {
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
function a(b) {
|
function a(b) {
|
||||||
if (foo) for (var i = 0, e = b.qoo(); ; i++) {}
|
if (foo) for (var i = 0, e = b.qoo(); ; i++) {}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
keep_continue: {
|
keep_continue: {
|
||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true
|
evaluate: true,
|
||||||
};
|
}
|
||||||
input: {
|
input: {
|
||||||
while (a) {
|
while (a) {
|
||||||
if (b) {
|
if (b) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
NaN_and_Infinity_must_have_parens: {
|
NaN_and_Infinity_must_have_parens: {
|
||||||
options = {};
|
options = {}
|
||||||
input: {
|
input: {
|
||||||
Infinity.toString();
|
Infinity.toString();
|
||||||
NaN.toString();
|
NaN.toString();
|
||||||
@@ -11,7 +11,7 @@ NaN_and_Infinity_must_have_parens: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
NaN_and_Infinity_should_not_be_replaced_when_they_are_redefined: {
|
NaN_and_Infinity_should_not_be_replaced_when_they_are_redefined: {
|
||||||
options = {};
|
options = {}
|
||||||
input: {
|
input: {
|
||||||
var Infinity, NaN;
|
var Infinity, NaN;
|
||||||
Infinity.toString();
|
Infinity.toString();
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
issue_611: {
|
issue_611: {
|
||||||
options = {
|
options = {
|
||||||
sequences: true,
|
sequences: true,
|
||||||
side_effects: true
|
side_effects: true,
|
||||||
};
|
}
|
||||||
input: {
|
input: {
|
||||||
define(function() {
|
define(function() {
|
||||||
function fn() {}
|
function fn() {}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
wrongly_optimized: {
|
wrongly_optimized: {
|
||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
|
||||||
booleans: true,
|
booleans: true,
|
||||||
evaluate: true
|
conditionals: true,
|
||||||
};
|
evaluate: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
function func() {
|
function func() {
|
||||||
foo();
|
foo();
|
||||||
@@ -16,7 +16,6 @@ wrongly_optimized: {
|
|||||||
function func() {
|
function func() {
|
||||||
foo();
|
foo();
|
||||||
}
|
}
|
||||||
// TODO: optimize to `func(), bar()`
|
func(), 1, bar();
|
||||||
(func(), 0) || bar();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,19 +21,19 @@ cond_5: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
some_condition() && some_other_condition() ? do_something() : alternate();
|
(some_condition() && some_other_condition() ? do_something : alternate)();
|
||||||
if (some_condition() && some_other_condition()) do_something();
|
if (some_condition() && some_other_condition()) do_something();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dead_code_const_annotation_regex: {
|
dead_code_const_annotation_regex: {
|
||||||
options = {
|
options = {
|
||||||
booleans : true,
|
booleans: true,
|
||||||
conditionals : true,
|
conditionals: true,
|
||||||
dead_code : true,
|
dead_code: true,
|
||||||
evaluate : true,
|
evaluate: true,
|
||||||
expression : true,
|
expression: true,
|
||||||
loops : true,
|
loops: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var unused;
|
var unused;
|
||||||
@@ -82,8 +82,9 @@ drop_value: {
|
|||||||
|
|
||||||
wrongly_optimized: {
|
wrongly_optimized: {
|
||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
|
||||||
booleans: true,
|
booleans: true,
|
||||||
|
conditionals: true,
|
||||||
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
expression: true,
|
expression: true,
|
||||||
}
|
}
|
||||||
@@ -99,8 +100,8 @@ wrongly_optimized: {
|
|||||||
function func() {
|
function func() {
|
||||||
foo();
|
foo();
|
||||||
}
|
}
|
||||||
// TODO: optimize to `func(), bar()`
|
func(), 1;
|
||||||
if (func(), !0) bar();
|
bar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,7 +196,7 @@ negate_iife_5_off: {
|
|||||||
expression: true,
|
expression: true,
|
||||||
negate_iife: false,
|
negate_iife: false,
|
||||||
sequences: true,
|
sequences: true,
|
||||||
};
|
}
|
||||||
input: {
|
input: {
|
||||||
if ((function(){ return t })()) {
|
if ((function(){ return t })()) {
|
||||||
foo(true);
|
foo(true);
|
||||||
@@ -248,7 +249,9 @@ issue_1254_negate_iife_nested: {
|
|||||||
conditional: {
|
conditional: {
|
||||||
options = {
|
options = {
|
||||||
expression: true,
|
expression: true,
|
||||||
pure_funcs: [ "pure" ],
|
pure_funcs: [
|
||||||
|
"pure"
|
||||||
|
],
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|||||||
@@ -1,37 +1,45 @@
|
|||||||
dont_reuse_prop: {
|
dont_reuse_prop: {
|
||||||
mangle_props = {
|
mangle = {
|
||||||
regex: /asd/
|
properties: {
|
||||||
};
|
regex: /asd/,
|
||||||
|
},
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
|
"aaaaaaaaaabbbbb";
|
||||||
var obj = {};
|
var obj = {};
|
||||||
obj.a = 123;
|
obj.a = 123;
|
||||||
obj.asd = 256;
|
obj.asd = 256;
|
||||||
console.log(obj.a);
|
console.log(obj.a);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
|
"aaaaaaaaaabbbbb";
|
||||||
var obj = {};
|
var obj = {};
|
||||||
obj.a = 123;
|
obj.a = 123;
|
||||||
obj.b = 256;
|
obj.b = 256;
|
||||||
console.log(obj.a);
|
console.log(obj.a);
|
||||||
}
|
}
|
||||||
|
expect_stdout: "123"
|
||||||
}
|
}
|
||||||
|
|
||||||
unmangleable_props_should_always_be_reserved: {
|
unmangleable_props_should_always_be_reserved: {
|
||||||
mangle_props = {
|
mangle = {
|
||||||
regex: /asd/
|
properties: {
|
||||||
};
|
regex: /asd/,
|
||||||
|
},
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
|
"aaaaaaaaaabbbbb";
|
||||||
var obj = {};
|
var obj = {};
|
||||||
obj.asd = 256;
|
obj.asd = 256;
|
||||||
obj.a = 123;
|
obj.a = 123;
|
||||||
console.log(obj.a);
|
console.log(obj.a);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
|
"aaaaaaaaaabbbbb";
|
||||||
var obj = {};
|
var obj = {};
|
||||||
obj.b = 256;
|
obj.b = 256;
|
||||||
obj.a = 123;
|
obj.a = 123;
|
||||||
console.log(obj.a);
|
console.log(obj.a);
|
||||||
}
|
}
|
||||||
}
|
expect_stdout: "123"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
negate_booleans_1: {
|
negate_booleans_1: {
|
||||||
options = {
|
options = {
|
||||||
comparisons: true
|
comparisons: true,
|
||||||
};
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = !a || !b || !c || !d || !e || !f;
|
var a = !a || !b || !c || !d || !e || !f;
|
||||||
}
|
}
|
||||||
@@ -12,8 +12,8 @@ negate_booleans_1: {
|
|||||||
|
|
||||||
negate_booleans_2: {
|
negate_booleans_2: {
|
||||||
options = {
|
options = {
|
||||||
comparisons: true
|
comparisons: true,
|
||||||
};
|
}
|
||||||
input: {
|
input: {
|
||||||
var match = !x && // should not touch this one
|
var match = !x && // should not touch this one
|
||||||
(!z || c) &&
|
(!z || c) &&
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
remove_redundant_sequence_items: {
|
remove_sequence: {
|
||||||
options = { side_effects: true };
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
(0, 1, eval)();
|
(0, 1, eval)();
|
||||||
(0, 1, logThis)();
|
(0, 1, logThis)();
|
||||||
@@ -12,14 +14,36 @@ remove_redundant_sequence_items: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dont_remove_this_binding_sequence: {
|
remove_redundant_sequence_items: {
|
||||||
options = { side_effects: true };
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
(0, eval)();
|
"use strict";
|
||||||
(0, logThis)();
|
(0, 1, eval)();
|
||||||
(0, _decorators.logThis)();
|
(0, 1, logThis)();
|
||||||
|
(0, 1, _decorators.logThis)();
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
(0, eval)();
|
||||||
|
logThis();
|
||||||
|
(0, _decorators.logThis)();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dont_remove_this_binding_sequence: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
(0, eval)();
|
||||||
|
(0, logThis)();
|
||||||
|
(0, _decorators.logThis)();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
(0, eval)();
|
(0, eval)();
|
||||||
logThis();
|
logThis();
|
||||||
(0, _decorators.logThis)();
|
(0, _decorators.logThis)();
|
||||||
|
|||||||
@@ -2,26 +2,25 @@ dont_mangle_arguments: {
|
|||||||
mangle = {
|
mangle = {
|
||||||
};
|
};
|
||||||
options = {
|
options = {
|
||||||
sequences : true,
|
booleans: true,
|
||||||
properties : true,
|
comparisons: true,
|
||||||
dead_code : true,
|
conditionals: true,
|
||||||
drop_debugger : true,
|
dead_code: true,
|
||||||
conditionals : true,
|
drop_debugger: true,
|
||||||
comparisons : true,
|
evaluate: true,
|
||||||
evaluate : true,
|
hoist_funs: true,
|
||||||
booleans : true,
|
hoist_vars: true,
|
||||||
loops : true,
|
if_return: true,
|
||||||
unused : true,
|
join_vars: true,
|
||||||
hoist_funs : true,
|
keep_fargs: true,
|
||||||
keep_fargs : true,
|
keep_fnames: false,
|
||||||
keep_fnames : false,
|
loops: true,
|
||||||
hoist_vars : true,
|
negate_iife: false,
|
||||||
if_return : true,
|
properties: true,
|
||||||
join_vars : true,
|
sequences: true,
|
||||||
cascade : true,
|
side_effects: true,
|
||||||
side_effects : true,
|
unused: true,
|
||||||
negate_iife : false
|
}
|
||||||
};
|
|
||||||
input: {
|
input: {
|
||||||
(function(){
|
(function(){
|
||||||
var arguments = arguments, not_arguments = 9;
|
var arguments = arguments, not_arguments = 9;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
keep_var_for_in: {
|
keep_var_for_in: {
|
||||||
options = {
|
options = {
|
||||||
hoist_vars: true,
|
hoist_vars: true,
|
||||||
unused: true
|
unused: true,
|
||||||
};
|
}
|
||||||
input: {
|
input: {
|
||||||
(function(obj){
|
(function(obj){
|
||||||
var foo = 5;
|
var foo = 5;
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
this_binding_conditionals: {
|
this_binding_conditionals: {
|
||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
evaluate : true
|
evaluate: true,
|
||||||
};
|
side_effects: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
|
"use strict";
|
||||||
(1 && a)();
|
(1 && a)();
|
||||||
(0 || a)();
|
(0 || a)();
|
||||||
(0 || 1 && a)();
|
(0 || 1 && a)();
|
||||||
@@ -25,6 +27,7 @@ this_binding_conditionals: {
|
|||||||
(1 ? eval : 0)();
|
(1 ? eval : 0)();
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
|
"use strict";
|
||||||
a();
|
a();
|
||||||
a();
|
a();
|
||||||
a();
|
a();
|
||||||
@@ -50,48 +53,111 @@ this_binding_conditionals: {
|
|||||||
this_binding_collapse_vars: {
|
this_binding_collapse_vars: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
toplevel: true,
|
unused: true,
|
||||||
};
|
}
|
||||||
input: {
|
input: {
|
||||||
var c = a; c();
|
function f() {
|
||||||
var d = a.b; d();
|
"use strict";
|
||||||
var e = eval; e();
|
var c = a; c();
|
||||||
|
var d = a.b; d();
|
||||||
|
var e = eval; e();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
a();
|
function f() {
|
||||||
(0, a.b)();
|
"use strict";
|
||||||
(0, eval)();
|
a();
|
||||||
|
(0, a.b)();
|
||||||
|
(0, eval)();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this_binding_side_effects: {
|
this_binding_side_effects: {
|
||||||
options = {
|
options = {
|
||||||
side_effects : true
|
side_effects: true,
|
||||||
};
|
}
|
||||||
input: {
|
input: {
|
||||||
(function (foo) {
|
(function(foo) {
|
||||||
(0, foo)();
|
(0, foo)();
|
||||||
(0, foo.bar)();
|
(0, foo.bar)();
|
||||||
(0, eval)('console.log(foo);');
|
(0, eval)("console.log(foo);");
|
||||||
}());
|
}());
|
||||||
(function (foo) {
|
(function(foo) {
|
||||||
|
"use strict";
|
||||||
|
(0, foo)();
|
||||||
|
(0, foo.bar)();
|
||||||
|
(0, eval)("console.log(foo);");
|
||||||
|
}());
|
||||||
|
(function(foo) {
|
||||||
var eval = console;
|
var eval = console;
|
||||||
(0, foo)();
|
(0, foo)();
|
||||||
(0, foo.bar)();
|
(0, foo.bar)();
|
||||||
(0, eval)('console.log(foo);');
|
(0, eval)("console.log(foo);");
|
||||||
}());
|
}());
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
(function (foo) {
|
(function(foo) {
|
||||||
foo();
|
foo();
|
||||||
(0, foo.bar)();
|
(0, foo.bar)();
|
||||||
(0, eval)('console.log(foo);');
|
(0, eval)("console.log(foo);");
|
||||||
}());
|
}());
|
||||||
(function (foo) {
|
(function(foo) {
|
||||||
|
"use strict";
|
||||||
|
foo();
|
||||||
|
(0, foo.bar)();
|
||||||
|
(0, eval)("console.log(foo);");
|
||||||
|
}());
|
||||||
|
(function(foo) {
|
||||||
var eval = console;
|
var eval = console;
|
||||||
foo();
|
foo();
|
||||||
(0, foo.bar)();
|
(0, foo.bar)();
|
||||||
(0, eval)('console.log(foo);');
|
eval("console.log(foo);");
|
||||||
}());
|
}());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this_binding_sequences: {
|
||||||
|
options = {
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(typeof function() {
|
||||||
|
return eval("this");
|
||||||
|
}());
|
||||||
|
console.log(typeof function() {
|
||||||
|
"use strict";
|
||||||
|
return eval("this");
|
||||||
|
}());
|
||||||
|
console.log(typeof function() {
|
||||||
|
return (0, eval)("this");
|
||||||
|
}());
|
||||||
|
console.log(typeof function() {
|
||||||
|
"use strict";
|
||||||
|
return (0, eval)("this");
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(typeof function() {
|
||||||
|
return eval("this");
|
||||||
|
}()),
|
||||||
|
console.log(typeof function() {
|
||||||
|
"use strict";
|
||||||
|
return eval("this");
|
||||||
|
}()),
|
||||||
|
console.log(typeof function() {
|
||||||
|
return (0, eval)("this");
|
||||||
|
}()),
|
||||||
|
console.log(typeof function() {
|
||||||
|
"use strict";
|
||||||
|
return (0, eval)("this");
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"object",
|
||||||
|
"undefined",
|
||||||
|
"object",
|
||||||
|
"object",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,9 +1,21 @@
|
|||||||
eval_collapse_vars: {
|
eval_collapse_vars: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars:true, sequences:false, properties:true, dead_code:true, conditionals:true,
|
booleans: true,
|
||||||
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
|
collapse_vars: true,
|
||||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true
|
comparisons: true,
|
||||||
};
|
conditionals: true,
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
hoist_funs: true,
|
||||||
|
if_return: true,
|
||||||
|
join_vars: true,
|
||||||
|
keep_fargs: true,
|
||||||
|
loops: true,
|
||||||
|
properties: true,
|
||||||
|
sequences: false,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
function f1() {
|
function f1() {
|
||||||
var e = 7;
|
var e = 7;
|
||||||
@@ -46,7 +58,10 @@ eval_collapse_vars: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
eval_unused: {
|
eval_unused: {
|
||||||
options = { unused: true, keep_fargs: false };
|
options = {
|
||||||
|
keep_fargs: false,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
function f1(a, eval, c, d, e) {
|
function f1(a, eval, c, d, e) {
|
||||||
return a('c') + eval;
|
return a('c') + eval;
|
||||||
|
|||||||
@@ -1,8 +1,19 @@
|
|||||||
issue979_reported: {
|
issue979_reported: {
|
||||||
options = {
|
options = {
|
||||||
sequences:true, properties:true, dead_code:true, conditionals:true,
|
booleans: true,
|
||||||
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
|
comparisons: true,
|
||||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true
|
conditionals: true,
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
hoist_funs: true,
|
||||||
|
if_return: true,
|
||||||
|
join_vars: true,
|
||||||
|
keep_fargs: true,
|
||||||
|
loops: true,
|
||||||
|
properties: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f1() {
|
function f1() {
|
||||||
@@ -30,9 +41,20 @@ issue979_reported: {
|
|||||||
|
|
||||||
issue979_test_negated_is_best: {
|
issue979_test_negated_is_best: {
|
||||||
options = {
|
options = {
|
||||||
sequences:true, properties:true, dead_code:true, conditionals:true,
|
booleans: true,
|
||||||
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
|
comparisons: true,
|
||||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true
|
conditionals: true,
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
hoist_funs: true,
|
||||||
|
if_return: true,
|
||||||
|
join_vars: true,
|
||||||
|
keep_fargs: true,
|
||||||
|
loops: true,
|
||||||
|
properties: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f3() {
|
function f3() {
|
||||||
|
|||||||
1057
test/compress/join_vars.js
Normal file
1057
test/compress/join_vars.js
Normal file
File diff suppressed because it is too large
Load Diff
1454
test/compress/keep_fargs.js
Normal file
1454
test/compress/keep_fargs.js
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user