Compare commits
694 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
4e0a22e5c8 | ||
|
|
1aa38051fb | ||
|
|
e62b879b48 | ||
|
|
c6c9f4f5a8 | ||
|
|
fec14379f6 | ||
|
|
79131cd647 | ||
|
|
c3f14a1481 | ||
|
|
7b13159cda | ||
|
|
95094b9c22 | ||
|
|
1ff8e9dd38 | ||
|
|
78309a293d | ||
|
|
695e182d59 | ||
|
|
dc33facfcb | ||
|
|
c70fb60384 | ||
|
|
793d61499b | ||
|
|
a277fe168d | ||
|
|
7d3b941e6e | ||
|
|
e95052a423 | ||
|
|
e667f0acb8 | ||
|
|
69ac794bc8 | ||
|
|
efdb65913b | ||
|
|
a1dedeb3ce | ||
|
|
d3c4a8e9e7 | ||
|
|
7e164aba8f | ||
|
|
22aedef849 | ||
|
|
58fae7dc07 | ||
|
|
5bf8d7e949 | ||
|
|
1df9d06f4a | ||
|
|
3408fc9d32 | ||
|
|
eae26756f1 | ||
|
|
43add9416b | ||
|
|
efcf167e5e | ||
|
|
6ed90913ca | ||
|
|
569c21e952 | ||
|
|
87c3a2c0ce | ||
|
|
baef8bf050 | ||
|
|
0813c5316f | ||
|
|
c88139492d | ||
|
|
cb45886512 | ||
|
|
050474ab44 | ||
|
|
f6c805ae1d | ||
|
|
9464d3c20f | ||
|
|
f18abd1b9c | ||
|
|
3be06ad085 | ||
|
|
265008c948 | ||
|
|
ff526be61d | ||
|
|
e005099fb1 | ||
|
|
504a436e9d | ||
|
|
3ca902258c | ||
|
|
fd0951231c | ||
|
|
9e29b6dad2 | ||
|
|
c391576d52 | ||
|
|
ac73c5d421 | ||
|
|
547f41beba | ||
|
|
daaefc17b9 | ||
|
|
1d407e761e | ||
|
|
2b44f4ae30 | ||
|
|
e51c3541da | ||
|
|
3bf194684b | ||
|
|
aae7d49d0c | ||
|
|
0459af2ecc | ||
|
|
04f2344efc | ||
|
|
bad9d5cf88 | ||
|
|
a0f5f862df | ||
|
|
41996be86f | ||
|
|
5fd8244a2e | ||
|
|
c14e280585 | ||
|
|
bc3fa78e8c | ||
|
|
8c7c107765 | ||
|
|
3dd328dce3 | ||
|
|
014f428153 | ||
|
|
a3b2eb75bd | ||
|
|
da295de82b | ||
|
|
4f8ca4626e | ||
|
|
e54748365c | ||
|
|
2d99d06601 | ||
|
|
98cf95e5b5 | ||
|
|
7313465cba | ||
|
|
2c7ee956fd | ||
|
|
ecf3563c45 | ||
|
|
dee5a27516 | ||
|
|
5a25d24b56 | ||
|
|
bffdc8dca8 | ||
|
|
69b5663653 | ||
|
|
ea9289771b | ||
|
|
2cb55b2ad0 | ||
|
|
bbb5f2a89c | ||
|
|
76d19b60ad | ||
|
|
9e62628171 | ||
|
|
9bf72cf758 | ||
|
|
64d74432f6 | ||
|
|
45ce369480 | ||
|
|
ca32a09032 | ||
|
|
6f954aa3d0 | ||
|
|
f05d4f7af3 | ||
|
|
88e7a542cd | ||
|
|
4dcff038cb | ||
|
|
b4b9305db0 | ||
|
|
28cfb65c47 | ||
|
|
0f4f01b66c | ||
|
|
5d9f1da3ab | ||
|
|
d1aa09c5c7 | ||
|
|
6d5f341999 | ||
|
|
4ffb6fce76 | ||
|
|
71a8d0d236 | ||
|
|
1a498db2d3 | ||
|
|
44dfa5a318 | ||
|
|
251ff1d1af | ||
|
|
ec443e422c | ||
|
|
32deb365d5 | ||
|
|
2244743545 | ||
|
|
04b8964505 | ||
|
|
d6fbc365e2 | ||
|
|
9a978843f5 | ||
|
|
0479ff0c54 | ||
|
|
cf72fe552f | ||
|
|
a1532eb076 | ||
|
|
c2a1bceb77 | ||
|
|
e3c9c22c75 | ||
|
|
0f4cd73dcc | ||
|
|
281e882d27 | ||
|
|
cc6aa3e5ac | ||
|
|
e869779a98 | ||
|
|
06cdb74279 | ||
|
|
ff289b90a9 | ||
|
|
9b6bc67c33 | ||
|
|
4b90dc1fdb | ||
|
|
951770fc68 | ||
|
|
48b3fe9952 | ||
|
|
a400741868 | ||
|
|
59a4e56bc8 | ||
|
|
1f1fccc45d | ||
|
|
b7f6b73f4e | ||
|
|
9469c03ac9 | ||
|
|
d57527697f | ||
|
|
f7ca4f2297 | ||
|
|
c076e7b60d | ||
|
|
4a55bb0be5 | ||
|
|
28ecea50a6 | ||
|
|
9a311705f5 | ||
|
|
ee3fe0f4cd | ||
|
|
87f6e1b091 | ||
|
|
c934fc8142 | ||
|
|
257ddc3bdb | ||
|
|
1ddc05725d | ||
|
|
e6b76a4879 | ||
|
|
a0c3836ba0 | ||
|
|
f8a71b56fd | ||
|
|
11e9bdc427 | ||
|
|
a84564d1a8 | ||
|
|
c595b84032 | ||
|
|
7cb1adf455 | ||
|
|
7bea38a05d | ||
|
|
0f910ee25c | ||
|
|
beb9659778 | ||
|
|
f1a833a7aa | ||
|
|
2e41cd6394 | ||
|
|
09f77c7d4d | ||
|
|
fef0bf9ee0 | ||
|
|
ae740b933f | ||
|
|
ec7f37f314 | ||
|
|
eb48a035e7 | ||
|
|
6ab3224c0d | ||
|
|
c909ffb715 | ||
|
|
f71f4905b0 | ||
|
|
fb177a6312 | ||
|
|
65da9acce6 | ||
|
|
67d0237f73 | ||
|
|
984a21704e | ||
|
|
aa3f647656 | ||
|
|
c526da59a1 | ||
|
|
581630e0a7 | ||
|
|
f5952933a0 | ||
|
|
f001e4cb9d | ||
|
|
57ce5bd9e0 | ||
|
|
861a79ac9f | ||
|
|
00996afd2c | ||
|
|
e76fb354eb | ||
|
|
3276740779 | ||
|
|
5509e51098 | ||
|
|
94f84727ce | ||
|
|
8a4f86528f | ||
|
|
adb0e882e9 | ||
|
|
f83d370f57 | ||
|
|
b19aa58cff | ||
|
|
0a65de89b9 | ||
|
|
6e86ee950d | ||
|
|
8ca2401ebe | ||
|
|
491f16c766 | ||
|
|
a30092e20f | ||
|
|
b1abe92e1a | ||
|
|
b454ce667e | ||
|
|
32283a0def | ||
|
|
ac51d4c5a0 | ||
|
|
0432a7abb9 | ||
|
|
f3a1694a41 | ||
|
|
2e0dc97003 | ||
|
|
701035621d | ||
|
|
79334dda10 | ||
|
|
e918748d88 | ||
|
|
6b2f34769a | ||
|
|
48ffbef51d | ||
|
|
c0f3feae9f | ||
|
|
a00040dd93 | ||
|
|
ee95c1b38b | ||
|
|
4bceb85cbf | ||
|
|
30a75049f5 | ||
|
|
a3cc3a9b87 | ||
|
|
96f8befdd7 | ||
|
|
cd58635dcc | ||
|
|
274331d0ea | ||
|
|
0489d6de64 | ||
|
|
fb092839c2 | ||
|
|
b7c112eefe | ||
|
|
b2b8a0d386 | ||
|
|
ac40301813 | ||
|
|
3563d8c09e | ||
|
|
5ae04b3545 | ||
|
|
a80b228d8b | ||
|
|
cf4bf4ceb1 | ||
|
|
8223b2e0db | ||
|
|
381bd3836e | ||
|
|
919d5e3482 | ||
|
|
e3a3db73ae | ||
|
|
d9344f30b8 | ||
|
|
be80f7e706 | ||
|
|
cf45e2f79b | ||
|
|
8354758f30 | ||
|
|
9e6b128374 | ||
|
|
93cdb194f4 | ||
|
|
b633706ce4 | ||
|
|
e9920f7ca1 | ||
|
|
7e465d4a01 | ||
|
|
aa80ee349d | ||
|
|
80e81765cf | ||
|
|
711f88dcb4 | ||
|
|
344d11d591 | ||
|
|
c7cdcf06a6 | ||
|
|
3ee55748d4 | ||
|
|
dedbeeff15 | ||
|
|
bd6dee52ab | ||
|
|
144052ca49 | ||
|
|
65c848cc6f | ||
|
|
8a8a94a596 | ||
|
|
8153b7bd8a | ||
|
|
d787d70127 | ||
|
|
3ac2421932 | ||
|
|
a9fc9ddc33 | ||
|
|
a5d62a3fc6 | ||
|
|
067e5a5762 | ||
|
|
33b5f31984 | ||
|
|
35a849dc48 | ||
|
|
b70591be1a | ||
|
|
b33e7f88e6 | ||
|
|
1f0333e9f1 | ||
|
|
eb98a7f2f3 | ||
|
|
78d1bb92d4 | ||
|
|
ea9ab9fb0e | ||
|
|
ce54c9ccee | ||
|
|
07accd2fbb | ||
|
|
18059cc94f | ||
|
|
b5e0e8c203 | ||
|
|
e5cb9275df | ||
|
|
17b81350d4 | ||
|
|
4d63d4f5b3 | ||
|
|
70d72ad806 | ||
|
|
fe9227a41b | ||
|
|
b49e142a26 | ||
|
|
ee3b39b909 | ||
|
|
9699ffb1af | ||
|
|
fdc9b9413b | ||
|
|
40ceddb48a | ||
|
|
7aa69117e1 | ||
|
|
bff7ad67bb | ||
|
|
c2334baa48 | ||
|
|
fb2b6c7c6f | ||
|
|
f5cbe19b75 | ||
|
|
b34fa11a13 | ||
|
|
320984c5f5 | ||
|
|
4365a51237 | ||
|
|
858e6c78a4 | ||
|
|
0b0296eb2a | ||
|
|
872270b149 | ||
|
|
b1c593a041 | ||
|
|
13be50a4a9 | ||
|
|
16cd5d57a5 | ||
|
|
834f9f3924 | ||
|
|
cf0951f726 | ||
|
|
852f78491a | ||
|
|
229e42cdee | ||
|
|
4e49302916 | ||
|
|
1e51586996 | ||
|
|
d48a3080ac | ||
|
|
26fbeece1c | ||
|
|
8898b8a0fe | ||
|
|
ec64acd2c8 | ||
|
|
ac0b61ed6e | ||
|
|
c06a50f338 | ||
|
|
09f9ae2de9 | ||
|
|
7e6331bb39 | ||
|
|
e275148998 | ||
|
|
974247c8c0 | ||
|
|
a0f4fd390a | ||
|
|
b8b133d91a | ||
|
|
c525a2b190 | ||
|
|
6ffbecb72b | ||
|
|
f0ff6189be | ||
|
|
6b3c49e458 | ||
|
|
f584ca8d07 | ||
|
|
ae4db00991 | ||
|
|
100307ab31 | ||
|
|
148047fbbf | ||
|
|
d11dca3cf9 | ||
|
|
e5badb9541 | ||
|
|
fa668a28b4 | ||
|
|
686a496b1c | ||
|
|
11676f9d72 | ||
|
|
dd31d12a91 | ||
|
|
eb55d8a9bb | ||
|
|
81f1df14d7 | ||
|
|
7f8d72d9d3 | ||
|
|
1eaa211e09 | ||
|
|
0610c020b1 | ||
|
|
0d7d4918eb | ||
|
|
48284844a4 | ||
|
|
ec2e5fa3a2 | ||
|
|
da17766ddd | ||
|
|
0913db8c84 | ||
|
|
5c7705fcad | ||
|
|
f6372483a0 | ||
|
|
98f330658f | ||
|
|
a7b3b0d3a5 | ||
|
|
0a35acbbe7 | ||
|
|
2a9989dd18 | ||
|
|
79b98a9fe8 | ||
|
|
057de570e6 | ||
|
|
557b3e412f | ||
|
|
8d74f34373 | ||
|
|
266ddd9639 | ||
|
|
e51c6ba380 | ||
|
|
6389e52305 | ||
|
|
e05510f3bc | ||
|
|
fc9804b909 | ||
|
|
4761d07e0b | ||
|
|
0111497fc9 | ||
|
|
7d8dea3b26 | ||
|
|
25fc02743a | ||
|
|
0bd8053524 | ||
|
|
1a78bbcd23 | ||
|
|
8430123e9d | ||
|
|
614db97cca | ||
|
|
d854523783 | ||
|
|
781f26eda1 | ||
|
|
37f4395cc0 | ||
|
|
de619ae5a6 | ||
|
|
86859f6d7e | ||
|
|
dcdcfe4d39 | ||
|
|
72306b9885 | ||
|
|
38756b1f26 | ||
|
|
85a09fc3b6 | ||
|
|
307b88d6cc | ||
|
|
fb049d3a81 | ||
|
|
67cca43358 | ||
|
|
642273c290 | ||
|
|
e8b23c7798 | ||
|
|
9edbe93df5 | ||
|
|
af37ecafe1 | ||
|
|
41a9329409 | ||
|
|
7eb52d2837 | ||
|
|
eb63fece2f | ||
|
|
2d8af8947e | ||
|
|
2650182f47 | ||
|
|
572b97b0bb | ||
|
|
698705a820 | ||
|
|
debc525fa1 | ||
|
|
5576e2737a | ||
|
|
b40d5de69c | ||
|
|
b7ef7840f3 | ||
|
|
85924bb32e | ||
|
|
a97690fc72 | ||
|
|
02c638209e | ||
|
|
030611b729 | ||
|
|
335b72df03 | ||
|
|
3a7d53f3cf | ||
|
|
9676167aac | ||
|
|
1840a0b282 | ||
|
|
ace8aaa0f4 | ||
|
|
0c003c92a8 | ||
|
|
85fbf86d7b | ||
|
|
aa82027a17 | ||
|
|
55c592dd43 | ||
|
|
fc1abd1c11 | ||
|
|
e645ba84cf | ||
|
|
6c99816855 | ||
|
|
2149bfb707 | ||
|
|
d7971ba0e4 | ||
|
|
5c4cfaa0a7 | ||
|
|
bb9c9707aa | ||
|
|
6c8e001fee | ||
|
|
9c53c7ada7 | ||
|
|
f99b7b630d | ||
|
|
ea31da2455 | ||
|
|
4d7746baf3 | ||
|
|
31d5825a86 | ||
|
|
8287ef6781 | ||
|
|
5cb5305cf3 | ||
|
|
00ad57e393 | ||
|
|
09d5707a8a | ||
|
|
1e390269d4 | ||
|
|
bc49dfd27a | ||
|
|
27eedbc302 | ||
|
|
5f464b41e2 | ||
|
|
bcc1318d4b | ||
|
|
a0e03c9df4 | ||
|
|
6641dcafb6 | ||
|
|
d2945744f2 | ||
|
|
35bc716625 | ||
|
|
f39fd3d583 | ||
|
|
65887d9a56 | ||
|
|
e9224ab444 | ||
|
|
4d9a085687 | ||
|
|
4fe630431c | ||
|
|
c55dd5ed74 | ||
|
|
e4fa4b109a | ||
|
|
4b4528ee05 | ||
|
|
187a0caf9d | ||
|
|
b5a7a231f7 | ||
|
|
3907a5e3b2 | ||
|
|
b434b75b36 | ||
|
|
c70d176f35 | ||
|
|
9317237372 | ||
|
|
98434258d0 | ||
|
|
45ddb9caeb | ||
|
|
9bcf702a6e | ||
|
|
f68de86a17 | ||
|
|
c3c7587796 | ||
|
|
07bb7262d0 | ||
|
|
21befe583f | ||
|
|
a9d4a6291b | ||
|
|
ee6c9fabb7 | ||
|
|
102d1b9137 |
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*.js text eol=lf
|
||||
29
.github/ISSUE_TEMPLATE.md
vendored
Normal file
29
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
**Bug report or feature request?**
|
||||
|
||||
<!-- 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`)**
|
||||
|
||||
**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.**
|
||||
|
||||
**JavaScript output or error produced.**
|
||||
|
||||
<!--
|
||||
Note: `uglify-js` only supports ES5.
|
||||
Those wishing to minify ES6 should use `uglify-es`.
|
||||
-->
|
||||
@@ -1,9 +1,14 @@
|
||||
language: node_js
|
||||
before_install: "npm install -g npm"
|
||||
node_js:
|
||||
- "0.12"
|
||||
- "0.10"
|
||||
- "0.12"
|
||||
- "4"
|
||||
- "6"
|
||||
- "8"
|
||||
env:
|
||||
- UGLIFYJS_TEST_ALL=1
|
||||
matrix:
|
||||
fast_finish: true
|
||||
sudo: false
|
||||
cache:
|
||||
directories: tmp
|
||||
|
||||
24
appveyor.yml
Normal file
24
appveyor.yml
Normal file
@@ -0,0 +1,24 @@
|
||||
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
|
||||
@@ -1,77 +0,0 @@
|
||||
#! /usr/bin/env node
|
||||
|
||||
"use strict";
|
||||
|
||||
var U2 = require("../tools/node");
|
||||
var fs = require("fs");
|
||||
var yargs = require("yargs");
|
||||
var ARGS = yargs
|
||||
.describe("o", "Output file")
|
||||
.argv;
|
||||
var files = ARGS._.slice();
|
||||
var output = {
|
||||
vars: {},
|
||||
props: {}
|
||||
};
|
||||
|
||||
if (ARGS.o) try {
|
||||
output = JSON.parse(fs.readFileSync(ARGS.o, "utf8"));
|
||||
} catch(ex) {}
|
||||
|
||||
files.forEach(getProps);
|
||||
|
||||
if (ARGS.o) {
|
||||
fs.writeFileSync(ARGS.o, JSON.stringify(output, null, 2), "utf8");
|
||||
} else {
|
||||
console.log("%s", JSON.stringify(output, null, 2));
|
||||
}
|
||||
|
||||
function getProps(filename) {
|
||||
var code = fs.readFileSync(filename, "utf8");
|
||||
var ast = U2.parse(code);
|
||||
|
||||
ast.walk(new U2.TreeWalker(function(node){
|
||||
if (node instanceof U2.AST_ObjectKeyVal) {
|
||||
add(node.key);
|
||||
}
|
||||
else if (node instanceof U2.AST_ObjectProperty) {
|
||||
add(node.key.name);
|
||||
}
|
||||
else if (node instanceof U2.AST_Dot) {
|
||||
add(node.property);
|
||||
}
|
||||
else if (node instanceof U2.AST_Sub) {
|
||||
addStrings(node.property);
|
||||
}
|
||||
}));
|
||||
|
||||
function addStrings(node) {
|
||||
var out = {};
|
||||
try {
|
||||
(function walk(node){
|
||||
node.walk(new U2.TreeWalker(function(node){
|
||||
if (node instanceof U2.AST_Seq) {
|
||||
walk(node.cdr);
|
||||
return true;
|
||||
}
|
||||
if (node instanceof U2.AST_String) {
|
||||
add(node.value);
|
||||
return true;
|
||||
}
|
||||
if (node instanceof U2.AST_Conditional) {
|
||||
walk(node.consequent);
|
||||
walk(node.alternative);
|
||||
return true;
|
||||
}
|
||||
throw out;
|
||||
}));
|
||||
})(node);
|
||||
} catch(ex) {
|
||||
if (ex !== out) throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
function add(name) {
|
||||
output.props[name] = true;
|
||||
}
|
||||
}
|
||||
889
bin/uglifyjs
889
bin/uglifyjs
@@ -3,571 +3,402 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
var UglifyJS = require("../tools/node");
|
||||
var sys = require("util");
|
||||
var yargs = require("yargs");
|
||||
// workaround for tty output truncation upon process.exit()
|
||||
[process.stdout, process.stderr].forEach(function(stream){
|
||||
if (stream._handle && stream._handle.setBlocking)
|
||||
stream._handle.setBlocking(true);
|
||||
});
|
||||
|
||||
var fs = require("fs");
|
||||
var info = require("../package.json");
|
||||
var path = require("path");
|
||||
var async = require("async");
|
||||
var acorn;
|
||||
var ARGS = yargs
|
||||
.usage("$0 input1.js [input2.js ...] [options]\n\
|
||||
Use a single dash to read input from the standard input.\
|
||||
\n\n\
|
||||
NOTE: by default there is no mangling/compression.\n\
|
||||
Without [options] it will simply parse input files and dump the AST\n\
|
||||
with whitespace and comments discarded. To achieve compression and\n\
|
||||
mangling you need to use `-c` and `-m`.\
|
||||
")
|
||||
.describe("source-map", "Specify an output file where to generate source map.")
|
||||
.describe("source-map-root", "The path to the original source to be included in the source map.")
|
||||
.describe("source-map-url", "The path to the source map to be added in //# sourceMappingURL. Defaults to the value passed with --source-map.")
|
||||
.describe("source-map-include-sources", "Pass this flag if you want to include the content of source files in the source map as sourcesContent property.")
|
||||
.describe("in-source-map", "Input source map, useful if you're compressing JS that was generated from some other original code.")
|
||||
.describe("screw-ie8", "Pass this flag if you don't care about full compliance with Internet Explorer 6-8 quirks (by default UglifyJS will try to be IE-proof).")
|
||||
.describe("expr", "Parse a single expression, rather than a program (for parsing JSON)")
|
||||
.describe("p", "Skip prefix for original filenames that appear in source maps. \
|
||||
For example -p 3 will drop 3 directories from file names and ensure they are relative paths. \
|
||||
You can also specify -p relative, which will make UglifyJS figure out itself the relative paths between original sources, \
|
||||
the source map and the output file.")
|
||||
.describe("o", "Output file (default STDOUT).")
|
||||
.describe("b", "Beautify output/specify output options.")
|
||||
.describe("m", "Mangle names/pass mangler options.")
|
||||
.describe("r", "Reserved names to exclude from mangling.")
|
||||
.describe("c", "Enable compressor/pass compressor options. \
|
||||
Pass options like -c hoist_vars=false,if_return=false. \
|
||||
Use -c with no argument to use the default compression options.")
|
||||
.describe("d", "Global definitions")
|
||||
.describe("e", "Embed everything in a big function, with a configurable parameter/argument list.")
|
||||
var program = require("commander");
|
||||
var UglifyJS = require("../tools/node");
|
||||
|
||||
.describe("comments", "Preserve copyright comments in the output. \
|
||||
By default this works like Google Closure, keeping JSDoc-style comments that contain \"@license\" or \"@preserve\". \
|
||||
You can optionally pass one of the following arguments to this flag:\n\
|
||||
- \"all\" to keep all comments\n\
|
||||
- a valid JS regexp (needs to start with a slash) to keep only comments that match.\n\
|
||||
\
|
||||
Note that currently not *all* comments can be kept when compression is on, \
|
||||
because of dead code removal or cascading statements into sequences.")
|
||||
|
||||
.describe("preamble", "Preamble to prepend to the output. You can use this to insert a \
|
||||
comment, for example for licensing information. This will not be \
|
||||
parsed, but the source map will adjust for its presence.")
|
||||
|
||||
.describe("stats", "Display operations run time on STDERR.")
|
||||
.describe("acorn", "Use Acorn for parsing.")
|
||||
.describe("spidermonkey", "Assume input files are SpiderMonkey AST format (as JSON).")
|
||||
.describe("self", "Build itself (UglifyJS2) as a library (implies --wrap=UglifyJS --export-all)")
|
||||
.describe("wrap", "Embed everything in a big function, making the “exports” and “global” variables available. \
|
||||
You need to pass an argument to this option to specify the name that your module will take when included in, say, a browser.")
|
||||
.describe("export-all", "Only used when --wrap, this tells UglifyJS to add code to automatically export all globals.")
|
||||
.describe("lint", "Display some scope warnings")
|
||||
.describe("v", "Verbose")
|
||||
.describe("V", "Print version number and exit.")
|
||||
.describe("noerr", "Don't throw an error for unknown options in -c, -b or -m.")
|
||||
.describe("bare-returns", "Allow return outside of functions. Useful when minifying CommonJS modules.")
|
||||
.describe("keep-fnames", "Do not mangle/drop function names. Useful for code relying on Function.prototype.name.")
|
||||
.describe("quotes", "Quote style (0 - auto, 1 - single, 2 - double, 3 - original)")
|
||||
.describe("reserved-file", "File containing reserved names")
|
||||
.describe("reserve-domprops", "Make (most?) DOM properties reserved for --mangle-props")
|
||||
.describe("mangle-props", "Mangle property names")
|
||||
.describe("mangle-regex", "Only mangle property names matching the regex")
|
||||
.describe("name-cache", "File to hold mangled names mappings")
|
||||
.describe("pure-funcs", "List of functions that can be safely removed if their return value is not used")
|
||||
.describe("dump-spidermonkey-ast", "Dump SpiderMonkey AST to stdout.")
|
||||
|
||||
.alias("p", "prefix")
|
||||
.alias("o", "output")
|
||||
.alias("v", "verbose")
|
||||
.alias("b", "beautify")
|
||||
.alias("m", "mangle")
|
||||
.alias("c", "compress")
|
||||
.alias("d", "define")
|
||||
.alias("r", "reserved")
|
||||
.alias("V", "version")
|
||||
.alias("e", "enclose")
|
||||
.alias("q", "quotes")
|
||||
|
||||
.string("source-map")
|
||||
.string("source-map-root")
|
||||
.string("source-map-url")
|
||||
.string("b")
|
||||
.string("beautify")
|
||||
.string("m")
|
||||
.string("mangle")
|
||||
.string("c")
|
||||
.string("compress")
|
||||
.string("d")
|
||||
.string("define")
|
||||
.string("e")
|
||||
.string("enclose")
|
||||
.string("comments")
|
||||
.string("wrap")
|
||||
.string("p")
|
||||
.string("prefix")
|
||||
.string("name-cache")
|
||||
.array("reserved-file")
|
||||
.array("pure-funcs")
|
||||
|
||||
.boolean("expr")
|
||||
.boolean("source-map-include-sources")
|
||||
.boolean("screw-ie8")
|
||||
.boolean("export-all")
|
||||
.boolean("self")
|
||||
.boolean("v")
|
||||
.boolean("verbose")
|
||||
.boolean("stats")
|
||||
.boolean("acorn")
|
||||
.boolean("spidermonkey")
|
||||
.boolean("dump-spidermonkey-ast")
|
||||
.boolean("lint")
|
||||
.boolean("V")
|
||||
.boolean("version")
|
||||
.boolean("noerr")
|
||||
.boolean("bare-returns")
|
||||
.boolean("keep-fnames")
|
||||
.boolean("mangle-props")
|
||||
.boolean("reserve-domprops")
|
||||
|
||||
.wrap(80)
|
||||
|
||||
.argv
|
||||
;
|
||||
|
||||
normalize(ARGS);
|
||||
|
||||
if (ARGS.noerr) {
|
||||
UglifyJS.DefaultsError.croak = function(msg, defs) {
|
||||
print_error("WARN: " + msg);
|
||||
var skip_keys = [ "cname", "enclosed", "inlined", "parent_scope", "scope", "thedef", "uses_eval", "uses_with" ];
|
||||
var files = {};
|
||||
var options = {
|
||||
compress: false,
|
||||
mangle: false
|
||||
};
|
||||
program.version(info.name + " " + info.version);
|
||||
program.parseArgv = program.parse;
|
||||
program.parse = undefined;
|
||||
if (process.argv.indexOf("ast") >= 0) program.helpInformation = UglifyJS.describe_ast;
|
||||
else if (process.argv.indexOf("options") >= 0) program.helpInformation = function() {
|
||||
var text = [];
|
||||
var options = UglifyJS.default_options();
|
||||
for (var option in options) {
|
||||
text.push("--" + (option == "output" ? "beautify" : option == "sourceMap" ? "source-map" : option) + " options:");
|
||||
text.push(format_object(options[option]));
|
||||
text.push("");
|
||||
}
|
||||
return text.join("\n");
|
||||
};
|
||||
program.option("-p, --parse <options>", "Specify parser options.", parse_js());
|
||||
program.option("-c, --compress [options]", "Enable compressor/specify compressor options.", parse_js());
|
||||
program.option("-m, --mangle [options]", "Mangle names/specify mangler options.", parse_js());
|
||||
program.option("--mangle-props [options]", "Mangle properties/specify mangler options.", parse_js());
|
||||
program.option("-b, --beautify [options]", "Beautify output/specify output options.", parse_js());
|
||||
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("--no-rename", "Disable symbol expansion.");
|
||||
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");
|
||||
}
|
||||
[
|
||||
"compress",
|
||||
"ie8",
|
||||
"mangle",
|
||||
"rename",
|
||||
"sourceMap",
|
||||
"toplevel",
|
||||
"wrap"
|
||||
].forEach(function(name) {
|
||||
if (name in program) {
|
||||
if (name == "rename" && program[name]) return;
|
||||
options[name] = program[name];
|
||||
}
|
||||
});
|
||||
if (program.beautify) {
|
||||
options.output = typeof program.beautify == "object" ? program.beautify : {};
|
||||
if (!("beautify" in options.output)) {
|
||||
options.output.beautify = true;
|
||||
}
|
||||
}
|
||||
if (program.comments) {
|
||||
if (typeof options.output != "object") options.output = {};
|
||||
options.output.comments = typeof program.comments == "string" ? program.comments : "some";
|
||||
}
|
||||
if (program.define) {
|
||||
if (typeof options.compress != "object") options.compress = {};
|
||||
if (typeof options.compress.global_defs != "object") options.compress.global_defs = {};
|
||||
for (var expr in program.define) {
|
||||
options.compress.global_defs[expr] = program.define[expr];
|
||||
}
|
||||
}
|
||||
if (program.keepFnames) {
|
||||
options.keep_fnames = true;
|
||||
}
|
||||
if (program.mangleProps) {
|
||||
if (program.mangleProps.domprops) {
|
||||
delete program.mangleProps.domprops;
|
||||
} else {
|
||||
if (typeof program.mangleProps != "object") program.mangleProps = {};
|
||||
if (!Array.isArray(program.mangleProps.reserved)) program.mangleProps.reserved = [];
|
||||
require("../tools/domprops").forEach(function(name) {
|
||||
UglifyJS._push_uniq(program.mangleProps.reserved, name);
|
||||
});
|
||||
}
|
||||
if (typeof options.mangle != "object") options.mangle = {};
|
||||
options.mangle.properties = program.mangleProps;
|
||||
}
|
||||
if (program.nameCache) {
|
||||
options.nameCache = JSON.parse(read_file(program.nameCache, "{}"));
|
||||
}
|
||||
if (program.output == "ast") {
|
||||
options.output = {
|
||||
ast: true,
|
||||
code: false
|
||||
};
|
||||
}
|
||||
|
||||
if (ARGS.version || ARGS.V) {
|
||||
var json = require("../package.json");
|
||||
print(json.name + ' ' + json.version);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
if (ARGS.ast_help) {
|
||||
var desc = UglifyJS.describe_ast();
|
||||
print(typeof desc == "string" ? desc : JSON.stringify(desc, null, 2));
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
if (ARGS.h || ARGS.help) {
|
||||
print(yargs.help());
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
if (ARGS.acorn) {
|
||||
acorn = require("acorn");
|
||||
}
|
||||
|
||||
var COMPRESS = getOptions("c", true);
|
||||
var MANGLE = getOptions("m", true);
|
||||
var BEAUTIFY = getOptions("b", true);
|
||||
var RESERVED = null;
|
||||
|
||||
if (ARGS.reserved_file) ARGS.reserved_file.forEach(function(filename){
|
||||
RESERVED = UglifyJS.readReservedFile(filename, RESERVED);
|
||||
});
|
||||
|
||||
if (ARGS.reserve_domprops) {
|
||||
RESERVED = UglifyJS.readDefaultReservedFile(RESERVED);
|
||||
}
|
||||
|
||||
if (ARGS.d) {
|
||||
if (COMPRESS) COMPRESS.global_defs = getOptions("d");
|
||||
}
|
||||
|
||||
if (ARGS.pure_funcs) {
|
||||
if (COMPRESS) COMPRESS.pure_funcs = ARGS.pure_funcs;
|
||||
}
|
||||
|
||||
if (ARGS.r) {
|
||||
if (MANGLE) MANGLE.except = ARGS.r.replace(/^\s+|\s+$/g).split(/\s*,+\s*/);
|
||||
}
|
||||
|
||||
if (RESERVED && MANGLE) {
|
||||
if (!MANGLE.except) MANGLE.except = RESERVED.vars;
|
||||
else MANGLE.except = MANGLE.except.concat(RESERVED.vars);
|
||||
}
|
||||
|
||||
function readNameCache(key) {
|
||||
return UglifyJS.readNameCache(ARGS.name_cache, key);
|
||||
}
|
||||
|
||||
function writeNameCache(key, cache) {
|
||||
return UglifyJS.writeNameCache(ARGS.name_cache, key, cache);
|
||||
}
|
||||
|
||||
function extractRegex(str) {
|
||||
if (/^\/.*\/[a-zA-Z]*$/.test(str)) {
|
||||
var regex_pos = str.lastIndexOf("/");
|
||||
return new RegExp(str.substr(1, regex_pos - 1), str.substr(regex_pos + 1));
|
||||
} else {
|
||||
throw new Error("Invalid regular expression: " + str);
|
||||
}
|
||||
}
|
||||
|
||||
if (ARGS.quotes === true) {
|
||||
ARGS.quotes = 3;
|
||||
}
|
||||
|
||||
var OUTPUT_OPTIONS = {
|
||||
beautify : BEAUTIFY ? true : false,
|
||||
preamble : ARGS.preamble || null,
|
||||
quote_style : ARGS.quotes != null ? ARGS.quotes : 0
|
||||
};
|
||||
|
||||
if (ARGS.screw_ie8) {
|
||||
if (COMPRESS) COMPRESS.screw_ie8 = true;
|
||||
if (MANGLE) MANGLE.screw_ie8 = true;
|
||||
OUTPUT_OPTIONS.screw_ie8 = true;
|
||||
}
|
||||
|
||||
if (ARGS.keep_fnames) {
|
||||
if (COMPRESS) COMPRESS.keep_fnames = true;
|
||||
if (MANGLE) MANGLE.keep_fnames = true;
|
||||
}
|
||||
|
||||
if (BEAUTIFY)
|
||||
UglifyJS.merge(OUTPUT_OPTIONS, BEAUTIFY);
|
||||
|
||||
if (ARGS.comments != null) {
|
||||
if (/^\/.*\/[a-zA-Z]*$/.test(ARGS.comments)) {
|
||||
try {
|
||||
OUTPUT_OPTIONS.comments = extractRegex(ARGS.comments);
|
||||
} catch (e) {
|
||||
print_error("ERROR: Invalid --comments: " + e.message);
|
||||
}
|
||||
} else if (ARGS.comments == "all") {
|
||||
OUTPUT_OPTIONS.comments = true;
|
||||
} else {
|
||||
OUTPUT_OPTIONS.comments = function(node, comment) {
|
||||
var text = comment.value;
|
||||
var type = comment.type;
|
||||
if (type == "comment2") {
|
||||
// multiline comment
|
||||
return /@preserve|@license|@cc_on/i.test(text);
|
||||
}
|
||||
}
|
||||
if (program.parse) {
|
||||
if (!program.parse.acorn && !program.parse.spidermonkey) {
|
||||
options.parse = program.parse;
|
||||
} else if (program.sourceMap && program.sourceMap.content == "inline") {
|
||||
fatal("ERROR: inline source map only works with built-in parser");
|
||||
}
|
||||
}
|
||||
|
||||
var files = ARGS._.slice();
|
||||
|
||||
if (ARGS.self) {
|
||||
if (files.length > 0) {
|
||||
var convert_path = function(name) {
|
||||
return name;
|
||||
};
|
||||
if (typeof program.sourceMap == "object" && "base" in program.sourceMap) {
|
||||
convert_path = function() {
|
||||
var base = program.sourceMap.base;
|
||||
delete options.sourceMap.base;
|
||||
return function(name) {
|
||||
return path.relative(base, name);
|
||||
};
|
||||
}();
|
||||
}
|
||||
if (program.verbose) {
|
||||
options.warnings = "verbose";
|
||||
} else if (program.warn) {
|
||||
options.warnings = true;
|
||||
}
|
||||
if (program.self) {
|
||||
if (program.args.length) {
|
||||
print_error("WARN: Ignoring input files since --self was passed");
|
||||
}
|
||||
files = UglifyJS.FILES;
|
||||
if (!ARGS.wrap) ARGS.wrap = "UglifyJS";
|
||||
if (!options.wrap) options.wrap = "UglifyJS";
|
||||
simple_glob(UglifyJS.FILES).forEach(function(name) {
|
||||
files[convert_path(name)] = read_file(name);
|
||||
});
|
||||
run();
|
||||
} else if (program.args.length) {
|
||||
simple_glob(program.args).forEach(function(name) {
|
||||
files[convert_path(name)] = read_file(name);
|
||||
});
|
||||
run();
|
||||
} else {
|
||||
var chunks = [];
|
||||
process.stdin.setEncoding("utf8");
|
||||
process.stdin.on("data", function(chunk) {
|
||||
chunks.push(chunk);
|
||||
}).on("end", function() {
|
||||
files = [ chunks.join("") ];
|
||||
run();
|
||||
});
|
||||
process.stdin.resume();
|
||||
}
|
||||
|
||||
var ORIG_MAP = ARGS.in_source_map;
|
||||
|
||||
if (ORIG_MAP) {
|
||||
ORIG_MAP = JSON.parse(fs.readFileSync(ORIG_MAP));
|
||||
if (files.length == 0) {
|
||||
print_error("INFO: Using file from the input source map: " + ORIG_MAP.file);
|
||||
files = [ ORIG_MAP.file ];
|
||||
}
|
||||
if (ARGS.source_map_root == null) {
|
||||
ARGS.source_map_root = ORIG_MAP.sourceRoot;
|
||||
}
|
||||
function convert_ast(fn) {
|
||||
return UglifyJS.AST_Node.from_mozilla_ast(Object.keys(files).reduce(fn, null));
|
||||
}
|
||||
|
||||
if (files.length == 0) {
|
||||
files = [ "-" ];
|
||||
}
|
||||
|
||||
if (files.indexOf("-") >= 0 && ARGS.source_map) {
|
||||
print_error("ERROR: Source map doesn't work with input from STDIN");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (files.filter(function(el){ return el == "-" }).length > 1) {
|
||||
print_error("ERROR: Can read a single file from STDIN (two or more dashes specified)");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
var STATS = {};
|
||||
var OUTPUT_FILE = ARGS.o;
|
||||
var TOPLEVEL = null;
|
||||
var P_RELATIVE = ARGS.p && ARGS.p == "relative";
|
||||
var SOURCES_CONTENT = {};
|
||||
|
||||
var SOURCE_MAP = ARGS.source_map ? UglifyJS.SourceMap({
|
||||
file: P_RELATIVE ? path.relative(path.dirname(ARGS.source_map), OUTPUT_FILE) : OUTPUT_FILE,
|
||||
root: ARGS.source_map_root,
|
||||
orig: ORIG_MAP,
|
||||
}) : null;
|
||||
|
||||
OUTPUT_OPTIONS.source_map = SOURCE_MAP;
|
||||
|
||||
try {
|
||||
var output = UglifyJS.OutputStream(OUTPUT_OPTIONS);
|
||||
var compressor = COMPRESS && UglifyJS.Compressor(COMPRESS);
|
||||
} catch(ex) {
|
||||
if (ex instanceof UglifyJS.DefaultsError) {
|
||||
print_error(ex.msg);
|
||||
print_error("Supported options:");
|
||||
print_error(sys.inspect(ex.defs));
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
async.eachLimit(files, 1, function (file, cb) {
|
||||
read_whole_file(file, function (err, code) {
|
||||
if (err) {
|
||||
print_error("ERROR: can't read file: " + file);
|
||||
process.exit(1);
|
||||
}
|
||||
if (ARGS.p != null) {
|
||||
if (P_RELATIVE) {
|
||||
file = path.relative(path.dirname(ARGS.source_map), file).replace(/\\/g, '/');
|
||||
} else {
|
||||
var p = parseInt(ARGS.p, 10);
|
||||
if (!isNaN(p)) {
|
||||
file = file.replace(/^\/+/, "").split(/\/+/).slice(ARGS.p).join("/");
|
||||
}
|
||||
}
|
||||
}
|
||||
SOURCES_CONTENT[file] = code;
|
||||
time_it("parse", function(){
|
||||
if (ARGS.spidermonkey) {
|
||||
var program = JSON.parse(code);
|
||||
if (!TOPLEVEL) TOPLEVEL = program;
|
||||
else TOPLEVEL.body = TOPLEVEL.body.concat(program.body);
|
||||
}
|
||||
else if (ARGS.acorn) {
|
||||
TOPLEVEL = acorn.parse(code, {
|
||||
locations : true,
|
||||
sourceFile : file,
|
||||
program : TOPLEVEL
|
||||
function run() {
|
||||
UglifyJS.AST_Node.warn_function = function(msg) {
|
||||
print_error("WARN: " + msg);
|
||||
};
|
||||
if (program.timings) options.timings = true;
|
||||
try {
|
||||
if (program.parse) {
|
||||
if (program.parse.acorn) {
|
||||
files = convert_ast(function(toplevel, name) {
|
||||
return require("acorn").parse(files[name], {
|
||||
locations: true,
|
||||
program: toplevel,
|
||||
sourceFile: name
|
||||
});
|
||||
});
|
||||
} else if (program.parse.spidermonkey) {
|
||||
files = convert_ast(function(toplevel, name) {
|
||||
var obj = JSON.parse(files[name]);
|
||||
if (!toplevel) return obj;
|
||||
toplevel.body = toplevel.body.concat(obj.body);
|
||||
return toplevel;
|
||||
});
|
||||
}
|
||||
else {
|
||||
try {
|
||||
TOPLEVEL = UglifyJS.parse(code, {
|
||||
filename : file,
|
||||
toplevel : TOPLEVEL,
|
||||
expression : ARGS.expr,
|
||||
bare_returns : ARGS.bare_returns,
|
||||
});
|
||||
} catch(ex) {
|
||||
if (ex instanceof UglifyJS.JS_Parse_Error) {
|
||||
print_error("Parse error at " + file + ":" + ex.line + "," + ex.col);
|
||||
print_error(ex.message);
|
||||
print_error(ex.stack);
|
||||
process.exit(1);
|
||||
}
|
||||
throw ex;
|
||||
}
|
||||
} catch (ex) {
|
||||
fatal(ex);
|
||||
}
|
||||
var result = UglifyJS.minify(files, options);
|
||||
if (result.error) {
|
||||
var ex = result.error;
|
||||
if (ex.name == "SyntaxError") {
|
||||
print_error("Parse error at " + ex.filename + ":" + ex.line + "," + ex.col);
|
||||
var col = ex.col;
|
||||
var lines = files[ex.filename].split(/\r?\n/);
|
||||
var line = lines[ex.line - 1];
|
||||
if (!line && !col) {
|
||||
line = lines[ex.line - 2];
|
||||
col = line.length;
|
||||
}
|
||||
if (line) {
|
||||
var limit = 70;
|
||||
if (col > limit) {
|
||||
line = line.slice(col - limit);
|
||||
col = limit;
|
||||
}
|
||||
};
|
||||
});
|
||||
cb();
|
||||
});
|
||||
}, function () {
|
||||
if (ARGS.acorn || ARGS.spidermonkey) time_it("convert_ast", function(){
|
||||
TOPLEVEL = UglifyJS.AST_Node.from_mozilla_ast(TOPLEVEL);
|
||||
});
|
||||
|
||||
if (ARGS.wrap != null) {
|
||||
TOPLEVEL = TOPLEVEL.wrap_commonjs(ARGS.wrap, ARGS.export_all);
|
||||
}
|
||||
|
||||
if (ARGS.enclose != null) {
|
||||
var arg_parameter_list = ARGS.enclose;
|
||||
if (arg_parameter_list === true) {
|
||||
arg_parameter_list = [];
|
||||
}
|
||||
else if (!(arg_parameter_list instanceof Array)) {
|
||||
arg_parameter_list = [arg_parameter_list];
|
||||
}
|
||||
TOPLEVEL = TOPLEVEL.wrap_enclose(arg_parameter_list);
|
||||
}
|
||||
|
||||
if (ARGS.mangle_props || ARGS.name_cache) (function(){
|
||||
var reserved = RESERVED ? RESERVED.props : null;
|
||||
var cache = readNameCache("props");
|
||||
var regex;
|
||||
|
||||
try {
|
||||
regex = ARGS.mangle_regex ? extractRegex(ARGS.mangle_regex) : null;
|
||||
} catch (e) {
|
||||
print_error("ERROR: Invalid --mangle-regex: " + e.message);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
TOPLEVEL = UglifyJS.mangle_properties(TOPLEVEL, {
|
||||
reserved : reserved,
|
||||
cache : cache,
|
||||
only_cache : !ARGS.mangle_props,
|
||||
regex : regex
|
||||
});
|
||||
writeNameCache("props", cache);
|
||||
})();
|
||||
|
||||
var SCOPE_IS_NEEDED = COMPRESS || MANGLE || ARGS.lint
|
||||
var TL_CACHE = readNameCache("vars");
|
||||
|
||||
if (SCOPE_IS_NEEDED) {
|
||||
time_it("scope", function(){
|
||||
TOPLEVEL.figure_out_scope({ screw_ie8: ARGS.screw_ie8, cache: TL_CACHE });
|
||||
if (ARGS.lint) {
|
||||
TOPLEVEL.scope_warnings();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (COMPRESS) {
|
||||
time_it("squeeze", function(){
|
||||
TOPLEVEL = TOPLEVEL.transform(compressor);
|
||||
});
|
||||
}
|
||||
|
||||
if (SCOPE_IS_NEEDED) {
|
||||
time_it("scope", function(){
|
||||
TOPLEVEL.figure_out_scope({ screw_ie8: ARGS.screw_ie8, cache: TL_CACHE });
|
||||
if (MANGLE && !TL_CACHE) {
|
||||
TOPLEVEL.compute_char_frequency(MANGLE);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (MANGLE) time_it("mangle", function(){
|
||||
MANGLE.cache = TL_CACHE;
|
||||
TOPLEVEL.mangle_names(MANGLE);
|
||||
});
|
||||
|
||||
writeNameCache("vars", TL_CACHE);
|
||||
|
||||
if (ARGS.source_map_include_sources) {
|
||||
for (var file in SOURCES_CONTENT) {
|
||||
if (SOURCES_CONTENT.hasOwnProperty(file)) {
|
||||
SOURCE_MAP.get().setSourceContent(file, SOURCES_CONTENT[file]);
|
||||
print_error(line.slice(0, 80));
|
||||
print_error(line.slice(0, col).replace(/\S/g, " ") + "^");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ARGS.dump_spidermonkey_ast) {
|
||||
print(JSON.stringify(TOPLEVEL.to_mozilla_ast(), null, 2));
|
||||
if (ex.defs) {
|
||||
print_error("Supported options:");
|
||||
print_error(format_object(ex.defs));
|
||||
}
|
||||
fatal(ex);
|
||||
} else if (program.output == "ast") {
|
||||
print(JSON.stringify(result.ast, function(key, value) {
|
||||
if (skip_key(key)) return;
|
||||
if (value instanceof UglifyJS.AST_Token) return;
|
||||
if (value instanceof UglifyJS.Dictionary) return;
|
||||
if (value instanceof UglifyJS.AST_Node) {
|
||||
var result = {
|
||||
_class: "AST_" + value.TYPE
|
||||
};
|
||||
value.CTOR.PROPS.forEach(function(prop) {
|
||||
result[prop] = value[prop];
|
||||
});
|
||||
return result;
|
||||
}
|
||||
return value;
|
||||
}, 2));
|
||||
} else if (program.output == "spidermonkey") {
|
||||
print(JSON.stringify(UglifyJS.minify(result.code, {
|
||||
compress: false,
|
||||
mangle: false,
|
||||
output: {
|
||||
ast: true,
|
||||
code: false
|
||||
}
|
||||
}).ast.to_mozilla_ast(), null, 2));
|
||||
} else if (program.output) {
|
||||
fs.writeFileSync(program.output, result.code);
|
||||
if (result.map) {
|
||||
fs.writeFileSync(program.output + ".map", result.map);
|
||||
}
|
||||
} else {
|
||||
time_it("generate", function(){
|
||||
TOPLEVEL.print(output);
|
||||
});
|
||||
print(result.code);
|
||||
}
|
||||
if (program.nameCache) {
|
||||
fs.writeFileSync(program.nameCache, JSON.stringify(options.nameCache));
|
||||
}
|
||||
if (result.timings) for (var phase in result.timings) {
|
||||
print_error("- " + phase + ": " + result.timings[phase].toFixed(3) + "s");
|
||||
}
|
||||
}
|
||||
|
||||
output = output.get();
|
||||
function fatal(message) {
|
||||
if (message instanceof Error) message = message.stack.replace(/^\S*?Error:/, "ERROR:")
|
||||
print_error(message);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (SOURCE_MAP) {
|
||||
fs.writeFileSync(ARGS.source_map, SOURCE_MAP, "utf8");
|
||||
var source_map_url = ARGS.source_map_url || (
|
||||
P_RELATIVE
|
||||
? path.relative(path.dirname(OUTPUT_FILE), ARGS.source_map)
|
||||
: ARGS.source_map
|
||||
);
|
||||
output += "\n//# sourceMappingURL=" + source_map_url;
|
||||
}
|
||||
|
||||
if (OUTPUT_FILE) {
|
||||
fs.writeFileSync(OUTPUT_FILE, output, "utf8");
|
||||
} else {
|
||||
print(output);
|
||||
// A file glob function that only supports "*" and "?" wildcards in the basename.
|
||||
// Example: "foo/bar/*baz??.*.js"
|
||||
// Argument `glob` may be a string or an array of strings.
|
||||
// Returns an array of strings. Garbage in, garbage out.
|
||||
function simple_glob(glob) {
|
||||
if (Array.isArray(glob)) {
|
||||
return [].concat.apply([], glob.map(simple_glob));
|
||||
}
|
||||
if (glob.match(/\*|\?/)) {
|
||||
var dir = path.dirname(glob);
|
||||
try {
|
||||
var entries = fs.readdirSync(dir);
|
||||
} catch (ex) {}
|
||||
if (entries) {
|
||||
var pattern = "^" + path.basename(glob)
|
||||
.replace(/[.+^$[\]\\(){}]/g, "\\$&")
|
||||
.replace(/\*/g, "[^/\\\\]*")
|
||||
.replace(/\?/g, "[^/\\\\]") + "$";
|
||||
var mod = process.platform === "win32" ? "i" : "";
|
||||
var rx = new RegExp(pattern, mod);
|
||||
var results = entries.filter(function(name) {
|
||||
return rx.test(name);
|
||||
}).map(function(name) {
|
||||
return path.join(dir, name);
|
||||
});
|
||||
if (results.length) return results;
|
||||
}
|
||||
}
|
||||
return [ glob ];
|
||||
}
|
||||
|
||||
if (ARGS.stats) {
|
||||
print_error(UglifyJS.string_template("Timing information (compressed {count} files):", {
|
||||
count: files.length
|
||||
}));
|
||||
for (var i in STATS) if (STATS.hasOwnProperty(i)) {
|
||||
print_error(UglifyJS.string_template("- {name}: {time}s", {
|
||||
name: i,
|
||||
time: (STATS[i] / 1000).toFixed(3)
|
||||
function read_file(path, default_value) {
|
||||
try {
|
||||
return fs.readFileSync(path, "utf8");
|
||||
} catch (ex) {
|
||||
if (ex.code == "ENOENT" && default_value != null) return default_value;
|
||||
fatal(ex);
|
||||
}
|
||||
}
|
||||
|
||||
function parse_js(flag) {
|
||||
return function(value, options) {
|
||||
options = options || {};
|
||||
try {
|
||||
UglifyJS.minify(value, {
|
||||
parse: {
|
||||
expression: true
|
||||
},
|
||||
compress: false,
|
||||
mangle: false,
|
||||
output: {
|
||||
ast: true,
|
||||
code: false
|
||||
}
|
||||
}).ast.walk(new UglifyJS.TreeWalker(function(node) {
|
||||
if (node instanceof UglifyJS.AST_Assign) {
|
||||
var name = node.left.print_to_string();
|
||||
var value = node.right;
|
||||
if (flag) {
|
||||
options[name] = value;
|
||||
} else if (value instanceof UglifyJS.AST_Array) {
|
||||
options[name] = value.elements.map(to_string);
|
||||
} 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) {
|
||||
return value instanceof UglifyJS.AST_Constant ? value.getValue() : value.print_to_string({
|
||||
quote_keys: true
|
||||
});
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/* -----[ functions ]----- */
|
||||
|
||||
function normalize(o) {
|
||||
for (var i in o) if (o.hasOwnProperty(i) && /-/.test(i)) {
|
||||
o[i.replace(/-/g, "_")] = o[i];
|
||||
delete o[i];
|
||||
}
|
||||
}
|
||||
|
||||
function getOptions(flag, constants) {
|
||||
var x = ARGS[flag];
|
||||
if (x == null || x === false) return null;
|
||||
var ret = {};
|
||||
if (x !== "") {
|
||||
if (Array.isArray(x)) x = x.map(function (v) { return "(" + v + ")"; }).join(", ");
|
||||
|
||||
var ast;
|
||||
try {
|
||||
ast = UglifyJS.parse(x, { expression: true });
|
||||
} catch(ex) {
|
||||
if (ex instanceof UglifyJS.JS_Parse_Error) {
|
||||
print_error("Error parsing arguments for flag `" + flag + "': " + x);
|
||||
process.exit(1);
|
||||
if (flag) {
|
||||
fatal("Error parsing arguments for '" + flag + "': " + value);
|
||||
} else {
|
||||
options[value] = null;
|
||||
}
|
||||
}
|
||||
ast.walk(new UglifyJS.TreeWalker(function(node){
|
||||
if (node instanceof UglifyJS.AST_Seq) return; // descend
|
||||
if (node instanceof UglifyJS.AST_Assign) {
|
||||
var name = node.left.print_to_string({ beautify: false }).replace(/-/g, "_");
|
||||
var value = node.right;
|
||||
if (constants)
|
||||
value = new Function("return (" + value.print_to_string() + ")")();
|
||||
ret[name] = value;
|
||||
return true; // no descend
|
||||
}
|
||||
if (node instanceof UglifyJS.AST_Symbol || node instanceof UglifyJS.AST_Binary) {
|
||||
var name = node.print_to_string({ beautify: false }).replace(/-/g, "_");
|
||||
ret[name] = true;
|
||||
return true; // no descend
|
||||
}
|
||||
print_error(node.TYPE)
|
||||
print_error("Error parsing arguments for flag `" + flag + "': " + x);
|
||||
process.exit(1);
|
||||
}));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
function read_whole_file(filename, cb) {
|
||||
if (filename == "-") {
|
||||
var chunks = [];
|
||||
process.stdin.setEncoding('utf-8');
|
||||
process.stdin.on('data', function (chunk) {
|
||||
chunks.push(chunk);
|
||||
}).on('end', function () {
|
||||
cb(null, chunks.join(""));
|
||||
});
|
||||
process.openStdin();
|
||||
} else {
|
||||
fs.readFile(filename, "utf-8", cb);
|
||||
return options;
|
||||
}
|
||||
}
|
||||
|
||||
function time_it(name, cont) {
|
||||
var t1 = new Date().getTime();
|
||||
var ret = cont();
|
||||
if (ARGS.stats) {
|
||||
var spent = new Date().getTime() - t1;
|
||||
if (STATS[name]) STATS[name] += spent;
|
||||
else STATS[name] = spent;
|
||||
function parse_source_map() {
|
||||
var parse = parse_js();
|
||||
return function(value, options) {
|
||||
var hasContent = options && "content" in options;
|
||||
var settings = parse(value, options);
|
||||
if (!hasContent && settings.content && settings.content != "inline") {
|
||||
print_error("INFO: Using input source map: " + settings.content);
|
||||
settings.content = read_file(settings.content, settings.content);
|
||||
}
|
||||
return settings;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
function skip_key(key) {
|
||||
return skip_keys.indexOf(key) >= 0;
|
||||
}
|
||||
|
||||
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) {
|
||||
console.error("%s", msg);
|
||||
process.stderr.write(msg);
|
||||
process.stderr.write("\n");
|
||||
}
|
||||
|
||||
function print(txt) {
|
||||
console.log("%s", txt);
|
||||
process.stdout.write(txt);
|
||||
process.stdout.write("\n");
|
||||
}
|
||||
|
||||
284
lib/ast.js
284
lib/ast.js
@@ -71,7 +71,7 @@ function DEFNODE(type, props, methods, base) {
|
||||
if (type) {
|
||||
ctor.prototype.TYPE = ctor.TYPE = type;
|
||||
}
|
||||
if (methods) for (i in methods) if (methods.hasOwnProperty(i)) {
|
||||
if (methods) for (i in methods) if (HOP(methods, i)) {
|
||||
if (/^\$/.test(i)) {
|
||||
ctor[i.substr(1)] = methods[i];
|
||||
} else {
|
||||
@@ -81,17 +81,30 @@ function DEFNODE(type, props, methods, base) {
|
||||
ctor.DEFMETHOD = function(name, method) {
|
||||
this.prototype[name] = method;
|
||||
};
|
||||
exports["AST_" + type] = ctor;
|
||||
if (typeof exports !== "undefined") {
|
||||
exports["AST_" + type] = ctor;
|
||||
}
|
||||
return ctor;
|
||||
};
|
||||
|
||||
var AST_Token = DEFNODE("Token", "type value line col pos endline endcol endpos nlb comments_before file raw", {
|
||||
var AST_Token = DEFNODE("Token", "type value line col pos endline endcol endpos nlb comments_before comments_after file raw", {
|
||||
}, null);
|
||||
|
||||
var AST_Node = DEFNODE("Node", "start end", {
|
||||
clone: function() {
|
||||
_clone: function(deep) {
|
||||
if (deep) {
|
||||
var self = this.clone();
|
||||
return self.transform(new TreeTransformer(function(node) {
|
||||
if (node !== self) {
|
||||
return node.clone(true);
|
||||
}
|
||||
}));
|
||||
}
|
||||
return new this.CTOR(this);
|
||||
},
|
||||
clone: function(deep) {
|
||||
return this._clone(deep);
|
||||
},
|
||||
$documentation: "Base class of all AST nodes",
|
||||
$propdoc: {
|
||||
start: "[AST_Token] The first token of this node",
|
||||
@@ -121,11 +134,10 @@ var AST_Debugger = DEFNODE("Debugger", null, {
|
||||
$documentation: "Represents a debugger statement",
|
||||
}, AST_Statement);
|
||||
|
||||
var AST_Directive = DEFNODE("Directive", "value scope quote", {
|
||||
var AST_Directive = DEFNODE("Directive", "value quote", {
|
||||
$documentation: "Represents a directive, like \"use strict\";",
|
||||
$propdoc: {
|
||||
value: "[string] The value of this directive as a plain string (it's not an AST_String!)",
|
||||
scope: "[AST_Scope/S] The scope that this directive affects",
|
||||
quote: "[string] the original quote character"
|
||||
},
|
||||
}, AST_Statement);
|
||||
@@ -143,12 +155,13 @@ var AST_SimpleStatement = DEFNODE("SimpleStatement", "body", {
|
||||
}, AST_Statement);
|
||||
|
||||
function walk_body(node, visitor) {
|
||||
if (node.body instanceof AST_Statement) {
|
||||
node.body._walk(visitor);
|
||||
var body = node.body;
|
||||
if (body instanceof AST_Statement) {
|
||||
body._walk(visitor);
|
||||
}
|
||||
else for (var i = 0, len = body.length; i < len; i++) {
|
||||
body[i]._walk(visitor);
|
||||
}
|
||||
else node.body.forEach(function(stat){
|
||||
stat._walk(visitor);
|
||||
});
|
||||
};
|
||||
|
||||
var AST_Block = DEFNODE("Block", "body", {
|
||||
@@ -168,21 +181,13 @@ var AST_BlockStatement = DEFNODE("BlockStatement", null, {
|
||||
}, AST_Block);
|
||||
|
||||
var AST_EmptyStatement = DEFNODE("EmptyStatement", null, {
|
||||
$documentation: "The empty statement (empty block or simply a semicolon)",
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this);
|
||||
}
|
||||
$documentation: "The empty statement (empty block or simply a semicolon)"
|
||||
}, AST_Statement);
|
||||
|
||||
var AST_StatementWithBody = DEFNODE("StatementWithBody", "body", {
|
||||
$documentation: "Base class for all statements that contain one nested body: `For`, `ForIn`, `Do`, `While`, `With`",
|
||||
$propdoc: {
|
||||
body: "[AST_Statement] the body; this should always be present, even if it's an AST_EmptyStatement"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
this.body._walk(visitor);
|
||||
});
|
||||
}
|
||||
}, AST_Statement);
|
||||
|
||||
@@ -196,6 +201,21 @@ var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", {
|
||||
this.label._walk(visitor);
|
||||
this.body._walk(visitor);
|
||||
});
|
||||
},
|
||||
clone: function(deep) {
|
||||
var node = this._clone(deep);
|
||||
if (deep) {
|
||||
var label = node.label;
|
||||
var def = this.label;
|
||||
node.walk(new TreeWalker(function(node) {
|
||||
if (node instanceof AST_LoopControl
|
||||
&& node.label && node.label.thedef === def) {
|
||||
node.label.thedef = label;
|
||||
label.references.push(node);
|
||||
}
|
||||
}));
|
||||
}
|
||||
return node;
|
||||
}
|
||||
}, AST_StatementWithBody);
|
||||
|
||||
@@ -278,10 +298,9 @@ var AST_With = DEFNODE("With", "expression", {
|
||||
|
||||
/* -----[ scope and functions ]----- */
|
||||
|
||||
var AST_Scope = DEFNODE("Scope", "directives variables functions uses_with uses_eval parent_scope enclosed cname", {
|
||||
var AST_Scope = DEFNODE("Scope", "variables functions uses_with uses_eval parent_scope enclosed cname", {
|
||||
$documentation: "Base class for all statements introducing a lexical scope",
|
||||
$propdoc: {
|
||||
directives: "[string*/S] an array of directives declared in this scope",
|
||||
variables: "[Object/S] a map of name -> SymbolDef for all variables/functions defined in this scope",
|
||||
functions: "[Object/S] like `variables`, but only lists function declarations",
|
||||
uses_with: "[boolean/S] tells whether this scope uses the `with` statement",
|
||||
@@ -297,62 +316,13 @@ var AST_Toplevel = DEFNODE("Toplevel", "globals", {
|
||||
$propdoc: {
|
||||
globals: "[Object/S] a map of name -> SymbolDef for all undeclared names",
|
||||
},
|
||||
wrap_enclose: function(arg_parameter_pairs) {
|
||||
var self = this;
|
||||
var args = [];
|
||||
var parameters = [];
|
||||
|
||||
arg_parameter_pairs.forEach(function(pair) {
|
||||
var splitAt = pair.lastIndexOf(":");
|
||||
|
||||
args.push(pair.substr(0, splitAt));
|
||||
parameters.push(pair.substr(splitAt + 1));
|
||||
});
|
||||
|
||||
var wrapped_tl = "(function(" + parameters.join(",") + "){ '$ORIG'; })(" + args.join(",") + ")";
|
||||
wrap_commonjs: function(name) {
|
||||
var body = this.body;
|
||||
var wrapped_tl = "(function(exports){'$ORIG';})(typeof " + name + "=='undefined'?(" + name + "={}):" + name + ");";
|
||||
wrapped_tl = parse(wrapped_tl);
|
||||
wrapped_tl = wrapped_tl.transform(new TreeTransformer(function before(node){
|
||||
if (node instanceof AST_Directive && node.value == "$ORIG") {
|
||||
return MAP.splice(self.body);
|
||||
}
|
||||
}));
|
||||
return wrapped_tl;
|
||||
},
|
||||
wrap_commonjs: function(name, export_all) {
|
||||
var self = this;
|
||||
var to_export = [];
|
||||
if (export_all) {
|
||||
self.figure_out_scope();
|
||||
self.walk(new TreeWalker(function(node){
|
||||
if (node instanceof AST_SymbolDeclaration && node.definition().global) {
|
||||
if (!find_if(function(n){ return n.name == node.name }, to_export))
|
||||
to_export.push(node);
|
||||
}
|
||||
}));
|
||||
}
|
||||
var wrapped_tl = "(function(exports, global){ '$ORIG'; '$EXPORTS'; global['" + name + "'] = exports; }({}, (function(){return this}())))";
|
||||
wrapped_tl = parse(wrapped_tl);
|
||||
wrapped_tl = wrapped_tl.transform(new TreeTransformer(function before(node){
|
||||
if (node instanceof AST_Directive) {
|
||||
switch (node.value) {
|
||||
case "$ORIG":
|
||||
return MAP.splice(self.body);
|
||||
case "$EXPORTS":
|
||||
var body = [];
|
||||
to_export.forEach(function(sym){
|
||||
body.push(new AST_SimpleStatement({
|
||||
body: new AST_Assign({
|
||||
left: new AST_Sub({
|
||||
expression: new AST_SymbolRef({ name: "exports" }),
|
||||
property: new AST_String({ value: sym.name }),
|
||||
}),
|
||||
operator: "=",
|
||||
right: new AST_SymbolRef(sym),
|
||||
}),
|
||||
}));
|
||||
});
|
||||
return MAP.splice(body);
|
||||
}
|
||||
return MAP.splice(body);
|
||||
}
|
||||
}));
|
||||
return wrapped_tl;
|
||||
@@ -369,9 +339,10 @@ var AST_Lambda = DEFNODE("Lambda", "name argnames uses_arguments", {
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
if (this.name) this.name._walk(visitor);
|
||||
this.argnames.forEach(function(arg){
|
||||
arg._walk(visitor);
|
||||
});
|
||||
var argnames = this.argnames;
|
||||
for (var i = 0, len = argnames.length; i < len; i++) {
|
||||
argnames[i]._walk(visitor);
|
||||
}
|
||||
walk_body(this, visitor);
|
||||
});
|
||||
}
|
||||
@@ -381,11 +352,11 @@ var AST_Accessor = DEFNODE("Accessor", null, {
|
||||
$documentation: "A setter/getter function. The `name` property is always null."
|
||||
}, AST_Lambda);
|
||||
|
||||
var AST_Function = DEFNODE("Function", null, {
|
||||
var AST_Function = DEFNODE("Function", "inlined", {
|
||||
$documentation: "A function expression"
|
||||
}, AST_Lambda);
|
||||
|
||||
var AST_Defun = DEFNODE("Defun", null, {
|
||||
var AST_Defun = DEFNODE("Defun", "inlined", {
|
||||
$documentation: "A function definition"
|
||||
}, AST_Lambda);
|
||||
|
||||
@@ -522,18 +493,19 @@ var AST_Finally = DEFNODE("Finally", null, {
|
||||
$documentation: "A `finally` node; only makes sense as part of a `try` statement"
|
||||
}, AST_Block);
|
||||
|
||||
/* -----[ VAR/CONST ]----- */
|
||||
/* -----[ VAR ]----- */
|
||||
|
||||
var AST_Definitions = DEFNODE("Definitions", "definitions", {
|
||||
$documentation: "Base class for `var` or `const` nodes (variable declarations/initializations)",
|
||||
$documentation: "Base class for `var` nodes (variable declarations/initializations)",
|
||||
$propdoc: {
|
||||
definitions: "[AST_VarDef*] array of variable definitions"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
this.definitions.forEach(function(def){
|
||||
def._walk(visitor);
|
||||
});
|
||||
var definitions = this.definitions;
|
||||
for (var i = 0, len = definitions.length; i < len; i++) {
|
||||
definitions[i]._walk(visitor);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, AST_Statement);
|
||||
@@ -542,14 +514,10 @@ var AST_Var = DEFNODE("Var", null, {
|
||||
$documentation: "A `var` statement"
|
||||
}, AST_Definitions);
|
||||
|
||||
var AST_Const = DEFNODE("Const", null, {
|
||||
$documentation: "A `const` statement"
|
||||
}, AST_Definitions);
|
||||
|
||||
var AST_VarDef = DEFNODE("VarDef", "name value", {
|
||||
$documentation: "A variable declaration; only appears in a AST_Definitions node",
|
||||
$propdoc: {
|
||||
name: "[AST_SymbolVar|AST_SymbolConst] name of the variable",
|
||||
name: "[AST_SymbolVar] name of the variable",
|
||||
value: "[AST_Node?] initializer, or null of there's no initializer"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
@@ -570,10 +538,11 @@ var AST_Call = DEFNODE("Call", "expression args", {
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
var args = this.args;
|
||||
for (var i = 0, len = args.length; i < len; i++) {
|
||||
args[i]._walk(visitor);
|
||||
}
|
||||
this.expression._walk(visitor);
|
||||
this.args.forEach(function(arg){
|
||||
arg._walk(visitor);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -582,61 +551,16 @@ var AST_New = DEFNODE("New", null, {
|
||||
$documentation: "An object instantiation. Derives from a function call since it has exactly the same properties"
|
||||
}, AST_Call);
|
||||
|
||||
var AST_Seq = DEFNODE("Seq", "car cdr", {
|
||||
$documentation: "A sequence expression (two comma-separated expressions)",
|
||||
var AST_Sequence = DEFNODE("Sequence", "expressions", {
|
||||
$documentation: "A sequence expression (comma-separated expressions)",
|
||||
$propdoc: {
|
||||
car: "[AST_Node] first element in sequence",
|
||||
cdr: "[AST_Node] second element in sequence"
|
||||
},
|
||||
$cons: function(x, y) {
|
||||
var seq = new AST_Seq(x);
|
||||
seq.car = x;
|
||||
seq.cdr = y;
|
||||
return seq;
|
||||
},
|
||||
$from_array: function(array) {
|
||||
if (array.length == 0) return null;
|
||||
if (array.length == 1) return array[0].clone();
|
||||
var list = null;
|
||||
for (var i = array.length; --i >= 0;) {
|
||||
list = AST_Seq.cons(array[i], list);
|
||||
}
|
||||
var p = list;
|
||||
while (p) {
|
||||
if (p.cdr && !p.cdr.cdr) {
|
||||
p.cdr = p.cdr.car;
|
||||
break;
|
||||
}
|
||||
p = p.cdr;
|
||||
}
|
||||
return list;
|
||||
},
|
||||
to_array: function() {
|
||||
var p = this, a = [];
|
||||
while (p) {
|
||||
a.push(p.car);
|
||||
if (p.cdr && !(p.cdr instanceof AST_Seq)) {
|
||||
a.push(p.cdr);
|
||||
break;
|
||||
}
|
||||
p = p.cdr;
|
||||
}
|
||||
return a;
|
||||
},
|
||||
add: function(node) {
|
||||
var p = this;
|
||||
while (p) {
|
||||
if (!(p.cdr instanceof AST_Seq)) {
|
||||
var cell = AST_Seq.cons(p.cdr, node);
|
||||
return p.cdr = cell;
|
||||
}
|
||||
p = p.cdr;
|
||||
}
|
||||
expressions: "[AST_Node*] array of expressions (at least two)"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
this.car._walk(visitor);
|
||||
if (this.cdr) this.cdr._walk(visitor);
|
||||
this.expressions.forEach(function(node) {
|
||||
node._walk(visitor);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -689,7 +613,7 @@ var AST_UnaryPostfix = DEFNODE("UnaryPostfix", null, {
|
||||
$documentation: "Unary postfix expression, i.e. `i++`"
|
||||
}, AST_Unary);
|
||||
|
||||
var AST_Binary = DEFNODE("Binary", "left operator right", {
|
||||
var AST_Binary = DEFNODE("Binary", "operator left right", {
|
||||
$documentation: "Binary expression, i.e. `a + b`",
|
||||
$propdoc: {
|
||||
left: "[AST_Node] left-hand side expression",
|
||||
@@ -733,9 +657,10 @@ var AST_Array = DEFNODE("Array", "elements", {
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
this.elements.forEach(function(el){
|
||||
el._walk(visitor);
|
||||
});
|
||||
var elements = this.elements;
|
||||
for (var i = 0, len = elements.length; i < len; i++) {
|
||||
elements[i]._walk(visitor);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -747,9 +672,10 @@ var AST_Object = DEFNODE("Object", "properties", {
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
this.properties.forEach(function(prop){
|
||||
prop._walk(visitor);
|
||||
});
|
||||
var properties = this.properties;
|
||||
for (var i = 0, len = properties.length; i < len; i++) {
|
||||
properties[i]._walk(visitor);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -757,8 +683,8 @@ var AST_Object = DEFNODE("Object", "properties", {
|
||||
var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", {
|
||||
$documentation: "Base class for literal object properties",
|
||||
$propdoc: {
|
||||
key: "[string] the property name converted to a string for ObjectKeyVal. For setters and getters this is an arbitrary AST_Node.",
|
||||
value: "[AST_Node] property value. For setters and getters this is an AST_Function."
|
||||
key: "[string] the property name converted to a string for ObjectKeyVal. For setters and getters this is an AST_SymbolAccessor.",
|
||||
value: "[AST_Node] property value. For setters and getters this is an AST_Accessor."
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
@@ -796,20 +722,13 @@ var AST_SymbolAccessor = DEFNODE("SymbolAccessor", null, {
|
||||
}, AST_Symbol);
|
||||
|
||||
var AST_SymbolDeclaration = DEFNODE("SymbolDeclaration", "init", {
|
||||
$documentation: "A declaration symbol (symbol in var/const, function name or argument, symbol in catch)",
|
||||
$propdoc: {
|
||||
init: "[AST_Node*/S] array of initializers for this declaration."
|
||||
}
|
||||
$documentation: "A declaration symbol (symbol in var, function name or argument, symbol in catch)",
|
||||
}, AST_Symbol);
|
||||
|
||||
var AST_SymbolVar = DEFNODE("SymbolVar", null, {
|
||||
$documentation: "Symbol defining a variable",
|
||||
}, AST_SymbolDeclaration);
|
||||
|
||||
var AST_SymbolConst = DEFNODE("SymbolConst", null, {
|
||||
$documentation: "A constant declaration"
|
||||
}, AST_SymbolDeclaration);
|
||||
|
||||
var AST_SymbolFunarg = DEFNODE("SymbolFunarg", null, {
|
||||
$documentation: "Symbol naming a function argument",
|
||||
}, AST_SymbolVar);
|
||||
@@ -938,23 +857,22 @@ TreeWalker.prototype = {
|
||||
if (!ret && descend) {
|
||||
descend.call(node);
|
||||
}
|
||||
this.pop(node);
|
||||
this.pop();
|
||||
return ret;
|
||||
},
|
||||
parent: function(n) {
|
||||
return this.stack[this.stack.length - 2 - (n || 0)];
|
||||
},
|
||||
push: function (node) {
|
||||
push: function(node) {
|
||||
if (node instanceof AST_Lambda) {
|
||||
this.directives = Object.create(this.directives);
|
||||
} else if (node instanceof AST_Directive) {
|
||||
this.directives[node.value] = this.directives[node.value] ? "up" : true;
|
||||
} else if (node instanceof AST_Directive && !this.directives[node.value]) {
|
||||
this.directives[node.value] = node;
|
||||
}
|
||||
this.stack.push(node);
|
||||
},
|
||||
pop: function(node) {
|
||||
this.stack.pop();
|
||||
if (node instanceof AST_Lambda) {
|
||||
pop: function() {
|
||||
if (this.stack.pop() instanceof AST_Lambda) {
|
||||
this.directives = Object.getPrototypeOf(this.directives);
|
||||
}
|
||||
},
|
||||
@@ -976,38 +894,20 @@ TreeWalker.prototype = {
|
||||
for (var i = 0; i < node.body.length; ++i) {
|
||||
var st = node.body[i];
|
||||
if (!(st instanceof AST_Directive)) break;
|
||||
if (st.value == type) return true;
|
||||
if (st.value == type) return st;
|
||||
}
|
||||
}
|
||||
},
|
||||
in_boolean_context: function() {
|
||||
loopcontrol_target: function(node) {
|
||||
var stack = this.stack;
|
||||
var i = stack.length, self = stack[--i];
|
||||
while (i > 0) {
|
||||
var p = stack[--i];
|
||||
if ((p instanceof AST_If && p.condition === self) ||
|
||||
(p instanceof AST_Conditional && p.condition === self) ||
|
||||
(p instanceof AST_DWLoop && p.condition === self) ||
|
||||
(p instanceof AST_For && p.condition === self) ||
|
||||
(p instanceof AST_UnaryPrefix && p.operator == "!" && p.expression === self))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (!(p instanceof AST_Binary && (p.operator == "&&" || p.operator == "||")))
|
||||
return false;
|
||||
self = p;
|
||||
}
|
||||
},
|
||||
loopcontrol_target: function(label) {
|
||||
var stack = this.stack;
|
||||
if (label) for (var i = stack.length; --i >= 0;) {
|
||||
if (node.label) for (var i = stack.length; --i >= 0;) {
|
||||
var x = stack[i];
|
||||
if (x instanceof AST_LabeledStatement && x.label.name == label.name) {
|
||||
if (x instanceof AST_LabeledStatement && x.label.name == node.label.name)
|
||||
return x.body;
|
||||
}
|
||||
} else for (var i = stack.length; --i >= 0;) {
|
||||
var x = stack[i];
|
||||
if (x instanceof AST_Switch || x instanceof AST_IterationStatement)
|
||||
if (x instanceof AST_IterationStatement
|
||||
|| node instanceof AST_Break && x instanceof AST_Switch)
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
5604
lib/compress.js
5604
lib/compress.js
File diff suppressed because it is too large
Load Diff
228
lib/minify.js
Normal file
228
lib/minify.js
Normal file
@@ -0,0 +1,228 @@
|
||||
"use strict";
|
||||
|
||||
var to_ascii = typeof atob == "undefined" ? function(b64) {
|
||||
return new Buffer(b64, "base64").toString();
|
||||
} : atob;
|
||||
var to_base64 = typeof btoa == "undefined" ? function(str) {
|
||||
return new Buffer(str).toString("base64");
|
||||
} : btoa;
|
||||
|
||||
function read_source_map(code) {
|
||||
var match = /\n\/\/# sourceMappingURL=data:application\/json(;.*?)?;base64,(.*)/.exec(code);
|
||||
if (!match) {
|
||||
AST_Node.warn("inline source map not found");
|
||||
return null;
|
||||
}
|
||||
return to_ascii(match[2]);
|
||||
}
|
||||
|
||||
function set_shorthand(name, options, keys) {
|
||||
if (options[name]) {
|
||||
keys.forEach(function(key) {
|
||||
if (options[key]) {
|
||||
if (typeof options[key] != "object") options[key] = {};
|
||||
if (!(name in options[key])) options[key][name] = options[name];
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function init_cache(cache) {
|
||||
if (!cache) return;
|
||||
if (!("cname" in cache)) cache.cname = -1;
|
||||
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 {
|
||||
cname: cache.cname,
|
||||
props: cache.props.toObject()
|
||||
};
|
||||
}
|
||||
|
||||
function minify(files, options) {
|
||||
var warn_function = AST_Node.warn_function;
|
||||
try {
|
||||
options = defaults(options, {
|
||||
compress: {},
|
||||
ie8: false,
|
||||
keep_fnames: false,
|
||||
mangle: {},
|
||||
nameCache: null,
|
||||
output: {},
|
||||
parse: {},
|
||||
rename: undefined,
|
||||
sourceMap: false,
|
||||
timings: false,
|
||||
toplevel: false,
|
||||
warnings: false,
|
||||
wrap: false,
|
||||
}, true);
|
||||
var timings = options.timings && {
|
||||
start: Date.now()
|
||||
};
|
||||
if (options.rename === undefined) {
|
||||
options.rename = options.compress && options.mangle;
|
||||
}
|
||||
set_shorthand("ie8", options, [ "compress", "mangle", "output" ]);
|
||||
set_shorthand("keep_fnames", options, [ "compress", "mangle" ]);
|
||||
set_shorthand("toplevel", options, [ "compress", "mangle" ]);
|
||||
set_shorthand("warnings", options, [ "compress" ]);
|
||||
var quoted_props;
|
||||
if (options.mangle) {
|
||||
options.mangle = defaults(options.mangle, {
|
||||
cache: options.nameCache && (options.nameCache.vars || {}),
|
||||
eval: false,
|
||||
ie8: false,
|
||||
keep_fnames: false,
|
||||
properties: false,
|
||||
reserved: [],
|
||||
toplevel: false,
|
||||
}, 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) {
|
||||
options.sourceMap = defaults(options.sourceMap, {
|
||||
content: null,
|
||||
filename: null,
|
||||
includeSources: false,
|
||||
root: null,
|
||||
url: null,
|
||||
}, true);
|
||||
}
|
||||
var warnings = [];
|
||||
if (options.warnings && !AST_Node.warn_function) {
|
||||
AST_Node.warn_function = function(warning) {
|
||||
warnings.push(warning);
|
||||
};
|
||||
}
|
||||
if (timings) timings.parse = Date.now();
|
||||
var toplevel;
|
||||
if (files instanceof AST_Toplevel) {
|
||||
toplevel = files;
|
||||
} else {
|
||||
if (typeof files == "string") {
|
||||
files = [ files ];
|
||||
}
|
||||
options.parse = options.parse || {};
|
||||
options.parse.toplevel = null;
|
||||
for (var name in files) if (HOP(files, name)) {
|
||||
options.parse.filename = name;
|
||||
options.parse.toplevel = parse(files[name], options.parse);
|
||||
if (options.sourceMap && options.sourceMap.content == "inline") {
|
||||
if (Object.keys(files).length > 1)
|
||||
throw new Error("inline source map only works with singular input");
|
||||
options.sourceMap.content = read_source_map(files[name]);
|
||||
}
|
||||
}
|
||||
toplevel = options.parse.toplevel;
|
||||
}
|
||||
if (quoted_props) {
|
||||
reserve_quoted_keys(toplevel, quoted_props);
|
||||
}
|
||||
if (options.wrap) {
|
||||
toplevel = toplevel.wrap_commonjs(options.wrap);
|
||||
}
|
||||
if (timings) timings.rename = Date.now();
|
||||
if (options.rename) {
|
||||
toplevel.figure_out_scope(options.mangle);
|
||||
toplevel.expand_names(options.mangle);
|
||||
}
|
||||
if (timings) timings.compress = Date.now();
|
||||
if (options.compress) toplevel = new Compressor(options.compress).compress(toplevel);
|
||||
if (timings) timings.scope = Date.now();
|
||||
if (options.mangle) toplevel.figure_out_scope(options.mangle);
|
||||
if (timings) timings.mangle = Date.now();
|
||||
if (options.mangle) {
|
||||
base54.reset();
|
||||
toplevel.compute_char_frequency(options.mangle);
|
||||
toplevel.mangle_names(options.mangle);
|
||||
}
|
||||
if (timings) timings.properties = Date.now();
|
||||
if (options.mangle && options.mangle.properties) {
|
||||
toplevel = mangle_properties(toplevel, options.mangle.properties);
|
||||
}
|
||||
if (timings) timings.output = Date.now();
|
||||
var result = {};
|
||||
if (options.output.ast) {
|
||||
result.ast = toplevel;
|
||||
}
|
||||
if (!HOP(options.output, "code") || options.output.code) {
|
||||
if (options.sourceMap) {
|
||||
if (typeof options.sourceMap.content == "string") {
|
||||
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 (files instanceof AST_Toplevel) {
|
||||
throw new Error("original source content unavailable");
|
||||
} else for (var name in files) if (HOP(files, name)) {
|
||||
options.output.source_map.get().setSourceContent(name, files[name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
delete options.output.ast;
|
||||
delete options.output.code;
|
||||
var stream = OutputStream(options.output);
|
||||
toplevel.print(stream);
|
||||
result.code = stream.get();
|
||||
if (options.sourceMap) {
|
||||
result.map = options.output.source_map.toString();
|
||||
if (options.sourceMap.url == "inline") {
|
||||
result.code += "\n//# sourceMappingURL=data:application/json;charset=utf-8;base64," + to_base64(result.map);
|
||||
} else if (options.sourceMap.url) {
|
||||
result.code += "\n//# sourceMappingURL=" + options.sourceMap.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) {
|
||||
timings.end = Date.now();
|
||||
result.timings = {
|
||||
parse: 1e-3 * (timings.rename - timings.parse),
|
||||
rename: 1e-3 * (timings.compress - timings.rename),
|
||||
compress: 1e-3 * (timings.scope - timings.compress),
|
||||
scope: 1e-3 * (timings.mangle - timings.scope),
|
||||
mangle: 1e-3 * (timings.properties - timings.mangle),
|
||||
properties: 1e-3 * (timings.output - timings.properties),
|
||||
output: 1e-3 * (timings.end - timings.output),
|
||||
total: 1e-3 * (timings.end - timings.start)
|
||||
}
|
||||
}
|
||||
if (warnings.length) {
|
||||
result.warnings = warnings;
|
||||
}
|
||||
return result;
|
||||
} catch (ex) {
|
||||
return { error: ex };
|
||||
} finally {
|
||||
AST_Node.warn_function = warn_function;
|
||||
}
|
||||
}
|
||||
@@ -45,20 +45,55 @@
|
||||
|
||||
(function(){
|
||||
|
||||
var MOZ_TO_ME = {
|
||||
ExpressionStatement: function(M) {
|
||||
var expr = M.expression;
|
||||
if (expr.type === "Literal" && typeof expr.value === "string") {
|
||||
return new AST_Directive({
|
||||
start: my_start_token(M),
|
||||
end: my_end_token(M),
|
||||
value: expr.value
|
||||
var normalize_directives = function(body) {
|
||||
var in_directive = true;
|
||||
|
||||
for (var i = 0; i < body.length; i++) {
|
||||
if (in_directive && body[i] instanceof AST_Statement && body[i].body instanceof AST_String) {
|
||||
body[i] = new AST_Directive({
|
||||
start: body[i].start,
|
||||
end: body[i].end,
|
||||
value: body[i].body.value
|
||||
});
|
||||
} else if (in_directive && !(body[i] instanceof AST_Statement && body[i].body instanceof AST_String)) {
|
||||
in_directive = false;
|
||||
}
|
||||
}
|
||||
|
||||
return body;
|
||||
};
|
||||
|
||||
var MOZ_TO_ME = {
|
||||
Program: function(M) {
|
||||
return new AST_Toplevel({
|
||||
start: my_start_token(M),
|
||||
end: my_end_token(M),
|
||||
body: normalize_directives(M.body.map(from_moz))
|
||||
});
|
||||
},
|
||||
FunctionDeclaration: function(M) {
|
||||
return new AST_Defun({
|
||||
start: my_start_token(M),
|
||||
end: my_end_token(M),
|
||||
name: from_moz(M.id),
|
||||
argnames: M.params.map(from_moz),
|
||||
body: normalize_directives(from_moz(M.body).body)
|
||||
});
|
||||
},
|
||||
FunctionExpression: function(M) {
|
||||
return new AST_Function({
|
||||
start: my_start_token(M),
|
||||
end: my_end_token(M),
|
||||
name: from_moz(M.id),
|
||||
argnames: M.params.map(from_moz),
|
||||
body: normalize_directives(from_moz(M.body).body)
|
||||
});
|
||||
},
|
||||
ExpressionStatement: function(M) {
|
||||
return new AST_SimpleStatement({
|
||||
start: my_start_token(M),
|
||||
end: my_end_token(M),
|
||||
body: from_moz(expr)
|
||||
body: from_moz(M.expression)
|
||||
});
|
||||
},
|
||||
TryStatement: function(M) {
|
||||
@@ -76,23 +111,28 @@
|
||||
},
|
||||
Property: function(M) {
|
||||
var key = M.key;
|
||||
var name = key.type == "Identifier" ? key.name : key.value;
|
||||
var args = {
|
||||
start : my_start_token(key),
|
||||
end : my_end_token(M.value),
|
||||
key : name,
|
||||
key : key.type == "Identifier" ? key.name : key.value,
|
||||
value : from_moz(M.value)
|
||||
};
|
||||
switch (M.kind) {
|
||||
case "init":
|
||||
return new AST_ObjectKeyVal(args);
|
||||
case "set":
|
||||
args.value.name = from_moz(key);
|
||||
return new AST_ObjectSetter(args);
|
||||
case "get":
|
||||
args.value.name = from_moz(key);
|
||||
return new AST_ObjectGetter(args);
|
||||
}
|
||||
if (M.kind == "init") return new AST_ObjectKeyVal(args);
|
||||
args.key = new AST_SymbolAccessor({
|
||||
name: args.key
|
||||
});
|
||||
args.value = new AST_Accessor(args.value);
|
||||
if (M.kind == "get") return new AST_ObjectGetter(args);
|
||||
if (M.kind == "set") return new AST_ObjectSetter(args);
|
||||
},
|
||||
ArrayExpression: function(M) {
|
||||
return new AST_Array({
|
||||
start : my_start_token(M),
|
||||
end : my_end_token(M),
|
||||
elements : M.elements.map(function(elem){
|
||||
return elem === null ? new AST_Hole() : from_moz(elem);
|
||||
})
|
||||
});
|
||||
},
|
||||
ObjectExpression: function(M) {
|
||||
return new AST_Object({
|
||||
@@ -105,7 +145,11 @@
|
||||
});
|
||||
},
|
||||
SequenceExpression: function(M) {
|
||||
return AST_Seq.from_array(M.expressions.map(from_moz));
|
||||
return new AST_Sequence({
|
||||
start : my_start_token(M),
|
||||
end : my_end_token(M),
|
||||
expressions: M.expressions.map(from_moz)
|
||||
});
|
||||
},
|
||||
MemberExpression: function(M) {
|
||||
return new (M.computed ? AST_Sub : AST_Dot)({
|
||||
@@ -124,7 +168,7 @@
|
||||
});
|
||||
},
|
||||
VariableDeclaration: function(M) {
|
||||
return new (M.kind === "const" ? AST_Const : AST_Var)({
|
||||
return new AST_Var({
|
||||
start : my_start_token(M),
|
||||
end : my_end_token(M),
|
||||
definitions : M.declarations.map(from_moz)
|
||||
@@ -160,7 +204,7 @@
|
||||
Identifier: function(M) {
|
||||
var p = FROM_MOZ_STACK[FROM_MOZ_STACK.length - 2];
|
||||
return new ( p.type == "LabeledStatement" ? AST_Label
|
||||
: p.type == "VariableDeclarator" && p.id === M ? (p.kind == "const" ? AST_SymbolConst : AST_SymbolVar)
|
||||
: p.type == "VariableDeclarator" && p.id === M ? AST_SymbolVar
|
||||
: p.type == "FunctionExpression" ? (p.id === M ? AST_SymbolLambda : AST_SymbolFunarg)
|
||||
: p.type == "FunctionDeclaration" ? (p.id === M ? AST_SymbolDefun : AST_SymbolFunarg)
|
||||
: p.type == "CatchClause" ? AST_SymbolCatch
|
||||
@@ -185,7 +229,6 @@
|
||||
});
|
||||
};
|
||||
|
||||
map("Program", AST_Toplevel, "body@body");
|
||||
map("EmptyStatement", AST_EmptyStatement);
|
||||
map("BlockStatement", AST_BlockStatement, "body@body");
|
||||
map("IfStatement", AST_If, "test>condition, consequent>body, alternate>alternative");
|
||||
@@ -201,13 +244,10 @@
|
||||
map("ForStatement", AST_For, "init>init, test>condition, update>step, body>body");
|
||||
map("ForInStatement", AST_ForIn, "left>init, right>object, body>body");
|
||||
map("DebuggerStatement", AST_Debugger);
|
||||
map("FunctionDeclaration", AST_Defun, "id>name, params@argnames, body%body");
|
||||
map("VariableDeclarator", AST_VarDef, "id>name, init>value");
|
||||
map("CatchClause", AST_Catch, "param>argname, body%body");
|
||||
|
||||
map("ThisExpression", AST_This);
|
||||
map("ArrayExpression", AST_Array, "elements@elements");
|
||||
map("FunctionExpression", AST_Function, "id>name, params@argnames, body%body");
|
||||
map("BinaryExpression", 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");
|
||||
@@ -215,6 +255,28 @@
|
||||
map("NewExpression", AST_New, "callee>expression, arguments@args");
|
||||
map("CallExpression", AST_Call, "callee>expression, arguments@args");
|
||||
|
||||
def_to_moz(AST_Toplevel, function To_Moz_Program(M) {
|
||||
return to_moz_scope("Program", M);
|
||||
});
|
||||
|
||||
def_to_moz(AST_Defun, function To_Moz_FunctionDeclaration(M) {
|
||||
return {
|
||||
type: "FunctionDeclaration",
|
||||
id: to_moz(M.name),
|
||||
params: M.argnames.map(to_moz),
|
||||
body: to_moz_scope("BlockStatement", M)
|
||||
}
|
||||
});
|
||||
|
||||
def_to_moz(AST_Function, function To_Moz_FunctionExpression(M) {
|
||||
return {
|
||||
type: "FunctionExpression",
|
||||
id: to_moz(M.name),
|
||||
params: M.argnames.map(to_moz),
|
||||
body: to_moz_scope("BlockStatement", M)
|
||||
}
|
||||
});
|
||||
|
||||
def_to_moz(AST_Directive, function To_Moz_Directive(M) {
|
||||
return {
|
||||
type: "ExpressionStatement",
|
||||
@@ -262,15 +324,15 @@
|
||||
def_to_moz(AST_Definitions, function To_Moz_VariableDeclaration(M) {
|
||||
return {
|
||||
type: "VariableDeclaration",
|
||||
kind: M instanceof AST_Const ? "const" : "var",
|
||||
kind: "var",
|
||||
declarations: M.definitions.map(to_moz)
|
||||
};
|
||||
});
|
||||
|
||||
def_to_moz(AST_Seq, function To_Moz_SequenceExpression(M) {
|
||||
def_to_moz(AST_Sequence, function To_Moz_SequenceExpression(M) {
|
||||
return {
|
||||
type: "SequenceExpression",
|
||||
expressions: M.to_array().map(to_moz)
|
||||
expressions: M.expressions.map(to_moz)
|
||||
};
|
||||
});
|
||||
|
||||
@@ -302,6 +364,13 @@
|
||||
};
|
||||
});
|
||||
|
||||
def_to_moz(AST_Array, function To_Moz_ArrayExpression(M) {
|
||||
return {
|
||||
type: "ArrayExpression",
|
||||
elements: M.elements.map(to_moz)
|
||||
};
|
||||
});
|
||||
|
||||
def_to_moz(AST_Object, function To_Moz_ObjectExpression(M) {
|
||||
return {
|
||||
type: "ObjectExpression",
|
||||
@@ -310,11 +379,10 @@
|
||||
});
|
||||
|
||||
def_to_moz(AST_ObjectProperty, function To_Moz_Property(M) {
|
||||
var key = (
|
||||
is_identifier(M.key)
|
||||
? {type: "Identifier", name: M.key}
|
||||
: {type: "Literal", value: M.key}
|
||||
);
|
||||
var key = {
|
||||
type: "Literal",
|
||||
value: M.key instanceof AST_SymbolAccessor ? M.key.name : M.key
|
||||
};
|
||||
var kind;
|
||||
if (M instanceof AST_ObjectKeyVal) {
|
||||
kind = "init";
|
||||
@@ -475,8 +543,8 @@
|
||||
moz_to_me = new Function("U2", "my_start_token", "my_end_token", "from_moz", "return(" + moz_to_me + ")")(
|
||||
exports, my_start_token, my_end_token, from_moz
|
||||
);
|
||||
me_to_moz = new Function("to_moz", "to_moz_block", "return(" + me_to_moz + ")")(
|
||||
to_moz, to_moz_block
|
||||
me_to_moz = new Function("to_moz", "to_moz_block", "to_moz_scope", "return(" + me_to_moz + ")")(
|
||||
to_moz, to_moz_block, to_moz_scope
|
||||
);
|
||||
MOZ_TO_ME[moztype] = moz_to_me;
|
||||
def_to_moz(mytype, me_to_moz);
|
||||
@@ -534,4 +602,14 @@
|
||||
};
|
||||
};
|
||||
|
||||
function to_moz_scope(type, node) {
|
||||
var body = node.body.map(to_moz);
|
||||
if (node.body[0] instanceof AST_SimpleStatement && node.body[0].body instanceof AST_String) {
|
||||
body.unshift(to_moz(new AST_EmptyStatement(node.body[0])));
|
||||
}
|
||||
return {
|
||||
type: type,
|
||||
body: body
|
||||
};
|
||||
};
|
||||
})();
|
||||
|
||||
841
lib/output.js
841
lib/output.js
File diff suppressed because it is too large
Load Diff
545
lib/parse.js
545
lib/parse.js
@@ -46,7 +46,7 @@
|
||||
|
||||
var KEYWORDS = 'break case catch const continue debugger default delete do else finally for function if in instanceof new return switch throw try typeof var void while with';
|
||||
var KEYWORDS_ATOM = 'false null true';
|
||||
var RESERVED_WORDS = 'abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized this throws transient volatile yield'
|
||||
var RESERVED_WORDS = 'abstract boolean byte char class double enum export extends final float goto implements import int interface let long native package private protected public short static super synchronized this throws transient volatile yield'
|
||||
+ " " + KEYWORDS_ATOM + " " + KEYWORDS;
|
||||
var KEYWORDS_BEFORE_EXPRESSION = 'return new delete throw else case';
|
||||
|
||||
@@ -107,14 +107,14 @@ var OPERATORS = makePredicate([
|
||||
"||"
|
||||
]);
|
||||
|
||||
var WHITESPACE_CHARS = makePredicate(characters(" \u00a0\n\r\t\f\u000b\u200b\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\uFEFF"));
|
||||
var WHITESPACE_CHARS = makePredicate(characters(" \u00a0\n\r\t\f\u000b\u200b\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000\uFEFF"));
|
||||
|
||||
var PUNC_BEFORE_EXPRESSION = makePredicate(characters("[{(,.;:"));
|
||||
var NEWLINE_CHARS = makePredicate(characters("\n\r\u2028\u2029"));
|
||||
|
||||
var PUNC_BEFORE_EXPRESSION = makePredicate(characters("[{(,;:"));
|
||||
|
||||
var PUNC_CHARS = makePredicate(characters("[]{}(),;:"));
|
||||
|
||||
var REGEXP_MODIFIERS = makePredicate(characters("gmsiy"));
|
||||
|
||||
/* -----[ Tokenizer ]----- */
|
||||
|
||||
// regexps adapted from http://xregexp.com/plugins/#unicode
|
||||
@@ -132,6 +132,18 @@ function is_letter(code) {
|
||||
|| (code >= 0xaa && UNICODE.letter.test(String.fromCharCode(code)));
|
||||
};
|
||||
|
||||
function is_surrogate_pair_head(code) {
|
||||
if (typeof code == "string")
|
||||
code = code.charCodeAt(0);
|
||||
return code >= 0xd800 && code <= 0xdbff;
|
||||
}
|
||||
|
||||
function is_surrogate_pair_tail(code) {
|
||||
if (typeof code == "string")
|
||||
code = code.charCodeAt(0);
|
||||
return code >= 0xdc00 && code <= 0xdfff;
|
||||
}
|
||||
|
||||
function is_digit(code) {
|
||||
return code >= 48 && code <= 57;
|
||||
};
|
||||
@@ -193,12 +205,11 @@ function JS_Parse_Error(message, filename, line, col, pos) {
|
||||
this.line = line;
|
||||
this.col = col;
|
||||
this.pos = pos;
|
||||
this.stack = new Error().stack;
|
||||
};
|
||||
|
||||
JS_Parse_Error.prototype.toString = function() {
|
||||
return this.message + " (line: " + this.line + ", col: " + this.col + ", pos: " + this.pos + ")" + "\n\n" + this.stack;
|
||||
};
|
||||
JS_Parse_Error.prototype = Object.create(Error.prototype);
|
||||
JS_Parse_Error.prototype.constructor = JS_Parse_Error;
|
||||
JS_Parse_Error.prototype.name = "SyntaxError";
|
||||
configure_error_stack(JS_Parse_Error);
|
||||
|
||||
function js_error(message, filename, line, col, pos) {
|
||||
throw new JS_Parse_Error(message, filename, line, col, pos);
|
||||
@@ -223,7 +234,9 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
tokcol : 0,
|
||||
newline_before : false,
|
||||
regex_allowed : false,
|
||||
comments_before : []
|
||||
comments_before : [],
|
||||
directives : {},
|
||||
directive_stack : []
|
||||
};
|
||||
|
||||
function peek() { return S.text.charAt(S.pos); };
|
||||
@@ -232,7 +245,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
var ch = S.text.charAt(S.pos++);
|
||||
if (signal_eof && !ch)
|
||||
throw EX_EOF;
|
||||
if ("\r\n\u2028\u2029".indexOf(ch) >= 0) {
|
||||
if (NEWLINE_CHARS(ch)) {
|
||||
S.newline_before = S.newline_before || !in_string;
|
||||
++S.line;
|
||||
S.col = 0;
|
||||
@@ -255,6 +268,16 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
return S.text.substr(S.pos, str.length) == str;
|
||||
};
|
||||
|
||||
function find_eol() {
|
||||
var text = S.text;
|
||||
for (var i = S.pos, n = S.text.length; i < n; ++i) {
|
||||
var ch = text[i];
|
||||
if (NEWLINE_CHARS(ch))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
|
||||
function find(what, signal_eof) {
|
||||
var pos = S.text.indexOf(what, S.pos);
|
||||
if (signal_eof && pos == -1) throw EX_EOF;
|
||||
@@ -272,7 +295,11 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
S.regex_allowed = ((type == "operator" && !UNARY_POSTFIX(value)) ||
|
||||
(type == "keyword" && KEYWORDS_BEFORE_EXPRESSION(value)) ||
|
||||
(type == "punc" && PUNC_BEFORE_EXPRESSION(value)));
|
||||
prev_was_dot = (type == "punc" && value == ".");
|
||||
if (type == "punc" && value == ".") {
|
||||
prev_was_dot = true;
|
||||
} else if (!is_comment) {
|
||||
prev_was_dot = false;
|
||||
}
|
||||
var ret = {
|
||||
type : type,
|
||||
value : value,
|
||||
@@ -290,19 +317,14 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
}
|
||||
if (!is_comment) {
|
||||
ret.comments_before = S.comments_before;
|
||||
S.comments_before = [];
|
||||
// make note of any newlines in the comments that came before
|
||||
for (var i = 0, len = ret.comments_before.length; i < len; i++) {
|
||||
ret.nlb = ret.nlb || ret.comments_before[i].nlb;
|
||||
}
|
||||
ret.comments_after = S.comments_before = [];
|
||||
}
|
||||
S.newline_before = false;
|
||||
return new AST_Token(ret);
|
||||
};
|
||||
|
||||
function skip_whitespace() {
|
||||
var ch;
|
||||
while (WHITESPACE_CHARS(ch = peek()) || ch == "\u2028" || ch == "\u2029")
|
||||
while (WHITESPACE_CHARS(peek()))
|
||||
next();
|
||||
};
|
||||
|
||||
@@ -336,6 +358,9 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
return is_alphanumeric_char(code);
|
||||
});
|
||||
if (prefix) num = prefix + num;
|
||||
if (RE_OCT_NUMBER.test(num) && next_token.has_directive("use strict")) {
|
||||
parse_error("Legacy octal literals are not allowed in strict mode");
|
||||
}
|
||||
var valid = parse_js_number(num);
|
||||
if (!isNaN(valid)) {
|
||||
return token("num", valid);
|
||||
@@ -353,7 +378,6 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
case 98 : return "\b";
|
||||
case 118 : return "\u000b"; // \v
|
||||
case 102 : return "\f";
|
||||
case 48 : return "\0";
|
||||
case 120 : return String.fromCharCode(hex_bytes(2)); // \x
|
||||
case 117 : return String.fromCharCode(hex_bytes(4)); // \u
|
||||
case 10 : return ""; // newline
|
||||
@@ -363,9 +387,27 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
if (ch >= "0" && ch <= "7")
|
||||
return read_octal_escape_sequence(ch);
|
||||
return ch;
|
||||
};
|
||||
|
||||
function read_octal_escape_sequence(ch) {
|
||||
// Read
|
||||
var p = peek();
|
||||
if (p >= "0" && p <= "7") {
|
||||
ch += next(true);
|
||||
if (ch[0] <= "3" && (p = peek()) >= "0" && p <= "7")
|
||||
ch += next(true);
|
||||
}
|
||||
|
||||
// Parse
|
||||
if (ch === "0") return "\0";
|
||||
if (ch.length > 0 && next_token.has_directive("use strict"))
|
||||
parse_error("Legacy octal escape sequences are not allowed in strict mode");
|
||||
return String.fromCharCode(parseInt(ch, 8));
|
||||
}
|
||||
|
||||
function hex_bytes(n) {
|
||||
var num = 0;
|
||||
for (; n > 0; --n) {
|
||||
@@ -381,25 +423,8 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
var quote = next(), ret = "";
|
||||
for (;;) {
|
||||
var ch = next(true, true);
|
||||
if (ch == "\\") {
|
||||
// read OctalEscapeSequence (XXX: deprecated if "strict mode")
|
||||
// https://github.com/mishoo/UglifyJS/issues/178
|
||||
var octal_len = 0, first = null;
|
||||
ch = read_while(function(ch){
|
||||
if (ch >= "0" && ch <= "7") {
|
||||
if (!first) {
|
||||
first = ch;
|
||||
return ++octal_len;
|
||||
}
|
||||
else if (first <= "3" && octal_len <= 2) return ++octal_len;
|
||||
else if (first >= "4" && octal_len <= 1) return ++octal_len;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
if (octal_len > 0) ch = String.fromCharCode(parseInt(ch, 8));
|
||||
else ch = read_escaped_char(true);
|
||||
}
|
||||
else if ("\r\n\u2028\u2029".indexOf(ch) >= 0) parse_error("Unterminated string constant");
|
||||
if (ch == "\\") ch = read_escaped_char(true);
|
||||
else if (NEWLINE_CHARS(ch)) parse_error("Unterminated string constant");
|
||||
else if (ch == quote) break;
|
||||
ret += ch;
|
||||
}
|
||||
@@ -410,7 +435,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
|
||||
function skip_line_comment(type) {
|
||||
var regex_allowed = S.regex_allowed;
|
||||
var i = find("\n"), ret;
|
||||
var i = find_eol(), ret;
|
||||
if (i == -1) {
|
||||
ret = S.text.substr(S.pos);
|
||||
S.pos = S.text.length;
|
||||
@@ -421,25 +446,18 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
S.col = S.tokcol + (S.pos - S.tokpos);
|
||||
S.comments_before.push(token(type, ret, true));
|
||||
S.regex_allowed = regex_allowed;
|
||||
return next_token();
|
||||
return next_token;
|
||||
};
|
||||
|
||||
var skip_multiline_comment = with_eof_error("Unterminated multiline comment", function(){
|
||||
var regex_allowed = S.regex_allowed;
|
||||
var i = find("*/", true);
|
||||
var text = S.text.substring(S.pos, i);
|
||||
var a = text.split("\n"), n = a.length;
|
||||
var text = S.text.substring(S.pos, i).replace(/\r\n|\r|\u2028|\u2029/g, '\n');
|
||||
// update stream position
|
||||
S.pos = i + 2;
|
||||
S.line += n - 1;
|
||||
if (n > 1) S.col = a[n - 1].length;
|
||||
else S.col += a[n - 1].length;
|
||||
S.col += 2;
|
||||
var nlb = S.newline_before = S.newline_before || text.indexOf("\n") >= 0;
|
||||
forward(text.length /* doesn't count \r\n as 2 char while S.pos - i does */ + 2);
|
||||
S.comments_before.push(token("comment2", text, true));
|
||||
S.regex_allowed = regex_allowed;
|
||||
S.newline_before = nlb;
|
||||
return next_token();
|
||||
return next_token;
|
||||
});
|
||||
|
||||
function read_name() {
|
||||
@@ -465,29 +483,33 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
return name;
|
||||
};
|
||||
|
||||
var read_regexp = with_eof_error("Unterminated regular expression", function(regexp){
|
||||
var read_regexp = with_eof_error("Unterminated regular expression", function(source) {
|
||||
var prev_backslash = false, ch, in_class = false;
|
||||
while ((ch = next(true))) if (prev_backslash) {
|
||||
regexp += "\\" + ch;
|
||||
while ((ch = next(true))) if (NEWLINE_CHARS(ch)) {
|
||||
parse_error("Unexpected line terminator");
|
||||
} else if (prev_backslash) {
|
||||
source += "\\" + ch;
|
||||
prev_backslash = false;
|
||||
} else if (ch == "[") {
|
||||
in_class = true;
|
||||
regexp += ch;
|
||||
source += ch;
|
||||
} else if (ch == "]" && in_class) {
|
||||
in_class = false;
|
||||
regexp += ch;
|
||||
source += ch;
|
||||
} else if (ch == "/" && !in_class) {
|
||||
break;
|
||||
} else if (ch == "\\") {
|
||||
prev_backslash = true;
|
||||
} else {
|
||||
regexp += ch;
|
||||
source += ch;
|
||||
}
|
||||
var mods = read_name();
|
||||
try {
|
||||
return token("regexp", new RegExp(regexp, mods));
|
||||
var regexp = new RegExp(source, mods);
|
||||
regexp.raw_source = source;
|
||||
return token("regexp", regexp);
|
||||
} catch(e) {
|
||||
parse_error(e.message);
|
||||
parse_error(e.message);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -548,36 +570,43 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
function next_token(force_regexp) {
|
||||
if (force_regexp != null)
|
||||
return read_regexp(force_regexp);
|
||||
skip_whitespace();
|
||||
start_token();
|
||||
if (html5_comments) {
|
||||
if (looking_at("<!--")) {
|
||||
forward(4);
|
||||
return skip_line_comment("comment3");
|
||||
}
|
||||
if (looking_at("-->") && S.newline_before) {
|
||||
forward(3);
|
||||
return skip_line_comment("comment4");
|
||||
}
|
||||
if (shebang && S.pos == 0 && looking_at("#!")) {
|
||||
start_token();
|
||||
forward(2);
|
||||
skip_line_comment("comment5");
|
||||
}
|
||||
var ch = peek();
|
||||
if (!ch) return token("eof");
|
||||
var code = ch.charCodeAt(0);
|
||||
switch (code) {
|
||||
case 34: case 39: return read_string(ch);
|
||||
case 46: return handle_dot();
|
||||
case 47: return handle_slash();
|
||||
}
|
||||
if (is_digit(code)) return read_num();
|
||||
if (PUNC_CHARS(ch)) return token("punc", next());
|
||||
if (OPERATOR_CHARS(ch)) return read_operator();
|
||||
if (code == 92 || is_identifier_start(code)) return read_word();
|
||||
|
||||
if (shebang) {
|
||||
if (S.pos == 0 && looking_at("#!")) {
|
||||
forward(2);
|
||||
return skip_line_comment("comment5");
|
||||
for (;;) {
|
||||
skip_whitespace();
|
||||
start_token();
|
||||
if (html5_comments) {
|
||||
if (looking_at("<!--")) {
|
||||
forward(4);
|
||||
skip_line_comment("comment3");
|
||||
continue;
|
||||
}
|
||||
if (looking_at("-->") && S.newline_before) {
|
||||
forward(3);
|
||||
skip_line_comment("comment4");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
var ch = peek();
|
||||
if (!ch) return token("eof");
|
||||
var code = ch.charCodeAt(0);
|
||||
switch (code) {
|
||||
case 34: case 39: return read_string(ch);
|
||||
case 46: return handle_dot();
|
||||
case 47: {
|
||||
var tok = handle_slash();
|
||||
if (tok === next_token) continue;
|
||||
return tok;
|
||||
}
|
||||
}
|
||||
if (is_digit(code)) return read_num();
|
||||
if (PUNC_CHARS(ch)) return token("punc", next());
|
||||
if (OPERATOR_CHARS(ch)) return read_operator();
|
||||
if (code == 92 || is_identifier_start(code)) return read_word();
|
||||
break;
|
||||
}
|
||||
parse_error("Unexpected character '" + ch + "'");
|
||||
};
|
||||
@@ -587,6 +616,34 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
return S;
|
||||
};
|
||||
|
||||
next_token.add_directive = function(directive) {
|
||||
S.directive_stack[S.directive_stack.length - 1].push(directive);
|
||||
|
||||
if (S.directives[directive] === undefined) {
|
||||
S.directives[directive] = 1;
|
||||
} else {
|
||||
S.directives[directive]++;
|
||||
}
|
||||
}
|
||||
|
||||
next_token.push_directives_stack = function() {
|
||||
S.directive_stack.push([]);
|
||||
}
|
||||
|
||||
next_token.pop_directives_stack = function() {
|
||||
var directives = S.directive_stack[S.directive_stack.length - 1];
|
||||
|
||||
for (var i = 0; i < directives.length; i++) {
|
||||
S.directives[directives[i]]--;
|
||||
}
|
||||
|
||||
S.directive_stack.pop();
|
||||
}
|
||||
|
||||
next_token.has_directive = function(directive) {
|
||||
return S.directives[directive] > 0;
|
||||
}
|
||||
|
||||
return next_token;
|
||||
|
||||
};
|
||||
@@ -633,23 +690,21 @@ var PRECEDENCE = (function(a, ret){
|
||||
{}
|
||||
);
|
||||
|
||||
var STATEMENTS_WITH_LABELS = array_to_hash([ "for", "do", "while", "switch" ]);
|
||||
|
||||
var ATOMIC_START_TOKEN = array_to_hash([ "atom", "num", "string", "regexp", "name" ]);
|
||||
var ATOMIC_START_TOKEN = makePredicate([ "atom", "num", "string", "regexp", "name" ]);
|
||||
|
||||
/* -----[ Parser ]----- */
|
||||
|
||||
function parse($TEXT, options) {
|
||||
|
||||
options = defaults(options, {
|
||||
strict : false,
|
||||
filename : null,
|
||||
toplevel : null,
|
||||
expression : false,
|
||||
html5_comments : true,
|
||||
bare_returns : false,
|
||||
expression : false,
|
||||
filename : null,
|
||||
html5_comments : true,
|
||||
shebang : true,
|
||||
});
|
||||
strict : false,
|
||||
toplevel : null,
|
||||
}, true);
|
||||
|
||||
var S = {
|
||||
input : (typeof $TEXT == "string"
|
||||
@@ -719,10 +774,15 @@ function parse($TEXT, options) {
|
||||
|
||||
function expect(punc) { return expect_token("punc", punc); };
|
||||
|
||||
function has_newline_before(token) {
|
||||
return token.nlb || !all(token.comments_before, function(comment) {
|
||||
return !comment.nlb;
|
||||
});
|
||||
}
|
||||
|
||||
function can_insert_semicolon() {
|
||||
return !options.strict && (
|
||||
S.token.nlb || is("eof") || is("punc", "}")
|
||||
);
|
||||
return !options.strict
|
||||
&& (is("eof") || is("punc", "}") || has_newline_before(S.token));
|
||||
};
|
||||
|
||||
function semicolon(optional) {
|
||||
@@ -756,21 +816,23 @@ function parse($TEXT, options) {
|
||||
};
|
||||
|
||||
var statement = embed_tokens(function() {
|
||||
var tmp;
|
||||
handle_regexp();
|
||||
switch (S.token.type) {
|
||||
case "string":
|
||||
var dir = S.in_directives, stat = simple_statement();
|
||||
// XXXv2: decide how to fix directives
|
||||
if (dir && stat.body instanceof AST_String && !is("punc", ",")) {
|
||||
return new AST_Directive({
|
||||
start : stat.body.start,
|
||||
end : stat.body.end,
|
||||
quote : stat.body.quote,
|
||||
value : stat.body.value,
|
||||
});
|
||||
if (S.in_directives) {
|
||||
var token = peek();
|
||||
if (S.token.raw.indexOf("\\") == -1
|
||||
&& (is_token(token, "punc", ";")
|
||||
|| is_token(token, "punc", "}")
|
||||
|| has_newline_before(token)
|
||||
|| is_token(token, "eof"))) {
|
||||
S.input.add_directive(S.token.value);
|
||||
} else {
|
||||
S.in_directives = false;
|
||||
}
|
||||
}
|
||||
return stat;
|
||||
var dir = S.in_directives, stat = simple_statement();
|
||||
return dir ? new AST_Directive(stat.body) : stat;
|
||||
case "num":
|
||||
case "regexp":
|
||||
case "operator":
|
||||
@@ -794,6 +856,7 @@ function parse($TEXT, options) {
|
||||
case "(":
|
||||
return simple_statement();
|
||||
case ";":
|
||||
S.in_directives = false;
|
||||
next();
|
||||
return new AST_EmptyStatement();
|
||||
default:
|
||||
@@ -801,81 +864,104 @@ function parse($TEXT, options) {
|
||||
}
|
||||
|
||||
case "keyword":
|
||||
switch (tmp = S.token.value, next(), tmp) {
|
||||
switch (S.token.value) {
|
||||
case "break":
|
||||
next();
|
||||
return break_cont(AST_Break);
|
||||
|
||||
case "continue":
|
||||
next();
|
||||
return break_cont(AST_Continue);
|
||||
|
||||
case "debugger":
|
||||
next();
|
||||
semicolon();
|
||||
return new AST_Debugger();
|
||||
|
||||
case "do":
|
||||
next();
|
||||
var body = in_loop(statement);
|
||||
expect_token("keyword", "while");
|
||||
var condition = parenthesised();
|
||||
semicolon(true);
|
||||
return new AST_Do({
|
||||
body : in_loop(statement),
|
||||
condition : (expect_token("keyword", "while"), tmp = parenthesised(), semicolon(true), tmp)
|
||||
body : body,
|
||||
condition : condition
|
||||
});
|
||||
|
||||
case "while":
|
||||
next();
|
||||
return new AST_While({
|
||||
condition : parenthesised(),
|
||||
body : in_loop(statement)
|
||||
});
|
||||
|
||||
case "for":
|
||||
next();
|
||||
return for_();
|
||||
|
||||
case "function":
|
||||
next();
|
||||
return function_(AST_Defun);
|
||||
|
||||
case "if":
|
||||
next();
|
||||
return if_();
|
||||
|
||||
case "return":
|
||||
if (S.in_function == 0 && !options.bare_returns)
|
||||
croak("'return' outside of function");
|
||||
next();
|
||||
var value = null;
|
||||
if (is("punc", ";")) {
|
||||
next();
|
||||
} else if (!can_insert_semicolon()) {
|
||||
value = expression(true);
|
||||
semicolon();
|
||||
}
|
||||
return new AST_Return({
|
||||
value: ( is("punc", ";")
|
||||
? (next(), null)
|
||||
: can_insert_semicolon()
|
||||
? null
|
||||
: (tmp = expression(true), semicolon(), tmp) )
|
||||
value: value
|
||||
});
|
||||
|
||||
case "switch":
|
||||
next();
|
||||
return new AST_Switch({
|
||||
expression : parenthesised(),
|
||||
body : in_loop(switch_body_)
|
||||
});
|
||||
|
||||
case "throw":
|
||||
if (S.token.nlb)
|
||||
next();
|
||||
if (has_newline_before(S.token))
|
||||
croak("Illegal newline after 'throw'");
|
||||
var value = expression(true);
|
||||
semicolon();
|
||||
return new AST_Throw({
|
||||
value: (tmp = expression(true), semicolon(), tmp)
|
||||
value: value
|
||||
});
|
||||
|
||||
case "try":
|
||||
next();
|
||||
return try_();
|
||||
|
||||
case "var":
|
||||
return tmp = var_(), semicolon(), tmp;
|
||||
|
||||
case "const":
|
||||
return tmp = const_(), semicolon(), tmp;
|
||||
next();
|
||||
var node = var_();
|
||||
semicolon();
|
||||
return node;
|
||||
|
||||
case "with":
|
||||
if (S.input.has_directive("use strict")) {
|
||||
croak("Strict mode may not include a with statement");
|
||||
}
|
||||
next();
|
||||
return new AST_With({
|
||||
expression : parenthesised(),
|
||||
body : statement()
|
||||
});
|
||||
|
||||
default:
|
||||
unexpected();
|
||||
}
|
||||
}
|
||||
unexpected();
|
||||
});
|
||||
|
||||
function labeled_statement() {
|
||||
@@ -937,8 +1023,12 @@ function parse($TEXT, options) {
|
||||
? (next(), var_(true))
|
||||
: expression(true, true);
|
||||
if (is("operator", "in")) {
|
||||
if (init instanceof AST_Var && init.definitions.length > 1)
|
||||
croak("Only one variable declaration allowed in for..in loop");
|
||||
if (init instanceof AST_Var) {
|
||||
if (init.definitions.length > 1)
|
||||
croak("Only one variable declaration allowed in for..in loop", init.start.line, init.start.col, init.start.pos);
|
||||
} else if (!is_assignable(init)) {
|
||||
croak("Invalid left-hand side in for..in loop", init.start.line, init.start.col, init.start.pos);
|
||||
}
|
||||
next();
|
||||
return for_in(init);
|
||||
}
|
||||
@@ -977,28 +1067,35 @@ function parse($TEXT, options) {
|
||||
var name = is("name") ? as_symbol(in_statement ? AST_SymbolDefun : AST_SymbolLambda) : null;
|
||||
if (in_statement && !name)
|
||||
unexpected();
|
||||
if (name && ctor !== AST_Accessor && !(name instanceof AST_SymbolDeclaration))
|
||||
unexpected(prev());
|
||||
expect("(");
|
||||
var argnames = [];
|
||||
for (var first = true; !is("punc", ")");) {
|
||||
if (first) first = false; else expect(",");
|
||||
argnames.push(as_symbol(AST_SymbolFunarg));
|
||||
}
|
||||
next();
|
||||
var loop = S.in_loop;
|
||||
var labels = S.labels;
|
||||
++S.in_function;
|
||||
S.in_directives = true;
|
||||
S.input.push_directives_stack();
|
||||
S.in_loop = 0;
|
||||
S.labels = [];
|
||||
var body = block_();
|
||||
if (S.input.has_directive("use strict")) {
|
||||
if (name) strict_verify_symbol(name);
|
||||
argnames.forEach(strict_verify_symbol);
|
||||
}
|
||||
S.input.pop_directives_stack();
|
||||
--S.in_function;
|
||||
S.in_loop = loop;
|
||||
S.labels = labels;
|
||||
return new ctor({
|
||||
name: name,
|
||||
argnames: (function(first, a){
|
||||
while (!is("punc", ")")) {
|
||||
if (first) first = false; else expect(",");
|
||||
a.push(as_symbol(AST_SymbolFunarg));
|
||||
}
|
||||
next();
|
||||
return a;
|
||||
})(true, []),
|
||||
body: (function(loop, labels){
|
||||
++S.in_function;
|
||||
S.in_directives = true;
|
||||
S.in_loop = 0;
|
||||
S.labels = [];
|
||||
var a = block_();
|
||||
--S.in_function;
|
||||
S.in_loop = loop;
|
||||
S.labels = labels;
|
||||
return a;
|
||||
})(S.in_loop, S.labels)
|
||||
argnames: argnames,
|
||||
body: body
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1094,12 +1191,12 @@ function parse($TEXT, options) {
|
||||
});
|
||||
};
|
||||
|
||||
function vardefs(no_in, in_const) {
|
||||
function vardefs(no_in) {
|
||||
var a = [];
|
||||
for (;;) {
|
||||
a.push(new AST_VarDef({
|
||||
start : S.token,
|
||||
name : as_symbol(in_const ? AST_SymbolConst : AST_SymbolVar),
|
||||
name : as_symbol(AST_SymbolVar),
|
||||
value : is("operator", "=") ? (next(), expression(false, no_in)) : null,
|
||||
end : prev()
|
||||
}));
|
||||
@@ -1113,15 +1210,7 @@ function parse($TEXT, options) {
|
||||
var var_ = function(no_in) {
|
||||
return new AST_Var({
|
||||
start : prev(),
|
||||
definitions : vardefs(no_in, false),
|
||||
end : prev()
|
||||
});
|
||||
};
|
||||
|
||||
var const_ = function() {
|
||||
return new AST_Const({
|
||||
start : prev(),
|
||||
definitions : vardefs(false, true),
|
||||
definitions : vardefs(no_in),
|
||||
end : prev()
|
||||
});
|
||||
};
|
||||
@@ -1148,7 +1237,6 @@ function parse($TEXT, options) {
|
||||
var tok = S.token, ret;
|
||||
switch (tok.type) {
|
||||
case "name":
|
||||
case "keyword":
|
||||
ret = _make_symbol(AST_SymbolRef);
|
||||
break;
|
||||
case "num":
|
||||
@@ -1178,13 +1266,6 @@ function parse($TEXT, options) {
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "operator":
|
||||
if (!is_identifier_string(tok.value)) {
|
||||
throw new JS_Parse_Error("Invalid getter/setter name: " + tok.value,
|
||||
tok.file, tok.line, tok.col, tok.pos);
|
||||
}
|
||||
ret = _make_symbol(AST_SymbolRef);
|
||||
break;
|
||||
}
|
||||
next();
|
||||
return ret;
|
||||
@@ -1200,9 +1281,26 @@ function parse($TEXT, options) {
|
||||
case "(":
|
||||
next();
|
||||
var ex = expression(true);
|
||||
var len = start.comments_before.length;
|
||||
[].unshift.apply(ex.start.comments_before, start.comments_before);
|
||||
start.comments_before = ex.start.comments_before;
|
||||
start.comments_before_length = len;
|
||||
if (len == 0 && start.comments_before.length > 0) {
|
||||
var comment = start.comments_before[0];
|
||||
if (!comment.nlb) {
|
||||
comment.nlb = start.nlb;
|
||||
start.nlb = false;
|
||||
}
|
||||
}
|
||||
start.comments_after = ex.start.comments_after;
|
||||
ex.start = start;
|
||||
ex.end = S.token;
|
||||
expect(")");
|
||||
var end = prev();
|
||||
end.comments_before = ex.end.comments_before;
|
||||
[].push.apply(ex.end.comments_after, end.comments_after);
|
||||
end.comments_after = ex.end.comments_after;
|
||||
ex.end = end;
|
||||
if (ex instanceof AST_Call) mark_pure(ex);
|
||||
return subscripts(ex, allow_calls);
|
||||
case "[":
|
||||
return subscripts(array_(), allow_calls);
|
||||
@@ -1218,7 +1316,7 @@ function parse($TEXT, options) {
|
||||
func.end = prev();
|
||||
return subscripts(func, allow_calls);
|
||||
}
|
||||
if (ATOMIC_START_TOKEN[S.token.type]) {
|
||||
if (ATOMIC_START_TOKEN(S.token.type)) {
|
||||
return subscripts(as_atom_node(), allow_calls);
|
||||
}
|
||||
unexpected();
|
||||
@@ -1246,6 +1344,10 @@ function parse($TEXT, options) {
|
||||
});
|
||||
});
|
||||
|
||||
var create_accessor = embed_tokens(function() {
|
||||
return function_(AST_Accessor);
|
||||
});
|
||||
|
||||
var object_ = embed_tokens(function() {
|
||||
expect("{");
|
||||
var first = true, a = [];
|
||||
@@ -1258,11 +1360,16 @@ function parse($TEXT, options) {
|
||||
var type = start.type;
|
||||
var name = as_property_name();
|
||||
if (type == "name" && !is("punc", ":")) {
|
||||
var key = new AST_SymbolAccessor({
|
||||
start: S.token,
|
||||
name: as_property_name(),
|
||||
end: prev()
|
||||
});
|
||||
if (name == "get") {
|
||||
a.push(new AST_ObjectGetter({
|
||||
start : start,
|
||||
key : as_atom_node(),
|
||||
value : function_(AST_Accessor),
|
||||
key : key,
|
||||
value : create_accessor(),
|
||||
end : prev()
|
||||
}));
|
||||
continue;
|
||||
@@ -1270,8 +1377,8 @@ function parse($TEXT, options) {
|
||||
if (name == "set") {
|
||||
a.push(new AST_ObjectSetter({
|
||||
start : start,
|
||||
key : as_atom_node(),
|
||||
value : function_(AST_Accessor),
|
||||
key : key,
|
||||
value : create_accessor(),
|
||||
end : prev()
|
||||
}));
|
||||
continue;
|
||||
@@ -1292,14 +1399,15 @@ function parse($TEXT, options) {
|
||||
|
||||
function as_property_name() {
|
||||
var tmp = S.token;
|
||||
next();
|
||||
switch (tmp.type) {
|
||||
case "operator":
|
||||
if (!KEYWORDS(tmp.value)) unexpected();
|
||||
case "num":
|
||||
case "string":
|
||||
case "name":
|
||||
case "operator":
|
||||
case "keyword":
|
||||
case "atom":
|
||||
next();
|
||||
return tmp.value;
|
||||
default:
|
||||
unexpected();
|
||||
@@ -1308,16 +1416,9 @@ function parse($TEXT, options) {
|
||||
|
||||
function as_name() {
|
||||
var tmp = S.token;
|
||||
if (tmp.type != "name") unexpected();
|
||||
next();
|
||||
switch (tmp.type) {
|
||||
case "name":
|
||||
case "operator":
|
||||
case "keyword":
|
||||
case "atom":
|
||||
return tmp.value;
|
||||
default:
|
||||
unexpected();
|
||||
}
|
||||
return tmp.value;
|
||||
};
|
||||
|
||||
function _make_symbol(type) {
|
||||
@@ -1329,16 +1430,37 @@ function parse($TEXT, options) {
|
||||
});
|
||||
};
|
||||
|
||||
function strict_verify_symbol(sym) {
|
||||
if (sym.name == "arguments" || sym.name == "eval")
|
||||
croak("Unexpected " + sym.name + " in strict mode", sym.start.line, sym.start.col, sym.start.pos);
|
||||
}
|
||||
|
||||
function as_symbol(type, noerror) {
|
||||
if (!is("name")) {
|
||||
if (!noerror) croak("Name expected");
|
||||
return null;
|
||||
}
|
||||
var sym = _make_symbol(type);
|
||||
if (S.input.has_directive("use strict") && sym instanceof AST_SymbolDeclaration) {
|
||||
strict_verify_symbol(sym);
|
||||
}
|
||||
next();
|
||||
return sym;
|
||||
};
|
||||
|
||||
function mark_pure(call) {
|
||||
var start = call.start;
|
||||
var comments = start.comments_before;
|
||||
var i = HOP(start, "comments_before_length") ? start.comments_before_length : comments.length;
|
||||
while (--i >= 0) {
|
||||
var comment = comments[i];
|
||||
if (/[@#]__PURE__/.test(comment.value)) {
|
||||
call.pure = comment;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var subscripts = function(expr, allow_calls) {
|
||||
var start = expr.start;
|
||||
if (is("punc", ".")) {
|
||||
@@ -1363,12 +1485,14 @@ function parse($TEXT, options) {
|
||||
}
|
||||
if (allow_calls && is("punc", "(")) {
|
||||
next();
|
||||
return subscripts(new AST_Call({
|
||||
var call = new AST_Call({
|
||||
start : start,
|
||||
expression : expr,
|
||||
args : expr_list(")"),
|
||||
end : prev()
|
||||
}), true);
|
||||
});
|
||||
mark_pure(call);
|
||||
return subscripts(call, true);
|
||||
}
|
||||
return expr;
|
||||
};
|
||||
@@ -1378,14 +1502,14 @@ function parse($TEXT, options) {
|
||||
if (is("operator") && UNARY_PREFIX(start.value)) {
|
||||
next();
|
||||
handle_regexp();
|
||||
var ex = make_unary(AST_UnaryPrefix, start.value, maybe_unary(allow_calls));
|
||||
var ex = make_unary(AST_UnaryPrefix, start, maybe_unary(allow_calls));
|
||||
ex.start = start;
|
||||
ex.end = prev();
|
||||
return ex;
|
||||
}
|
||||
var val = expr_atom(allow_calls);
|
||||
while (is("operator") && UNARY_POSTFIX(S.token.value) && !S.token.nlb) {
|
||||
val = make_unary(AST_UnaryPostfix, S.token.value, val);
|
||||
while (is("operator") && UNARY_POSTFIX(S.token.value) && !has_newline_before(S.token)) {
|
||||
val = make_unary(AST_UnaryPostfix, S.token, val);
|
||||
val.start = start;
|
||||
val.end = S.token;
|
||||
next();
|
||||
@@ -1393,9 +1517,19 @@ function parse($TEXT, options) {
|
||||
return val;
|
||||
};
|
||||
|
||||
function make_unary(ctor, op, expr) {
|
||||
if ((op == "++" || op == "--") && !is_assignable(expr))
|
||||
croak("Invalid use of " + op + " operator");
|
||||
function make_unary(ctor, token, expr) {
|
||||
var op = token.value;
|
||||
switch (op) {
|
||||
case "++":
|
||||
case "--":
|
||||
if (!is_assignable(expr))
|
||||
croak("Invalid use of " + op + " operator", token.line, token.col, token.pos);
|
||||
break;
|
||||
case "delete":
|
||||
if (expr instanceof AST_SymbolRef && S.input.has_directive("use strict"))
|
||||
croak("Calling delete on expression not allowed in strict mode", expr.start.line, expr.start.col, expr.start.pos);
|
||||
break;
|
||||
}
|
||||
return new ctor({ operator: op, expression: expr });
|
||||
};
|
||||
|
||||
@@ -1440,9 +1574,7 @@ function parse($TEXT, options) {
|
||||
};
|
||||
|
||||
function is_assignable(expr) {
|
||||
if (!options.strict) return true;
|
||||
if (expr instanceof AST_This) return false;
|
||||
return (expr instanceof AST_PropAccess || expr instanceof AST_Symbol);
|
||||
return expr instanceof AST_PropAccess || expr instanceof AST_SymbolRef;
|
||||
};
|
||||
|
||||
var maybe_assign = function(no_in) {
|
||||
@@ -1466,17 +1598,18 @@ function parse($TEXT, options) {
|
||||
|
||||
var expression = function(commas, no_in) {
|
||||
var start = S.token;
|
||||
var expr = maybe_assign(no_in);
|
||||
if (commas && is("punc", ",")) {
|
||||
var exprs = [];
|
||||
while (true) {
|
||||
exprs.push(maybe_assign(no_in));
|
||||
if (!commas || !is("punc", ",")) break;
|
||||
next();
|
||||
return new AST_Seq({
|
||||
start : start,
|
||||
car : expr,
|
||||
cdr : expression(true, no_in),
|
||||
end : peek()
|
||||
});
|
||||
commas = true;
|
||||
}
|
||||
return expr;
|
||||
return exprs.length == 1 ? exprs[0] : new AST_Sequence({
|
||||
start : start,
|
||||
expressions : exprs,
|
||||
end : peek()
|
||||
});
|
||||
};
|
||||
|
||||
function in_loop(cont) {
|
||||
@@ -1493,8 +1626,10 @@ function parse($TEXT, options) {
|
||||
return (function(){
|
||||
var start = S.token;
|
||||
var body = [];
|
||||
S.input.push_directives_stack();
|
||||
while (!is("eof"))
|
||||
body.push(statement());
|
||||
S.input.pop_directives_stack();
|
||||
var end = prev();
|
||||
var toplevel = options.toplevel;
|
||||
if (toplevel) {
|
||||
|
||||
@@ -43,8 +43,16 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
function find_builtins() {
|
||||
var a = [];
|
||||
function find_builtins(reserved) {
|
||||
// NaN will be included due to Number.NaN
|
||||
[
|
||||
"null",
|
||||
"true",
|
||||
"false",
|
||||
"Infinity",
|
||||
"-Infinity",
|
||||
"undefined",
|
||||
].forEach(add);
|
||||
[ Object, Array, Function, Number,
|
||||
String, Boolean, Error, Math,
|
||||
Date, RegExp
|
||||
@@ -55,22 +63,52 @@ function find_builtins() {
|
||||
}
|
||||
});
|
||||
function add(name) {
|
||||
push_uniq(a, name);
|
||||
push_uniq(reserved, name);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
function reserve_quoted_keys(ast, reserved) {
|
||||
function add(name) {
|
||||
push_uniq(reserved, name);
|
||||
}
|
||||
|
||||
ast.walk(new TreeWalker(function(node) {
|
||||
if (node instanceof AST_ObjectKeyVal && node.quote) {
|
||||
add(node.key);
|
||||
} else if (node instanceof AST_Sub) {
|
||||
addStrings(node.property, add);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
function addStrings(node, add) {
|
||||
node.walk(new TreeWalker(function(node) {
|
||||
if (node instanceof AST_Sequence) {
|
||||
addStrings(node.tail_node(), add);
|
||||
} else if (node instanceof AST_String) {
|
||||
add(node.value);
|
||||
} else if (node instanceof AST_Conditional) {
|
||||
addStrings(node.consequent, add);
|
||||
addStrings(node.alternative, add);
|
||||
}
|
||||
return true;
|
||||
}));
|
||||
}
|
||||
|
||||
function mangle_properties(ast, options) {
|
||||
options = defaults(options, {
|
||||
reserved : null,
|
||||
cache : null,
|
||||
only_cache : false,
|
||||
regex : null
|
||||
});
|
||||
builtins: false,
|
||||
cache: null,
|
||||
debug: false,
|
||||
keep_quoted: false,
|
||||
only_cache: false,
|
||||
regex: null,
|
||||
reserved: null,
|
||||
}, true);
|
||||
|
||||
var reserved = options.reserved;
|
||||
if (reserved == null)
|
||||
reserved = find_builtins();
|
||||
if (!Array.isArray(reserved)) reserved = [];
|
||||
if (!options.builtins) find_builtins(reserved);
|
||||
|
||||
var cache = options.cache;
|
||||
if (cache == null) {
|
||||
@@ -82,6 +120,15 @@ function mangle_properties(ast, options) {
|
||||
|
||||
var regex = options.regex;
|
||||
|
||||
// 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'
|
||||
// the same as passing an empty string.
|
||||
var debug = options.debug !== false;
|
||||
var debug_name_suffix;
|
||||
if (debug) {
|
||||
debug_name_suffix = (options.debug === true ? "" : options.debug);
|
||||
}
|
||||
|
||||
var names_to_mangle = [];
|
||||
var unmangleable = [];
|
||||
|
||||
@@ -95,14 +142,10 @@ function mangle_properties(ast, options) {
|
||||
add(node.key.name);
|
||||
}
|
||||
else if (node instanceof AST_Dot) {
|
||||
if (this.parent() instanceof AST_Assign) {
|
||||
add(node.property);
|
||||
}
|
||||
add(node.property);
|
||||
}
|
||||
else if (node instanceof AST_Sub) {
|
||||
if (this.parent() instanceof AST_Assign) {
|
||||
addStrings(node.property);
|
||||
}
|
||||
addStrings(node.property, add);
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -118,21 +161,9 @@ function mangle_properties(ast, options) {
|
||||
else if (node instanceof AST_Dot) {
|
||||
node.property = mangle(node.property);
|
||||
}
|
||||
else if (node instanceof AST_Sub) {
|
||||
else if (!options.keep_quoted && node instanceof AST_Sub) {
|
||||
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
|
||||
@@ -143,7 +174,7 @@ function mangle_properties(ast, options) {
|
||||
if (options.only_cache) {
|
||||
return cache.props.has(name);
|
||||
}
|
||||
if (/^[0-9.]+$/.test(name)) return false;
|
||||
if (/^-?[0-9]+(\.[0-9]+)?(e[+-][0-9]+)?$/.test(name)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -170,44 +201,32 @@ function mangle_properties(ast, options) {
|
||||
|
||||
var mangled = cache.props.get(name);
|
||||
if (!mangled) {
|
||||
do {
|
||||
mangled = base54(++cache.cname);
|
||||
} while (!can_mangle(mangled));
|
||||
if (debug) {
|
||||
// debug mode: use a prefix and suffix to preserve readability, e.g. o.foo -> o._$foo$NNN_.
|
||||
var debug_mangled = "_$" + name + "$" + debug_name_suffix + "_";
|
||||
|
||||
if (can_mangle(debug_mangled)) {
|
||||
mangled = debug_mangled;
|
||||
}
|
||||
}
|
||||
|
||||
// either debug mode is off, or it is on and we could not use the mangled name
|
||||
if (!mangled) {
|
||||
do {
|
||||
mangled = base54(++cache.cname);
|
||||
} while (!can_mangle(mangled));
|
||||
}
|
||||
|
||||
cache.props.set(name, mangled);
|
||||
}
|
||||
return mangled;
|
||||
}
|
||||
|
||||
function addStrings(node) {
|
||||
var out = {};
|
||||
try {
|
||||
(function walk(node){
|
||||
node.walk(new TreeWalker(function(node){
|
||||
if (node instanceof AST_Seq) {
|
||||
walk(node.cdr);
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_String) {
|
||||
add(node.value);
|
||||
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_Seq) {
|
||||
node.cdr = mangleStrings(node.cdr);
|
||||
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);
|
||||
@@ -219,5 +238,4 @@ function mangle_properties(ast, options) {
|
||||
return node;
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
537
lib/scope.js
537
lib/scope.js
@@ -43,18 +43,21 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
function SymbolDef(scope, index, orig) {
|
||||
function SymbolDef(scope, orig) {
|
||||
this.name = orig.name;
|
||||
this.orig = [ orig ];
|
||||
this.eliminated = 0;
|
||||
this.scope = scope;
|
||||
this.references = [];
|
||||
this.replaced = 0;
|
||||
this.global = false;
|
||||
this.mangled_name = null;
|
||||
this.undeclared = false;
|
||||
this.constant = false;
|
||||
this.index = index;
|
||||
this.id = SymbolDef.next_id++;
|
||||
};
|
||||
|
||||
SymbolDef.next_id = 1;
|
||||
|
||||
SymbolDef.prototype = {
|
||||
unmangleable: function(options) {
|
||||
if (!options) options = {};
|
||||
@@ -73,20 +76,28 @@ SymbolDef.prototype = {
|
||||
}
|
||||
else if (!this.mangled_name && !this.unmangleable(options)) {
|
||||
var s = this.scope;
|
||||
if (!options.screw_ie8 && this.orig[0] instanceof AST_SymbolLambda)
|
||||
var sym = this.orig[0];
|
||||
if (options.ie8 && sym instanceof AST_SymbolLambda)
|
||||
s = s.parent_scope;
|
||||
this.mangled_name = s.next_mangled(options, this);
|
||||
var def;
|
||||
if (def = this.redefined()) {
|
||||
this.mangled_name = def.mangled_name || def.name;
|
||||
} else
|
||||
this.mangled_name = s.next_mangled(options, this);
|
||||
if (this.global && cache) {
|
||||
cache.set(this.name, this.mangled_name);
|
||||
}
|
||||
}
|
||||
},
|
||||
redefined: function() {
|
||||
return this.defun && this.defun.variables.get(this.name);
|
||||
}
|
||||
};
|
||||
|
||||
AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||
options = defaults(options, {
|
||||
screw_ie8: false,
|
||||
cache: null
|
||||
cache: null,
|
||||
ie8: false,
|
||||
});
|
||||
|
||||
// pass 1: setup scope chaining and handle definitions
|
||||
@@ -94,26 +105,23 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||
var scope = self.parent_scope = null;
|
||||
var labels = new Dictionary();
|
||||
var defun = null;
|
||||
var last_var_had_const_pragma = false;
|
||||
var nesting = 0;
|
||||
var tw = new TreeWalker(function(node, descend){
|
||||
if (options.screw_ie8 && node instanceof AST_Catch) {
|
||||
if (node instanceof AST_Catch) {
|
||||
var save_scope = scope;
|
||||
scope = new AST_Scope(node);
|
||||
scope.init_scope_vars(nesting);
|
||||
scope.parent_scope = save_scope;
|
||||
scope.init_scope_vars(save_scope);
|
||||
descend();
|
||||
scope = save_scope;
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_Scope) {
|
||||
node.init_scope_vars(nesting);
|
||||
var save_scope = node.parent_scope = scope;
|
||||
node.init_scope_vars(scope);
|
||||
var save_scope = scope;
|
||||
var save_defun = defun;
|
||||
var save_labels = labels;
|
||||
defun = scope = node;
|
||||
labels = new Dictionary();
|
||||
++nesting; descend(); --nesting;
|
||||
descend();
|
||||
scope = save_scope;
|
||||
defun = save_defun;
|
||||
labels = save_labels;
|
||||
@@ -152,18 +160,19 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||
// later.
|
||||
(node.scope = defun.parent_scope).def_function(node);
|
||||
}
|
||||
else if (node instanceof AST_Var) {
|
||||
last_var_had_const_pragma = node.has_const_pragma();
|
||||
}
|
||||
else if (node instanceof AST_SymbolVar
|
||||
|| node instanceof AST_SymbolConst) {
|
||||
var def = defun.def_variable(node);
|
||||
def.constant = node instanceof AST_SymbolConst || last_var_had_const_pragma;
|
||||
def.init = tw.parent().value;
|
||||
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) {
|
||||
(options.screw_ie8 ? scope : defun)
|
||||
.def_variable(node);
|
||||
scope.def_variable(node).defun = defun;
|
||||
}
|
||||
else if (node instanceof AST_LabelRef) {
|
||||
var sym = labels.get(node.name);
|
||||
@@ -178,16 +187,8 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||
self.walk(tw);
|
||||
|
||||
// pass 2: find back references and eval
|
||||
var func = null;
|
||||
var globals = self.globals = new Dictionary();
|
||||
self.globals = new Dictionary();
|
||||
var tw = new TreeWalker(function(node, descend){
|
||||
if (node instanceof AST_Lambda) {
|
||||
var prev_func = func;
|
||||
func = node;
|
||||
descend();
|
||||
func = prev_func;
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_LoopControl && node.label) {
|
||||
node.label.thedef.references.push(node);
|
||||
return true;
|
||||
@@ -201,63 +202,102 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||
}
|
||||
var sym = node.scope.find_variable(name);
|
||||
if (!sym) {
|
||||
var g;
|
||||
if (globals.has(name)) {
|
||||
g = globals.get(name);
|
||||
} else {
|
||||
g = new SymbolDef(self, globals.size(), node);
|
||||
g.undeclared = true;
|
||||
g.global = true;
|
||||
globals.set(name, g);
|
||||
}
|
||||
node.thedef = g;
|
||||
if (func && name == "arguments") {
|
||||
func.uses_arguments = true;
|
||||
}
|
||||
} else {
|
||||
node.thedef = sym;
|
||||
sym = self.def_global(node);
|
||||
} else if (sym.scope instanceof AST_Lambda && name == "arguments") {
|
||||
sym.scope.uses_arguments = true;
|
||||
}
|
||||
node.reference();
|
||||
node.thedef = sym;
|
||||
node.reference(options);
|
||||
return true;
|
||||
}
|
||||
// ensure mangling works if catch reuses a scope variable
|
||||
var def;
|
||||
if (node instanceof AST_SymbolCatch && (def = node.definition().redefined())) {
|
||||
var s = node.scope;
|
||||
while (s) {
|
||||
push_uniq(s.enclosed, def);
|
||||
if (s === def.scope) break;
|
||||
s = s.parent_scope;
|
||||
}
|
||||
}
|
||||
});
|
||||
self.walk(tw);
|
||||
|
||||
// pass 3: fix up any scoping issue with IE8
|
||||
if (options.ie8) {
|
||||
self.walk(new TreeWalker(function(node, descend) {
|
||||
if (node instanceof AST_SymbolCatch) {
|
||||
var name = node.name;
|
||||
var refs = node.thedef.references;
|
||||
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;
|
||||
node.reference(options);
|
||||
return true;
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
if (options.cache) {
|
||||
this.cname = options.cache.cname;
|
||||
}
|
||||
});
|
||||
|
||||
AST_Scope.DEFMETHOD("init_scope_vars", function(nesting){
|
||||
this.variables = new Dictionary(); // map name to AST_SymbolVar (variables defined in this scope; includes functions)
|
||||
this.functions = new Dictionary(); // map name to AST_SymbolDefun (functions defined in this scope)
|
||||
this.uses_with = false; // will be set to true if this or some nested scope uses the `with` statement
|
||||
this.uses_eval = false; // will be set to true if this or nested scope uses the global `eval`
|
||||
this.parent_scope = null; // the parent scope
|
||||
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
|
||||
this.nesting = nesting; // the nesting level of this scope (0 means toplevel)
|
||||
AST_Toplevel.DEFMETHOD("def_global", function(node){
|
||||
var globals = this.globals, name = node.name;
|
||||
if (globals.has(name)) {
|
||||
return globals.get(name);
|
||||
} else {
|
||||
var g = new SymbolDef(this, node);
|
||||
g.undeclared = true;
|
||||
g.global = true;
|
||||
globals.set(name, g);
|
||||
return g;
|
||||
}
|
||||
});
|
||||
|
||||
AST_Scope.DEFMETHOD("init_scope_vars", function(parent_scope){
|
||||
this.variables = new Dictionary(); // map name to AST_SymbolVar (variables defined in this scope; includes functions)
|
||||
this.functions = new Dictionary(); // map name to AST_SymbolDefun (functions defined in this scope)
|
||||
this.uses_with = false; // will be set to true if this or some nested scope uses the `with` statement
|
||||
this.uses_eval = false; // will be set to true if this or nested scope uses the global `eval`
|
||||
this.parent_scope = parent_scope; // the parent scope
|
||||
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(){
|
||||
AST_Scope.prototype.init_scope_vars.apply(this, arguments);
|
||||
this.uses_arguments = false;
|
||||
|
||||
var symbol = new AST_VarDef({ name: "arguments", start: this.start, end: this.end });
|
||||
var def = new SymbolDef(this, this.variables.size(), symbol);
|
||||
this.variables.set(symbol.name, def);
|
||||
this.def_variable(new AST_SymbolFunarg({
|
||||
name: "arguments",
|
||||
start: this.start,
|
||||
end: this.end
|
||||
}));
|
||||
});
|
||||
|
||||
AST_SymbolRef.DEFMETHOD("reference", function() {
|
||||
AST_Symbol.DEFMETHOD("mark_enclosed", function(options) {
|
||||
var def = this.definition();
|
||||
def.references.push(this);
|
||||
var s = this.scope;
|
||||
while (s) {
|
||||
push_uniq(s.enclosed, def);
|
||||
if (options.keep_fnames) {
|
||||
s.functions.each(function(d) {
|
||||
push_uniq(def.scope.enclosed, d);
|
||||
});
|
||||
}
|
||||
if (s === def.scope) break;
|
||||
s = s.parent_scope;
|
||||
}
|
||||
this.frame = this.scope.nesting - def.scope.nesting;
|
||||
});
|
||||
|
||||
AST_Symbol.DEFMETHOD("reference", function(options) {
|
||||
this.definition().references.push(this);
|
||||
this.mark_enclosed(options);
|
||||
});
|
||||
|
||||
AST_Scope.DEFMETHOD("find_variable", function(name){
|
||||
@@ -273,7 +313,7 @@ AST_Scope.DEFMETHOD("def_function", function(symbol){
|
||||
AST_Scope.DEFMETHOD("def_variable", function(symbol){
|
||||
var def;
|
||||
if (!this.variables.has(symbol.name)) {
|
||||
def = new SymbolDef(this, this.variables.size(), symbol);
|
||||
def = new SymbolDef(this, symbol);
|
||||
this.variables.set(symbol.name, def);
|
||||
def.global = !this.parent_scope;
|
||||
} else {
|
||||
@@ -290,8 +330,8 @@ AST_Scope.DEFMETHOD("next_mangled", function(options){
|
||||
if (!is_identifier(m)) continue; // skip over "do"
|
||||
|
||||
// https://github.com/mishoo/UglifyJS2/issues/242 -- do not
|
||||
// shadow a name excepted from mangling.
|
||||
if (options.except.indexOf(m) >= 0) continue;
|
||||
// shadow a name reserved from mangling.
|
||||
if (member(m, options.reserved)) continue;
|
||||
|
||||
// we must ensure that the mangled name does not shadow a name
|
||||
// from some parent scope that is referenced in this or in
|
||||
@@ -311,49 +351,30 @@ AST_Function.DEFMETHOD("next_mangled", function(options, def){
|
||||
// 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;
|
||||
|
||||
while (true) {
|
||||
var name = AST_Lambda.prototype.next_mangled.call(this, options, def);
|
||||
if (!(tricky_def && tricky_def.mangled_name == name))
|
||||
if (!tricky_name || tricky_name != name)
|
||||
return name;
|
||||
}
|
||||
});
|
||||
|
||||
AST_Scope.DEFMETHOD("references", function(sym){
|
||||
if (sym instanceof AST_Symbol) sym = sym.definition();
|
||||
return this.enclosed.indexOf(sym) < 0 ? null : sym;
|
||||
});
|
||||
|
||||
AST_Symbol.DEFMETHOD("unmangleable", function(options){
|
||||
return this.definition().unmangleable(options);
|
||||
});
|
||||
|
||||
// property accessors are not mangleable
|
||||
AST_SymbolAccessor.DEFMETHOD("unmangleable", function(){
|
||||
return true;
|
||||
var def = this.definition();
|
||||
return !def || def.unmangleable(options);
|
||||
});
|
||||
|
||||
// labels are always mangleable
|
||||
AST_Label.DEFMETHOD("unmangleable", function(){
|
||||
return false;
|
||||
});
|
||||
AST_Label.DEFMETHOD("unmangleable", return_false);
|
||||
|
||||
AST_Symbol.DEFMETHOD("unreferenced", 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", function(){
|
||||
return false;
|
||||
});
|
||||
|
||||
AST_Label.DEFMETHOD("undeclared", function(){
|
||||
return false;
|
||||
});
|
||||
|
||||
AST_Symbol.DEFMETHOD("definition", function(){
|
||||
return this.thedef;
|
||||
});
|
||||
@@ -362,29 +383,23 @@ AST_Symbol.DEFMETHOD("global", function(){
|
||||
return this.definition().global;
|
||||
});
|
||||
|
||||
AST_Var.DEFMETHOD("has_const_pragma", function() {
|
||||
var comments_before = this.start && this.start.comments_before;
|
||||
var lastComment = comments_before && comments_before[comments_before.length - 1];
|
||||
return lastComment && /@const\b/.test(lastComment.value);
|
||||
});
|
||||
|
||||
AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options){
|
||||
return defaults(options, {
|
||||
except : [],
|
||||
AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options) {
|
||||
options = defaults(options, {
|
||||
eval : false,
|
||||
sort : false,
|
||||
ie8 : false,
|
||||
keep_fnames : false,
|
||||
reserved : [],
|
||||
toplevel : false,
|
||||
screw_ie8 : false,
|
||||
keep_fnames : false
|
||||
});
|
||||
if (!Array.isArray(options.reserved)) options.reserved = [];
|
||||
// Never mangle arguments
|
||||
push_uniq(options.reserved, "arguments");
|
||||
return options;
|
||||
});
|
||||
|
||||
AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
||||
options = this._default_mangler_options(options);
|
||||
|
||||
// Never mangle arguments
|
||||
options.except.push('arguments');
|
||||
|
||||
// We only need to mangle declaration nodes. Special logic wired
|
||||
// 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
|
||||
@@ -393,11 +408,7 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
||||
var to_mangle = [];
|
||||
|
||||
if (options.cache) {
|
||||
this.globals.each(function(symbol){
|
||||
if (options.except.indexOf(symbol.name) < 0) {
|
||||
to_mangle.push(symbol);
|
||||
}
|
||||
});
|
||||
this.globals.each(collect);
|
||||
}
|
||||
|
||||
var tw = new TreeWalker(function(node, descend){
|
||||
@@ -409,16 +420,7 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
||||
return true; // don't descend again in TreeWalker
|
||||
}
|
||||
if (node instanceof AST_Scope) {
|
||||
var p = tw.parent(), a = [];
|
||||
node.variables.each(function(symbol){
|
||||
if (options.except.indexOf(symbol.name) < 0) {
|
||||
a.push(symbol);
|
||||
}
|
||||
});
|
||||
if (options.sort) a.sort(function(a, b){
|
||||
return b.references.length - a.references.length;
|
||||
});
|
||||
to_mangle.push.apply(to_mangle, a);
|
||||
node.variables.each(collect);
|
||||
return;
|
||||
}
|
||||
if (node instanceof AST_Label) {
|
||||
@@ -427,7 +429,7 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
||||
node.mangled_name = name;
|
||||
return true;
|
||||
}
|
||||
if (options.screw_ie8 && node instanceof AST_SymbolCatch) {
|
||||
if (!options.ie8 && node instanceof AST_SymbolCatch) {
|
||||
to_mangle.push(node.definition());
|
||||
return;
|
||||
}
|
||||
@@ -438,109 +440,146 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
||||
if (options.cache) {
|
||||
options.cache.cname = this.cname;
|
||||
}
|
||||
|
||||
function collect(symbol) {
|
||||
if (!member(symbol.name, options.reserved)) {
|
||||
to_mangle.push(symbol);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
AST_Toplevel.DEFMETHOD("find_unique_prefix", function(options) {
|
||||
var letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_";
|
||||
var cache = options.cache && options.cache.props;
|
||||
var prefixes = Object.create(null);
|
||||
options.reserved.forEach(add_prefix);
|
||||
this.globals.each(add_def);
|
||||
this.walk(new TreeWalker(function(node) {
|
||||
if (node instanceof AST_Scope) node.variables.each(add_def);
|
||||
if (node instanceof AST_SymbolCatch) add_def(node.definition());
|
||||
}));
|
||||
var prefix, i = 0;
|
||||
do {
|
||||
prefix = create_name(i++);
|
||||
} while (prefixes[prefix]);
|
||||
return prefix;
|
||||
|
||||
function add_prefix(name) {
|
||||
if (/[0-9]$/.test(name)) {
|
||||
prefixes[name.replace(/[0-9]+$/, "")] = true;
|
||||
}
|
||||
}
|
||||
|
||||
function add_def(def) {
|
||||
var name = def.name;
|
||||
if (def.global && cache && cache.has(name)) name = cache.get(name);
|
||||
else if (!def.unmangleable(options)) return;
|
||||
add_prefix(name);
|
||||
}
|
||||
|
||||
function create_name(num) {
|
||||
var name = "";
|
||||
do {
|
||||
name += letters[num % letters.length];
|
||||
num = Math.floor(num / letters.length);
|
||||
} while (num);
|
||||
return name;
|
||||
}
|
||||
});
|
||||
|
||||
AST_Toplevel.DEFMETHOD("expand_names", function(options) {
|
||||
options = this._default_mangler_options(options);
|
||||
var prefix = this.find_unique_prefix(options);
|
||||
this.globals.each(rename);
|
||||
this.walk(new TreeWalker(function(node) {
|
||||
if (node instanceof AST_Scope) node.variables.each(rename);
|
||||
if (node instanceof AST_SymbolCatch) rename(node.definition());
|
||||
}));
|
||||
|
||||
function rename(def) {
|
||||
if (def.global || def.unmangleable(options)) return;
|
||||
if (member(def.name, options.reserved)) return;
|
||||
var d = def.redefined();
|
||||
def.name = d ? d.name : prefix + def.id;
|
||||
def.orig.forEach(function(sym) {
|
||||
sym.name = def.name;
|
||||
});
|
||||
def.references.forEach(function(sym) {
|
||||
sym.name = def.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 = this._default_mangler_options(options);
|
||||
var tw = new TreeWalker(function(node){
|
||||
if (node instanceof AST_Constant)
|
||||
base54.consider(node.print_to_string());
|
||||
else if (node instanceof AST_Return)
|
||||
base54.consider("return");
|
||||
else if (node instanceof AST_Throw)
|
||||
base54.consider("throw");
|
||||
else if (node instanceof AST_Continue)
|
||||
base54.consider("continue");
|
||||
else if (node instanceof AST_Break)
|
||||
base54.consider("break");
|
||||
else if (node instanceof AST_Debugger)
|
||||
base54.consider("debugger");
|
||||
else if (node instanceof AST_Directive)
|
||||
base54.consider(node.value);
|
||||
else if (node instanceof AST_While)
|
||||
base54.consider("while");
|
||||
else if (node instanceof AST_Do)
|
||||
base54.consider("do while");
|
||||
else if (node instanceof AST_If) {
|
||||
base54.consider("if");
|
||||
if (node.alternative) base54.consider("else");
|
||||
}
|
||||
else if (node instanceof AST_Var)
|
||||
base54.consider("var");
|
||||
else if (node instanceof AST_Const)
|
||||
base54.consider("const");
|
||||
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);
|
||||
try {
|
||||
AST_Node.prototype.print = function(stream, force_parens) {
|
||||
this._print(stream, force_parens);
|
||||
if (this instanceof AST_Symbol && !this.unmangleable(options)) {
|
||||
base54.consider(this.name, -1);
|
||||
} else if (options.properties) {
|
||||
if (this instanceof AST_Dot) {
|
||||
base54.consider(this.property, -1);
|
||||
} else if (this instanceof AST_Sub) {
|
||||
skip_string(this.property);
|
||||
}
|
||||
}
|
||||
};
|
||||
base54.consider(this.print_to_string(), 1);
|
||||
} finally {
|
||||
AST_Node.prototype.print = AST_Node.prototype._print;
|
||||
}
|
||||
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 string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_0123456789";
|
||||
var leading = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_".split("");
|
||||
var digits = "0123456789".split("");
|
||||
var chars, frequency;
|
||||
function reset() {
|
||||
frequency = Object.create(null);
|
||||
chars = string.split("").map(function(ch){ return ch.charCodeAt(0) });
|
||||
chars.forEach(function(ch){ frequency[ch] = 0 });
|
||||
leading.forEach(function(ch) {
|
||||
frequency[ch] = 0;
|
||||
});
|
||||
digits.forEach(function(ch) {
|
||||
frequency[ch] = 0;
|
||||
});
|
||||
}
|
||||
base54.consider = function(str){
|
||||
base54.consider = function(str, delta) {
|
||||
for (var i = str.length; --i >= 0;) {
|
||||
var code = str.charCodeAt(i);
|
||||
if (code in frequency) ++frequency[code];
|
||||
frequency[str[i]] += delta;
|
||||
}
|
||||
};
|
||||
function compare(a, b) {
|
||||
return frequency[b] - frequency[a];
|
||||
}
|
||||
base54.sort = function() {
|
||||
chars = mergeSort(chars, function(a, b){
|
||||
if (is_digit(a) && !is_digit(b)) return 1;
|
||||
if (is_digit(b) && !is_digit(a)) return -1;
|
||||
return frequency[b] - frequency[a];
|
||||
});
|
||||
chars = mergeSort(leading, compare).concat(mergeSort(digits, compare));
|
||||
};
|
||||
base54.reset = reset;
|
||||
reset();
|
||||
base54.get = function(){ return chars };
|
||||
base54.freq = function(){ return frequency };
|
||||
function base54(num) {
|
||||
var ret = "", base = 54;
|
||||
num++;
|
||||
do {
|
||||
num--;
|
||||
ret += String.fromCharCode(chars[num % base]);
|
||||
ret += chars[num % base];
|
||||
num = Math.floor(num / base);
|
||||
base = 64;
|
||||
} while (num > 0);
|
||||
@@ -548,89 +587,3 @@ var base54 = (function() {
|
||||
};
|
||||
return base54;
|
||||
})();
|
||||
|
||||
AST_Toplevel.DEFMETHOD("scope_warnings", function(options){
|
||||
options = defaults(options, {
|
||||
undeclared : false, // this makes a lot of noise
|
||||
unreferenced : true,
|
||||
assign_to_global : true,
|
||||
func_arguments : true,
|
||||
nested_defuns : true,
|
||||
eval : true
|
||||
});
|
||||
var tw = new TreeWalker(function(node){
|
||||
if (options.undeclared
|
||||
&& node instanceof AST_SymbolRef
|
||||
&& node.undeclared())
|
||||
{
|
||||
// XXX: this also warns about JS standard names,
|
||||
// i.e. Object, Array, parseInt etc. Should add a list of
|
||||
// exceptions.
|
||||
AST_Node.warn("Undeclared symbol: {name} [{file}:{line},{col}]", {
|
||||
name: node.name,
|
||||
file: node.start.file,
|
||||
line: node.start.line,
|
||||
col: node.start.col
|
||||
});
|
||||
}
|
||||
if (options.assign_to_global)
|
||||
{
|
||||
var sym = null;
|
||||
if (node instanceof AST_Assign && node.left instanceof AST_SymbolRef)
|
||||
sym = node.left;
|
||||
else if (node instanceof AST_ForIn && node.init instanceof AST_SymbolRef)
|
||||
sym = node.init;
|
||||
if (sym
|
||||
&& (sym.undeclared()
|
||||
|| (sym.global() && sym.scope !== sym.definition().scope))) {
|
||||
AST_Node.warn("{msg}: {name} [{file}:{line},{col}]", {
|
||||
msg: sym.undeclared() ? "Accidental global?" : "Assignment to global",
|
||||
name: sym.name,
|
||||
file: sym.start.file,
|
||||
line: sym.start.line,
|
||||
col: sym.start.col
|
||||
});
|
||||
}
|
||||
}
|
||||
if (options.eval
|
||||
&& node instanceof AST_SymbolRef
|
||||
&& node.undeclared()
|
||||
&& node.name == "eval") {
|
||||
AST_Node.warn("Eval is used [{file}:{line},{col}]", node.start);
|
||||
}
|
||||
if (options.unreferenced
|
||||
&& (node instanceof AST_SymbolDeclaration || node instanceof AST_Label)
|
||||
&& !(node instanceof AST_SymbolCatch)
|
||||
&& node.unreferenced()) {
|
||||
AST_Node.warn("{type} {name} is declared but not referenced [{file}:{line},{col}]", {
|
||||
type: node instanceof AST_Label ? "Label" : "Symbol",
|
||||
name: node.name,
|
||||
file: node.start.file,
|
||||
line: node.start.line,
|
||||
col: node.start.col
|
||||
});
|
||||
}
|
||||
if (options.func_arguments
|
||||
&& node instanceof AST_Lambda
|
||||
&& node.uses_arguments) {
|
||||
AST_Node.warn("arguments used in function {name} [{file}:{line},{col}]", {
|
||||
name: node.name ? node.name.name : "anonymous",
|
||||
file: node.start.file,
|
||||
line: node.start.line,
|
||||
col: node.start.col
|
||||
});
|
||||
}
|
||||
if (options.nested_defuns
|
||||
&& node instanceof AST_Defun
|
||||
&& !(tw.parent() instanceof AST_Scope)) {
|
||||
AST_Node.warn("Function {name} declared in nested statement \"{type}\" [{file}:{line},{col}]", {
|
||||
name: node.name.name,
|
||||
type: tw.parent().TYPE,
|
||||
file: node.start.file,
|
||||
line: node.start.line,
|
||||
col: node.start.col
|
||||
});
|
||||
}
|
||||
});
|
||||
this.walk(tw);
|
||||
});
|
||||
|
||||
@@ -58,6 +58,16 @@ function SourceMap(options) {
|
||||
sourceRoot : options.root
|
||||
});
|
||||
var orig_map = options.orig && new MOZ_SourceMap.SourceMapConsumer(options.orig);
|
||||
|
||||
if (orig_map && Array.isArray(options.orig.sources)) {
|
||||
orig_map._sources.toArray().forEach(function(source) {
|
||||
var sourceContent = orig_map.sourceContentFor(source, true);
|
||||
if (sourceContent) {
|
||||
generator.setSourceContent(source, sourceContent);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function add(source, gen_line, gen_col, orig_line, orig_col, name) {
|
||||
if (orig_map) {
|
||||
var info = orig_map.originalPositionFor({
|
||||
|
||||
@@ -60,17 +60,14 @@ TreeTransformer.prototype = new TreeWalker;
|
||||
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);
|
||||
x = this;
|
||||
descend(x, tw);
|
||||
if (tw.after) {
|
||||
y = tw.after(x, in_list);
|
||||
if (y !== undefined) x = y;
|
||||
}
|
||||
}
|
||||
tw.pop(this);
|
||||
tw.pop();
|
||||
return x;
|
||||
});
|
||||
};
|
||||
@@ -174,9 +171,8 @@ TreeTransformer.prototype = new TreeWalker;
|
||||
self.args = do_list(self.args, tw);
|
||||
});
|
||||
|
||||
_(AST_Seq, function(self, tw){
|
||||
self.car = self.car.transform(tw);
|
||||
self.cdr = self.cdr.transform(tw);
|
||||
_(AST_Sequence, function(self, tw){
|
||||
self.expressions = do_list(self.expressions, tw);
|
||||
});
|
||||
|
||||
_(AST_Dot, function(self, tw){
|
||||
|
||||
105
lib/utils.js
105
lib/utils.js
@@ -43,26 +43,12 @@
|
||||
|
||||
"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) {
|
||||
return str.split("");
|
||||
};
|
||||
|
||||
function member(name, array) {
|
||||
for (var i = array.length; --i >= 0;)
|
||||
if (array[i] == name)
|
||||
return true;
|
||||
return false;
|
||||
return array.indexOf(name) >= 0;
|
||||
};
|
||||
|
||||
function find_if(func, array) {
|
||||
@@ -81,13 +67,28 @@ function repeat_string(str, i) {
|
||||
return d;
|
||||
};
|
||||
|
||||
function configure_error_stack(fn) {
|
||||
Object.defineProperty(fn.prototype, "stack", {
|
||||
get: function() {
|
||||
var err = new Error(this.message);
|
||||
err.name = this.name;
|
||||
try {
|
||||
throw err;
|
||||
} catch(e) {
|
||||
return e.stack;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function DefaultsError(msg, defs) {
|
||||
Error.call(this, msg);
|
||||
this.msg = msg;
|
||||
this.message = msg;
|
||||
this.defs = defs;
|
||||
};
|
||||
DefaultsError.prototype = Object.create(Error.prototype);
|
||||
DefaultsError.prototype.constructor = DefaultsError;
|
||||
DefaultsError.prototype.name = "DefaultsError";
|
||||
configure_error_stack(DefaultsError);
|
||||
|
||||
DefaultsError.croak = function(msg, defs) {
|
||||
throw new DefaultsError(msg, defs);
|
||||
@@ -97,24 +98,28 @@ function defaults(args, defs, croak) {
|
||||
if (args === true)
|
||||
args = {};
|
||||
var ret = args || {};
|
||||
if (croak) for (var i in ret) if (ret.hasOwnProperty(i) && !defs.hasOwnProperty(i))
|
||||
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 (defs.hasOwnProperty(i)) {
|
||||
ret[i] = (args && args.hasOwnProperty(i)) ? args[i] : defs[i];
|
||||
for (var i in defs) if (HOP(defs, i)) {
|
||||
ret[i] = (args && HOP(args, i)) ? args[i] : defs[i];
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
function merge(obj, ext) {
|
||||
var count = 0;
|
||||
for (var i in ext) if (ext.hasOwnProperty(i)) {
|
||||
for (var i in ext) if (HOP(ext, i)) {
|
||||
obj[i] = ext[i];
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
};
|
||||
|
||||
function noop() {};
|
||||
function noop() {}
|
||||
function return_false() { return false; }
|
||||
function return_true() { return true; }
|
||||
function return_this() { return this; }
|
||||
function return_null() { return null; }
|
||||
|
||||
var MAP = (function(){
|
||||
function MAP(a, f, backwards) {
|
||||
@@ -150,7 +155,7 @@ var MAP = (function(){
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i in a) if (a.hasOwnProperty(i)) if (doit()) break;
|
||||
for (i in a) if (HOP(a, i)) if (doit()) break;
|
||||
}
|
||||
return top.concat(ret);
|
||||
};
|
||||
@@ -171,7 +176,7 @@ function push_uniq(array, el) {
|
||||
|
||||
function string_template(text, props) {
|
||||
return text.replace(/\{(.+?)\}/g, function(str, p){
|
||||
return props[p];
|
||||
return props && props[p];
|
||||
});
|
||||
};
|
||||
|
||||
@@ -205,18 +210,6 @@ function mergeSort(array, cmp) {
|
||||
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) {
|
||||
@@ -230,10 +223,19 @@ function makePredicate(words) {
|
||||
}
|
||||
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 === " + JSON.stringify(arr[0]) + ";";
|
||||
if (arr.length == 1) return f += "return str === " + quote(arr[0]) + ";";
|
||||
f += "switch(str){";
|
||||
for (var i = 0; i < arr.length; ++i) f += "case " + JSON.stringify(arr[i]) + ":";
|
||||
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
|
||||
@@ -308,3 +310,30 @@ Dictionary.fromObject = function(obj) {
|
||||
dict._size = merge(dict._values, obj);
|
||||
return dict;
|
||||
};
|
||||
|
||||
function HOP(obj, prop) {
|
||||
return Object.prototype.hasOwnProperty.call(obj, prop);
|
||||
}
|
||||
|
||||
// return true if the node at the top of the stack (that means the
|
||||
// innermost node in the current output) is lexically the first in
|
||||
// a statement.
|
||||
function first_in_statement(stack) {
|
||||
var node = stack.parent(-1);
|
||||
for (var i = 0, p; p = stack.parent(i); i++) {
|
||||
if (p instanceof AST_Statement && p.body === node)
|
||||
return true;
|
||||
if ((p instanceof AST_Sequence && p.expressions[0] === node) ||
|
||||
(p.TYPE == "Call" && p.expression === node ) ||
|
||||
(p instanceof AST_Dot && p.expression === node ) ||
|
||||
(p instanceof AST_Sub && p.expression === node ) ||
|
||||
(p instanceof AST_Conditional && p.condition === node ) ||
|
||||
(p instanceof AST_Binary && p.left === node ) ||
|
||||
(p instanceof AST_UnaryPostfix && p.expression === node ))
|
||||
{
|
||||
node = p;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
128
npm-shrinkwrap.json
generated
128
npm-shrinkwrap.json
generated
@@ -1,128 +0,0 @@
|
||||
{
|
||||
"name": "uglify-js",
|
||||
"version": "2.4.24",
|
||||
"dependencies": {
|
||||
"abbrev": {
|
||||
"version": "1.0.7",
|
||||
"from": "abbrev@>=1.0.0 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.7.tgz"
|
||||
},
|
||||
"amdefine": {
|
||||
"version": "1.0.0",
|
||||
"from": "amdefine@>=0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.0.tgz"
|
||||
},
|
||||
"async": {
|
||||
"version": "0.2.10",
|
||||
"from": "async@>=0.2.6 <0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz"
|
||||
},
|
||||
"camelcase": {
|
||||
"version": "1.2.1",
|
||||
"from": "camelcase@>=1.0.2 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz"
|
||||
},
|
||||
"decamelize": {
|
||||
"version": "1.0.0",
|
||||
"from": "decamelize@>=1.0.0 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.0.0.tgz"
|
||||
},
|
||||
"deep-is": {
|
||||
"version": "0.1.3",
|
||||
"from": "deep-is@>=0.1.2 <0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz"
|
||||
},
|
||||
"esprima": {
|
||||
"version": "1.1.1",
|
||||
"from": "esprima@>=1.1.1 <1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/esprima/-/esprima-1.1.1.tgz"
|
||||
},
|
||||
"estraverse": {
|
||||
"version": "1.5.1",
|
||||
"from": "estraverse@>=1.5.1 <1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.5.1.tgz"
|
||||
},
|
||||
"esutils": {
|
||||
"version": "1.0.0",
|
||||
"from": "esutils@>=1.0.0 <1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/esutils/-/esutils-1.0.0.tgz"
|
||||
},
|
||||
"fast-levenshtein": {
|
||||
"version": "1.0.7",
|
||||
"from": "fast-levenshtein@>=1.0.0 <1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-1.0.7.tgz"
|
||||
},
|
||||
"levn": {
|
||||
"version": "0.2.5",
|
||||
"from": "levn@>=0.2.5 <0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/levn/-/levn-0.2.5.tgz"
|
||||
},
|
||||
"nopt": {
|
||||
"version": "2.1.2",
|
||||
"from": "nopt@>=2.1.2 <2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/nopt/-/nopt-2.1.2.tgz"
|
||||
},
|
||||
"optionator": {
|
||||
"version": "0.5.0",
|
||||
"from": "optionator@>=0.5.0 <0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.5.0.tgz"
|
||||
},
|
||||
"prelude-ls": {
|
||||
"version": "1.1.2",
|
||||
"from": "prelude-ls@>=1.1.1 <1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz"
|
||||
},
|
||||
"reflect": {
|
||||
"version": "0.1.3",
|
||||
"from": "git://github.com/zaach/reflect.js.git",
|
||||
"resolved": "git://github.com/zaach/reflect.js.git#286bcd79661c96ecc404357d3c0e35fdb54a6967"
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.5.1",
|
||||
"from": "source-map@>=0.5.1 <0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.1.tgz"
|
||||
},
|
||||
"type-check": {
|
||||
"version": "0.3.1",
|
||||
"from": "type-check@>=0.3.1 <0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.1.tgz"
|
||||
},
|
||||
"uglify-js": {
|
||||
"version": "2.4.24",
|
||||
"from": "git://github.com/mishoo/UglifyJS2.git",
|
||||
"resolved": "git://github.com/mishoo/UglifyJS2.git#2a06c7758e24a64740473c8031eafbb7fefa213f",
|
||||
"dependencies": {
|
||||
"source-map": {
|
||||
"version": "0.1.34",
|
||||
"from": "source-map@0.1.34",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.34.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"uglify-to-browserify": {
|
||||
"version": "1.0.2",
|
||||
"from": "uglify-to-browserify@>=1.0.0 <1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz"
|
||||
},
|
||||
"window-size": {
|
||||
"version": "0.1.0",
|
||||
"from": "window-size@0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz"
|
||||
},
|
||||
"wordwrap": {
|
||||
"version": "0.0.2",
|
||||
"from": "wordwrap@0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz"
|
||||
},
|
||||
"yargs": {
|
||||
"version": "3.10.0",
|
||||
"from": "yargs@>=3.10.0 <3.11.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz"
|
||||
},
|
||||
"zeparser": {
|
||||
"version": "0.0.7",
|
||||
"from": "git://github.com/qfox/ZeParser.git",
|
||||
"resolved": "git://github.com/qfox/ZeParser.git#c99240c5ba7054c467733800ff38265958a2dda9"
|
||||
}
|
||||
}
|
||||
}
|
||||
24
package.json
24
package.json
@@ -4,7 +4,7 @@
|
||||
"homepage": "http://lisperator.net/uglifyjs",
|
||||
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
||||
"license": "BSD-2-Clause",
|
||||
"version": "2.6.2",
|
||||
"version": "3.3.2",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
},
|
||||
@@ -29,26 +29,16 @@
|
||||
"LICENSE"
|
||||
],
|
||||
"dependencies": {
|
||||
"async": "~0.2.6",
|
||||
"source-map": "~0.5.1",
|
||||
"uglify-to-browserify": "~1.0.0",
|
||||
"yargs": "~3.10.0"
|
||||
"commander": "~2.12.1",
|
||||
"source-map": "~0.6.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"acorn": "~0.6.0",
|
||||
"escodegen": "~1.3.3",
|
||||
"esfuzz": "~0.3.1",
|
||||
"estraverse": "~1.5.1",
|
||||
"mocha": "~2.3.4"
|
||||
},
|
||||
"browserify": {
|
||||
"transform": [
|
||||
"uglify-to-browserify"
|
||||
]
|
||||
"acorn": "~5.2.1",
|
||||
"mocha": "~3.5.1",
|
||||
"semver": "~5.4.1"
|
||||
},
|
||||
"scripts": {
|
||||
"shrinkwrap": "rm ./npm-shrinkwrap.json; rm -rf ./node_modules; npm i && npm shrinkwrap && npm outdated",
|
||||
"test": "node test/run-tests.js"
|
||||
},
|
||||
"keywords": ["uglify", "uglify-js", "minify", "minifier"]
|
||||
"keywords": ["uglify", "uglify-js", "minify", "minifier", "es5"]
|
||||
}
|
||||
|
||||
85
test/benchmark.js
Normal file
85
test/benchmark.js
Normal file
@@ -0,0 +1,85 @@
|
||||
#! /usr/bin/env node
|
||||
// -*- js -*-
|
||||
|
||||
"use strict";
|
||||
|
||||
var createHash = require("crypto").createHash;
|
||||
var fetch = require("./fetch");
|
||||
var fork = require("child_process").fork;
|
||||
var zlib = require("zlib");
|
||||
var args = process.argv.slice(2);
|
||||
if (!args.length) {
|
||||
args.push("-mc");
|
||||
}
|
||||
args.push("--timings");
|
||||
var urls = [
|
||||
"https://code.jquery.com/jquery-3.2.1.js",
|
||||
"https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.4/angular.js",
|
||||
"https://cdnjs.cloudflare.com/ajax/libs/mathjs/3.9.0/math.js",
|
||||
"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.js",
|
||||
"https://unpkg.com/react@15.3.2/dist/react.js",
|
||||
"http://builds.emberjs.com/tags/v2.11.0/ember.prod.js",
|
||||
"https://cdn.jsdelivr.net/lodash/4.17.4/lodash.js",
|
||||
"https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.js",
|
||||
"https://raw.githubusercontent.com/kangax/html-minifier/v3.5.7/dist/htmlminifier.js",
|
||||
];
|
||||
var results = {};
|
||||
var remaining = 2 * urls.length;
|
||||
function done() {
|
||||
if (!--remaining) {
|
||||
var failures = [];
|
||||
urls.forEach(function(url) {
|
||||
var info = results[url];
|
||||
console.log();
|
||||
console.log(url);
|
||||
console.log(info.log);
|
||||
console.log("Original:", info.input, "bytes");
|
||||
console.log("Uglified:", info.output, "bytes");
|
||||
console.log("GZipped: ", info.gzip, "bytes");
|
||||
console.log("SHA1 sum:", info.sha1);
|
||||
if (info.code) {
|
||||
failures.push(url);
|
||||
}
|
||||
});
|
||||
if (failures.length) {
|
||||
console.error("Benchmark failed:");
|
||||
failures.forEach(function(url) {
|
||||
console.error(url);
|
||||
});
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
urls.forEach(function(url) {
|
||||
results[url] = {
|
||||
input: 0,
|
||||
output: 0,
|
||||
gzip: 0,
|
||||
log: ""
|
||||
};
|
||||
fetch(url, function(err, res) {
|
||||
if (err) throw err;
|
||||
var uglifyjs = fork("bin/uglifyjs", args, { silent: true });
|
||||
res.on("data", function(data) {
|
||||
results[url].input += data.length;
|
||||
}).pipe(uglifyjs.stdin);
|
||||
uglifyjs.stdout.on("data", function(data) {
|
||||
results[url].output += data.length;
|
||||
}).pipe(zlib.createGzip({
|
||||
level: zlib.Z_BEST_COMPRESSION
|
||||
})).on("data", function(data) {
|
||||
results[url].gzip += data.length;
|
||||
}).pipe(createHash("sha1")).on("data", function(data) {
|
||||
results[url].sha1 = data.toString("hex");
|
||||
done();
|
||||
});
|
||||
uglifyjs.stderr.setEncoding("utf8");
|
||||
uglifyjs.stderr.on("data", function(data) {
|
||||
results[url].log += data;
|
||||
});
|
||||
uglifyjs.on("exit", function(code) {
|
||||
results[url].code = code;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
67
test/compress/angular-inject.js
vendored
67
test/compress/angular-inject.js
vendored
@@ -1,67 +0,0 @@
|
||||
ng_inject_defun: {
|
||||
options = {
|
||||
angular: true
|
||||
};
|
||||
input: {
|
||||
/*@ngInject*/
|
||||
function Controller(dependency) {
|
||||
return dependency;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function Controller(dependency) {
|
||||
return dependency;
|
||||
}
|
||||
Controller.$inject=['dependency']
|
||||
}
|
||||
}
|
||||
|
||||
ng_inject_assignment: {
|
||||
options = {
|
||||
angular: true
|
||||
};
|
||||
input: {
|
||||
/*@ngInject*/
|
||||
var Controller = function(dependency) {
|
||||
return dependency;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var Controller = function(dependency) {
|
||||
return dependency;
|
||||
}
|
||||
Controller.$inject=['dependency']
|
||||
}
|
||||
}
|
||||
|
||||
ng_inject_inline: {
|
||||
options = {
|
||||
angular: true
|
||||
};
|
||||
input: {
|
||||
angular.module('a').
|
||||
factory('b',
|
||||
/*@ngInject*/
|
||||
function(dependency) {
|
||||
return dependency;
|
||||
}).
|
||||
directive('c',
|
||||
/*@ngInject*/
|
||||
function(anotherDependency) {
|
||||
return anotherDependency;
|
||||
})
|
||||
}
|
||||
expect: {
|
||||
angular.module('a').
|
||||
factory('b',[
|
||||
'dependency',
|
||||
function(dependency) {
|
||||
return dependency;
|
||||
}]).
|
||||
directive('c',[
|
||||
'anotherDependency',
|
||||
function(anotherDependency) {
|
||||
return anotherDependency;
|
||||
}])
|
||||
}
|
||||
}
|
||||
@@ -21,10 +21,19 @@ constant_join: {
|
||||
input: {
|
||||
var a = [ "foo", "bar", "baz" ].join("");
|
||||
var a1 = [ "foo", "bar", "baz" ].join();
|
||||
var a2 = [ "foo", "bar", "baz" ].join(null);
|
||||
var a3 = [ "foo", "bar", "baz" ].join(void 0);
|
||||
var a4 = [ "foo", , "baz" ].join();
|
||||
var a5 = [ "foo", null, "baz" ].join();
|
||||
var a6 = [ "foo", void 0, "baz" ].join();
|
||||
var b = [ "foo", 1, 2, 3, "bar" ].join("");
|
||||
var c = [ boo(), "foo", 1, 2, 3, "bar", bar() ].join("");
|
||||
var c1 = [ boo(), bar(), "foo", 1, 2, 3, "bar", bar() ].join("");
|
||||
var c2 = [ 1, 2, "foo", "bar", baz() ].join("");
|
||||
var c3 = [ boo() + bar() + "foo", 1, 2, 3, "bar", bar() + "foo" ].join("");
|
||||
var c4 = [ 1, 2, null, undefined, "foo", "bar", baz() ].join("");
|
||||
var c5 = [ boo() + bar() + "foo", 1, 2, 3, "bar", bar() + "foo" ].join();
|
||||
var c6 = [ 1, 2, null, undefined, "foo", "bar", baz() ].join();
|
||||
var d = [ "foo", 1 + 2 + "bar", "baz" ].join("-");
|
||||
var e = [].join(foo + bar);
|
||||
var f = [].join("");
|
||||
@@ -33,10 +42,19 @@ constant_join: {
|
||||
expect: {
|
||||
var a = "foobarbaz";
|
||||
var a1 = "foo,bar,baz";
|
||||
var a2 = "foonullbarnullbaz";
|
||||
var a3 = "foo,bar,baz";
|
||||
var a4 = "foo,,baz";
|
||||
var a5 = "foo,,baz";
|
||||
var a6 = "foo,,baz";
|
||||
var b = "foo123bar";
|
||||
var c = boo() + "foo123bar" + bar();
|
||||
var c1 = "" + boo() + bar() + "foo123bar" + bar();
|
||||
var c2 = "12foobar" + baz();
|
||||
var c3 = boo() + bar() + "foo123bar" + bar() + "foo";
|
||||
var c4 = "12foobar" + baz();
|
||||
var c5 = [ boo() + bar() + "foo", 1, 2, 3, "bar", bar() + "foo" ].join();
|
||||
var c6 = [ "1,2,,,foo,bar", baz() ].join();
|
||||
var d = "foo-3bar-baz";
|
||||
var e = [].join(foo + bar);
|
||||
var f = "";
|
||||
@@ -72,3 +90,152 @@ constant_join_2: {
|
||||
var f = "strstr" + variable + "foobarmoo" + foo;
|
||||
}
|
||||
}
|
||||
|
||||
constant_join_3: {
|
||||
options = {
|
||||
unsafe: true,
|
||||
evaluate: true,
|
||||
};
|
||||
input: {
|
||||
var a = [ null ].join();
|
||||
var b = [ , ].join();
|
||||
var c = [ , 1, , 3 ].join();
|
||||
var d = [ foo ].join();
|
||||
var e = [ foo, null, undefined, bar ].join("-");
|
||||
var f = [ foo, bar ].join("");
|
||||
var g = [ null, "foo", null, bar + "baz" ].join("");
|
||||
var h = [ null, "foo", null, bar + "baz" ].join("-");
|
||||
var i = [ "foo" + bar, null, baz + "moo" ].join("");
|
||||
var j = [ foo + "bar", baz ].join("");
|
||||
var k = [ foo, "bar" + baz ].join("");
|
||||
var l = [ foo, bar + "baz" ].join("");
|
||||
}
|
||||
expect: {
|
||||
var a = "";
|
||||
var b = "";
|
||||
var c = ",1,,3";
|
||||
var d = "" + foo;
|
||||
var e = [ foo, "-", bar ].join("-");
|
||||
var f = "" + foo + bar;
|
||||
var g = "foo" + bar + "baz";
|
||||
var h = [ "-foo-", bar + "baz" ].join("-");
|
||||
var i = "foo" + bar + baz + "moo";
|
||||
var j = foo + "bar" + baz;
|
||||
var k = foo + "bar" + baz;
|
||||
var l = foo + (bar + "baz");
|
||||
}
|
||||
}
|
||||
|
||||
for_loop: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unsafe: true,
|
||||
unused: true,
|
||||
};
|
||||
input: {
|
||||
function f0() {
|
||||
var a = [1, 2, 3];
|
||||
var b = 0;
|
||||
for (var i = 0; i < a.length; i++)
|
||||
b += a[i];
|
||||
return b;
|
||||
}
|
||||
function f1() {
|
||||
var a = [1, 2, 3];
|
||||
var b = 0;
|
||||
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]++;
|
||||
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"
|
||||
}
|
||||
|
||||
35
test/compress/ascii.js
Normal file
35
test/compress/ascii.js
Normal file
@@ -0,0 +1,35 @@
|
||||
ascii_only_true: {
|
||||
options = {}
|
||||
beautify = {
|
||||
ascii_only : true,
|
||||
ie8 : false,
|
||||
beautify : false,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
return "\x000\x001\x007\x008\x00" +
|
||||
"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" +
|
||||
"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" +
|
||||
"\x20\x21\x22\x23 ... \x7d\x7e\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: {
|
||||
options = {}
|
||||
beautify = {
|
||||
ascii_only : false,
|
||||
ie8 : false,
|
||||
beautify : false,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
return "\x000\x001\x007\x008\x00" +
|
||||
"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" +
|
||||
"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" +
|
||||
"\x20\x21\x22\x23 ... \x7d\x7e\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\'}'
|
||||
}
|
||||
@@ -16,7 +16,6 @@ asm_mixed: {
|
||||
hoist_vars : true,
|
||||
if_return : true,
|
||||
join_vars : true,
|
||||
cascade : true,
|
||||
side_effects : true,
|
||||
negate_iife : true
|
||||
};
|
||||
@@ -90,13 +89,13 @@ asm_mixed: {
|
||||
}
|
||||
function no_asm_GeometricMean(stdlib, foreign, buffer) {
|
||||
function logSum(start, end) {
|
||||
start = 0 | start, end = 0 | end;
|
||||
start |= 0, end |= 0;
|
||||
var sum = 0, p = 0, q = 0;
|
||||
for (p = start << 3, q = end << 3; (0 | q) > (0 | p); p = p + 8 | 0) sum += +log(values[p >> 3]);
|
||||
for (p = start << 3, q = end << 3; (0 | p) < (0 | q); p = p + 8 | 0) sum += +log(values[p >> 3]);
|
||||
return +sum;
|
||||
}
|
||||
function geometricMean(start, end) {
|
||||
return start = 0 | start, end = 0 | end, +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);
|
||||
return { geometricMean: geometricMean };
|
||||
@@ -104,3 +103,65 @@ 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;'
|
||||
}
|
||||
|
||||
238
test/compress/assignment.js
Normal file
238
test/compress/assignment.js
Normal file
@@ -0,0 +1,238 @@
|
||||
op_equals_left_local_var: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
var x;
|
||||
|
||||
x = x + 3;
|
||||
x = x - 3;
|
||||
x = x / 3;
|
||||
x = x * 3;
|
||||
x = x >> 3;
|
||||
x = x << 3;
|
||||
x = x >>> 3;
|
||||
x = x | 3;
|
||||
x = x ^ 3;
|
||||
x = x % 3;
|
||||
x = x & 3;
|
||||
|
||||
x = x + g();
|
||||
x = x - g();
|
||||
x = x / g();
|
||||
x = x * g();
|
||||
x = x >> g();
|
||||
x = x << g();
|
||||
x = x >>> g();
|
||||
x = x | g();
|
||||
x = x ^ g();
|
||||
x = x % g();
|
||||
x = x & g();
|
||||
}
|
||||
expect: {
|
||||
var x;
|
||||
|
||||
x += 3;
|
||||
x -= 3;
|
||||
x /= 3;
|
||||
x *= 3;
|
||||
x >>= 3;
|
||||
x <<= 3;
|
||||
x >>>= 3;
|
||||
x |= 3;
|
||||
x ^= 3;
|
||||
x %= 3;
|
||||
x &= 3;
|
||||
|
||||
x += g();
|
||||
x -= g();
|
||||
x /= g();
|
||||
x *= g();
|
||||
x >>= g();
|
||||
x <<= g();
|
||||
x >>>= g();
|
||||
x |= g();
|
||||
x ^= g();
|
||||
x %= g();
|
||||
x &= g();
|
||||
}
|
||||
}
|
||||
|
||||
op_equals_right_local_var: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
var x;
|
||||
|
||||
x = (x -= 2) ^ x;
|
||||
|
||||
x = 3 + x;
|
||||
x = 3 - x;
|
||||
x = 3 / x;
|
||||
x = 3 * x;
|
||||
x = 3 >> x;
|
||||
x = 3 << x;
|
||||
x = 3 >>> x;
|
||||
x = 3 | x;
|
||||
x = 3 ^ x;
|
||||
x = 3 % x;
|
||||
x = 3 & x;
|
||||
|
||||
x = g() + x;
|
||||
x = g() - x;
|
||||
x = g() / x;
|
||||
x = g() * x;
|
||||
x = g() >> x;
|
||||
x = g() << x;
|
||||
x = g() >>> x;
|
||||
x = g() | x;
|
||||
x = g() ^ x;
|
||||
x = g() % x;
|
||||
x = g() & x;
|
||||
}
|
||||
expect: {
|
||||
var x;
|
||||
|
||||
x = (x -= 2) ^ x;
|
||||
|
||||
x = 3 + x;
|
||||
x = 3 - x;
|
||||
x = 3 / x;
|
||||
x *= 3;
|
||||
x = 3 >> x;
|
||||
x = 3 << x;
|
||||
x = 3 >>> x;
|
||||
x |= 3;
|
||||
x ^= 3;
|
||||
x = 3 % x;
|
||||
x &= 3;
|
||||
|
||||
x = g() + x;
|
||||
x = g() - x;
|
||||
x = g() / x;
|
||||
x = g() * x;
|
||||
x = g() >> x;
|
||||
x = g() << x;
|
||||
x = g() >>> x;
|
||||
x = g() | x;
|
||||
x = g() ^ x;
|
||||
x = g() % x;
|
||||
x = g() & x;
|
||||
}
|
||||
}
|
||||
op_equals_left_global_var: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
x = x + 3;
|
||||
x = x - 3;
|
||||
x = x / 3;
|
||||
x = x * 3;
|
||||
x = x >> 3;
|
||||
x = x << 3;
|
||||
x = x >>> 3;
|
||||
x = x | 3;
|
||||
x = x ^ 3;
|
||||
x = x % 3;
|
||||
x = x & 3;
|
||||
|
||||
x = x + g();
|
||||
x = x - g();
|
||||
x = x / g();
|
||||
x = x * g();
|
||||
x = x >> g();
|
||||
x = x << g();
|
||||
x = x >>> g();
|
||||
x = x | g();
|
||||
x = x ^ g();
|
||||
x = x % g();
|
||||
x = x & g();
|
||||
}
|
||||
expect: {
|
||||
x += 3;
|
||||
x -= 3;
|
||||
x /= 3;
|
||||
x *= 3;
|
||||
x >>= 3;
|
||||
x <<= 3;
|
||||
x >>>= 3;
|
||||
x |= 3;
|
||||
x ^= 3;
|
||||
x %= 3;
|
||||
x &= 3;
|
||||
|
||||
x += g();
|
||||
x -= g();
|
||||
x /= g();
|
||||
x *= g();
|
||||
x >>= g();
|
||||
x <<= g();
|
||||
x >>>= g();
|
||||
x |= g();
|
||||
x ^= g();
|
||||
x %= g();
|
||||
x &= g();
|
||||
}
|
||||
}
|
||||
|
||||
op_equals_right_global_var: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
x = (x -= 2) ^ x;
|
||||
|
||||
x = 3 + x;
|
||||
x = 3 - x;
|
||||
x = 3 / x;
|
||||
x = 3 * x;
|
||||
x = 3 >> x;
|
||||
x = 3 << x;
|
||||
x = 3 >>> x;
|
||||
x = 3 | x;
|
||||
x = 3 ^ x;
|
||||
x = 3 % x;
|
||||
x = 3 & x;
|
||||
|
||||
x = g() + x;
|
||||
x = g() - x;
|
||||
x = g() / x;
|
||||
x = g() * x;
|
||||
x = g() >> x;
|
||||
x = g() << x;
|
||||
x = g() >>> x;
|
||||
x = g() | x;
|
||||
x = g() ^ x;
|
||||
x = g() % x;
|
||||
x = g() & x;
|
||||
}
|
||||
expect: {
|
||||
x = (x -= 2) ^ x;
|
||||
|
||||
x = 3 + x;
|
||||
x = 3 - x;
|
||||
x = 3 / x;
|
||||
x *= 3;
|
||||
x = 3 >> x;
|
||||
x = 3 << x;
|
||||
x = 3 >>> x;
|
||||
x |= 3;
|
||||
x ^= 3;
|
||||
x = 3 % x;
|
||||
x &= 3;
|
||||
|
||||
x = g() + x;
|
||||
x = g() - x;
|
||||
x = g() / x;
|
||||
x = g() * x;
|
||||
x = g() >> x;
|
||||
x = g() << x;
|
||||
x = g() >>> x;
|
||||
x = g() | x;
|
||||
x = g() ^ x;
|
||||
x = g() % x;
|
||||
x = g() & x;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
114
test/compress/comparing.js
Normal file
114
test/compress/comparing.js
Normal file
@@ -0,0 +1,114 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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"
|
||||
}
|
||||
@@ -11,6 +11,9 @@ concat_1: {
|
||||
var d = 1 + x() + 2 + 3 + "boo";
|
||||
|
||||
var e = 1 + x() + 2 + "X" + 3 + "boo";
|
||||
|
||||
// be careful with concatentation with "\0" with octal-looking strings.
|
||||
var f = "\0" + 360 + "\0" + 8 + "\0";
|
||||
}
|
||||
expect: {
|
||||
var a = "foobar" + x() + "moofoo" + y() + "xyz" + q();
|
||||
@@ -18,5 +21,203 @@ concat_1: {
|
||||
var c = 1 + x() + 2 + "boo";
|
||||
var d = 1 + x() + 2 + 3 + "boo";
|
||||
var e = 1 + x() + 2 + "X3boo";
|
||||
var f = "\x00360\x008\0";
|
||||
}
|
||||
}
|
||||
|
||||
concat_2: {
|
||||
options = {};
|
||||
input: {
|
||||
console.log(
|
||||
1 + (2 + 3),
|
||||
1 + (2 + "3"),
|
||||
1 + ("2" + 3),
|
||||
1 + ("2" + "3"),
|
||||
"1" + (2 + 3),
|
||||
"1" + (2 + "3"),
|
||||
"1" + ("2" + 3),
|
||||
"1" + ("2" + "3")
|
||||
);
|
||||
}
|
||||
expect: {
|
||||
console.log(
|
||||
1 + (2 + 3),
|
||||
1 + (2 + "3"),
|
||||
1 + "2" + 3,
|
||||
1 + "2" + "3",
|
||||
"1" + (2 + 3),
|
||||
"1" + 2 + "3",
|
||||
"1" + "2" + 3,
|
||||
"1" + "2" + "3"
|
||||
);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
concat_3: {
|
||||
options = {};
|
||||
input: {
|
||||
console.log(
|
||||
1 + 2 + (3 + 4 + 5),
|
||||
1 + 2 + (3 + 4 + "5"),
|
||||
1 + 2 + (3 + "4" + 5),
|
||||
1 + 2 + (3 + "4" + "5"),
|
||||
1 + 2 + ("3" + 4 + 5),
|
||||
1 + 2 + ("3" + 4 + "5"),
|
||||
1 + 2 + ("3" + "4" + 5),
|
||||
1 + 2 + ("3" + "4" + "5")
|
||||
);
|
||||
}
|
||||
expect: {
|
||||
console.log(
|
||||
1 + 2 + (3 + 4 + 5),
|
||||
1 + 2 + (3 + 4 + "5"),
|
||||
1 + 2 + (3 + "4") + 5,
|
||||
1 + 2 + (3 + "4") + "5",
|
||||
1 + 2 + "3" + 4 + 5,
|
||||
1 + 2 + "3" + 4 + "5",
|
||||
1 + 2 + "3" + "4" + 5,
|
||||
1 + 2 + "3" + "4" + "5"
|
||||
);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
concat_4: {
|
||||
options = {};
|
||||
input: {
|
||||
console.log(
|
||||
1 + "2" + (3 + 4 + 5),
|
||||
1 + "2" + (3 + 4 + "5"),
|
||||
1 + "2" + (3 + "4" + 5),
|
||||
1 + "2" + (3 + "4" + "5"),
|
||||
1 + "2" + ("3" + 4 + 5),
|
||||
1 + "2" + ("3" + 4 + "5"),
|
||||
1 + "2" + ("3" + "4" + 5),
|
||||
1 + "2" + ("3" + "4" + "5")
|
||||
);
|
||||
}
|
||||
expect: {
|
||||
console.log(
|
||||
1 + "2" + (3 + 4 + 5),
|
||||
1 + "2" + (3 + 4) + "5",
|
||||
1 + "2" + 3 + "4" + 5,
|
||||
1 + "2" + 3 + "4" + "5",
|
||||
1 + "2" + "3" + 4 + 5,
|
||||
1 + "2" + "3" + 4 + "5",
|
||||
1 + "2" + "3" + "4" + 5,
|
||||
1 + "2" + "3" + "4" + "5"
|
||||
);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
concat_5: {
|
||||
options = {};
|
||||
input: {
|
||||
console.log(
|
||||
"1" + 2 + (3 + 4 + 5),
|
||||
"1" + 2 + (3 + 4 + "5"),
|
||||
"1" + 2 + (3 + "4" + 5),
|
||||
"1" + 2 + (3 + "4" + "5"),
|
||||
"1" + 2 + ("3" + 4 + 5),
|
||||
"1" + 2 + ("3" + 4 + "5"),
|
||||
"1" + 2 + ("3" + "4" + 5),
|
||||
"1" + 2 + ("3" + "4" + "5")
|
||||
);
|
||||
}
|
||||
expect: {
|
||||
console.log(
|
||||
"1" + 2 + (3 + 4 + 5),
|
||||
"1" + 2 + (3 + 4) + "5",
|
||||
"1" + 2 + 3 + "4" + 5,
|
||||
"1" + 2 + 3 + "4" + "5",
|
||||
"1" + 2 + "3" + 4 + 5,
|
||||
"1" + 2 + "3" + 4 + "5",
|
||||
"1" + 2 + "3" + "4" + 5,
|
||||
"1" + 2 + "3" + "4" + "5"
|
||||
);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
concat_6: {
|
||||
options = {};
|
||||
input: {
|
||||
console.log(
|
||||
"1" + "2" + (3 + 4 + 5),
|
||||
"1" + "2" + (3 + 4 + "5"),
|
||||
"1" + "2" + (3 + "4" + 5),
|
||||
"1" + "2" + (3 + "4" + "5"),
|
||||
"1" + "2" + ("3" + 4 + 5),
|
||||
"1" + "2" + ("3" + 4 + "5"),
|
||||
"1" + "2" + ("3" + "4" + 5),
|
||||
"1" + "2" + ("3" + "4" + "5")
|
||||
);
|
||||
}
|
||||
expect: {
|
||||
console.log(
|
||||
"1" + "2" + (3 + 4 + 5),
|
||||
"1" + "2" + (3 + 4) + "5",
|
||||
"1" + "2" + 3 + "4" + 5,
|
||||
"1" + "2" + 3 + "4" + "5",
|
||||
"1" + "2" + "3" + 4 + 5,
|
||||
"1" + "2" + "3" + 4 + "5",
|
||||
"1" + "2" + "3" + "4" + 5,
|
||||
"1" + "2" + "3" + "4" + "5"
|
||||
);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
concat_7: {
|
||||
input: {
|
||||
console.log(
|
||||
"" + 1,
|
||||
"" + "1",
|
||||
"" + 1 + 2,
|
||||
"" + 1 + "2",
|
||||
"" + "1" + 2,
|
||||
"" + "1" + "2",
|
||||
"" + (x += "foo")
|
||||
);
|
||||
}
|
||||
expect: {
|
||||
console.log(
|
||||
"" + 1,
|
||||
"1",
|
||||
"" + 1 + 2,
|
||||
1 + "2",
|
||||
"1" + 2,
|
||||
"1" + "2",
|
||||
x += "foo"
|
||||
);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
concat_8: {
|
||||
input: {
|
||||
console.log(
|
||||
1 + "",
|
||||
"1" + "",
|
||||
1 + 2 + "",
|
||||
1 + "2" + "",
|
||||
"1" + 2 + "",
|
||||
"1" + "2" + "",
|
||||
(x += "foo") + ""
|
||||
);
|
||||
}
|
||||
expect: {
|
||||
console.log(
|
||||
1 + "",
|
||||
"1",
|
||||
1 + 2 + "",
|
||||
1 + "2",
|
||||
"1" + 2,
|
||||
"1" + "2",
|
||||
x += "foo"
|
||||
);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
@@ -50,7 +50,8 @@ ifs_3_should_warn: {
|
||||
conditionals : true,
|
||||
dead_code : true,
|
||||
evaluate : true,
|
||||
booleans : true
|
||||
booleans : true,
|
||||
side_effects : true,
|
||||
};
|
||||
input: {
|
||||
var x, y;
|
||||
@@ -135,16 +136,28 @@ ifs_6: {
|
||||
comparisons: true
|
||||
};
|
||||
input: {
|
||||
var x;
|
||||
var x, y;
|
||||
if (!foo && !bar && !baz && !boo) {
|
||||
x = 10;
|
||||
} else {
|
||||
x = 20;
|
||||
}
|
||||
if (y) {
|
||||
x[foo] = 10;
|
||||
} else {
|
||||
x[foo] = 20;
|
||||
}
|
||||
if (foo) {
|
||||
x[bar] = 10;
|
||||
} else {
|
||||
x[bar] = 20;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var x;
|
||||
var x, y;
|
||||
x = foo || bar || baz || boo ? 20 : 10;
|
||||
x[foo] = y ? 10 : 20;
|
||||
foo ? x[bar] = 10 : x[bar] = 20;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,16 +166,24 @@ cond_1: {
|
||||
conditionals: true
|
||||
};
|
||||
input: {
|
||||
var do_something; // if undeclared it's assumed to have side-effects
|
||||
if (some_condition()) {
|
||||
do_something(x);
|
||||
} else {
|
||||
do_something(y);
|
||||
function foo(do_something, some_condition) {
|
||||
if (some_condition) {
|
||||
do_something(x);
|
||||
} else {
|
||||
do_something(y);
|
||||
}
|
||||
if (some_condition) {
|
||||
side_effects(x);
|
||||
} else {
|
||||
side_effects(y);
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var do_something;
|
||||
do_something(some_condition() ? x : y);
|
||||
function foo(do_something, some_condition) {
|
||||
do_something(some_condition ? x : y);
|
||||
some_condition ? side_effects(x) : side_effects(y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,16 +192,18 @@ cond_2: {
|
||||
conditionals: true
|
||||
};
|
||||
input: {
|
||||
var x, FooBar;
|
||||
if (some_condition()) {
|
||||
x = new FooBar(1);
|
||||
} else {
|
||||
x = new FooBar(2);
|
||||
function foo(x, FooBar, some_condition) {
|
||||
if (some_condition) {
|
||||
x = new FooBar(1);
|
||||
} else {
|
||||
x = new FooBar(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var x, FooBar;
|
||||
x = new FooBar(some_condition() ? 1 : 2);
|
||||
function foo(x, FooBar, some_condition) {
|
||||
x = new FooBar(some_condition ? 1 : 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,10 +236,16 @@ cond_4: {
|
||||
} else {
|
||||
do_something();
|
||||
}
|
||||
if (some_condition()) {
|
||||
side_effects();
|
||||
} else {
|
||||
side_effects();
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var do_something;
|
||||
some_condition(), do_something();
|
||||
some_condition(), side_effects();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,7 +279,8 @@ cond_5: {
|
||||
cond_7: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
evaluate : true
|
||||
evaluate : true,
|
||||
side_effects: true,
|
||||
};
|
||||
input: {
|
||||
var x, y, z, a, b;
|
||||
@@ -407,8 +437,8 @@ cond_8: {
|
||||
a = !condition;
|
||||
a = !condition;
|
||||
|
||||
a = condition ? 1 : false;
|
||||
a = condition ? 0 : true;
|
||||
a = !!condition && 1;
|
||||
a = !condition || 0;
|
||||
a = condition ? 1 : 0;
|
||||
}
|
||||
}
|
||||
@@ -490,8 +520,8 @@ cond_8b: {
|
||||
a = !condition;
|
||||
a = !condition;
|
||||
|
||||
a = condition ? 1 : !1;
|
||||
a = condition ? 0 : !0;
|
||||
a = !!condition && 1;
|
||||
a = !condition || 0;
|
||||
a = condition ? 1 : 0;
|
||||
}
|
||||
}
|
||||
@@ -557,7 +587,7 @@ cond_8c: {
|
||||
|
||||
a = !!condition;
|
||||
a = !condition;
|
||||
a = condition() ? !0 : !-3.5;
|
||||
a = !!condition() || !-3.5;
|
||||
|
||||
a = !!condition;
|
||||
a = !!condition;
|
||||
@@ -573,169 +603,101 @@ cond_8c: {
|
||||
a = !condition;
|
||||
a = !condition;
|
||||
|
||||
a = condition ? 1 : false;
|
||||
a = condition ? 0 : true;
|
||||
a = !!condition && 1;
|
||||
a = !condition || 0;
|
||||
a = condition ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
conditional_and: {
|
||||
cond_9: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
evaluate : true
|
||||
};
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
// compress these
|
||||
|
||||
a = true && condition;
|
||||
a = 1 && console.log("a");
|
||||
a = 2 * 3 && 2 * condition;
|
||||
a = 5 == 5 && condition + 3;
|
||||
a = "string" && 4 - condition;
|
||||
a = 5 + "" && condition / 5;
|
||||
a = -4.5 && 6 << condition;
|
||||
a = 6 && 7;
|
||||
|
||||
a = false && condition;
|
||||
a = NaN && console.log("b");
|
||||
a = 0 && console.log("c");
|
||||
a = undefined && 2 * condition;
|
||||
a = null && condition + 3;
|
||||
a = 2 * 3 - 6 && 4 - condition;
|
||||
a = 10 == 7 && condition / 5;
|
||||
a = !"string" && 6 % condition;
|
||||
a = 0 && 7;
|
||||
|
||||
// don't compress these
|
||||
|
||||
a = condition && true;
|
||||
a = console.log("a") && 2;
|
||||
a = 4 - condition && "string";
|
||||
a = 6 << condition && -4.5;
|
||||
|
||||
a = condition && false;
|
||||
a = console.log("b") && NaN;
|
||||
a = console.log("c") && 0;
|
||||
a = 2 * condition && undefined;
|
||||
a = condition + 3 && null;
|
||||
|
||||
function f(x, y) {
|
||||
g() ? x(1) : x(2);
|
||||
x ? (y || x)() : (y || x)();
|
||||
x ? y(a, b) : y(d, b, c);
|
||||
x ? y(a, b, c) : y(a, b, c);
|
||||
x ? y(a, b, c) : y(a, b, f);
|
||||
x ? y(a, b, c) : y(a, e, c);
|
||||
x ? y(a, b, c) : y(a, e, f);
|
||||
x ? y(a, b, c) : y(d, b, c);
|
||||
x ? y(a, b, c) : y(d, b, f);
|
||||
x ? y(a, b, c) : y(d, e, c);
|
||||
x ? y(a, b, c) : y(d, e, f);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
|
||||
a = condition;
|
||||
a = console.log("a");
|
||||
a = 2 * condition;
|
||||
a = condition + 3;
|
||||
a = 4 - condition;
|
||||
a = condition / 5;
|
||||
a = 6 << condition;
|
||||
a = 7;
|
||||
|
||||
a = false;
|
||||
a = NaN;
|
||||
a = 0;
|
||||
a = void 0;
|
||||
a = null;
|
||||
a = 0;
|
||||
a = false;
|
||||
a = false;
|
||||
a = 0;
|
||||
|
||||
a = condition && true;
|
||||
a = console.log("a") && 2;
|
||||
a = 4 - condition && "string";
|
||||
a = 6 << condition && -4.5;
|
||||
|
||||
a = condition && false;
|
||||
a = console.log("b") && NaN;
|
||||
a = console.log("c") && 0;
|
||||
a = 2 * condition && void 0;
|
||||
a = condition + 3 && null;
|
||||
function f(x, y) {
|
||||
g() ? x(1) : x(2);
|
||||
x, (y || x)();
|
||||
x ? y(a, b) : y(d, b, c);
|
||||
x, y(a, b, c);
|
||||
y(a, b, x ? c : f);
|
||||
y(a, x ? b : e, c);
|
||||
x ? y(a, b, c) : y(a, e, f);
|
||||
y(x ? a : d, b, c);
|
||||
x ? y(a, b, c) : y(d, b, f);
|
||||
x ? y(a, b, c) : y(d, e, c);
|
||||
x ? y(a, b, c) : y(d, e, f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
conditional_or: {
|
||||
ternary_boolean_consequent: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
evaluate : true
|
||||
};
|
||||
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
|
||||
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
|
||||
keep_fargs:true, if_return:true, join_vars:true, side_effects:true
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
// compress these
|
||||
|
||||
a = true || condition;
|
||||
a = 1 || console.log("a");
|
||||
a = 2 * 3 || 2 * condition;
|
||||
a = 5 == 5 || condition + 3;
|
||||
a = "string" || 4 - condition;
|
||||
a = 5 + "" || condition / 5;
|
||||
a = -4.5 || 6 << condition;
|
||||
a = 6 || 7;
|
||||
|
||||
a = false || condition;
|
||||
a = 0 || console.log("b");
|
||||
a = NaN || console.log("c");
|
||||
a = undefined || 2 * condition;
|
||||
a = null || condition + 3;
|
||||
a = 2 * 3 - 6 || 4 - condition;
|
||||
a = 10 == 7 || condition / 5;
|
||||
a = !"string" || 6 % condition;
|
||||
a = null || 7;
|
||||
|
||||
a = console.log(undefined && condition || null);
|
||||
a = console.log(undefined || condition && null);
|
||||
|
||||
// don't compress these
|
||||
|
||||
a = condition || true;
|
||||
a = console.log("a") || 2;
|
||||
a = 4 - condition || "string";
|
||||
a = 6 << condition || -4.5;
|
||||
|
||||
a = condition || false;
|
||||
a = console.log("b") || NaN;
|
||||
a = console.log("c") || 0;
|
||||
a = 2 * condition || undefined;
|
||||
a = condition + 3 || null;
|
||||
|
||||
function f1() { return a == b ? true : x; }
|
||||
function f2() { return a == b ? false : x; }
|
||||
function f3() { return a < b ? !0 : x; }
|
||||
function f4() { return a < b ? !1 : x; }
|
||||
function f5() { return c ? !0 : x; }
|
||||
function f6() { return c ? false : x; }
|
||||
function f7() { return !c ? true : x; }
|
||||
function f8() { return !c ? !1 : x; }
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
function f1() { return a == b || x; }
|
||||
function f2() { return a != b && x; }
|
||||
function f3() { return a < b || x; }
|
||||
function f4() { return !(a < b) && x; }
|
||||
function f5() { return !!c || x; }
|
||||
function f6() { return !c && x; }
|
||||
function f7() { return !c || x; }
|
||||
function f8() { return !!c && x; }
|
||||
}
|
||||
}
|
||||
|
||||
a = true;
|
||||
a = 1;
|
||||
a = 6;
|
||||
a = true;
|
||||
a = "string";
|
||||
a = "5";
|
||||
a = -4.5;
|
||||
a = 6;
|
||||
|
||||
a = condition;
|
||||
a = console.log("b");
|
||||
a = console.log("c");
|
||||
a = 2 * condition;
|
||||
a = condition + 3;
|
||||
a = 4 - condition;
|
||||
a = condition / 5;
|
||||
a = 6 % condition;
|
||||
a = 7;
|
||||
|
||||
a = console.log(null);
|
||||
a = console.log(condition && null);
|
||||
|
||||
a = condition || true;
|
||||
a = console.log("a") || 2;
|
||||
a = 4 - condition || "string";
|
||||
a = 6 << condition || -4.5;
|
||||
|
||||
a = condition || false;
|
||||
a = console.log("b") || NaN;
|
||||
a = console.log("c") || 0;
|
||||
a = 2 * condition || void 0;
|
||||
a = condition + 3 || null;
|
||||
ternary_boolean_alternative: {
|
||||
options = {
|
||||
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
|
||||
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
|
||||
keep_fargs:true, if_return:true, join_vars:true, side_effects:true
|
||||
}
|
||||
input: {
|
||||
function f1() { return a == b ? x : true; }
|
||||
function f2() { return a == b ? x : false; }
|
||||
function f3() { return a < b ? x : !0; }
|
||||
function f4() { return a < b ? x : !1; }
|
||||
function f5() { return c ? x : true; }
|
||||
function f6() { return c ? x : !1; }
|
||||
function f7() { return !c ? x : !0; }
|
||||
function f8() { return !c ? x : false; }
|
||||
}
|
||||
expect: {
|
||||
function f1() { return a != b || x; }
|
||||
function f2() { return a == b && x; }
|
||||
function f3() { return !(a < b) || x; }
|
||||
function f4() { return a < b && x; }
|
||||
function f5() { return !c || x; }
|
||||
function f6() { return !!c && x; }
|
||||
function f7() { return !!c || x; }
|
||||
function f8() { return !c && x; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -812,3 +774,432 @@ trivial_boolean_ternary_expressions : {
|
||||
f(!(x >= y));
|
||||
}
|
||||
}
|
||||
|
||||
issue_1154: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
side_effects: true,
|
||||
};
|
||||
input: {
|
||||
function f1(x) { return x ? -1 : -1; }
|
||||
function f2(x) { return x ? +2 : +2; }
|
||||
function f3(x) { return x ? ~3 : ~3; }
|
||||
function f4(x) { return x ? !4 : !4; }
|
||||
function f5(x) { return x ? void 5 : void 5; }
|
||||
function f6(x) { return x ? typeof 6 : typeof 6; }
|
||||
|
||||
function g1() { return g() ? -1 : -1; }
|
||||
function g2() { return g() ? +2 : +2; }
|
||||
function g3() { return g() ? ~3 : ~3; }
|
||||
function g4() { return g() ? !4 : !4; }
|
||||
function g5() { return g() ? void 5 : void 5; }
|
||||
function g6() { return g() ? typeof 6 : typeof 6; }
|
||||
}
|
||||
expect: {
|
||||
function f1(x) { return -1; }
|
||||
function f2(x) { return 2; }
|
||||
function f3(x) { return -4; }
|
||||
function f4(x) { return !1; }
|
||||
function f5(x) { return; }
|
||||
function f6(x) { return "number"; }
|
||||
|
||||
function g1() { return g(), -1; }
|
||||
function g2() { return g(), 2; }
|
||||
function g3() { return g(), -4; }
|
||||
function g4() { return g(), !1; }
|
||||
function g5() { return void g(); }
|
||||
function g6() { return g(), "number"; }
|
||||
}
|
||||
}
|
||||
|
||||
no_evaluate: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
evaluate : false,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function f(b) {
|
||||
a = b ? !0 : !0;
|
||||
a = b ? ~1 : ~1;
|
||||
a = b ? -2 : -2;
|
||||
a = b ? +3 : +3;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(b) {
|
||||
a = !0;
|
||||
a = ~1;
|
||||
a = -2;
|
||||
a = +3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
equality_conditionals_false: {
|
||||
options = {
|
||||
conditionals: false,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b, c) {
|
||||
console.log(
|
||||
a == (b ? a : a),
|
||||
a == (b ? a : c),
|
||||
a != (b ? a : a),
|
||||
a != (b ? a : c),
|
||||
a === (b ? a : a),
|
||||
a === (b ? a : c),
|
||||
a !== (b ? a : a),
|
||||
a !== (b ? a : c)
|
||||
);
|
||||
}
|
||||
f(0, 0, 0);
|
||||
f(0, true, 0);
|
||||
f(1, 2, 3);
|
||||
f(1, null, 3);
|
||||
f(NaN);
|
||||
f(NaN, "foo");
|
||||
}
|
||||
expect: {
|
||||
function f(a, b, c) {
|
||||
console.log(
|
||||
a == (b ? a : a),
|
||||
a == (b ? a : c),
|
||||
a != (b ? a : a),
|
||||
a != (b ? a : c),
|
||||
a === (b ? a : a),
|
||||
a === (b ? a : c),
|
||||
a !== (b ? a : a),
|
||||
a !== (b ? a : c)
|
||||
);
|
||||
}
|
||||
f(0, 0, 0),
|
||||
f(0, true, 0),
|
||||
f(1, 2, 3),
|
||||
f(1, null, 3),
|
||||
f(NaN),
|
||||
f(NaN, "foo");
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
equality_conditionals_true: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b, c) {
|
||||
console.log(
|
||||
a == (b ? a : a),
|
||||
a == (b ? a : c),
|
||||
a != (b ? a : a),
|
||||
a != (b ? a : c),
|
||||
a === (b ? a : a),
|
||||
a === (b ? a : c),
|
||||
a !== (b ? a : a),
|
||||
a !== (b ? a : c)
|
||||
);
|
||||
}
|
||||
f(0, 0, 0);
|
||||
f(0, true, 0);
|
||||
f(1, 2, 3);
|
||||
f(1, null, 3);
|
||||
f(NaN);
|
||||
f(NaN, "foo");
|
||||
}
|
||||
expect: {
|
||||
function f(a, b, c) {
|
||||
console.log(
|
||||
(b, a == a),
|
||||
a == (b ? a : c),
|
||||
(b, a != a),
|
||||
a != (b ? a : c),
|
||||
(b, a === a),
|
||||
a === (b ? a : c),
|
||||
(b, a !== a),
|
||||
a !== (b ? a : c)
|
||||
);
|
||||
}
|
||||
f(0, 0, 0),
|
||||
f(0, true, 0),
|
||||
f(1, 2, 3),
|
||||
f(1, null, 3),
|
||||
f(NaN),
|
||||
f(NaN, "foo");
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1645_1: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
var a = 100, b = 10;
|
||||
(b = a) ? a++ + (b += a) ? b += a : b += a : b ^= a;
|
||||
console.log(a, b);
|
||||
}
|
||||
expect: {
|
||||
var a = 100, b = 10;
|
||||
(b = a) ? (a++ + (b += a), b += a) : b ^= a;
|
||||
console.log(a,b);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1645_2: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
var a = 0;
|
||||
function f() {
|
||||
return a++;
|
||||
}
|
||||
f() ? a += 2 : a += 4;
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = 0;
|
||||
function f(){
|
||||
return a++;
|
||||
}
|
||||
f() ? a += 2 : a += 4;
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
condition_symbol_matches_consequent: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
function foo(x, y) {
|
||||
return x ? x : y;
|
||||
}
|
||||
function bar() {
|
||||
return g ? g : h;
|
||||
}
|
||||
var g = 4;
|
||||
var h = 5;
|
||||
console.log(foo(3, null), foo(0, 7), foo(true, false), bar());
|
||||
}
|
||||
expect: {
|
||||
function foo(x, y) {
|
||||
return x || y;
|
||||
}
|
||||
function bar() {
|
||||
return g || h;
|
||||
}
|
||||
var g = 4;
|
||||
var h = 5;
|
||||
console.log(foo(3, null), foo(0, 7), foo(true, false), bar());
|
||||
}
|
||||
expect_stdout: "3 7 true 4"
|
||||
}
|
||||
|
||||
delete_conditional_1: {
|
||||
options = {
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
console.log(delete (1 ? undefined : x));
|
||||
console.log(delete (1 ? void 0 : x));
|
||||
console.log(delete (1 ? Infinity : x));
|
||||
console.log(delete (1 ? 1 / 0 : x));
|
||||
console.log(delete (1 ? NaN : x));
|
||||
console.log(delete (1 ? 0 / 0 : x));
|
||||
}
|
||||
expect: {
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
delete_conditional_2: {
|
||||
options = {
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
keep_infinity: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
console.log(delete (0 ? x : undefined));
|
||||
console.log(delete (0 ? x : void 0));
|
||||
console.log(delete (0 ? x : Infinity));
|
||||
console.log(delete (0 ? x : 1 / 0));
|
||||
console.log(delete (0 ? x : NaN));
|
||||
console.log(delete (0 ? x : 0 / 0));
|
||||
}
|
||||
expect: {
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_2535_1: {
|
||||
options = {
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
passes: 2,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
if (true || x()) y();
|
||||
if (true && x()) y();
|
||||
if (x() || true) y();
|
||||
if (x() && true) y();
|
||||
if (false || x()) y();
|
||||
if (false && x()) y();
|
||||
if (x() || false) y();
|
||||
if (x() && false) y();
|
||||
}
|
||||
expect: {
|
||||
y();
|
||||
x() && y();
|
||||
(x(), 1) && y();
|
||||
x() && y();
|
||||
x() && y();
|
||||
x() && y();
|
||||
(x(), 0) && y();
|
||||
}
|
||||
}
|
||||
|
||||
issue_2535_2: {
|
||||
options = {
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function x() {}
|
||||
function y() {
|
||||
return "foo";
|
||||
}
|
||||
console.log((x() || true) || y());
|
||||
console.log((y() || true) || x());
|
||||
console.log((x() || true) && y());
|
||||
console.log((y() || true) && x());
|
||||
console.log((x() && true) || y());
|
||||
console.log((y() && true) || x());
|
||||
console.log((x() && true) && y());
|
||||
console.log((y() && true) && x());
|
||||
console.log((x() || false) || y());
|
||||
console.log((y() || false) || x());
|
||||
console.log((x() || false) && y());
|
||||
console.log((y() || false) && x());
|
||||
console.log((x() && false) || y());
|
||||
console.log((y() && false) || x());
|
||||
console.log((x() && false) && y());
|
||||
console.log((y() && false) && x());
|
||||
}
|
||||
expect: {
|
||||
function x() {}
|
||||
function y() {
|
||||
return "foo";
|
||||
}
|
||||
console.log(x() || !0);
|
||||
console.log(y() || !0);
|
||||
console.log((x(), y()));
|
||||
console.log((y(), x()));
|
||||
console.log(!!x() || y());
|
||||
console.log(!!y() || x());
|
||||
console.log(x() && y());
|
||||
console.log(y() && x());
|
||||
console.log(x() || y());
|
||||
console.log(y() || x());
|
||||
console.log(!!x() && y());
|
||||
console.log(!!y() && x());
|
||||
console.log((x(), y()));
|
||||
console.log((y(), x()));
|
||||
console.log(x() && !1);
|
||||
console.log(y() && !1);
|
||||
}
|
||||
expect_stdout: [
|
||||
"true",
|
||||
"foo",
|
||||
"foo",
|
||||
"undefined",
|
||||
"foo",
|
||||
"true",
|
||||
"undefined",
|
||||
"undefined",
|
||||
"foo",
|
||||
"foo",
|
||||
"false",
|
||||
"undefined",
|
||||
"foo",
|
||||
"undefined",
|
||||
"undefined",
|
||||
"false",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2560: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
inline: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function log(x) {
|
||||
console.log(x);
|
||||
}
|
||||
function foo() {
|
||||
return log;
|
||||
}
|
||||
function bar() {
|
||||
if (x !== (x = foo())) {
|
||||
x(1);
|
||||
} else {
|
||||
x(2);
|
||||
}
|
||||
}
|
||||
var x = function() {
|
||||
console.log("init");
|
||||
};
|
||||
bar();
|
||||
bar();
|
||||
}
|
||||
expect: {
|
||||
function log(x) {
|
||||
console.log(x);
|
||||
}
|
||||
function bar() {
|
||||
x !== (x = log) ? x(1) : x(2);
|
||||
}
|
||||
var x = function() {
|
||||
console.log("init");
|
||||
};
|
||||
bar();
|
||||
bar();
|
||||
}
|
||||
expect_stdout: [
|
||||
"1",
|
||||
"2",
|
||||
]
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,24 +1,24 @@
|
||||
drop_console_1: {
|
||||
options = {};
|
||||
input: {
|
||||
console.log('foo');
|
||||
console.log.apply(console, arguments);
|
||||
}
|
||||
expect: {
|
||||
console.log('foo');
|
||||
console.log.apply(console, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
drop_console_1: {
|
||||
options = { drop_console: true };
|
||||
input: {
|
||||
console.log('foo');
|
||||
console.log.apply(console, arguments);
|
||||
}
|
||||
expect: {
|
||||
// with regular compression these will be stripped out as well
|
||||
void 0;
|
||||
void 0;
|
||||
}
|
||||
}
|
||||
drop_console_1: {
|
||||
options = {};
|
||||
input: {
|
||||
console.log('foo');
|
||||
console.log.apply(console, arguments);
|
||||
}
|
||||
expect: {
|
||||
console.log('foo');
|
||||
console.log.apply(console, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
drop_console_2: {
|
||||
options = { drop_console: true };
|
||||
input: {
|
||||
console.log('foo');
|
||||
console.log.apply(console, arguments);
|
||||
}
|
||||
expect: {
|
||||
// with regular compression these will be stripped out as well
|
||||
void 0;
|
||||
void 0;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
1342
test/compress/evaluate.js
Normal file
1342
test/compress/evaluate.js
Normal file
File diff suppressed because it is too large
Load Diff
1449
test/compress/functions.js
Normal file
1449
test/compress/functions.js
Normal file
File diff suppressed because it is too large
Load Diff
199
test/compress/global_defs.js
Normal file
199
test/compress/global_defs.js
Normal file
@@ -0,0 +1,199 @@
|
||||
must_replace: {
|
||||
options = {
|
||||
global_defs: {
|
||||
D: "foo bar",
|
||||
}
|
||||
}
|
||||
input: {
|
||||
console.log(D);
|
||||
}
|
||||
expect: {
|
||||
console.log("foo bar");
|
||||
}
|
||||
}
|
||||
|
||||
keyword: {
|
||||
options = {
|
||||
global_defs: {
|
||||
undefined: 0,
|
||||
NaN: 1,
|
||||
Infinity: 2,
|
||||
},
|
||||
}
|
||||
input: {
|
||||
console.log(undefined, NaN, Infinity);
|
||||
}
|
||||
expect: {
|
||||
console.log(0, 1, 2);
|
||||
}
|
||||
}
|
||||
|
||||
object: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
global_defs: {
|
||||
CONFIG: {
|
||||
DEBUG: [ 0 ],
|
||||
VALUE: 42,
|
||||
},
|
||||
},
|
||||
side_effects: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
function f(CONFIG) {
|
||||
// CONFIG not global - do not replace
|
||||
return CONFIG.VALUE;
|
||||
}
|
||||
function g() {
|
||||
var CONFIG = { VALUE: 1 };
|
||||
// CONFIG not global - do not replace
|
||||
return CONFIG.VALUE;
|
||||
}
|
||||
function h() {
|
||||
return CONFIG.VALUE;
|
||||
}
|
||||
if (CONFIG.DEBUG[0])
|
||||
console.debug("foo");
|
||||
}
|
||||
expect: {
|
||||
function f(CONFIG) {
|
||||
return CONFIG.VALUE;
|
||||
}
|
||||
function g() {
|
||||
var CONFIG = { VALUE: 1 };
|
||||
return CONFIG.VALUE;
|
||||
}
|
||||
function h() {
|
||||
return 42;
|
||||
}
|
||||
if (0)
|
||||
console.debug("foo");
|
||||
}
|
||||
}
|
||||
|
||||
expanded: {
|
||||
options = {
|
||||
global_defs: {
|
||||
"CONFIG.DEBUG": [ 0 ],
|
||||
"CONFIG.VALUE": 42,
|
||||
},
|
||||
}
|
||||
input: {
|
||||
function f(CONFIG) {
|
||||
// CONFIG not global - do not replace
|
||||
return CONFIG.VALUE;
|
||||
}
|
||||
function g() {
|
||||
var CONFIG = { VALUE: 1 };
|
||||
// CONFIG not global - do not replace
|
||||
return CONFIG.VALUE;
|
||||
}
|
||||
function h() {
|
||||
return CONFIG.VALUE;
|
||||
}
|
||||
if (CONFIG.DEBUG[0])
|
||||
console.debug("foo");
|
||||
}
|
||||
expect: {
|
||||
function f(CONFIG) {
|
||||
return CONFIG.VALUE;
|
||||
}
|
||||
function g() {
|
||||
var CONFIG = { VALUE: 1 };
|
||||
return CONFIG.VALUE;
|
||||
}
|
||||
function h() {
|
||||
return 42;
|
||||
}
|
||||
if ([0][0])
|
||||
console.debug("foo");
|
||||
}
|
||||
}
|
||||
|
||||
mixed: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
global_defs: {
|
||||
"CONFIG.VALUE": 42,
|
||||
"FOO.BAR": "moo",
|
||||
},
|
||||
properties: true,
|
||||
}
|
||||
input: {
|
||||
var FOO = { BAR: 0 };
|
||||
console.log(FOO.BAR);
|
||||
console.log(++CONFIG.DEBUG);
|
||||
console.log(++CONFIG.VALUE);
|
||||
console.log(++CONFIG["VAL" + "UE"]);
|
||||
console.log(++DEBUG[CONFIG.VALUE]);
|
||||
CONFIG.VALUE.FOO = "bar";
|
||||
console.log(CONFIG);
|
||||
}
|
||||
expect: {
|
||||
var FOO = { BAR: 0 };
|
||||
console.log("moo");
|
||||
console.log(++CONFIG.DEBUG);
|
||||
console.log(++CONFIG.VALUE);
|
||||
console.log(++CONFIG.VALUE);
|
||||
console.log(++DEBUG[42]);
|
||||
CONFIG.VALUE.FOO = "bar";
|
||||
console.log(CONFIG);
|
||||
}
|
||||
expect_warnings: [
|
||||
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:127,22]',
|
||||
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:128,22]',
|
||||
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:130,8]',
|
||||
]
|
||||
}
|
||||
|
||||
issue_1801: {
|
||||
options = {
|
||||
booleans: true,
|
||||
global_defs: {
|
||||
"CONFIG.FOO.BAR": true,
|
||||
},
|
||||
}
|
||||
input: {
|
||||
console.log(CONFIG.FOO.BAR);
|
||||
}
|
||||
expect: {
|
||||
console.log(!0);
|
||||
}
|
||||
}
|
||||
|
||||
issue_1986: {
|
||||
options = {
|
||||
global_defs: {
|
||||
"@alert": "console.log",
|
||||
},
|
||||
}
|
||||
input: {
|
||||
alert(42);
|
||||
}
|
||||
expect: {
|
||||
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();
|
||||
}
|
||||
}
|
||||
666
test/compress/hoist_props.js
Normal file
666
test/compress/hoist_props.js
Normal file
@@ -0,0 +1,666 @@
|
||||
issue_2377_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
hoist_props: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var obj = {
|
||||
foo: 1,
|
||||
bar: 2,
|
||||
square: function(x) {
|
||||
return x * x;
|
||||
},
|
||||
cube: function(x) {
|
||||
return x * x * x;
|
||||
},
|
||||
};
|
||||
console.log(obj.foo, obj.cube(3));
|
||||
}
|
||||
expect: {
|
||||
var obj_foo = 1, obj_cube = function(x) {
|
||||
return x * x * x;
|
||||
};
|
||||
console.log(obj_foo, obj_cube(3));
|
||||
}
|
||||
expect_stdout: "1 27"
|
||||
}
|
||||
|
||||
issue_2377_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
hoist_props: true,
|
||||
passes: 2,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var obj = {
|
||||
foo: 1,
|
||||
bar: 2,
|
||||
square: function(x) {
|
||||
return x * x;
|
||||
},
|
||||
cube: function(x) {
|
||||
return x * x * x;
|
||||
},
|
||||
};
|
||||
console.log(obj.foo, obj.cube(3));
|
||||
}
|
||||
expect: {
|
||||
console.log(1, (x = 3, x * x * x));
|
||||
var x;
|
||||
}
|
||||
expect_stdout: "1 27"
|
||||
}
|
||||
|
||||
issue_2377_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
hoist_props: true,
|
||||
passes: 4,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var obj = {
|
||||
foo: 1,
|
||||
bar: 2,
|
||||
square: function(x) {
|
||||
return x * x;
|
||||
},
|
||||
cube: function(x) {
|
||||
return x * x * x;
|
||||
},
|
||||
};
|
||||
console.log(obj.foo, obj.cube(3));
|
||||
}
|
||||
expect: {
|
||||
console.log(1, 27);
|
||||
}
|
||||
expect_stdout: "1 27"
|
||||
}
|
||||
|
||||
direct_access_1: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 0;
|
||||
var obj = {
|
||||
a: 1,
|
||||
b: 2,
|
||||
};
|
||||
for (var k in obj) a++;
|
||||
console.log(a, obj.a);
|
||||
}
|
||||
expect: {
|
||||
var a = 0;
|
||||
var obj = {
|
||||
a: 1,
|
||||
b: 2,
|
||||
};
|
||||
for (var k in obj) a++;
|
||||
console.log(a, obj.a);
|
||||
}
|
||||
expect_stdout: "2 1"
|
||||
}
|
||||
|
||||
direct_access_2: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = { a: 1 };
|
||||
var f = function(k) {
|
||||
if (o[k]) return "PASS";
|
||||
};
|
||||
console.log(f("a"));
|
||||
}
|
||||
expect: {
|
||||
var o = { a: 1 };
|
||||
console.log(function(k) {
|
||||
if (o[k]) return "PASS";
|
||||
}("a"));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
direct_access_3: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = { a: 1 };
|
||||
o.b;
|
||||
console.log(o.a);
|
||||
}
|
||||
expect: {
|
||||
var o = { a: 1 };
|
||||
o.b;
|
||||
console.log(o.a);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
single_use: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var obj = {
|
||||
bar: function() {
|
||||
return 42;
|
||||
},
|
||||
};
|
||||
console.log(obj.bar());
|
||||
}
|
||||
expect: {
|
||||
console.log({
|
||||
bar: function() {
|
||||
return 42;
|
||||
},
|
||||
}.bar());
|
||||
}
|
||||
}
|
||||
|
||||
name_collision_1: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var obj_foo = 1;
|
||||
var obj_bar = 2;
|
||||
function f() {
|
||||
var obj = {
|
||||
foo: 3,
|
||||
bar: 4,
|
||||
"b-r": 5,
|
||||
"b+r": 6,
|
||||
"b!r": 7,
|
||||
};
|
||||
console.log(obj_foo, obj.foo, obj.bar, obj["b-r"], obj["b+r"], obj["b!r"]);
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
var obj_foo = 1;
|
||||
var obj_bar = 2;
|
||||
function f() {
|
||||
var obj_foo$0 = 3,
|
||||
obj_bar = 4,
|
||||
obj_b_r = 5,
|
||||
obj_b_r$0 = 6,
|
||||
obj_b_r$1 = 7;
|
||||
console.log(obj_foo, obj_foo$0, obj_bar, obj_b_r, obj_b_r$0, obj_b_r$1);
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect_stdout: "1 3 4 5 6 7"
|
||||
}
|
||||
|
||||
name_collision_2: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
p: 1,
|
||||
0: function(x) {
|
||||
return x;
|
||||
},
|
||||
1: function(x) {
|
||||
return x + 1;
|
||||
}
|
||||
}, o__$0 = 2, o__$1 = 3;
|
||||
console.log(o.p === o.p, o[0](4), o[1](5), o__$0, o__$1);
|
||||
}
|
||||
expect: {
|
||||
var o_p = 1,
|
||||
o__ = function(x) {
|
||||
return x;
|
||||
},
|
||||
o__$2 = function(x) {
|
||||
return x + 1;
|
||||
},
|
||||
o__$0 = 2,
|
||||
o__$1 = 3;
|
||||
console.log(o_p === o_p, o__(4), o__$2(5), o__$0, o__$1);
|
||||
}
|
||||
expect_stdout: "true 4 6 2 3"
|
||||
}
|
||||
|
||||
name_collision_3: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
p: 1,
|
||||
0: function(x) {
|
||||
return x;
|
||||
},
|
||||
1: function(x) {
|
||||
return x + 1;
|
||||
}
|
||||
}, o__$0 = 2, o__$1 = 3;
|
||||
console.log(o.p === o.p, o[0](4), o[1](5));
|
||||
}
|
||||
expect: {
|
||||
var o_p = 1,
|
||||
o__ = function(x) {
|
||||
return x;
|
||||
},
|
||||
o__$2 = function(x) {
|
||||
return x + 1;
|
||||
},
|
||||
o__$0 = 2,
|
||||
o__$1 = 3;
|
||||
console.log(o_p === o_p, o__(4), o__$2(5));
|
||||
}
|
||||
expect_stdout: "true 4 6"
|
||||
}
|
||||
|
||||
contains_this_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_props: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
u: function() {
|
||||
return this === this;
|
||||
},
|
||||
p: 1
|
||||
};
|
||||
console.log(o.p, o.p);
|
||||
}
|
||||
expect: {
|
||||
console.log(1, 1);
|
||||
}
|
||||
expect_stdout: "1 1"
|
||||
}
|
||||
|
||||
contains_this_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_props: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
u: function() {
|
||||
return this === this;
|
||||
},
|
||||
p: 1
|
||||
};
|
||||
console.log(o.p, o.p, o.u);
|
||||
}
|
||||
expect: {
|
||||
console.log(1, 1, function() {
|
||||
return this === this;
|
||||
});
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
contains_this_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_props: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
u: function() {
|
||||
return this === this;
|
||||
},
|
||||
p: 1
|
||||
};
|
||||
console.log(o.p, o.p, o.u());
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
u: function() {
|
||||
return this === this;
|
||||
},
|
||||
p: 1
|
||||
};
|
||||
console.log(o.p, o.p, o.u());
|
||||
}
|
||||
expect_stdout: "1 1 true"
|
||||
}
|
||||
|
||||
new_this: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_props: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
a: 1,
|
||||
b: 2,
|
||||
f: function(a) {
|
||||
this.b = a;
|
||||
}
|
||||
};
|
||||
console.log(new o.f(o.a).b, o.b);
|
||||
}
|
||||
expect: {
|
||||
console.log(new function(a) {
|
||||
this.b = a;
|
||||
}(1).b, 2);
|
||||
}
|
||||
expect_stdout: "1 2"
|
||||
}
|
||||
|
||||
issue_2473_1: {
|
||||
options = {
|
||||
hoist_props: false,
|
||||
reduce_vars: true,
|
||||
top_retain: [ "x", "y" ],
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var x = {};
|
||||
var y = [];
|
||||
var z = {};
|
||||
}
|
||||
expect: {
|
||||
var x = {};
|
||||
var y = [];
|
||||
}
|
||||
}
|
||||
|
||||
issue_2473_2: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
top_retain: [ "x", "y" ],
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var x = {};
|
||||
var y = [];
|
||||
var z = {};
|
||||
}
|
||||
expect: {
|
||||
var x = {};
|
||||
var y = [];
|
||||
}
|
||||
}
|
||||
|
||||
issue_2473_3: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
top_retain: "o",
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
a: 1,
|
||||
b: 2,
|
||||
};
|
||||
console.log(o.a, o.b);
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
a: 1,
|
||||
b: 2,
|
||||
};
|
||||
console.log(o.a, o.b);
|
||||
}
|
||||
expect_stdout: "1 2"
|
||||
}
|
||||
|
||||
issue_2473_4: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
top_retain: "o",
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
var o = {
|
||||
a: 1,
|
||||
b: 2,
|
||||
};
|
||||
console.log(o.a, o.b);
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
var o_a = 1, o_b = 2;
|
||||
console.log(o_a, o_b);
|
||||
})();
|
||||
}
|
||||
expect_stdout: "1 2"
|
||||
}
|
||||
|
||||
issue_2508_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
a: [ 1 ],
|
||||
f: function(x) {
|
||||
console.log(x);
|
||||
}
|
||||
};
|
||||
o.f(o.a);
|
||||
}
|
||||
expect: {
|
||||
(function(x) {
|
||||
console.log(x);
|
||||
})([ 1 ]);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_2508_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
a: { b: 2 },
|
||||
f: function(x) {
|
||||
console.log(x);
|
||||
}
|
||||
};
|
||||
o.f(o.a);
|
||||
}
|
||||
expect: {
|
||||
(function(x) {
|
||||
console.log(x);
|
||||
})({ b: 2 });
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_2508_3: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
a: [ o ],
|
||||
f: function(x) {
|
||||
console.log(x);
|
||||
}
|
||||
};
|
||||
o.f(o.a);
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
a: [ o ],
|
||||
f: function(x) {
|
||||
console.log(x);
|
||||
}
|
||||
};
|
||||
o.f(o.a);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_2508_4: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
a: { b: o },
|
||||
f: function(x) {
|
||||
console.log(x);
|
||||
}
|
||||
};
|
||||
o.f(o.a);
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
a: { b: o },
|
||||
f: function(x) {
|
||||
console.log(x);
|
||||
}
|
||||
};
|
||||
o.f(o.a);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_2508_5: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
f: function(x) {
|
||||
console.log(x);
|
||||
}
|
||||
};
|
||||
o.f(o.f);
|
||||
}
|
||||
expect: {
|
||||
var o_f = function(x) {
|
||||
console.log(x);
|
||||
};
|
||||
o_f(o_f);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_2519: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function testFunc() {
|
||||
var dimensions = {
|
||||
minX: 5,
|
||||
maxX: 6,
|
||||
};
|
||||
var scale = 1;
|
||||
var d = {
|
||||
x: (dimensions.maxX + dimensions.minX) / 2,
|
||||
};
|
||||
return d.x * scale;
|
||||
}
|
||||
console.log(testFunc());
|
||||
}
|
||||
expect: {
|
||||
function testFunc() {
|
||||
return 1 * ((6 + 5) / 2);
|
||||
}
|
||||
console.log(testFunc());
|
||||
}
|
||||
expect_stdout: "5.5"
|
||||
}
|
||||
111
test/compress/hoist_vars.js
Normal file
111
test/compress/hoist_vars.js
Normal file
@@ -0,0 +1,111 @@
|
||||
statements: {
|
||||
options = {
|
||||
hoist_funs: false,
|
||||
hoist_vars: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
var a = 1;
|
||||
var b = 2;
|
||||
var c = 3;
|
||||
function g() {}
|
||||
return g(a, b, c);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
var a = 1, b = 2, c = 3;
|
||||
function g() {}
|
||||
return g(a, b, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
statements_funs: {
|
||||
options = {
|
||||
hoist_funs: true,
|
||||
hoist_vars: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
var a = 1;
|
||||
var b = 2;
|
||||
var c = 3;
|
||||
function g() {}
|
||||
return g(a, b, c);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
function g() {}
|
||||
var a = 1, b = 2, c = 3;
|
||||
return g(a, b, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sequences: {
|
||||
options = {
|
||||
hoist_funs: false,
|
||||
hoist_vars: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
var a = 1, b = 2;
|
||||
function g() {}
|
||||
var c = 3;
|
||||
return g(a, b, c);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
var c, a = 1, b = 2;
|
||||
function g() {}
|
||||
c = 3;
|
||||
return g(a, b, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sequences_funs: {
|
||||
options = {
|
||||
hoist_funs: true,
|
||||
hoist_vars: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
var a = 1, b = 2;
|
||||
function g() {}
|
||||
var c = 3;
|
||||
return g(a, b, c);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
function g() {}
|
||||
var a = 1, b = 2, c = 3;
|
||||
return g(a, b, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -47,22 +47,6 @@ html_comment_in_greater_than_or_equal: {
|
||||
expect_exact: "function f(a,b){return a-- >=b}";
|
||||
}
|
||||
|
||||
html_comment_in_right_shift_assign: {
|
||||
input: {
|
||||
// Note: illegal javascript
|
||||
function f(a, b) { return a-- >>= b; }
|
||||
}
|
||||
expect_exact: "function f(a,b){return a-- >>=b}";
|
||||
}
|
||||
|
||||
html_comment_in_zero_fill_right_shift_assign: {
|
||||
input: {
|
||||
// Note: illegal javascript
|
||||
function f(a, b) { return a-- >>>= b; }
|
||||
}
|
||||
expect_exact: "function f(a,b){return a-- >>>=b}";
|
||||
}
|
||||
|
||||
html_comment_in_string_literal: {
|
||||
input: {
|
||||
function f() { return "<!--HTML-->comment in<!--string literal-->"; }
|
||||
|
||||
328
test/compress/if_return.js
Normal file
328
test/compress/if_return.js
Normal file
@@ -0,0 +1,328 @@
|
||||
if_return_1: {
|
||||
options = {
|
||||
if_return : true,
|
||||
sequences : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
side_effects : true,
|
||||
dead_code : true,
|
||||
}
|
||||
input: {
|
||||
function f(x) {
|
||||
if (x) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(x){if(x)return!0}
|
||||
}
|
||||
}
|
||||
|
||||
if_return_2: {
|
||||
options = {
|
||||
if_return : true,
|
||||
sequences : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
side_effects : true,
|
||||
dead_code : true,
|
||||
}
|
||||
input: {
|
||||
function f(x, y) {
|
||||
if (x)
|
||||
return 3;
|
||||
if (y)
|
||||
return c();
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(x,y){return x?3:y?c():void 0}
|
||||
}
|
||||
}
|
||||
|
||||
if_return_3: {
|
||||
options = {
|
||||
if_return : true,
|
||||
sequences : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
side_effects : true,
|
||||
dead_code : true,
|
||||
}
|
||||
input: {
|
||||
function f(x) {
|
||||
a();
|
||||
if (x) {
|
||||
b();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(x){if(a(),x)return b(),!1}
|
||||
}
|
||||
}
|
||||
|
||||
if_return_4: {
|
||||
options = {
|
||||
if_return : true,
|
||||
sequences : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
side_effects : true,
|
||||
dead_code : true,
|
||||
}
|
||||
input: {
|
||||
function f(x, y) {
|
||||
a();
|
||||
if (x) return 3;
|
||||
b();
|
||||
if (y) return c();
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(x,y){return a(),x?3:(b(),y?c():void 0)}
|
||||
}
|
||||
}
|
||||
|
||||
if_return_5: {
|
||||
options = {
|
||||
if_return : true,
|
||||
sequences : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
side_effects : true,
|
||||
dead_code : true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
if (x)
|
||||
return;
|
||||
return 7;
|
||||
if (y)
|
||||
return j;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(){if(!x)return 7}
|
||||
}
|
||||
}
|
||||
|
||||
if_return_6: {
|
||||
options = {
|
||||
if_return : true,
|
||||
sequences : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
side_effects : true,
|
||||
dead_code : true,
|
||||
}
|
||||
input: {
|
||||
function f(x) {
|
||||
return x ? true : void 0;
|
||||
return y;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
// suboptimal
|
||||
function f(x){return!!x||void 0}
|
||||
}
|
||||
}
|
||||
|
||||
if_return_7: {
|
||||
options = {
|
||||
if_return : true,
|
||||
sequences : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
side_effects : true,
|
||||
dead_code : true,
|
||||
}
|
||||
input: {
|
||||
function f(x) {
|
||||
if (x) {
|
||||
return true;
|
||||
}
|
||||
foo();
|
||||
bar();
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(x){if(x)return!0;foo(),bar()}
|
||||
}
|
||||
}
|
||||
|
||||
if_return_8: {
|
||||
options = {
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
conditionals: true,
|
||||
side_effects : true,
|
||||
}
|
||||
input: {
|
||||
function f(e) {
|
||||
if (2 == e) return foo();
|
||||
if (3 == e) return bar();
|
||||
if (4 == e) return baz();
|
||||
fail(e);
|
||||
}
|
||||
|
||||
function g(e) {
|
||||
if (a(e)) return foo();
|
||||
if (b(e)) return bar();
|
||||
if (c(e)) return baz();
|
||||
fail(e);
|
||||
}
|
||||
|
||||
function h(e) {
|
||||
if (a(e)) return foo();
|
||||
else if (b(e)) return bar();
|
||||
else if (c(e)) return baz();
|
||||
else fail(e);
|
||||
}
|
||||
|
||||
function i(e) {
|
||||
if (a(e)) return foo();
|
||||
else if (b(e)) return bar();
|
||||
else if (c(e)) return baz();
|
||||
fail(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(e){return 2==e?foo():3==e?bar():4==e?baz():void fail(e)}
|
||||
function g(e){return a(e)?foo():b(e)?bar():c(e)?baz():void fail(e)}
|
||||
function h(e){return a(e)?foo():b(e)?bar():c(e)?baz():void fail(e)}
|
||||
function i(e){return a(e)?foo():b(e)?bar():c(e)?baz():void fail(e)}
|
||||
}
|
||||
}
|
||||
|
||||
issue_1089: {
|
||||
options = {
|
||||
if_return : true,
|
||||
sequences : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
side_effects : true,
|
||||
dead_code : true,
|
||||
}
|
||||
input: {
|
||||
function x() {
|
||||
var f = document.getElementById("fname");
|
||||
if (f.files[0].size > 12345) {
|
||||
alert("alert");
|
||||
f.focus();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function x() {
|
||||
var f = document.getElementById("fname");
|
||||
if (f.files[0].size > 12345)
|
||||
return alert("alert"), f.focus(), !1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_1437: {
|
||||
options = {
|
||||
if_return : true,
|
||||
sequences : true,
|
||||
conditionals : false
|
||||
}
|
||||
input: {
|
||||
function x() {
|
||||
if (a())
|
||||
return b();
|
||||
if (c())
|
||||
return d();
|
||||
else
|
||||
e();
|
||||
f();
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function x() {
|
||||
if (a())
|
||||
return b();
|
||||
if (c())
|
||||
return d();
|
||||
else
|
||||
e()
|
||||
f();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_1437_conditionals: {
|
||||
options = {
|
||||
conditionals : true,
|
||||
if_return : true,
|
||||
sequences : true
|
||||
}
|
||||
input: {
|
||||
function x() {
|
||||
if (a())
|
||||
return b();
|
||||
if (c())
|
||||
return d();
|
||||
else
|
||||
e();
|
||||
f();
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function x() {
|
||||
return a() ? b() : c() ? d() : (e(), f(), void 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_512: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function a() {
|
||||
if (b()) {
|
||||
c();
|
||||
return;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function a() {
|
||||
if (!b()) throw e;
|
||||
c();
|
||||
}
|
||||
}
|
||||
}
|
||||
256
test/compress/issue-1034.js
Normal file
256
test/compress/issue-1034.js
Normal file
@@ -0,0 +1,256 @@
|
||||
non_hoisted_function_after_return: {
|
||||
options = {
|
||||
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
|
||||
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
|
||||
if_return: true, join_vars: true, side_effects: true
|
||||
}
|
||||
input: {
|
||||
function foo(x) {
|
||||
if (x) {
|
||||
return bar();
|
||||
not_called1();
|
||||
} else {
|
||||
return baz();
|
||||
not_called2();
|
||||
}
|
||||
function bar() { return 7; }
|
||||
return not_reached;
|
||||
function UnusedFunction() {}
|
||||
function baz() { return 8; }
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function foo(x) {
|
||||
return x ? bar() : baz();
|
||||
function bar() { return 7 }
|
||||
function baz() { return 8 }
|
||||
}
|
||||
}
|
||||
expect_warnings: [
|
||||
'WARN: Dropping unreachable code [test/compress/issue-1034.js:11,16]',
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:14,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:17,12]",
|
||||
"WARN: Dropping unused function UnusedFunction [test/compress/issue-1034.js:18,21]"
|
||||
]
|
||||
}
|
||||
|
||||
non_hoisted_function_after_return_2a: {
|
||||
options = {
|
||||
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
|
||||
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
|
||||
if_return: true, join_vars: true, side_effects: true,
|
||||
collapse_vars: false, passes: 2, warnings: "verbose"
|
||||
}
|
||||
input: {
|
||||
function foo(x) {
|
||||
if (x) {
|
||||
return bar(1);
|
||||
var a = not_called(1);
|
||||
} else {
|
||||
return bar(2);
|
||||
var b = not_called(2);
|
||||
}
|
||||
var c = bar(3);
|
||||
function bar(x) { return 7 - x; }
|
||||
function nope() {}
|
||||
return b || c;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function foo(x) {
|
||||
return bar(x ? 1 : 2);
|
||||
function bar(x) {
|
||||
return 7 - x;
|
||||
}
|
||||
}
|
||||
}
|
||||
expect_warnings: [
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:48,16]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:48,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:51,16]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:51,16]",
|
||||
"WARN: Dropping unused variable a [test/compress/issue-1034.js:48,20]",
|
||||
"WARN: Dropping unused function nope [test/compress/issue-1034.js:55,21]",
|
||||
"WARN: pass 0: last_count: Infinity, count: 37",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:53,12]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:53,12]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:56,12]",
|
||||
"WARN: Dropping unused variable b [test/compress/issue-1034.js:51,20]",
|
||||
"WARN: Dropping unused variable c [test/compress/issue-1034.js:53,16]",
|
||||
"WARN: pass 1: last_count: 37, count: 18",
|
||||
]
|
||||
}
|
||||
|
||||
non_hoisted_function_after_return_2b: {
|
||||
options = {
|
||||
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
|
||||
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
|
||||
if_return: true, join_vars: true, side_effects: true,
|
||||
collapse_vars: false
|
||||
}
|
||||
input: {
|
||||
function foo(x) {
|
||||
if (x) {
|
||||
return bar(1);
|
||||
} else {
|
||||
return bar(2);
|
||||
var b;
|
||||
}
|
||||
var c = bar(3);
|
||||
function bar(x) {
|
||||
return 7 - x;
|
||||
}
|
||||
return b || c;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function foo(x) {
|
||||
return bar(x ? 1 : 2);
|
||||
function bar(x) { return 7 - x; }
|
||||
}
|
||||
}
|
||||
expect_warnings: [
|
||||
// duplicate warnings no longer emitted
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:97,16]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:97,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:99,12]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:99,12]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:103,12]",
|
||||
]
|
||||
}
|
||||
|
||||
non_hoisted_function_after_return_strict: {
|
||||
options = {
|
||||
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
|
||||
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
|
||||
if_return: true, join_vars: true, side_effects: true
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function foo(x) {
|
||||
if (x) {
|
||||
return bar();
|
||||
not_called1();
|
||||
} else {
|
||||
return baz();
|
||||
not_called2();
|
||||
}
|
||||
function bar() { return 7; }
|
||||
return not_reached;
|
||||
function UnusedFunction() {}
|
||||
function baz() { return 8; }
|
||||
}
|
||||
console.log(foo(0), foo(1));
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function foo(x) {
|
||||
return x ? bar() : baz();
|
||||
function bar() { return 7 }
|
||||
function baz() { return 8 }
|
||||
}
|
||||
console.log(foo(0), foo(1));
|
||||
}
|
||||
expect_stdout: "8 7"
|
||||
expect_warnings: [
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:133,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:136,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:139,12]",
|
||||
"WARN: Dropping unused function UnusedFunction [test/compress/issue-1034.js:140,21]",
|
||||
]
|
||||
}
|
||||
|
||||
non_hoisted_function_after_return_2a_strict: {
|
||||
options = {
|
||||
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
|
||||
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
|
||||
if_return: true, join_vars: true, side_effects: true,
|
||||
collapse_vars: false, passes: 2, warnings: "verbose"
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function foo(x) {
|
||||
if (x) {
|
||||
return bar(1);
|
||||
var a = not_called(1);
|
||||
} else {
|
||||
return bar(2);
|
||||
var b = not_called(2);
|
||||
}
|
||||
var c = bar(3);
|
||||
function bar(x) { return 7 - x; }
|
||||
function nope() {}
|
||||
return b || c;
|
||||
}
|
||||
console.log(foo(0), foo(1));
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function foo(x) {
|
||||
return bar(x ? 1 : 2);
|
||||
function bar(x) {
|
||||
return 7 - x;
|
||||
}
|
||||
}
|
||||
console.log(foo(0), foo(1));
|
||||
}
|
||||
expect_stdout: "5 6"
|
||||
expect_warnings: [
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:175,16]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:175,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:178,16]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:178,16]",
|
||||
"WARN: Dropping unused variable a [test/compress/issue-1034.js:175,20]",
|
||||
"WARN: Dropping unused function nope [test/compress/issue-1034.js:182,21]",
|
||||
"WARN: pass 0: last_count: Infinity, count: 48",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:180,12]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:180,12]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:183,12]",
|
||||
"WARN: Dropping unused variable b [test/compress/issue-1034.js:178,20]",
|
||||
"WARN: Dropping unused variable c [test/compress/issue-1034.js:180,16]",
|
||||
"WARN: pass 1: last_count: 48, count: 29",
|
||||
]
|
||||
}
|
||||
|
||||
non_hoisted_function_after_return_2b_strict: {
|
||||
options = {
|
||||
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
|
||||
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
|
||||
if_return: true, join_vars: true, side_effects: true,
|
||||
collapse_vars: false
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function foo(x) {
|
||||
if (x) {
|
||||
return bar(1);
|
||||
} else {
|
||||
return bar(2);
|
||||
var b;
|
||||
}
|
||||
var c = bar(3);
|
||||
function bar(x) {
|
||||
return 7 - x;
|
||||
}
|
||||
return b || c;
|
||||
}
|
||||
console.log(foo(0), foo(1));
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function foo(x) {
|
||||
return bar(x ? 1 : 2);
|
||||
function bar(x) { return 7 - x; }
|
||||
}
|
||||
console.log(foo(0), foo(1));
|
||||
}
|
||||
expect_stdout: "5 6"
|
||||
expect_warnings: [
|
||||
// duplicate warnings no longer emitted
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:229,16]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:229,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:231,12]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:231,12]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:235,12]",
|
||||
]
|
||||
}
|
||||
30
test/compress/issue-1041.js
Normal file
30
test/compress/issue-1041.js
Normal file
@@ -0,0 +1,30 @@
|
||||
const_pragma: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
};
|
||||
|
||||
input: {
|
||||
/** @const */ var goog = goog || {};
|
||||
}
|
||||
expect: {
|
||||
var goog = goog || {};
|
||||
}
|
||||
}
|
||||
|
||||
// for completeness' sake
|
||||
not_const: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
};
|
||||
|
||||
input: {
|
||||
var goog = goog || {};
|
||||
}
|
||||
expect: {
|
||||
var goog = goog || {};
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
typeof_eq_undefined: {
|
||||
options = {
|
||||
comparisons: true
|
||||
};
|
||||
input: { a = typeof b.c != "undefined" }
|
||||
expect: { a = "undefined" != typeof b.c }
|
||||
}
|
||||
|
||||
typeof_eq_undefined_unsafe: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
unsafe: true
|
||||
};
|
||||
input: { a = typeof b.c != "undefined" }
|
||||
expect: { a = void 0 !== b.c }
|
||||
}
|
||||
|
||||
typeof_eq_undefined_unsafe2: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
unsafe: true
|
||||
};
|
||||
input: { a = "undefined" != typeof b.c }
|
||||
expect: { a = void 0 !== b.c }
|
||||
}
|
||||
164
test/compress/issue-1052.js
Normal file
164
test/compress/issue-1052.js
Normal file
@@ -0,0 +1,164 @@
|
||||
multiple_functions: {
|
||||
options = {
|
||||
hoist_funs: false,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
( function() {
|
||||
if ( !window ) {
|
||||
return;
|
||||
}
|
||||
function f() {}
|
||||
function g() {}
|
||||
} )();
|
||||
}
|
||||
expect: {
|
||||
( function() {
|
||||
// NOTE: other compression steps will reduce this
|
||||
// down to just `window`.
|
||||
if ( window );
|
||||
function f() {}
|
||||
function g() {}
|
||||
} )();
|
||||
}
|
||||
}
|
||||
|
||||
single_function: {
|
||||
options = {
|
||||
hoist_funs: false,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
( function() {
|
||||
if ( !window ) {
|
||||
return;
|
||||
}
|
||||
function f() {}
|
||||
} )();
|
||||
}
|
||||
expect: {
|
||||
( function() {
|
||||
if ( window );
|
||||
function f() {}
|
||||
} )();
|
||||
}
|
||||
}
|
||||
|
||||
deeply_nested: {
|
||||
options = {
|
||||
hoist_funs: false,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
( function() {
|
||||
if ( !window ) {
|
||||
return;
|
||||
}
|
||||
function f() {}
|
||||
function g() {}
|
||||
if ( !document ) {
|
||||
return;
|
||||
}
|
||||
function h() {}
|
||||
} )();
|
||||
}
|
||||
expect: {
|
||||
( function() {
|
||||
// NOTE: other compression steps will reduce this
|
||||
// down to just `window`.
|
||||
if ( window )
|
||||
if (document);
|
||||
function f() {}
|
||||
function g() {}
|
||||
function h() {}
|
||||
} )();
|
||||
}
|
||||
}
|
||||
|
||||
not_hoisted_when_already_nested: {
|
||||
options = {
|
||||
hoist_funs: false,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
( function() {
|
||||
if ( !window ) {
|
||||
return;
|
||||
}
|
||||
if ( foo ) function f() {}
|
||||
} )();
|
||||
}
|
||||
expect: {
|
||||
( function() {
|
||||
if ( window )
|
||||
if ( foo ) function f() {}
|
||||
} )();
|
||||
}
|
||||
}
|
||||
|
||||
defun_if_return: {
|
||||
options = {
|
||||
hoist_funs: false,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
function e() {
|
||||
function f() {}
|
||||
if (!window) return;
|
||||
else function g() {}
|
||||
function h() {}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function e() {
|
||||
function f() {}
|
||||
if (window) function g() {}
|
||||
function h() {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defun_hoist_funs: {
|
||||
options = {
|
||||
hoist_funs: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
function e() {
|
||||
function f() {}
|
||||
if (!window) return;
|
||||
else function g() {}
|
||||
function h() {}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function e() {
|
||||
function f() {}
|
||||
function g() {}
|
||||
function h() {}
|
||||
if (window);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defun_else_if_return: {
|
||||
options = {
|
||||
hoist_funs: false,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
function e() {
|
||||
function f() {}
|
||||
if (window) function g() {}
|
||||
else return;
|
||||
function h() {}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function e() {
|
||||
function f() {}
|
||||
if (window) function g() {}
|
||||
function h() {}
|
||||
}
|
||||
}
|
||||
}
|
||||
303
test/compress/issue-1105.js
Normal file
303
test/compress/issue-1105.js
Normal file
@@ -0,0 +1,303 @@
|
||||
with_in_global_scope: {
|
||||
options = {
|
||||
unused: true
|
||||
}
|
||||
input: {
|
||||
var o = 42;
|
||||
with(o) {
|
||||
var foo = 'something'
|
||||
}
|
||||
doSomething(o);
|
||||
}
|
||||
expect: {
|
||||
var o=42;
|
||||
with(o)
|
||||
var foo = "something";
|
||||
doSomething(o);
|
||||
}
|
||||
}
|
||||
with_in_function_scope: {
|
||||
options = {
|
||||
unused: true
|
||||
}
|
||||
input: {
|
||||
function foo() {
|
||||
var o = 42;
|
||||
with(o) {
|
||||
var foo = "something"
|
||||
}
|
||||
doSomething(o);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function foo() {
|
||||
var o=42;
|
||||
with(o)
|
||||
var foo = "something";
|
||||
doSomething(o)
|
||||
}
|
||||
}
|
||||
}
|
||||
compress_with_with_in_other_scope: {
|
||||
options = {
|
||||
unused: true
|
||||
}
|
||||
input: {
|
||||
function foo() {
|
||||
var o = 42;
|
||||
with(o) {
|
||||
var foo = "something"
|
||||
}
|
||||
doSomething(o);
|
||||
}
|
||||
function bar() {
|
||||
var unused = 42;
|
||||
return something();
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function foo() {
|
||||
var o = 42;
|
||||
with(o)
|
||||
var foo = "something";
|
||||
doSomething(o)
|
||||
}
|
||||
function bar() {
|
||||
return something()
|
||||
}
|
||||
}
|
||||
}
|
||||
with_using_existing_variable_outside_scope: {
|
||||
options = {
|
||||
unused: true
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
var o = {};
|
||||
var unused = {}; // Doesn't get removed because upper scope uses with
|
||||
function foo() {
|
||||
with(o) {
|
||||
var foo = "something"
|
||||
}
|
||||
doSomething(o);
|
||||
}
|
||||
foo()
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
var o = {};
|
||||
var unused = {};
|
||||
function foo() {
|
||||
with(o)
|
||||
var foo = "something";
|
||||
doSomething(o)
|
||||
}
|
||||
foo()
|
||||
}
|
||||
}
|
||||
}
|
||||
check_drop_unused_in_peer_function: {
|
||||
options = {
|
||||
unused: true
|
||||
}
|
||||
input: {
|
||||
function outer() {
|
||||
var o = {};
|
||||
var unused = {}; // should be kept
|
||||
function foo() { // should be kept
|
||||
function not_in_use() {
|
||||
var nested_unused = "foo"; // should be dropped
|
||||
return 24;
|
||||
}
|
||||
var unused = {}; // should be kept
|
||||
with (o) {
|
||||
var foo = "something";
|
||||
}
|
||||
doSomething(o);
|
||||
}
|
||||
function bar() {
|
||||
var unused = {}; // should be dropped
|
||||
doSomethingElse();
|
||||
}
|
||||
foo();
|
||||
bar();
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function outer() {
|
||||
var o = {};
|
||||
var unused = {}; // should be kept
|
||||
function foo() { // should be kept
|
||||
function not_in_use() {
|
||||
return 24;
|
||||
}
|
||||
var unused = {}; // should be kept
|
||||
with (o)
|
||||
var foo = "something";
|
||||
doSomething(o);
|
||||
}
|
||||
function bar() {
|
||||
doSomethingElse();
|
||||
}
|
||||
foo();
|
||||
bar();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Infinity_not_in_with_scope: {
|
||||
options = {
|
||||
unused: true
|
||||
}
|
||||
input: {
|
||||
var o = { Infinity: 'oInfinity' };
|
||||
var vInfinity = "Infinity";
|
||||
vInfinity = Infinity;
|
||||
}
|
||||
expect: {
|
||||
var o = { Infinity: 'oInfinity' }
|
||||
var vInfinity = "Infinity"
|
||||
vInfinity = 1/0
|
||||
}
|
||||
}
|
||||
|
||||
Infinity_in_with_scope: {
|
||||
options = {
|
||||
unused: true
|
||||
}
|
||||
input: {
|
||||
var o = { Infinity: 'oInfinity' };
|
||||
var vInfinity = "Infinity";
|
||||
with (o) { vInfinity = Infinity; }
|
||||
}
|
||||
expect: {
|
||||
var o = { Infinity: 'oInfinity' }
|
||||
var vInfinity = "Infinity"
|
||||
with (o) vInfinity = Infinity
|
||||
}
|
||||
}
|
||||
|
||||
assorted_Infinity_NaN_undefined_in_with_scope: {
|
||||
options = {
|
||||
unused: true,
|
||||
evaluate: true,
|
||||
dead_code: true,
|
||||
conditionals: true,
|
||||
comparisons: true,
|
||||
booleans: true,
|
||||
hoist_funs: true,
|
||||
keep_fargs: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
side_effects: true,
|
||||
sequences: false,
|
||||
keep_infinity: false,
|
||||
}
|
||||
input: {
|
||||
var f = console.log;
|
||||
var o = {
|
||||
undefined : 3,
|
||||
NaN : 4,
|
||||
Infinity : 5,
|
||||
};
|
||||
if (o) {
|
||||
f(undefined, void 0);
|
||||
f(NaN, 0/0);
|
||||
f(Infinity, 1/0);
|
||||
f(-Infinity, -(1/0));
|
||||
f(2 + 7 + undefined, 2 + 7 + void 0);
|
||||
}
|
||||
with (o) {
|
||||
f(undefined, void 0);
|
||||
f(NaN, 0/0);
|
||||
f(Infinity, 1/0);
|
||||
f(-Infinity, -(1/0));
|
||||
f(2 + 7 + undefined, 2 + 7 + void 0);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var f = console.log, o = {
|
||||
undefined : 3,
|
||||
NaN : 4,
|
||||
Infinity : 5
|
||||
};
|
||||
if (o) {
|
||||
f(void 0, void 0);
|
||||
f(NaN, NaN);
|
||||
f(1/0, 1/0);
|
||||
f(-1/0, -1/0);
|
||||
f(NaN, NaN);
|
||||
}
|
||||
with (o) {
|
||||
f(undefined, void 0);
|
||||
f(NaN, 0/0);
|
||||
f(Infinity, 1/0);
|
||||
f(-Infinity, -1/0);
|
||||
f(9 + undefined, 9 + void 0);
|
||||
}
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
assorted_Infinity_NaN_undefined_in_with_scope_keep_infinity: {
|
||||
options = {
|
||||
unused: true,
|
||||
evaluate: true,
|
||||
dead_code: true,
|
||||
conditionals: true,
|
||||
comparisons: true,
|
||||
booleans: true,
|
||||
hoist_funs: true,
|
||||
keep_fargs: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
side_effects: true,
|
||||
sequences: false,
|
||||
keep_infinity: true,
|
||||
}
|
||||
input: {
|
||||
var f = console.log;
|
||||
var o = {
|
||||
undefined : 3,
|
||||
NaN : 4,
|
||||
Infinity : 5,
|
||||
};
|
||||
if (o) {
|
||||
f(undefined, void 0);
|
||||
f(NaN, 0/0);
|
||||
f(Infinity, 1/0);
|
||||
f(-Infinity, -(1/0));
|
||||
f(2 + 7 + undefined, 2 + 7 + void 0);
|
||||
}
|
||||
with (o) {
|
||||
f(undefined, void 0);
|
||||
f(NaN, 0/0);
|
||||
f(Infinity, 1/0);
|
||||
f(-Infinity, -(1/0));
|
||||
f(2 + 7 + undefined, 2 + 7 + void 0);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var f = console.log, o = {
|
||||
undefined : 3,
|
||||
NaN : 4,
|
||||
Infinity : 5
|
||||
};
|
||||
if (o) {
|
||||
f(void 0, void 0);
|
||||
f(NaN, NaN);
|
||||
f(Infinity, 1/0);
|
||||
f(-Infinity, -1/0);
|
||||
f(NaN, NaN);
|
||||
}
|
||||
with (o) {
|
||||
f(undefined, void 0);
|
||||
f(NaN, 0/0);
|
||||
f(Infinity, 1/0);
|
||||
f(-Infinity, -1/0);
|
||||
f(9 + undefined, 9 + void 0);
|
||||
}
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
51
test/compress/issue-1202.js
Normal file
51
test/compress/issue-1202.js
Normal file
@@ -0,0 +1,51 @@
|
||||
mangle_keep_fnames_false: {
|
||||
options = {
|
||||
keep_fnames : true,
|
||||
keep_fargs : true,
|
||||
}
|
||||
mangle = {
|
||||
keep_fnames : false,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function total() {
|
||||
return function n(a, b, c) {
|
||||
return a + b + c;
|
||||
};
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function total() {
|
||||
return function t(n, r, u) {
|
||||
return n + r + u;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mangle_keep_fnames_true: {
|
||||
options = {
|
||||
keep_fnames : true,
|
||||
keep_fargs : true,
|
||||
}
|
||||
mangle = {
|
||||
keep_fnames : true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function total() {
|
||||
return function n(a, b, c) {
|
||||
return a + b + c;
|
||||
};
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function total() {
|
||||
return function n(t, r, u) {
|
||||
return t + r + u;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
183
test/compress/issue-1261.js
Normal file
183
test/compress/issue-1261.js
Normal file
@@ -0,0 +1,183 @@
|
||||
pure_function_calls: {
|
||||
options = {
|
||||
evaluate : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
side_effects : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
if_return : true,
|
||||
join_vars : true,
|
||||
negate_iife : true,
|
||||
}
|
||||
input: {
|
||||
// pure top-level IIFE will be dropped
|
||||
// @__PURE__ - comment
|
||||
(function() {
|
||||
console.log("iife0");
|
||||
})();
|
||||
|
||||
// pure top-level IIFE assigned to unreferenced var will not be dropped
|
||||
var iife1 = /*@__PURE__*/(function() {
|
||||
console.log("iife1");
|
||||
function iife1() {}
|
||||
return iife1;
|
||||
})();
|
||||
|
||||
(function(){
|
||||
// pure IIFE in function scope assigned to unreferenced var will be dropped
|
||||
var iife2 = /*#__PURE__*/(function() {
|
||||
console.log("iife2");
|
||||
function iife2() {}
|
||||
return iife2;
|
||||
})();
|
||||
})();
|
||||
|
||||
// comment #__PURE__ comment
|
||||
bar(), baz(), quux();
|
||||
a.b(), /* @__PURE__ */ c.d.e(), f.g();
|
||||
}
|
||||
expect: {
|
||||
var iife1 = function() {
|
||||
console.log("iife1");
|
||||
function iife1() {}
|
||||
return iife1;
|
||||
}();
|
||||
|
||||
baz(), quux();
|
||||
a.b(), f.g();
|
||||
}
|
||||
expect_warnings: [
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:16,8]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:16,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:29,37]",
|
||||
"WARN: Dropping unused variable iife2 [test/compress/issue-1261.js:29,16]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:27,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:37,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:38,31]",
|
||||
]
|
||||
}
|
||||
|
||||
pure_function_calls_toplevel: {
|
||||
options = {
|
||||
evaluate : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
side_effects : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
if_return : true,
|
||||
join_vars : true,
|
||||
negate_iife : true,
|
||||
toplevel : true,
|
||||
}
|
||||
input: {
|
||||
// pure top-level IIFE will be dropped
|
||||
// @__PURE__ - comment
|
||||
(function() {
|
||||
console.log("iife0");
|
||||
})();
|
||||
|
||||
// pure top-level IIFE assigned to unreferenced var will be dropped
|
||||
var iife1 = /*@__PURE__*/(function() {
|
||||
console.log("iife1");
|
||||
function iife1() {}
|
||||
return iife1;
|
||||
})();
|
||||
|
||||
(function(){
|
||||
// pure IIFE in function scope assigned to unreferenced var will be dropped
|
||||
var iife2 = /*#__PURE__*/(function() {
|
||||
console.log("iife2");
|
||||
function iife2() {}
|
||||
return iife2;
|
||||
})();
|
||||
})();
|
||||
|
||||
// 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
|
||||
bar(), baz(), quux();
|
||||
a.b(), /* @__PURE__ */ c.d.e(), f.g();
|
||||
}
|
||||
expect: {
|
||||
baz(), quux();
|
||||
a.b(), f.g();
|
||||
}
|
||||
expect_warnings: [
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:77,8]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:77,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:90,37]",
|
||||
"WARN: Dropping unused variable iife2 [test/compress/issue-1261.js:90,16]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:88,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:105,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:106,31]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:82,33]",
|
||||
"WARN: Dropping unused variable iife1 [test/compress/issue-1261.js:82,12]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:98,45]",
|
||||
"WARN: Dropping unused variable MyClass [test/compress/issue-1261.js:98,12]",
|
||||
]
|
||||
}
|
||||
|
||||
should_warn: {
|
||||
options = {
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
/* @__PURE__ */(function(){x})(), void/* @__PURE__ */(function(){y})();
|
||||
/* @__PURE__ */(function(){x})() || true ? foo() : bar();
|
||||
true || /* @__PURE__ */(function(){y})() ? foo() : bar();
|
||||
/* @__PURE__ */(function(){x})() && false ? foo() : bar();
|
||||
false && /* @__PURE__ */(function(){y})() ? foo() : bar();
|
||||
/* @__PURE__ */(function(){x})() + "foo" ? bar() : baz();
|
||||
"foo" + /* @__PURE__ */(function(){y})() ? bar() : baz();
|
||||
/* @__PURE__ */(function(){x})() ? foo() : foo();
|
||||
[/* @__PURE__ */(function(){x})()] ? foo() : bar();
|
||||
!{ foo: /* @__PURE__ */(function(){x})() } ? bar() : baz();
|
||||
}
|
||||
expect: {
|
||||
foo();
|
||||
foo();
|
||||
bar();
|
||||
bar();
|
||||
bar();
|
||||
bar();
|
||||
foo();
|
||||
foo();
|
||||
baz();
|
||||
}
|
||||
expect_warnings: [
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:135,61]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:135,23]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:135,23]",
|
||||
"WARN: Boolean || always true [test/compress/issue-1261.js:136,23]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:136,23]",
|
||||
"WARN: Condition always true [test/compress/issue-1261.js:136,23]",
|
||||
"WARN: Condition left of || always true [test/compress/issue-1261.js:137,8]",
|
||||
"WARN: Condition always true [test/compress/issue-1261.js:137,8]",
|
||||
"WARN: Boolean && always false [test/compress/issue-1261.js:138,23]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:138,23]",
|
||||
"WARN: Condition always false [test/compress/issue-1261.js:138,23]",
|
||||
"WARN: Condition left of && always false [test/compress/issue-1261.js:139,8]",
|
||||
"WARN: Condition always false [test/compress/issue-1261.js:139,8]",
|
||||
"WARN: + in boolean context always true [test/compress/issue-1261.js:140,23]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:140,23]",
|
||||
"WARN: Condition always true [test/compress/issue-1261.js:140,23]",
|
||||
"WARN: + in boolean context always true [test/compress/issue-1261.js:141,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:141,31]",
|
||||
"WARN: Condition always true [test/compress/issue-1261.js:141,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:142,23]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:143,24]",
|
||||
"WARN: Condition always true [test/compress/issue-1261.js:143,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:144,31]",
|
||||
"WARN: Condition always false [test/compress/issue-1261.js:144,8]",
|
||||
]
|
||||
}
|
||||
49
test/compress/issue-1275.js
Normal file
49
test/compress/issue-1275.js
Normal file
@@ -0,0 +1,49 @@
|
||||
string_plus_optimization: {
|
||||
options = {
|
||||
side_effects : true,
|
||||
evaluate : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
dead_code : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
if_return : true,
|
||||
join_vars : true,
|
||||
hoist_funs : true,
|
||||
};
|
||||
input: {
|
||||
function foo(anything) {
|
||||
function throwing_function() {
|
||||
throw "nope";
|
||||
}
|
||||
try {
|
||||
console.log('0' + throwing_function() ? "yes" : "no");
|
||||
} catch (ex) {
|
||||
console.log(ex);
|
||||
}
|
||||
console.log('0' + anything ? "yes" : "no");
|
||||
console.log(anything + '0' ? "Yes" : "No");
|
||||
console.log('' + anything);
|
||||
console.log(anything + '');
|
||||
}
|
||||
foo();
|
||||
}
|
||||
expect: {
|
||||
function foo(anything) {
|
||||
function throwing_function() {
|
||||
throw "nope";
|
||||
}
|
||||
try {
|
||||
console.log((throwing_function(), "yes"));
|
||||
} catch (ex) {
|
||||
console.log(ex);
|
||||
}
|
||||
console.log("yes");
|
||||
console.log("Yes");
|
||||
console.log('' + anything);
|
||||
console.log(anything + '');
|
||||
}
|
||||
foo();
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
63
test/compress/issue-1321.js
Normal file
63
test/compress/issue-1321.js
Normal file
@@ -0,0 +1,63 @@
|
||||
issue_1321_no_debug: {
|
||||
mangle = {
|
||||
properties: {
|
||||
keep_quoted: true,
|
||||
},
|
||||
}
|
||||
input: {
|
||||
var x = {};
|
||||
x.foo = 1;
|
||||
x["a"] = 2 * x.foo;
|
||||
console.log(x.foo, x["a"]);
|
||||
}
|
||||
expect: {
|
||||
var x = {};
|
||||
x.x = 1;
|
||||
x["a"] = 2 * x.x;
|
||||
console.log(x.x, x["a"]);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1321_debug: {
|
||||
mangle = {
|
||||
properties: {
|
||||
debug: "",
|
||||
keep_quoted: true,
|
||||
},
|
||||
}
|
||||
input: {
|
||||
var x = {};
|
||||
x.foo = 1;
|
||||
x["_$foo$_"] = 2 * x.foo;
|
||||
console.log(x.foo, x["_$foo$_"]);
|
||||
}
|
||||
expect: {
|
||||
var x = {};
|
||||
x.x = 1;
|
||||
x["_$foo$_"] = 2 * x.x;
|
||||
console.log(x.x, x["_$foo$_"]);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1321_with_quoted: {
|
||||
mangle = {
|
||||
properties: {
|
||||
keep_quoted: false,
|
||||
},
|
||||
}
|
||||
input: {
|
||||
var x = {};
|
||||
x.foo = 1;
|
||||
x["a"] = 2 * x.foo;
|
||||
console.log(x.foo, x["a"]);
|
||||
}
|
||||
expect: {
|
||||
var x = {};
|
||||
x.x = 1;
|
||||
x["o"] = 2 * x.x;
|
||||
console.log(x.x, x["o"]);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
151
test/compress/issue-1431.js
Normal file
151
test/compress/issue-1431.js
Normal file
@@ -0,0 +1,151 @@
|
||||
level_zero: {
|
||||
options = {
|
||||
keep_fnames: true
|
||||
}
|
||||
mangle = {
|
||||
keep_fnames: true
|
||||
}
|
||||
input: {
|
||||
function f(x) {
|
||||
function n(a) {
|
||||
return a * a;
|
||||
}
|
||||
return function() {
|
||||
return x;
|
||||
};
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(r) {
|
||||
function n(n) {
|
||||
return n * n;
|
||||
}
|
||||
return function() {
|
||||
return r;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
level_one: {
|
||||
options = {
|
||||
keep_fnames: true
|
||||
}
|
||||
mangle = {
|
||||
keep_fnames: true
|
||||
}
|
||||
input: {
|
||||
function f(x) {
|
||||
return function() {
|
||||
function n(a) {
|
||||
return a * a;
|
||||
}
|
||||
return x(n);
|
||||
};
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(r) {
|
||||
return function() {
|
||||
function n(n) {
|
||||
return n * n;
|
||||
}
|
||||
return r(n);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
level_two: {
|
||||
options = {
|
||||
keep_fnames: true
|
||||
}
|
||||
mangle = {
|
||||
keep_fnames: true
|
||||
}
|
||||
input: {
|
||||
function f(x) {
|
||||
return function() {
|
||||
function r(a) {
|
||||
return a * a;
|
||||
}
|
||||
return function() {
|
||||
function n(a) {
|
||||
return a * a;
|
||||
}
|
||||
return x(n);
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(t) {
|
||||
return function() {
|
||||
function r(n) {
|
||||
return n * n;
|
||||
}
|
||||
return function() {
|
||||
function n(n) {
|
||||
return n * n;
|
||||
}
|
||||
return t(n);
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
level_three: {
|
||||
options = {
|
||||
keep_fnames: true
|
||||
}
|
||||
mangle = {
|
||||
keep_fnames: true
|
||||
}
|
||||
input: {
|
||||
function f(x) {
|
||||
return function() {
|
||||
function r(a) {
|
||||
return a * a;
|
||||
}
|
||||
return [
|
||||
function() {
|
||||
function t(a) {
|
||||
return a * a;
|
||||
}
|
||||
return t;
|
||||
},
|
||||
function() {
|
||||
function n(a) {
|
||||
return a * a;
|
||||
}
|
||||
return x(n);
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(t) {
|
||||
return function() {
|
||||
function r(n) {
|
||||
return n * n;
|
||||
}
|
||||
return [
|
||||
function() {
|
||||
function t(n) {
|
||||
return n * n;
|
||||
}
|
||||
return t;
|
||||
},
|
||||
function() {
|
||||
function n(n) {
|
||||
return n * n;
|
||||
}
|
||||
return t(n);
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
61
test/compress/issue-1443.js
Normal file
61
test/compress/issue-1443.js
Normal file
@@ -0,0 +1,61 @@
|
||||
// tests assume that variable `undefined` not redefined and has `void 0` as value
|
||||
|
||||
unsafe_undefined: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
unsafe: true
|
||||
}
|
||||
mangle = {}
|
||||
input: {
|
||||
function f(undefined) {
|
||||
return function() {
|
||||
if (a)
|
||||
return b;
|
||||
if (c)
|
||||
return d;
|
||||
};
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(n) {
|
||||
return function() {
|
||||
return a ? b : c ? d : n;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
keep_fnames: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
unsafe: true
|
||||
}
|
||||
mangle = {
|
||||
keep_fnames: true
|
||||
}
|
||||
input: {
|
||||
function f(undefined) {
|
||||
return function() {
|
||||
function n(a) {
|
||||
return a * a;
|
||||
}
|
||||
if (a)
|
||||
return b;
|
||||
if (c)
|
||||
return d;
|
||||
};
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(r) {
|
||||
return function() {
|
||||
function n(n) {
|
||||
return n * n;
|
||||
}
|
||||
return a ? b : c ? d : r;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
75
test/compress/issue-1446.js
Normal file
75
test/compress/issue-1446.js
Normal file
@@ -0,0 +1,75 @@
|
||||
typeof_eq_undefined: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
typeofs: true,
|
||||
}
|
||||
input: {
|
||||
var a = typeof b != "undefined";
|
||||
b = typeof a != "undefined";
|
||||
var c = typeof d.e !== "undefined";
|
||||
var f = "undefined" === typeof g;
|
||||
g = "undefined" === typeof f;
|
||||
var h = "undefined" == typeof i.j;
|
||||
}
|
||||
expect: {
|
||||
var a = "undefined" != typeof b;
|
||||
b = void 0 !== a;
|
||||
var c = void 0 !== d.e;
|
||||
var f = "undefined" == typeof g;
|
||||
g = void 0 === f;
|
||||
var h = void 0 === i.j;
|
||||
}
|
||||
}
|
||||
|
||||
typeof_eq_undefined_ie8: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
ie8: true,
|
||||
typeofs: true,
|
||||
}
|
||||
input: {
|
||||
var a = typeof b != "undefined";
|
||||
b = typeof a != "undefined";
|
||||
var c = typeof d.e !== "undefined";
|
||||
var f = "undefined" === typeof g;
|
||||
g = "undefined" === typeof f;
|
||||
var h = "undefined" == typeof i.j;
|
||||
}
|
||||
expect: {
|
||||
var a = "undefined" != typeof b;
|
||||
b = void 0 !== a;
|
||||
var c = "undefined" != typeof d.e;
|
||||
var f = "undefined" == typeof g;
|
||||
g = void 0 === f;
|
||||
var h = "undefined" == typeof i.j;
|
||||
}
|
||||
}
|
||||
|
||||
undefined_redefined: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
typeofs: true,
|
||||
}
|
||||
input: {
|
||||
function f(undefined) {
|
||||
var n = 1;
|
||||
return typeof n == "undefined";
|
||||
}
|
||||
}
|
||||
expect_exact: "function f(undefined){var n=1;return void 0===n}"
|
||||
}
|
||||
|
||||
undefined_redefined_mangle: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
typeofs: true,
|
||||
}
|
||||
mangle = {}
|
||||
input: {
|
||||
function f(undefined) {
|
||||
var n = 1;
|
||||
return typeof n == "undefined";
|
||||
}
|
||||
}
|
||||
expect_exact: "function f(n){var r=1;return void 0===r}"
|
||||
}
|
||||
45
test/compress/issue-1447.js
Normal file
45
test/compress/issue-1447.js
Normal file
@@ -0,0 +1,45 @@
|
||||
else_with_empty_block: {
|
||||
options = {}
|
||||
input: {
|
||||
if (x)
|
||||
yes();
|
||||
else {
|
||||
}
|
||||
}
|
||||
expect_exact: "if(x)yes();"
|
||||
}
|
||||
|
||||
else_with_empty_statement: {
|
||||
options = {}
|
||||
input: {
|
||||
if (x)
|
||||
yes();
|
||||
else
|
||||
;
|
||||
}
|
||||
expect_exact: "if(x)yes();"
|
||||
}
|
||||
|
||||
conditional_false_stray_else_in_loop: {
|
||||
options = {
|
||||
evaluate : true,
|
||||
comparisons : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
loops : true,
|
||||
side_effects : true,
|
||||
dead_code : true,
|
||||
hoist_vars : true,
|
||||
join_vars : true,
|
||||
if_return : true,
|
||||
conditionals : false,
|
||||
}
|
||||
input: {
|
||||
for (var i = 1; i <= 4; ++i) {
|
||||
if (i <= 2) continue;
|
||||
console.log(i);
|
||||
}
|
||||
}
|
||||
expect_exact: "for(var i=1;i<=4;++i)if(!(i<=2))console.log(i);"
|
||||
expect_stdout: true
|
||||
}
|
||||
19
test/compress/issue-1569.js
Normal file
19
test/compress/issue-1569.js
Normal file
@@ -0,0 +1,19 @@
|
||||
inner_reference: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
!function f(a) {
|
||||
return a && f(a - 1) + a;
|
||||
}(42);
|
||||
!function g(a) {
|
||||
return a;
|
||||
}(42);
|
||||
}
|
||||
expect: {
|
||||
!function f(a) {
|
||||
return a && f(a - 1) + a;
|
||||
}(42);
|
||||
!void 0;
|
||||
}
|
||||
}
|
||||
87
test/compress/issue-1588.js
Normal file
87
test/compress/issue-1588.js
Normal file
@@ -0,0 +1,87 @@
|
||||
screw_ie8: {
|
||||
options = {
|
||||
ie8: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
try { throw "foo"; } catch (x) { console.log(x); }
|
||||
}
|
||||
expect_exact: 'try{throw"foo"}catch(o){console.log(o)}'
|
||||
expect_stdout: [
|
||||
"foo"
|
||||
]
|
||||
}
|
||||
|
||||
support_ie8: {
|
||||
options = {
|
||||
ie8: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
try { throw "foo"; } catch (x) { console.log(x); }
|
||||
}
|
||||
expect_exact: 'try{throw"foo"}catch(x){console.log(x)}'
|
||||
expect_stdout: "foo"
|
||||
}
|
||||
|
||||
safe_undefined: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
unsafe: false,
|
||||
}
|
||||
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(function(n) {
|
||||
return function() {
|
||||
return a ? b : c ? d : void 0;
|
||||
};
|
||||
}(1)());
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
unsafe_undefined: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
unsafe: true,
|
||||
}
|
||||
mangle = {}
|
||||
input: {
|
||||
var a, c;
|
||||
console.log(function(undefined) {
|
||||
return function() {
|
||||
if (a)
|
||||
return b;
|
||||
if (c)
|
||||
return d;
|
||||
};
|
||||
}()());
|
||||
}
|
||||
expect: {
|
||||
var a, c;
|
||||
console.log(function(n) {
|
||||
return function() {
|
||||
return a ? b : c ? d : n;
|
||||
};
|
||||
}()());
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
54
test/compress/issue-1609.js
Normal file
54
test/compress/issue-1609.js
Normal file
@@ -0,0 +1,54 @@
|
||||
chained_evaluation_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
var a = 1;
|
||||
(function() {
|
||||
var b = a, c;
|
||||
c = f(b);
|
||||
c.bar = b;
|
||||
})();
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
(function() {
|
||||
f(1).bar = 1;
|
||||
})();
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
||||
chained_evaluation_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
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() {
|
||||
var b = "long piece of string";
|
||||
f(b).bar = b;
|
||||
})();
|
||||
})();
|
||||
}
|
||||
}
|
||||
88
test/compress/issue-1639.js
Normal file
88
test/compress/issue-1639.js
Normal file
@@ -0,0 +1,88 @@
|
||||
|
||||
issue_1639_1: {
|
||||
options = {
|
||||
booleans: true,
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
join_vars: true,
|
||||
loops: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var a = 100, b = 10;
|
||||
|
||||
var L1 = 5;
|
||||
while (--L1 > 0) {
|
||||
if ((--b), false) {
|
||||
if (b) {
|
||||
var ignore = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log(a, b);
|
||||
}
|
||||
expect: {
|
||||
for (var a = 100, b = 10, L1 = 5; --L1 > 0;)
|
||||
if (--b, 0) var ignore = 0;
|
||||
console.log(a, b);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1639_2: {
|
||||
options = {
|
||||
booleans: true,
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
join_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var a = 100, b = 10;
|
||||
|
||||
function f19() {
|
||||
if (++a, false)
|
||||
if (a)
|
||||
if (++a);
|
||||
}
|
||||
f19();
|
||||
|
||||
console.log(a, b);
|
||||
}
|
||||
expect: {
|
||||
var a = 100, b = 10;
|
||||
function f19() {
|
||||
++a, 0;
|
||||
}
|
||||
f19(),
|
||||
console.log(a, b);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1639_3: {
|
||||
options = {
|
||||
booleans: true,
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var a = 100, b = 10;
|
||||
a++ && false && a ? 0 : 0;
|
||||
console.log(a, b);
|
||||
}
|
||||
expect: {
|
||||
var a = 100, b = 10;
|
||||
a++,
|
||||
console.log(a, b);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
45
test/compress/issue-1656.js
Normal file
45
test/compress/issue-1656.js
Normal file
@@ -0,0 +1,45 @@
|
||||
f7: {
|
||||
options = {
|
||||
booleans: true,
|
||||
collapse_vars: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
drop_debugger: true,
|
||||
evaluate: true,
|
||||
hoist_funs: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
loops: true,
|
||||
negate_iife: true,
|
||||
passes: 3,
|
||||
properties: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
beautify = {
|
||||
beautify: true,
|
||||
}
|
||||
input: {
|
||||
var a = 100, b = 10;
|
||||
function f22464() {
|
||||
var brake146670 = 5;
|
||||
while (((b = a) ? !a : ~a ? null : b += a) && --brake146670 > 0) {
|
||||
}
|
||||
}
|
||||
f22464();
|
||||
console.log(a, b);
|
||||
}
|
||||
expect_exact: [
|
||||
"var b = 10;",
|
||||
"",
|
||||
"!function() {",
|
||||
" b = 100;",
|
||||
"}(), console.log(100, b);",
|
||||
]
|
||||
expect_stdout: true
|
||||
}
|
||||
166
test/compress/issue-1673.js
Normal file
166
test/compress/issue-1673.js
Normal file
@@ -0,0 +1,166 @@
|
||||
side_effects_catch: {
|
||||
options = {
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
function g() {
|
||||
try {
|
||||
throw 0;
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
g();
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
(function() {
|
||||
try {
|
||||
throw 0;
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
})();
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
side_effects_else: {
|
||||
options = {
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(x) {
|
||||
function g() {
|
||||
if (x);
|
||||
else console.log("PASS");
|
||||
}
|
||||
g();
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect: {
|
||||
function f(x) {
|
||||
(function() {
|
||||
if (x);
|
||||
else console.log("PASS");
|
||||
})();
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
side_effects_finally: {
|
||||
options = {
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
function g() {
|
||||
try {
|
||||
x();
|
||||
} catch (e) {
|
||||
} finally {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
g();
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
(function() {
|
||||
try {
|
||||
x();
|
||||
} catch (e) {
|
||||
} finally {
|
||||
console.log("PASS");
|
||||
}
|
||||
})();
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
side_effects_label: {
|
||||
options = {
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(x) {
|
||||
function g() {
|
||||
L: {
|
||||
console.log("PASS");
|
||||
break L;
|
||||
}
|
||||
}
|
||||
g();
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect: {
|
||||
function f(x) {
|
||||
(function() {
|
||||
L: {
|
||||
console.log("PASS");
|
||||
break L;
|
||||
}
|
||||
})();
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
side_effects_switch: {
|
||||
options = {
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
function g() {
|
||||
switch (0) {
|
||||
default:
|
||||
case console.log("PASS"):
|
||||
}
|
||||
}
|
||||
g();
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
(function() {
|
||||
switch (0) {
|
||||
default:
|
||||
case console.log("PASS"):
|
||||
}
|
||||
})();
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
347
test/compress/issue-1704.js
Normal file
347
test/compress/issue-1704.js
Normal file
@@ -0,0 +1,347 @@
|
||||
mangle_catch: {
|
||||
options = {
|
||||
ie8: false,
|
||||
toplevel: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL";
|
||||
try {
|
||||
throw 1;
|
||||
} catch (args) {
|
||||
a = "PASS";
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'var a="FAIL";try{throw 1}catch(o){a="PASS"}console.log(a);'
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
mangle_catch_ie8: {
|
||||
options = {
|
||||
ie8: true,
|
||||
toplevel: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL";
|
||||
try {
|
||||
throw 1;
|
||||
} catch (args) {
|
||||
a = "PASS";
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'var a="FAIL";try{throw 1}catch(args){a="PASS"}console.log(a);'
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
mangle_catch_var: {
|
||||
options = {
|
||||
ie8: false,
|
||||
toplevel: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL";
|
||||
try {
|
||||
throw 1;
|
||||
} catch (args) {
|
||||
var a = "PASS";
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'var a="FAIL";try{throw 1}catch(o){var a="PASS"}console.log(a);'
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
mangle_catch_var_ie8: {
|
||||
options = {
|
||||
ie8: true,
|
||||
toplevel: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL";
|
||||
try {
|
||||
throw 1;
|
||||
} catch (args) {
|
||||
var a = "PASS";
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'var a="FAIL";try{throw 1}catch(args){var a="PASS"}console.log(a);'
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
mangle_catch_toplevel: {
|
||||
options = {
|
||||
ie8: false,
|
||||
toplevel: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL";
|
||||
try {
|
||||
throw 1;
|
||||
} catch (args) {
|
||||
a = "PASS";
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'var o="FAIL";try{throw 1}catch(c){o="PASS"}console.log(o);'
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
mangle_catch_ie8_toplevel: {
|
||||
options = {
|
||||
ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL";
|
||||
try {
|
||||
throw 1;
|
||||
} catch (args) {
|
||||
a = "PASS";
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'var o="FAIL";try{throw 1}catch(c){o="PASS"}console.log(o);'
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
mangle_catch_var_toplevel: {
|
||||
options = {
|
||||
ie8: false,
|
||||
toplevel: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL";
|
||||
try {
|
||||
throw 1;
|
||||
} catch (args) {
|
||||
var a = "PASS";
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'var o="FAIL";try{throw 1}catch(r){var o="PASS"}console.log(o);'
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
mangle_catch_var_ie8_toplevel: {
|
||||
options = {
|
||||
ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL";
|
||||
try {
|
||||
throw 1;
|
||||
} catch (args) {
|
||||
var a = "PASS";
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'var o="FAIL";try{throw 1}catch(r){var o="PASS"}console.log(o);'
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
mangle_catch_redef_1: {
|
||||
options = {
|
||||
ie8: false,
|
||||
toplevel: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
try {
|
||||
throw "FAIL1";
|
||||
} catch (a) {
|
||||
var a = "FAIL2";
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'var a="PASS";try{throw"FAIL1"}catch(a){var a="FAIL2"}console.log(a);'
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
mangle_catch_redef_1_ie8: {
|
||||
options = {
|
||||
ie8: true,
|
||||
toplevel: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
try {
|
||||
throw "FAIL1";
|
||||
} catch (a) {
|
||||
var a = "FAIL2";
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'var a="PASS";try{throw"FAIL1"}catch(a){var a="FAIL2"}console.log(a);'
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
mangle_catch_redef_1_toplevel: {
|
||||
options = {
|
||||
ie8: false,
|
||||
toplevel: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
try {
|
||||
throw "FAIL1";
|
||||
} catch (a) {
|
||||
var a = "FAIL2";
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'var o="PASS";try{throw"FAIL1"}catch(o){var o="FAIL2"}console.log(o);'
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
mangle_catch_redef_1_ie8_toplevel: {
|
||||
options = {
|
||||
ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
try {
|
||||
throw "FAIL1";
|
||||
} catch (a) {
|
||||
var a = "FAIL2";
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'var o="PASS";try{throw"FAIL1"}catch(o){var o="FAIL2"}console.log(o);'
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
mangle_catch_redef_2: {
|
||||
options = {
|
||||
ie8: false,
|
||||
toplevel: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
try {
|
||||
throw "FAIL1";
|
||||
} catch (a) {
|
||||
var a = "FAIL2";
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'try{throw"FAIL1"}catch(a){var a="FAIL2"}console.log(a);'
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
mangle_catch_redef_2_ie8: {
|
||||
options = {
|
||||
ie8: true,
|
||||
toplevel: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
try {
|
||||
throw "FAIL1";
|
||||
} catch (a) {
|
||||
var a = "FAIL2";
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'try{throw"FAIL1"}catch(a){var a="FAIL2"}console.log(a);'
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
mangle_catch_redef_2_toplevel: {
|
||||
options = {
|
||||
ie8: false,
|
||||
toplevel: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
try {
|
||||
throw "FAIL1";
|
||||
} catch (a) {
|
||||
var a = "FAIL2";
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'try{throw"FAIL1"}catch(o){var o="FAIL2"}console.log(o);'
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
mangle_catch_redef_2_ie8_toplevel: {
|
||||
options = {
|
||||
ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
try {
|
||||
throw "FAIL1";
|
||||
} catch (a) {
|
||||
var a = "FAIL2";
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'try{throw"FAIL1"}catch(o){var o="FAIL2"}console.log(o);'
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
97
test/compress/issue-1733.js
Normal file
97
test/compress/issue-1733.js
Normal file
@@ -0,0 +1,97 @@
|
||||
function_iife_catch: {
|
||||
mangle = {
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
function f(n) {
|
||||
!function() {
|
||||
try {
|
||||
throw 0;
|
||||
} catch (n) {
|
||||
var a = 1;
|
||||
console.log(n, a);
|
||||
}
|
||||
}();
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect_exact: "function f(o){!function(){try{throw 0}catch(c){var o=1;console.log(c,o)}}()}f();"
|
||||
expect_stdout: "0 1"
|
||||
}
|
||||
|
||||
function_iife_catch_ie8: {
|
||||
mangle = {
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
function f(n) {
|
||||
!function() {
|
||||
try {
|
||||
throw 0;
|
||||
} catch (n) {
|
||||
var a = 1;
|
||||
console.log(n, a);
|
||||
}
|
||||
}();
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect_exact: "function f(o){!function(){try{throw 0}catch(o){var c=1;console.log(o,c)}}()}f();"
|
||||
expect_stdout: "0 1"
|
||||
}
|
||||
|
||||
function_catch_catch: {
|
||||
mangle = {
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
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(c){try{throw 2}catch(o){var o=3;console.log(o)}}console.log(o)}f();"
|
||||
expect_stdout: [
|
||||
"3",
|
||||
"undefined",
|
||||
]
|
||||
}
|
||||
|
||||
function_catch_catch_ie8: {
|
||||
mangle = {
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
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(c){try{throw 2}catch(o){var o=3;console.log(o)}}console.log(o)}f();"
|
||||
expect_stdout: [
|
||||
"3",
|
||||
"undefined",
|
||||
]
|
||||
}
|
||||
54
test/compress/issue-1750.js
Normal file
54
test/compress/issue-1750.js
Normal file
@@ -0,0 +1,54 @@
|
||||
case_1: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
var a = 0, b = 1;
|
||||
switch (true) {
|
||||
case a || true:
|
||||
default:
|
||||
b = 2;
|
||||
case true:
|
||||
}
|
||||
console.log(a, b);
|
||||
}
|
||||
expect: {
|
||||
var a = 0, b = 1;
|
||||
switch (true) {
|
||||
case a || true:
|
||||
b = 2;
|
||||
}
|
||||
console.log(a, b);
|
||||
}
|
||||
expect_stdout: "0 2"
|
||||
}
|
||||
|
||||
case_2: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
var a = 0, b = 1;
|
||||
switch (0) {
|
||||
default:
|
||||
b = 2;
|
||||
case a:
|
||||
a = 3;
|
||||
case 0:
|
||||
}
|
||||
console.log(a, b);
|
||||
}
|
||||
expect: {
|
||||
var a = 0, b = 1;
|
||||
switch (0) {
|
||||
case a:
|
||||
a = 3;
|
||||
}
|
||||
console.log(a, b);
|
||||
}
|
||||
expect_stdout: "3 1"
|
||||
}
|
||||
245
test/compress/issue-1770.js
Normal file
245
test/compress/issue-1770.js
Normal file
@@ -0,0 +1,245 @@
|
||||
mangle_props: {
|
||||
mangle = {
|
||||
properties: true,
|
||||
}
|
||||
input: {
|
||||
var obj = {
|
||||
undefined: 1,
|
||||
NaN: 2,
|
||||
Infinity: 3,
|
||||
"-Infinity": 4,
|
||||
null: 5,
|
||||
};
|
||||
console.log(
|
||||
obj[void 0],
|
||||
obj[undefined],
|
||||
obj["undefined"],
|
||||
obj[0/0],
|
||||
obj[NaN],
|
||||
obj["NaN"],
|
||||
obj[1/0],
|
||||
obj[Infinity],
|
||||
obj["Infinity"],
|
||||
obj[-1/0],
|
||||
obj[-Infinity],
|
||||
obj["-Infinity"],
|
||||
obj[null],
|
||||
obj["null"]
|
||||
);
|
||||
}
|
||||
expect: {
|
||||
var obj = {
|
||||
undefined: 1,
|
||||
NaN: 2,
|
||||
Infinity: 3,
|
||||
"-Infinity": 4,
|
||||
null: 5,
|
||||
};
|
||||
console.log(
|
||||
obj[void 0],
|
||||
obj[void 0],
|
||||
obj["undefined"],
|
||||
obj[0/0],
|
||||
obj[NaN],
|
||||
obj["NaN"],
|
||||
obj[1/0],
|
||||
obj[1/0],
|
||||
obj["Infinity"],
|
||||
obj[-1/0],
|
||||
obj[-1/0],
|
||||
obj["-Infinity"],
|
||||
obj[null],
|
||||
obj["null"]
|
||||
);
|
||||
}
|
||||
expect_stdout: "1 1 1 2 2 2 3 3 3 4 4 4 5 5"
|
||||
}
|
||||
|
||||
numeric_literal: {
|
||||
mangle = {
|
||||
properties: true,
|
||||
}
|
||||
beautify = {
|
||||
beautify: true,
|
||||
}
|
||||
input: {
|
||||
var obj = {
|
||||
0: 0,
|
||||
"-0": 1,
|
||||
42: 2,
|
||||
"42": 3,
|
||||
0x25: 4,
|
||||
"0x25": 5,
|
||||
1E42: 6,
|
||||
"1E42": 7,
|
||||
"1e+42": 8,
|
||||
};
|
||||
console.log(obj[-0], obj[-""], obj["-0"]);
|
||||
console.log(obj[42], obj["42"]);
|
||||
console.log(obj[0x25], obj["0x25"], obj[37], obj["37"]);
|
||||
console.log(obj[1E42], obj["1E42"], obj["1e+42"]);
|
||||
}
|
||||
expect_exact: [
|
||||
'var obj = {',
|
||||
' 0: 0,',
|
||||
' "-0": 1,',
|
||||
' 42: 2,',
|
||||
' "42": 3,',
|
||||
' 37: 4,',
|
||||
' o: 5,',
|
||||
' 1e42: 6,',
|
||||
' b: 7,',
|
||||
' "1e+42": 8',
|
||||
'};',
|
||||
'',
|
||||
'console.log(obj[-0], obj[-""], obj["-0"]);',
|
||||
'',
|
||||
'console.log(obj[42], obj["42"]);',
|
||||
'',
|
||||
'console.log(obj[37], obj["o"], obj[37], obj["37"]);',
|
||||
'',
|
||||
'console.log(obj[1e42], obj["b"], obj["1e+42"]);',
|
||||
]
|
||||
expect_stdout: [
|
||||
"0 0 1",
|
||||
"3 3",
|
||||
"4 5 4 4",
|
||||
"8 7 8",
|
||||
]
|
||||
}
|
||||
|
||||
identifier: {
|
||||
mangle = {
|
||||
properties: true,
|
||||
}
|
||||
input: {
|
||||
var obj = {
|
||||
abstract: 1,
|
||||
boolean: 2,
|
||||
byte: 3,
|
||||
char: 4,
|
||||
class: 5,
|
||||
double: 6,
|
||||
enum: 7,
|
||||
export: 8,
|
||||
extends: 9,
|
||||
final: 10,
|
||||
float: 11,
|
||||
goto: 12,
|
||||
implements: 13,
|
||||
import: 14,
|
||||
int: 15,
|
||||
interface: 16,
|
||||
let: 17,
|
||||
long: 18,
|
||||
native: 19,
|
||||
package: 20,
|
||||
private: 21,
|
||||
protected: 22,
|
||||
public: 23,
|
||||
short: 24,
|
||||
static: 25,
|
||||
super: 26,
|
||||
synchronized: 27,
|
||||
this: 28,
|
||||
throws: 29,
|
||||
transient: 30,
|
||||
volatile: 31,
|
||||
yield: 32,
|
||||
false: 33,
|
||||
null: 34,
|
||||
true: 35,
|
||||
break: 36,
|
||||
case: 37,
|
||||
catch: 38,
|
||||
const: 39,
|
||||
continue: 40,
|
||||
debugger: 41,
|
||||
default: 42,
|
||||
delete: 43,
|
||||
do: 44,
|
||||
else: 45,
|
||||
finally: 46,
|
||||
for: 47,
|
||||
function: 48,
|
||||
if: 49,
|
||||
in: 50,
|
||||
instanceof: 51,
|
||||
new: 52,
|
||||
return: 53,
|
||||
switch: 54,
|
||||
throw: 55,
|
||||
try: 56,
|
||||
typeof: 57,
|
||||
var: 58,
|
||||
void: 59,
|
||||
while: 60,
|
||||
with: 61,
|
||||
};
|
||||
}
|
||||
expect: {
|
||||
var obj = {
|
||||
e: 1,
|
||||
t: 2,
|
||||
n: 3,
|
||||
a: 4,
|
||||
i: 5,
|
||||
o: 6,
|
||||
r: 7,
|
||||
l: 8,
|
||||
s: 9,
|
||||
c: 10,
|
||||
f: 11,
|
||||
u: 12,
|
||||
d: 13,
|
||||
h: 14,
|
||||
p: 15,
|
||||
b: 16,
|
||||
v: 17,
|
||||
w: 18,
|
||||
y: 19,
|
||||
g: 20,
|
||||
m: 21,
|
||||
k: 22,
|
||||
x: 23,
|
||||
j: 24,
|
||||
z: 25,
|
||||
q: 26,
|
||||
A: 27,
|
||||
B: 28,
|
||||
C: 29,
|
||||
D: 30,
|
||||
F: 31,
|
||||
G: 32,
|
||||
false: 33,
|
||||
null: 34,
|
||||
true: 35,
|
||||
H: 36,
|
||||
I: 37,
|
||||
J: 38,
|
||||
K: 39,
|
||||
L: 40,
|
||||
M: 41,
|
||||
N: 42,
|
||||
O: 43,
|
||||
P: 44,
|
||||
Q: 45,
|
||||
R: 46,
|
||||
S: 47,
|
||||
T: 48,
|
||||
U: 49,
|
||||
V: 50,
|
||||
W: 51,
|
||||
X: 52,
|
||||
Y: 53,
|
||||
Z: 54,
|
||||
$: 55,
|
||||
_: 56,
|
||||
ee: 57,
|
||||
te: 58,
|
||||
ne: 59,
|
||||
ae: 60,
|
||||
ie: 61,
|
||||
};
|
||||
}
|
||||
}
|
||||
17
test/compress/issue-1787.js
Normal file
17
test/compress/issue-1787.js
Normal file
@@ -0,0 +1,17 @@
|
||||
unary_prefix: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
var x = -(2 / 3);
|
||||
return x;
|
||||
}());
|
||||
}
|
||||
expect_exact: "console.log(-2/3);"
|
||||
expect_stdout: true
|
||||
}
|
||||
138
test/compress/issue-1833.js
Normal file
138
test/compress/issue-1833.js
Normal file
@@ -0,0 +1,138 @@
|
||||
iife_for: {
|
||||
options = {
|
||||
negate_iife: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
function g() {
|
||||
L: for (;;) break L;
|
||||
}
|
||||
g();
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
!function() {
|
||||
!function() {
|
||||
L: for (;;) break L;
|
||||
}();
|
||||
}();
|
||||
}
|
||||
}
|
||||
|
||||
iife_for_in: {
|
||||
options = {
|
||||
negate_iife: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
function g() {
|
||||
L: for (var a in x) break L;
|
||||
}
|
||||
g();
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
!function() {
|
||||
!function() {
|
||||
L: for (var a in x) break L;
|
||||
}();
|
||||
}();
|
||||
}
|
||||
}
|
||||
|
||||
iife_do: {
|
||||
options = {
|
||||
negate_iife: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
function g() {
|
||||
L: do {
|
||||
break L;
|
||||
} while (1);
|
||||
}
|
||||
g();
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
!function() {
|
||||
!function() {
|
||||
L: do {
|
||||
break L;
|
||||
} while (1);
|
||||
}();
|
||||
}();
|
||||
}
|
||||
}
|
||||
|
||||
iife_while: {
|
||||
options = {
|
||||
negate_iife: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
function g() {
|
||||
L: while (1) break L;
|
||||
}
|
||||
g();
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
!function() {
|
||||
!function() {
|
||||
L: while (1) break L;
|
||||
}();
|
||||
}();
|
||||
}
|
||||
}
|
||||
|
||||
label_do: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
L: do {
|
||||
continue L;
|
||||
} while (0);
|
||||
}
|
||||
expect: {
|
||||
L: do {
|
||||
continue L;
|
||||
} while (0);
|
||||
}
|
||||
}
|
||||
|
||||
label_while: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
dead_code: true,
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
L: while (0) continue L;
|
||||
}
|
||||
}
|
||||
expect_exact: "function f(){L:0}"
|
||||
}
|
||||
31
test/compress/issue-1943.js
Normal file
31
test/compress/issue-1943.js
Normal file
@@ -0,0 +1,31 @@
|
||||
operator: {
|
||||
input: {
|
||||
a. //comment
|
||||
typeof
|
||||
}
|
||||
expect_exact: "a.typeof;"
|
||||
}
|
||||
|
||||
name: {
|
||||
input: {
|
||||
a. //comment
|
||||
b
|
||||
}
|
||||
expect_exact: "a.b;"
|
||||
}
|
||||
|
||||
keyword: {
|
||||
input: {
|
||||
a. //comment
|
||||
default
|
||||
}
|
||||
expect_exact: "a.default;"
|
||||
}
|
||||
|
||||
atom: {
|
||||
input: {
|
||||
a. //comment
|
||||
true
|
||||
}
|
||||
expect_exact: "a.true;"
|
||||
}
|
||||
@@ -1,11 +1,70 @@
|
||||
do_not_update_lhs: {
|
||||
options = { global_defs: { DEBUG: false } };
|
||||
input: { DEBUG = false; }
|
||||
expect: { DEBUG = false; }
|
||||
options = {
|
||||
global_defs: { DEBUG: 0 }
|
||||
}
|
||||
input: {
|
||||
DEBUG++;
|
||||
DEBUG += 1;
|
||||
DEBUG = 1;
|
||||
}
|
||||
expect: {
|
||||
DEBUG++;
|
||||
DEBUG += 1;
|
||||
DEBUG = 1;
|
||||
}
|
||||
}
|
||||
|
||||
do_update_rhs: {
|
||||
options = { global_defs: { DEBUG: false } };
|
||||
input: { MY_DEBUG = DEBUG; }
|
||||
expect: { MY_DEBUG = false; }
|
||||
options = {
|
||||
global_defs: { DEBUG: 0 }
|
||||
}
|
||||
input: {
|
||||
MY_DEBUG = DEBUG;
|
||||
MY_DEBUG += DEBUG;
|
||||
}
|
||||
expect: {
|
||||
MY_DEBUG = 0;
|
||||
MY_DEBUG += 0;
|
||||
}
|
||||
}
|
||||
|
||||
mixed: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
global_defs: {
|
||||
DEBUG: 0,
|
||||
ENV: 1,
|
||||
FOO: 2,
|
||||
}
|
||||
}
|
||||
input: {
|
||||
var ENV = 3;
|
||||
var FOO = 4;
|
||||
f(ENV * 10);
|
||||
--FOO;
|
||||
DEBUG = 1;
|
||||
DEBUG++;
|
||||
DEBUG += 1;
|
||||
f(DEBUG);
|
||||
x = DEBUG;
|
||||
}
|
||||
expect: {
|
||||
var ENV = 3;
|
||||
var FOO = 4;
|
||||
f(10);
|
||||
--FOO;
|
||||
DEBUG = 1;
|
||||
DEBUG++;
|
||||
DEBUG += 1;
|
||||
f(0);
|
||||
x = 0;
|
||||
}
|
||||
expect_warnings: [
|
||||
'WARN: global_defs ENV redefined [test/compress/issue-208.js:41,12]',
|
||||
'WARN: global_defs FOO redefined [test/compress/issue-208.js:42,12]',
|
||||
'WARN: global_defs FOO redefined [test/compress/issue-208.js:44,10]',
|
||||
'WARN: global_defs DEBUG redefined [test/compress/issue-208.js:45,8]',
|
||||
'WARN: global_defs DEBUG redefined [test/compress/issue-208.js:46,8]',
|
||||
'WARN: global_defs DEBUG redefined [test/compress/issue-208.js:47,8]',
|
||||
]
|
||||
}
|
||||
|
||||
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;",
|
||||
]
|
||||
}
|
||||
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"
|
||||
}
|
||||
55
test/compress/issue-368.js
Normal file
55
test/compress/issue-368.js
Normal file
@@ -0,0 +1,55 @@
|
||||
collapse: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f1() {
|
||||
var a;
|
||||
a = typeof b === 'function' ? b() : b;
|
||||
return a !== undefined && c();
|
||||
}
|
||||
function f2(b) {
|
||||
var a;
|
||||
b = c();
|
||||
a = typeof b === 'function' ? b() : b;
|
||||
return 'stirng' == typeof a && d();
|
||||
}
|
||||
function f3(c) {
|
||||
var a;
|
||||
a = b(a / 2);
|
||||
if (a < 0) {
|
||||
a++;
|
||||
++c;
|
||||
return c / 2;
|
||||
}
|
||||
}
|
||||
function f4(c) {
|
||||
var a;
|
||||
a = b(a / 2);
|
||||
if (a < 0) {
|
||||
a++;
|
||||
c++;
|
||||
return c / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f1() {
|
||||
return void 0 !== ('function' === typeof b ? b() : b) && c();
|
||||
}
|
||||
function f2(b) {
|
||||
return 'stirng' == typeof ('function' === typeof (b = c()) ? b() : b) && d();
|
||||
}
|
||||
function f3(c) {
|
||||
var a;
|
||||
if ((a = b(a / 2)) < 0) return a++, ++c / 2;
|
||||
}
|
||||
function f4(c) {
|
||||
var a;
|
||||
if ((a = b(a / 2)) < 0) return a++, ++c / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ NaN_and_Infinity_must_have_parens: {
|
||||
}
|
||||
expect: {
|
||||
(1/0).toString();
|
||||
NaN.toString(); // transformation to 0/0 dropped
|
||||
NaN.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,3 +23,135 @@ NaN_and_Infinity_should_not_be_replaced_when_they_are_redefined: {
|
||||
NaN.toString();
|
||||
}
|
||||
}
|
||||
|
||||
NaN_and_Infinity_must_have_parens_evaluate: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
(123456789 / 0).toString();
|
||||
(+"foo").toString();
|
||||
}
|
||||
expect: {
|
||||
(1/0).toString();
|
||||
NaN.toString();
|
||||
}
|
||||
}
|
||||
|
||||
NaN_and_Infinity_should_not_be_replaced_when_they_are_redefined_evaluate: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
var Infinity, NaN;
|
||||
(123456789 / 0).toString();
|
||||
(+"foo").toString();
|
||||
}
|
||||
expect: {
|
||||
var Infinity, NaN;
|
||||
(1/0).toString();
|
||||
(0/0).toString();
|
||||
}
|
||||
}
|
||||
|
||||
beautify_off_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
}
|
||||
beautify = {
|
||||
beautify: false,
|
||||
}
|
||||
input: {
|
||||
var NaN;
|
||||
console.log(
|
||||
null,
|
||||
undefined,
|
||||
Infinity,
|
||||
NaN,
|
||||
Infinity * undefined,
|
||||
Infinity.toString(),
|
||||
NaN.toString(),
|
||||
(Infinity * undefined).toString()
|
||||
);
|
||||
}
|
||||
expect_exact: "var NaN;console.log(null,void 0,1/0,NaN,0/0,(1/0).toString(),NaN.toString(),(0/0).toString());"
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
beautify_off_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
}
|
||||
beautify = {
|
||||
beautify: false,
|
||||
}
|
||||
input: {
|
||||
console.log(
|
||||
null.toString(),
|
||||
undefined.toString()
|
||||
);
|
||||
}
|
||||
expect_exact: "console.log(null.toString(),(void 0).toString());"
|
||||
}
|
||||
|
||||
beautify_on_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
}
|
||||
beautify = {
|
||||
beautify: true,
|
||||
}
|
||||
input: {
|
||||
var NaN;
|
||||
console.log(
|
||||
null,
|
||||
undefined,
|
||||
Infinity,
|
||||
NaN,
|
||||
Infinity * undefined,
|
||||
Infinity.toString(),
|
||||
NaN.toString(),
|
||||
(Infinity * undefined).toString()
|
||||
);
|
||||
}
|
||||
expect_exact: [
|
||||
"var NaN;",
|
||||
"",
|
||||
"console.log(null, void 0, 1 / 0, NaN, 0 / 0, (1 / 0).toString(), NaN.toString(), (0 / 0).toString());",
|
||||
]
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
beautify_on_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
}
|
||||
beautify = {
|
||||
beautify: true,
|
||||
}
|
||||
input: {
|
||||
console.log(
|
||||
null.toString(),
|
||||
undefined.toString()
|
||||
);
|
||||
}
|
||||
expect_exact: "console.log(null.toString(), (void 0).toString());"
|
||||
}
|
||||
|
||||
issue_1724: {
|
||||
input: {
|
||||
var a = 0;
|
||||
++a % Infinity | Infinity ? a++ : 0;
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: "var a=0;++a%(1/0)|1/0?a++:0;console.log(a);"
|
||||
expect_stdout: "2"
|
||||
}
|
||||
|
||||
issue_1725: {
|
||||
input: {
|
||||
([].length === 0) % Infinity ? console.log("PASS") : console.log("FAIL");
|
||||
}
|
||||
expect_exact: '(0===[].length)%(1/0)?console.log("PASS"):console.log("FAIL");'
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -17,6 +17,6 @@ wrongly_optimized: {
|
||||
foo();
|
||||
}
|
||||
// TODO: optimize to `func(), bar()`
|
||||
(func(), 0) || bar();
|
||||
(func(), 1) && bar();
|
||||
}
|
||||
}
|
||||
|
||||
320
test/compress/issue-640.js
Normal file
320
test/compress/issue-640.js
Normal file
@@ -0,0 +1,320 @@
|
||||
cond_5: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
expression: true,
|
||||
}
|
||||
input: {
|
||||
if (some_condition()) {
|
||||
if (some_other_condition()) {
|
||||
do_something();
|
||||
} else {
|
||||
alternate();
|
||||
}
|
||||
} else {
|
||||
alternate();
|
||||
}
|
||||
|
||||
if (some_condition()) {
|
||||
if (some_other_condition()) {
|
||||
do_something();
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
some_condition() && some_other_condition() ? do_something() : alternate();
|
||||
if (some_condition() && some_other_condition()) do_something();
|
||||
}
|
||||
}
|
||||
|
||||
dead_code_const_annotation_regex: {
|
||||
options = {
|
||||
booleans : true,
|
||||
conditionals : true,
|
||||
dead_code : true,
|
||||
evaluate : true,
|
||||
expression : true,
|
||||
loops : true,
|
||||
}
|
||||
input: {
|
||||
var unused;
|
||||
// @constraint this shouldn't be a constant
|
||||
var CONST_FOO_ANN = false;
|
||||
if (CONST_FOO_ANN) {
|
||||
console.log("reachable");
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var unused;
|
||||
var CONST_FOO_ANN = !1;
|
||||
if (CONST_FOO_ANN) console.log('reachable');
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
drop_console_2: {
|
||||
options = {
|
||||
drop_console: true,
|
||||
expression: true,
|
||||
}
|
||||
input: {
|
||||
console.log('foo');
|
||||
console.log.apply(console, arguments);
|
||||
}
|
||||
expect: {
|
||||
// with regular compression these will be stripped out as well
|
||||
void 0;
|
||||
void 0;
|
||||
}
|
||||
}
|
||||
|
||||
drop_value: {
|
||||
options = {
|
||||
expression: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(1, [2, foo()], 3, {a:1, b:bar()});
|
||||
}
|
||||
expect: {
|
||||
foo(), {a:1, b:bar()};
|
||||
}
|
||||
}
|
||||
|
||||
wrongly_optimized: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
booleans: true,
|
||||
evaluate: true,
|
||||
expression: true,
|
||||
}
|
||||
input: {
|
||||
function func() {
|
||||
foo();
|
||||
}
|
||||
if (func() || true) {
|
||||
bar();
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function func() {
|
||||
foo();
|
||||
}
|
||||
// TODO: optimize to `func(), bar()`
|
||||
if (func(), 1) bar();
|
||||
}
|
||||
}
|
||||
|
||||
negate_iife_1: {
|
||||
options = {
|
||||
expression: true,
|
||||
negate_iife: true,
|
||||
}
|
||||
input: {
|
||||
(function(){ stuff() })();
|
||||
}
|
||||
expect: {
|
||||
(function(){ stuff() })();
|
||||
}
|
||||
}
|
||||
|
||||
negate_iife_3: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
expression: true,
|
||||
negate_iife: true,
|
||||
}
|
||||
input: {
|
||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||
}
|
||||
expect: {
|
||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||
}
|
||||
}
|
||||
|
||||
negate_iife_3_off: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
expression: true,
|
||||
negate_iife: false,
|
||||
}
|
||||
input: {
|
||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||
}
|
||||
expect: {
|
||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||
}
|
||||
}
|
||||
|
||||
negate_iife_4: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
expression: true,
|
||||
negate_iife: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||
(function(){
|
||||
console.log("something");
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
!function(){ return t }() ? console.log(false) : console.log(true), function(){
|
||||
console.log("something");
|
||||
}();
|
||||
}
|
||||
}
|
||||
|
||||
negate_iife_5: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
expression: true,
|
||||
negate_iife: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
if ((function(){ return t })()) {
|
||||
foo(true);
|
||||
} else {
|
||||
bar(false);
|
||||
}
|
||||
(function(){
|
||||
console.log("something");
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
!function(){ return t }() ? bar(false) : foo(true), function(){
|
||||
console.log("something");
|
||||
}();
|
||||
}
|
||||
}
|
||||
|
||||
negate_iife_5_off: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
expression: true,
|
||||
negate_iife: false,
|
||||
sequences: true,
|
||||
};
|
||||
input: {
|
||||
if ((function(){ return t })()) {
|
||||
foo(true);
|
||||
} else {
|
||||
bar(false);
|
||||
}
|
||||
(function(){
|
||||
console.log("something");
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
!function(){ return t }() ? bar(false) : foo(true), function(){
|
||||
console.log("something");
|
||||
}();
|
||||
}
|
||||
}
|
||||
|
||||
issue_1254_negate_iife_true: {
|
||||
options = {
|
||||
expression: true,
|
||||
negate_iife: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
return function() {
|
||||
console.log('test')
|
||||
};
|
||||
})()();
|
||||
}
|
||||
expect_exact: '(function(){return function(){console.log("test")}})()();'
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1254_negate_iife_nested: {
|
||||
options = {
|
||||
expression: true,
|
||||
negate_iife: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
return function() {
|
||||
console.log('test')
|
||||
};
|
||||
})()()()()();
|
||||
}
|
||||
expect_exact: '(function(){return function(){console.log("test")}})()()()()();'
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
conditional: {
|
||||
options = {
|
||||
expression: true,
|
||||
pure_funcs: [ "pure" ],
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
pure(1 | a() ? 2 & b() : 7 ^ c());
|
||||
pure(1 | a() ? 2 & b() : 5);
|
||||
pure(1 | a() ? 4 : 7 ^ c());
|
||||
pure(1 | a() ? 4 : 5);
|
||||
pure(3 ? 2 & b() : 7 ^ c());
|
||||
pure(3 ? 2 & b() : 5);
|
||||
pure(3 ? 4 : 7 ^ c());
|
||||
pure(3 ? 4 : 5);
|
||||
}
|
||||
expect: {
|
||||
1 | a() ? b() : c();
|
||||
1 | a() && b();
|
||||
1 | a() || c();
|
||||
a();
|
||||
3 ? b() : c();
|
||||
3 && b();
|
||||
3 || c();
|
||||
pure(3 ? 4 : 5);
|
||||
}
|
||||
}
|
||||
|
||||
limit_1: {
|
||||
options = {
|
||||
expression: true,
|
||||
sequences: 3,
|
||||
}
|
||||
input: {
|
||||
a;
|
||||
b;
|
||||
c;
|
||||
d;
|
||||
e;
|
||||
f;
|
||||
g;
|
||||
h;
|
||||
i;
|
||||
j;
|
||||
k;
|
||||
}
|
||||
expect: {
|
||||
// Turned into a single return statement
|
||||
// so it can no longer be split into lines
|
||||
a,b,c,d,e,f,g,h,i,j,k;
|
||||
}
|
||||
}
|
||||
|
||||
iife: {
|
||||
options = {
|
||||
expression: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
x = 42;
|
||||
(function a() {})();
|
||||
!function b() {}();
|
||||
~function c() {}();
|
||||
+function d() {}();
|
||||
-function e() {}();
|
||||
void function f() {}();
|
||||
typeof function g() {}();
|
||||
}
|
||||
expect: {
|
||||
x = 42, function a() {}(), function b() {}(), function c() {}(),
|
||||
function d() {}(), function e() {}(), function f() {}(), typeof function g() {}();
|
||||
}
|
||||
}
|
||||
@@ -1,37 +1,45 @@
|
||||
dont_reuse_prop: {
|
||||
mangle_props = {
|
||||
regex: /asd/
|
||||
};
|
||||
|
||||
mangle = {
|
||||
properties: {
|
||||
regex: /asd/,
|
||||
},
|
||||
}
|
||||
input: {
|
||||
"aaaaaaaaaabbbbb";
|
||||
var obj = {};
|
||||
obj.a = 123;
|
||||
obj.asd = 256;
|
||||
console.log(obj.a);
|
||||
}
|
||||
expect: {
|
||||
"aaaaaaaaaabbbbb";
|
||||
var obj = {};
|
||||
obj.a = 123;
|
||||
obj.b = 256;
|
||||
console.log(obj.a);
|
||||
}
|
||||
expect_stdout: "123"
|
||||
}
|
||||
|
||||
unmangleable_props_should_always_be_reserved: {
|
||||
mangle_props = {
|
||||
regex: /asd/
|
||||
};
|
||||
|
||||
mangle = {
|
||||
properties: {
|
||||
regex: /asd/,
|
||||
},
|
||||
}
|
||||
input: {
|
||||
"aaaaaaaaaabbbbb";
|
||||
var obj = {};
|
||||
obj.asd = 256;
|
||||
obj.a = 123;
|
||||
console.log(obj.a);
|
||||
}
|
||||
expect: {
|
||||
"aaaaaaaaaabbbbb";
|
||||
var obj = {};
|
||||
obj.b = 256;
|
||||
obj.a = 123;
|
||||
console.log(obj.a);
|
||||
}
|
||||
}
|
||||
expect_stdout: "123"
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ dont_mangle_arguments: {
|
||||
hoist_vars : true,
|
||||
if_return : true,
|
||||
join_vars : true,
|
||||
cascade : true,
|
||||
side_effects : true,
|
||||
negate_iife : false
|
||||
};
|
||||
@@ -29,4 +28,5 @@ dont_mangle_arguments: {
|
||||
})(5,6,7);
|
||||
}
|
||||
expect_exact: "(function(){var arguments=arguments,o=9;console.log(o,arguments)})(5,6,7);"
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
this_binding_conditionals: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
evaluate : true
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
};
|
||||
input: {
|
||||
(1 && a)();
|
||||
@@ -50,6 +51,8 @@ this_binding_conditionals: {
|
||||
this_binding_collapse_vars: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
};
|
||||
input: {
|
||||
var c = a; c();
|
||||
|
||||
@@ -2,7 +2,7 @@ eval_collapse_vars: {
|
||||
options = {
|
||||
collapse_vars:true, sequences:false, properties:true, dead_code:true, conditionals:true,
|
||||
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
|
||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true
|
||||
keep_fargs:true, if_return:true, join_vars:true, side_effects:true
|
||||
};
|
||||
input: {
|
||||
function f1() {
|
||||
@@ -42,6 +42,7 @@ eval_collapse_vars: {
|
||||
eval("console.log(a);");
|
||||
})(eval);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
eval_unused: {
|
||||
@@ -84,5 +85,5 @@ eval_mangle: {
|
||||
return a + eval('c');
|
||||
}
|
||||
}
|
||||
expect_exact: 'function f1(n,c,e,a,o){return n("c")+c}function f2(a,b,c,d,e){return a+eval("c")}function f3(a,eval,c,d,e){return a+eval("c")}'
|
||||
expect_exact: 'function f1(n,c,e,a,f){return n("c")+c}function f2(a,b,c,d,e){return a+eval("c")}function f3(a,eval,c,d,e){return a+eval("c")}'
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ issue979_reported: {
|
||||
options = {
|
||||
sequences:true, properties:true, dead_code:true, conditionals:true,
|
||||
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
|
||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true
|
||||
keep_fargs:true, if_return:true, join_vars:true, side_effects:true
|
||||
}
|
||||
input: {
|
||||
function f1() {
|
||||
@@ -32,7 +32,7 @@ issue979_test_negated_is_best: {
|
||||
options = {
|
||||
sequences:true, properties:true, dead_code:true, conditionals:true,
|
||||
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
|
||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true
|
||||
keep_fargs:true, if_return:true, join_vars:true, side_effects:true
|
||||
}
|
||||
input: {
|
||||
function f3() {
|
||||
@@ -82,7 +82,7 @@ issue979_test_negated_is_best: {
|
||||
1!=a||2!=b||foo();
|
||||
}
|
||||
function f7() {
|
||||
return 1!=a&&2!=b?bar():void foo();
|
||||
if(1!=a&&2!=b)return bar();foo()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ labels_1: {
|
||||
expect: {
|
||||
foo || console.log("bar");
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
labels_2: {
|
||||
@@ -40,6 +41,7 @@ labels_3: {
|
||||
for (var i = 0; i < 5; ++i)
|
||||
i < 3 || console.log(i);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
labels_4: {
|
||||
@@ -54,6 +56,7 @@ labels_4: {
|
||||
for (var i = 0; i < 5; ++i)
|
||||
i < 3 || console.log(i);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
labels_5: {
|
||||
|
||||
@@ -144,4 +144,351 @@ parse_do_while_without_semicolon: {
|
||||
expect: {
|
||||
do x(); while (false);y();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
evaluate: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
loops: true,
|
||||
passes: 2,
|
||||
side_effects: true,
|
||||
};
|
||||
input: {
|
||||
while (true) {
|
||||
a();
|
||||
}
|
||||
while (false) {
|
||||
b();
|
||||
}
|
||||
do {
|
||||
c();
|
||||
} while (true);
|
||||
do {
|
||||
d();
|
||||
} while (false);
|
||||
}
|
||||
expect: {
|
||||
for(;;)
|
||||
a();
|
||||
for(;;)
|
||||
c();
|
||||
d();
|
||||
}
|
||||
}
|
||||
|
||||
issue_1532: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
function f(x, y) {
|
||||
do {
|
||||
if (x) break;
|
||||
foo();
|
||||
} while (false);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(x, y) {
|
||||
do {
|
||||
if (x) break;
|
||||
foo();
|
||||
} while (false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_186: {
|
||||
beautify = {
|
||||
beautify: false,
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
var x = 3;
|
||||
if (foo())
|
||||
do
|
||||
do
|
||||
alert(x);
|
||||
while (--x);
|
||||
while (x);
|
||||
else
|
||||
bar();
|
||||
}
|
||||
expect_exact: 'var x=3;if(foo())do{do{alert(x)}while(--x)}while(x);else bar();'
|
||||
}
|
||||
|
||||
issue_186_ie8: {
|
||||
beautify = {
|
||||
beautify: false,
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
var x = 3;
|
||||
if (foo())
|
||||
do
|
||||
do
|
||||
alert(x);
|
||||
while (--x);
|
||||
while (x);
|
||||
else
|
||||
bar();
|
||||
}
|
||||
expect_exact: 'var x=3;if(foo()){do{do{alert(x)}while(--x)}while(x)}else bar();'
|
||||
}
|
||||
|
||||
issue_186_beautify: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
var x = 3;
|
||||
if (foo())
|
||||
do
|
||||
do
|
||||
alert(x);
|
||||
while (--x);
|
||||
while (x);
|
||||
else
|
||||
bar();
|
||||
}
|
||||
expect_exact: [
|
||||
'var x = 3;',
|
||||
'',
|
||||
'if (foo()) do {',
|
||||
' do {',
|
||||
' alert(x);',
|
||||
' } while (--x);',
|
||||
'} while (x); else bar();',
|
||||
]
|
||||
}
|
||||
|
||||
issue_186_beautify_ie8: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
var x = 3;
|
||||
if (foo())
|
||||
do
|
||||
do
|
||||
alert(x);
|
||||
while (--x);
|
||||
while (x);
|
||||
else
|
||||
bar();
|
||||
}
|
||||
expect_exact: [
|
||||
'var x = 3;',
|
||||
'',
|
||||
'if (foo()) {',
|
||||
' do {',
|
||||
' do {',
|
||||
' alert(x);',
|
||||
' } while (--x);',
|
||||
' } while (x);',
|
||||
'} else bar();',
|
||||
]
|
||||
}
|
||||
|
||||
issue_186_bracketize: {
|
||||
beautify = {
|
||||
beautify: false,
|
||||
bracketize: true,
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
var x = 3;
|
||||
if (foo())
|
||||
do
|
||||
do
|
||||
alert(x);
|
||||
while (--x);
|
||||
while (x);
|
||||
else
|
||||
bar();
|
||||
}
|
||||
expect_exact: 'var x=3;if(foo()){do{do{alert(x)}while(--x)}while(x)}else{bar()}'
|
||||
}
|
||||
|
||||
issue_186_bracketize_ie8: {
|
||||
beautify = {
|
||||
beautify: false,
|
||||
bracketize: true,
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
var x = 3;
|
||||
if (foo())
|
||||
do
|
||||
do
|
||||
alert(x);
|
||||
while (--x);
|
||||
while (x);
|
||||
else
|
||||
bar();
|
||||
}
|
||||
expect_exact: 'var x=3;if(foo()){do{do{alert(x)}while(--x)}while(x)}else{bar()}'
|
||||
}
|
||||
|
||||
issue_186_beautify_bracketize: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
bracketize: true,
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
var x = 3;
|
||||
if (foo())
|
||||
do
|
||||
do
|
||||
alert(x);
|
||||
while (--x);
|
||||
while (x);
|
||||
else
|
||||
bar();
|
||||
}
|
||||
expect_exact: [
|
||||
'var x = 3;',
|
||||
'',
|
||||
'if (foo()) {',
|
||||
' do {',
|
||||
' do {',
|
||||
' alert(x);',
|
||||
' } while (--x);',
|
||||
' } while (x);',
|
||||
'} else {',
|
||||
' bar();',
|
||||
'}',
|
||||
]
|
||||
}
|
||||
|
||||
issue_186_beautify_bracketize_ie8: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
bracketize: true,
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
var x = 3;
|
||||
if (foo())
|
||||
do
|
||||
do
|
||||
alert(x);
|
||||
while (--x);
|
||||
while (x);
|
||||
else
|
||||
bar();
|
||||
}
|
||||
expect_exact: [
|
||||
'var x = 3;',
|
||||
'',
|
||||
'if (foo()) {',
|
||||
' do {',
|
||||
' do {',
|
||||
' alert(x);',
|
||||
' } while (--x);',
|
||||
' } while (x);',
|
||||
'} else {',
|
||||
' bar();',
|
||||
'}',
|
||||
]
|
||||
}
|
||||
|
||||
issue_1648: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
loops: true,
|
||||
passes: 2,
|
||||
sequences: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
x();
|
||||
var b = 1;
|
||||
while (1);
|
||||
}
|
||||
}
|
||||
expect_exact: "function f(){for(x();1;);}"
|
||||
}
|
||||
|
||||
do_switch: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
do {
|
||||
switch (a) {
|
||||
case b:
|
||||
continue;
|
||||
}
|
||||
} while (false);
|
||||
}
|
||||
expect: {
|
||||
do {
|
||||
switch (a) {
|
||||
case b:
|
||||
continue;
|
||||
}
|
||||
} while (false);
|
||||
}
|
||||
}
|
||||
|
||||
in_parenthesis_1: {
|
||||
input: {
|
||||
for (("foo" in {});0;);
|
||||
}
|
||||
expect_exact: 'for(("foo"in{});0;);'
|
||||
}
|
||||
|
||||
in_parenthesis_2: {
|
||||
input: {
|
||||
for ((function(){ "foo" in {}; });0;);
|
||||
}
|
||||
expect_exact: 'for(function(){"foo"in{}};0;);'
|
||||
}
|
||||
|
||||
init_side_effects: {
|
||||
options = {
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
};
|
||||
input: {
|
||||
for (function() {}(), i = 0; i < 5; i++) console.log(i);
|
||||
for (function() {}(); i < 10; i++) console.log(i);
|
||||
}
|
||||
expect: {
|
||||
for (i = 0; i < 5; i++) console.log(i);
|
||||
for (; i < 10; i++) console.log(i);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
dead_code_condition: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
loops: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
for (var a = 0, b = 5; (a += 1, 3) - 3 && b > 0; b--) {
|
||||
var c = function() {
|
||||
b--;
|
||||
}(a++);
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var c;
|
||||
var a = 0, b = 5;
|
||||
a += 1, 0,
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
39
test/compress/max_line_len.js
Normal file
39
test/compress/max_line_len.js
Normal file
@@ -0,0 +1,39 @@
|
||||
too_short: {
|
||||
beautify = {
|
||||
max_line_len: 10,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
return { c: 42, d: a(), e: "foo"};
|
||||
}
|
||||
}
|
||||
expect_exact: [
|
||||
'function f(a){',
|
||||
'return{',
|
||||
'c:42,',
|
||||
'd:a(),',
|
||||
'e:"foo"}}',
|
||||
]
|
||||
expect_warnings: [
|
||||
"WARN: Output exceeds 10 characters"
|
||||
]
|
||||
}
|
||||
|
||||
just_enough: {
|
||||
beautify = {
|
||||
max_line_len: 14,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
return { c: 42, d: a(), e: "foo"};
|
||||
}
|
||||
}
|
||||
expect_exact: [
|
||||
'function f(a){',
|
||||
'return{c:42,',
|
||||
'd:a(),e:"foo"}',
|
||||
'}',
|
||||
]
|
||||
expect_warnings: [
|
||||
]
|
||||
}
|
||||
@@ -10,56 +10,173 @@ negate_iife_1: {
|
||||
}
|
||||
}
|
||||
|
||||
negate_iife_2: {
|
||||
negate_iife_1_off: {
|
||||
options = {
|
||||
negate_iife: true
|
||||
negate_iife: false,
|
||||
};
|
||||
input: {
|
||||
(function(){ return {} })().x = 10; // should not transform this one
|
||||
(function(){ stuff() })();
|
||||
}
|
||||
expect: {
|
||||
expect_exact: '(function(){stuff()})();'
|
||||
}
|
||||
|
||||
negate_iife_2: {
|
||||
options = {
|
||||
inline: true,
|
||||
negate_iife: true,
|
||||
};
|
||||
input: {
|
||||
(function(){ return {} })().x = 10;
|
||||
}
|
||||
expect_exact: "({}).x=10;"
|
||||
}
|
||||
|
||||
negate_iife_2_side_effects: {
|
||||
options = {
|
||||
inline: true,
|
||||
negate_iife: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(function(){ return {} })().x = 10;
|
||||
}
|
||||
expect_exact: "({}).x=10;"
|
||||
}
|
||||
|
||||
negate_iife_3: {
|
||||
options = {
|
||||
negate_iife: true,
|
||||
conditionals: true
|
||||
};
|
||||
input: {
|
||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||
}
|
||||
expect: {
|
||||
!function(){ return t }() ? console.log(false) : console.log(true);
|
||||
}
|
||||
}
|
||||
|
||||
negate_iife_3_evaluate: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
negate_iife: true,
|
||||
}
|
||||
input: {
|
||||
(function(){ return true })() ? console.log(true) : console.log(false);
|
||||
}
|
||||
expect: {
|
||||
!function(){ return true }() ? console.log(false) : console.log(true);
|
||||
console.log(true);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
negate_iife_3_side_effects: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
negate_iife: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||
}
|
||||
expect: {
|
||||
!function(){ return t }() ? console.log(false) : console.log(true);
|
||||
}
|
||||
}
|
||||
|
||||
negate_iife_3: {
|
||||
negate_iife_3_off: {
|
||||
options = {
|
||||
negate_iife: false,
|
||||
conditionals: true,
|
||||
};
|
||||
input: {
|
||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||
}
|
||||
expect: {
|
||||
!function(){ return t }() ? console.log(false) : console.log(true);
|
||||
}
|
||||
}
|
||||
|
||||
negate_iife_3_off_evaluate: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
negate_iife: false,
|
||||
}
|
||||
input: {
|
||||
(function(){ return true })() ? console.log(true) : console.log(false);
|
||||
}
|
||||
expect: {
|
||||
console.log(true);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
negate_iife_4: {
|
||||
options = {
|
||||
negate_iife: true,
|
||||
conditionals: true,
|
||||
sequences: true
|
||||
};
|
||||
input: {
|
||||
(function(){ return true })() ? console.log(true) : console.log(false);
|
||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||
(function(){
|
||||
console.log("something");
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
!function(){ return true }() ? console.log(false) : console.log(true), function(){
|
||||
!function(){ return t }() ? console.log(false) : console.log(true), function(){
|
||||
console.log("something");
|
||||
}();
|
||||
}
|
||||
}
|
||||
|
||||
negate_iife_4: {
|
||||
sequence_off: {
|
||||
options = {
|
||||
negate_iife: false,
|
||||
conditionals: true,
|
||||
sequences: true,
|
||||
passes: 2,
|
||||
};
|
||||
input: {
|
||||
function f() {
|
||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||
(function(){
|
||||
console.log("something");
|
||||
})();
|
||||
}
|
||||
function g() {
|
||||
(function(){
|
||||
console.log("something");
|
||||
})();
|
||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
!function(){ return t }() ? console.log(false) : console.log(true), function(){
|
||||
console.log("something");
|
||||
}();
|
||||
}
|
||||
function g() {
|
||||
(function(){
|
||||
console.log("something");
|
||||
})(), function(){ return t }() ? console.log(true) : console.log(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
negate_iife_5: {
|
||||
options = {
|
||||
negate_iife: true,
|
||||
sequences: true,
|
||||
conditionals: true,
|
||||
};
|
||||
input: {
|
||||
if ((function(){ return true })()) {
|
||||
if ((function(){ return t })()) {
|
||||
foo(true);
|
||||
} else {
|
||||
bar(false);
|
||||
@@ -69,8 +186,233 @@ negate_iife_4: {
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
!function(){ return true }() ? bar(false) : foo(true), function(){
|
||||
!function(){ return t }() ? bar(false) : foo(true), function(){
|
||||
console.log("something");
|
||||
}();
|
||||
}
|
||||
}
|
||||
|
||||
negate_iife_5_off: {
|
||||
options = {
|
||||
negate_iife: false,
|
||||
sequences: true,
|
||||
conditionals: true,
|
||||
};
|
||||
input: {
|
||||
if ((function(){ return t })()) {
|
||||
foo(true);
|
||||
} else {
|
||||
bar(false);
|
||||
}
|
||||
(function(){
|
||||
console.log("something");
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
!function(){ return t }() ? bar(false) : foo(true), function(){
|
||||
console.log("something");
|
||||
}();
|
||||
}
|
||||
}
|
||||
|
||||
negate_iife_nested: {
|
||||
options = {
|
||||
negate_iife: true,
|
||||
sequences: true,
|
||||
conditionals: true,
|
||||
};
|
||||
input: {
|
||||
function Foo(f) {
|
||||
this.f = f;
|
||||
}
|
||||
new Foo(function() {
|
||||
(function(x) {
|
||||
(function(y) {
|
||||
console.log(y);
|
||||
})(x);
|
||||
})(7);
|
||||
}).f();
|
||||
}
|
||||
expect: {
|
||||
function Foo(f) {
|
||||
this.f = f;
|
||||
}
|
||||
new Foo(function() {
|
||||
!function(x) {
|
||||
!function(y) {
|
||||
console.log(y);
|
||||
}(x);
|
||||
}(7);
|
||||
}).f();
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
negate_iife_nested_off: {
|
||||
options = {
|
||||
negate_iife: false,
|
||||
sequences: true,
|
||||
conditionals: true,
|
||||
};
|
||||
input: {
|
||||
function Foo(f) {
|
||||
this.f = f;
|
||||
}
|
||||
new Foo(function() {
|
||||
(function(x) {
|
||||
(function(y) {
|
||||
console.log(y);
|
||||
})(x);
|
||||
})(7);
|
||||
}).f();
|
||||
}
|
||||
expect: {
|
||||
function Foo(f) {
|
||||
this.f = f;
|
||||
}
|
||||
new Foo(function() {
|
||||
(function(x) {
|
||||
(function(y) {
|
||||
console.log(y);
|
||||
})(x);
|
||||
})(7);
|
||||
}).f();
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
negate_iife_issue_1073: {
|
||||
options = {
|
||||
negate_iife: true,
|
||||
sequences: true,
|
||||
conditionals: true,
|
||||
};
|
||||
input: {
|
||||
new (function(a) {
|
||||
return function Foo() {
|
||||
this.x = a;
|
||||
console.log(this);
|
||||
};
|
||||
}(7))();
|
||||
}
|
||||
expect: {
|
||||
new (function(a) {
|
||||
return function Foo() {
|
||||
this.x = a,
|
||||
console.log(this);
|
||||
};
|
||||
}(7))();
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1254_negate_iife_false: {
|
||||
options = {
|
||||
negate_iife: false,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
return function() {
|
||||
console.log('test')
|
||||
};
|
||||
})()();
|
||||
}
|
||||
expect_exact: '(function(){return function(){console.log("test")}})()();'
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1254_negate_iife_true: {
|
||||
options = {
|
||||
negate_iife: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
return function() {
|
||||
console.log('test')
|
||||
};
|
||||
})()();
|
||||
}
|
||||
expect_exact: '!function(){return function(){console.log("test")}}()();'
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1254_negate_iife_nested: {
|
||||
options = {
|
||||
negate_iife: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
return function() {
|
||||
console.log('test')
|
||||
};
|
||||
})()()()()();
|
||||
}
|
||||
expect_exact: '!function(){return function(){console.log("test")}}()()()()();'
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1288: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
negate_iife: true,
|
||||
side_effects: false,
|
||||
};
|
||||
input: {
|
||||
if (w) ;
|
||||
else {
|
||||
(function f() {})();
|
||||
}
|
||||
if (!x) {
|
||||
(function() {
|
||||
x = {};
|
||||
})();
|
||||
}
|
||||
if (y)
|
||||
(function() {})();
|
||||
else
|
||||
(function(z) {
|
||||
return z;
|
||||
})(0);
|
||||
}
|
||||
expect: {
|
||||
w || !function f() {}();
|
||||
x || !function() {
|
||||
x = {};
|
||||
}();
|
||||
y ? !function() {}() : !function(z) {
|
||||
return z;
|
||||
}(0);
|
||||
}
|
||||
}
|
||||
|
||||
issue_1288_side_effects: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
negate_iife: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
if (w) ;
|
||||
else {
|
||||
(function f() {})();
|
||||
}
|
||||
if (!x) {
|
||||
(function() {
|
||||
x = {};
|
||||
})();
|
||||
}
|
||||
if (y)
|
||||
(function() {})();
|
||||
else
|
||||
(function(z) {
|
||||
return z;
|
||||
})(0);
|
||||
}
|
||||
expect: {
|
||||
w;
|
||||
x || function() {
|
||||
x = {};
|
||||
}();
|
||||
y;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,3 +10,91 @@ new_statement: {
|
||||
}
|
||||
expect_exact: "new x(1);new x(1)(2);new x(1)(2)(3);new new x(1);new new x(1)(2);new new x(1)(2);(new new x(1))(2);"
|
||||
}
|
||||
|
||||
new_statements_2: {
|
||||
input: {
|
||||
new x;
|
||||
new new x;
|
||||
new new new x;
|
||||
new true;
|
||||
new (0);
|
||||
new (!0);
|
||||
new (bar = function(foo) {this.foo=foo;})(123);
|
||||
new (bar = function(foo) {this.foo=foo;})();
|
||||
}
|
||||
expect_exact: "new x;new(new x);new(new(new x));new true;new 0;new(!0);new(bar=function(foo){this.foo=foo})(123);new(bar=function(foo){this.foo=foo});"
|
||||
}
|
||||
|
||||
new_statements_3: {
|
||||
input: {
|
||||
new (function(foo){this.foo=foo;})(1);
|
||||
new (function(foo){this.foo=foo;})();
|
||||
new (function test(foo){this.foo=foo;})(1);
|
||||
new (function test(foo){this.foo=foo;})();
|
||||
}
|
||||
expect_exact: "new function(foo){this.foo=foo}(1);new function(foo){this.foo=foo};new function test(foo){this.foo=foo}(1);new function test(foo){this.foo=foo};"
|
||||
}
|
||||
|
||||
new_with_rewritten_true_value: {
|
||||
options = { booleans: true }
|
||||
input: {
|
||||
new true;
|
||||
}
|
||||
expect_exact: "new(!0);"
|
||||
}
|
||||
|
||||
new_with_many_parameters: {
|
||||
input: {
|
||||
new foo.bar("baz");
|
||||
new x(/123/, 456);
|
||||
}
|
||||
expect_exact: 'new foo.bar("baz");new x(/123/,456);'
|
||||
}
|
||||
|
||||
new_constructor_with_unary_arguments: {
|
||||
input: {
|
||||
new x();
|
||||
new x(-1);
|
||||
new x(-1, -2);
|
||||
new x(void 1, +2, -3, ~4, !5, --a, ++b, c--, d++, typeof e, delete f);
|
||||
new (-1); // should parse despite being invalid at runtime.
|
||||
new (-1)(); // should parse despite being invalid at runtime.
|
||||
new (-1)(-2); // should parse despite being invalid at runtime.
|
||||
}
|
||||
expect_exact: "new x;new x(-1);new x(-1,-2);new x(void 1,+2,-3,~4,!5,--a,++b,c--,d++,typeof e,delete f);new(-1);new(-1);new(-1)(-2);"
|
||||
}
|
||||
|
||||
call_with_unary_arguments: {
|
||||
input: {
|
||||
x();
|
||||
x(-1);
|
||||
x(-1, -2);
|
||||
x(void 1, +2, -3, ~4, !5, --a, ++b, c--, d++, typeof e, delete f);
|
||||
(-1)(); // should parse despite being invalid at runtime.
|
||||
(-1)(-2); // should parse despite being invalid at runtime.
|
||||
}
|
||||
expect_exact: "x();x(-1);x(-1,-2);x(void 1,+2,-3,~4,!5,--a,++b,c--,d++,typeof e,delete f);(-1)();(-1)(-2);"
|
||||
}
|
||||
|
||||
new_with_unary_prefix: {
|
||||
input: {
|
||||
var bar = (+new Date()).toString(32);
|
||||
}
|
||||
expect_exact: 'var bar=(+new Date).toString(32);';
|
||||
}
|
||||
|
||||
dot_parenthesis_1: {
|
||||
input: {
|
||||
console.log(new (Math.random().constructor) instanceof Number);
|
||||
}
|
||||
expect_exact: "console.log(new(Math.random().constructor)instanceof Number);"
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
dot_parenthesis_2: {
|
||||
input: {
|
||||
console.log(typeof new function(){Math.random()}.constructor);
|
||||
}
|
||||
expect_exact: "console.log(typeof new function(){Math.random()}.constructor);"
|
||||
expect_stdout: "function"
|
||||
}
|
||||
|
||||
38
test/compress/node_version.js
Normal file
38
test/compress/node_version.js
Normal file
@@ -0,0 +1,38 @@
|
||||
eval_let_6: {
|
||||
input: {
|
||||
eval("let a;");
|
||||
console.log();
|
||||
}
|
||||
expect: {
|
||||
eval("let a;");
|
||||
console.log();
|
||||
}
|
||||
expect_stdout: ""
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
eval_let_4: {
|
||||
input: {
|
||||
eval("let a;");
|
||||
console.log();
|
||||
}
|
||||
expect: {
|
||||
eval("let a;");
|
||||
console.log();
|
||||
}
|
||||
expect_stdout: SyntaxError("Block-scoped declarations (let, const, function, class) not yet supported outside strict mode")
|
||||
node_version: "4"
|
||||
}
|
||||
|
||||
eval_let_0: {
|
||||
input: {
|
||||
eval("let a;");
|
||||
console.log();
|
||||
}
|
||||
expect: {
|
||||
eval("let a;");
|
||||
console.log();
|
||||
}
|
||||
expect_stdout: SyntaxError("Unexpected identifier")
|
||||
node_version: "<=0.12"
|
||||
}
|
||||
204
test/compress/numbers.js
Normal file
204
test/compress/numbers.js
Normal file
@@ -0,0 +1,204 @@
|
||||
hex_numbers_in_parentheses_for_prototype_functions: {
|
||||
input: {
|
||||
(-2);
|
||||
(-2).toFixed(0);
|
||||
|
||||
(2);
|
||||
(2).toFixed(0);
|
||||
|
||||
(0.2);
|
||||
(0.2).toFixed(0);
|
||||
|
||||
(0.00000002);
|
||||
(0.00000002).toFixed(0);
|
||||
|
||||
(1000000000000000128);
|
||||
(1000000000000000128).toFixed(0);
|
||||
}
|
||||
expect_exact: "-2;(-2).toFixed(0);2;2..toFixed(0);.2;.2.toFixed(0);2e-8;2e-8.toFixed(0);0xde0b6b3a7640080;(0xde0b6b3a7640080).toFixed(0);"
|
||||
}
|
||||
|
||||
comparisons: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
console.log(
|
||||
~x === 42,
|
||||
x % n === 42
|
||||
);
|
||||
}
|
||||
expect: {
|
||||
console.log(
|
||||
42 == ~x,
|
||||
x % n == 42
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
evaluate_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe_math: false,
|
||||
}
|
||||
input: {
|
||||
console.log(
|
||||
x + 1 + 2,
|
||||
x * 1 * 2,
|
||||
+x + 1 + 2,
|
||||
1 + x + 2 + 3,
|
||||
1 | x | 2 | 3,
|
||||
1 + x-- + 2 + 3,
|
||||
1 + (x*y + 2) + 3,
|
||||
1 + (2 + x + 3),
|
||||
1 + (2 + ~x + 3),
|
||||
-y + (2 + ~x + 3),
|
||||
1 & (2 & x & 3),
|
||||
1 + (2 + (x |= 0) + 3)
|
||||
);
|
||||
}
|
||||
expect: {
|
||||
console.log(
|
||||
x + 1 + 2,
|
||||
1 * x * 2,
|
||||
+x + 1 + 2,
|
||||
1 + x + 2 + 3,
|
||||
3 | x,
|
||||
1 + x-- + 2 + 3,
|
||||
x*y + 2 + 1 + 3,
|
||||
1 + (2 + x + 3),
|
||||
2 + ~x + 3 + 1,
|
||||
-y + (2 + ~x + 3),
|
||||
0 & x,
|
||||
2 + (x |= 0) + 3 + 1
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
evaluate_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe_math: true,
|
||||
}
|
||||
input: {
|
||||
console.log(
|
||||
x + 1 + 2,
|
||||
x * 1 * 2,
|
||||
+x + 1 + 2,
|
||||
1 + x + 2 + 3,
|
||||
1 | x | 2 | 3,
|
||||
1 + x-- + 2 + 3,
|
||||
1 + (x*y + 2) + 3,
|
||||
1 + (2 + x + 3),
|
||||
1 & (2 & x & 3),
|
||||
1 + (2 + (x |= 0) + 3)
|
||||
);
|
||||
}
|
||||
expect: {
|
||||
console.log(
|
||||
x + 1 + 2,
|
||||
2 * x,
|
||||
3 + +x,
|
||||
1 + x + 2 + 3,
|
||||
3 | x,
|
||||
6 + x--,
|
||||
6 + x*y,
|
||||
1 + (2 + x + 3),
|
||||
0 & x,
|
||||
6 + (x |= 0)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
evaluate_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe: true,
|
||||
unsafe_math: true,
|
||||
}
|
||||
input: {
|
||||
console.log(1 + Number(x) + 2);
|
||||
}
|
||||
expect: {
|
||||
console.log(3 + +x);
|
||||
}
|
||||
}
|
||||
|
||||
evaluate_4: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
console.log(
|
||||
1+ +a,
|
||||
+a+1,
|
||||
1+-a,
|
||||
-a+1,
|
||||
+a+ +b,
|
||||
+a+-b,
|
||||
-a+ +b,
|
||||
-a+-b
|
||||
);
|
||||
}
|
||||
expect: {
|
||||
console.log(
|
||||
+a+1,
|
||||
+a+1,
|
||||
1-a,
|
||||
1-a,
|
||||
+a+ +b,
|
||||
+a-b,
|
||||
-a+ +b,
|
||||
-a-b
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
issue_1710: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
var x = {};
|
||||
console.log((x += 1) + -x);
|
||||
}
|
||||
expect: {
|
||||
var x = {};
|
||||
console.log((x += 1) + -x);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
unary_binary_parenthesis: {
|
||||
input: {
|
||||
var v = [ 0, 1, NaN, Infinity, null, undefined, true, false, "", "foo", /foo/ ];
|
||||
v.forEach(function(x) {
|
||||
v.forEach(function(y) {
|
||||
console.log(
|
||||
+(x*y),
|
||||
+(x/y),
|
||||
+(x%y),
|
||||
-(x*y),
|
||||
-(x/y),
|
||||
-(x%y)
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
var v = [ 0, 1, NaN, 1/0, null, void 0, true, false, "", "foo", /foo/ ];
|
||||
v.forEach(function(x) {
|
||||
v.forEach(function(y) {
|
||||
console.log(
|
||||
+x*y,
|
||||
+x/y,
|
||||
+x%y,
|
||||
-x*y,
|
||||
-x/y,
|
||||
-x%y
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
416
test/compress/pure_funcs.js
Normal file
416
test/compress/pure_funcs.js
Normal file
@@ -0,0 +1,416 @@
|
||||
array: {
|
||||
options = {
|
||||
pure_funcs: [ "Math.floor" ],
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
function f(b) {
|
||||
Math.floor(a / b);
|
||||
Math.floor(c / b);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
function f(b) {
|
||||
c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func: {
|
||||
options = {
|
||||
pure_funcs: function(node) {
|
||||
return !~node.args[0].print_to_string().indexOf("a");
|
||||
},
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b) {
|
||||
Math.floor(a / b);
|
||||
Math.floor(c / b);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(a, b) {
|
||||
Math.floor(c / b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
side_effects: {
|
||||
options = {
|
||||
pure_funcs: [ "console.log" ],
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b) {
|
||||
console.log(a());
|
||||
console.log(b);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(a, b) {
|
||||
a();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unused: {
|
||||
options = {
|
||||
pure_funcs: [ "pure" ],
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function foo() {
|
||||
var u = pure(1);
|
||||
var x = pure(2);
|
||||
var y = pure(x);
|
||||
var z = pure(pure(side_effects()));
|
||||
return pure(3);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function foo() {
|
||||
side_effects();
|
||||
return pure(3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
babel: {
|
||||
options = {
|
||||
pure_funcs: [ "_classCallCheck" ],
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function _classCallCheck(instance, Constructor) {
|
||||
if (!(instance instanceof Constructor))
|
||||
throw new TypeError("Cannot call a class as a function");
|
||||
}
|
||||
var Foo = function Foo() {
|
||||
_classCallCheck(this, Foo);
|
||||
};
|
||||
}
|
||||
expect: {
|
||||
function _classCallCheck(instance, Constructor) {
|
||||
if (!(instance instanceof Constructor))
|
||||
throw new TypeError("Cannot call a class as a function");
|
||||
}
|
||||
var Foo = function() {
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
conditional: {
|
||||
options = {
|
||||
pure_funcs: [ "pure" ],
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
pure(1 | a() ? 2 & b() : 7 ^ c());
|
||||
pure(1 | a() ? 2 & b() : 5);
|
||||
pure(1 | a() ? 4 : 7 ^ c());
|
||||
pure(1 | a() ? 4 : 5);
|
||||
pure(3 ? 2 & b() : 7 ^ c());
|
||||
pure(3 ? 2 & b() : 5);
|
||||
pure(3 ? 4 : 7 ^ c());
|
||||
pure(3 ? 4 : 5);
|
||||
}
|
||||
expect: {
|
||||
1 | a() ? b() : c();
|
||||
1 | a() && b();
|
||||
1 | a() || c();
|
||||
a();
|
||||
3 ? b() : c();
|
||||
3 && b();
|
||||
3 || c();
|
||||
}
|
||||
}
|
||||
|
||||
relational: {
|
||||
options = {
|
||||
pure_funcs: [ "foo" ],
|
||||
side_effects :true,
|
||||
}
|
||||
input: {
|
||||
foo() in foo();
|
||||
foo() instanceof bar();
|
||||
foo() < "bar";
|
||||
bar() > foo();
|
||||
bar() != bar();
|
||||
bar() !== "bar";
|
||||
"bar" == foo();
|
||||
"bar" === bar();
|
||||
"bar" >= "bar";
|
||||
}
|
||||
expect: {
|
||||
bar();
|
||||
bar();
|
||||
bar(), bar();
|
||||
bar();
|
||||
bar();
|
||||
}
|
||||
}
|
||||
|
||||
arithmetic: {
|
||||
options = {
|
||||
pure_funcs: [ "foo" ],
|
||||
side_effects :true,
|
||||
}
|
||||
input: {
|
||||
foo() + foo();
|
||||
foo() - bar();
|
||||
foo() * "bar";
|
||||
bar() / foo();
|
||||
bar() & bar();
|
||||
bar() | "bar";
|
||||
"bar" >> foo();
|
||||
"bar" << bar();
|
||||
"bar" >>> "bar";
|
||||
}
|
||||
expect: {
|
||||
bar();
|
||||
bar();
|
||||
bar(), bar();
|
||||
bar();
|
||||
bar();
|
||||
}
|
||||
}
|
||||
|
||||
boolean_and: {
|
||||
options = {
|
||||
pure_funcs: [ "foo" ],
|
||||
side_effects :true,
|
||||
}
|
||||
input: {
|
||||
foo() && foo();
|
||||
foo() && bar();
|
||||
foo() && "bar";
|
||||
bar() && foo();
|
||||
bar() && bar();
|
||||
bar() && "bar";
|
||||
"bar" && foo();
|
||||
"bar" && bar();
|
||||
"bar" && "bar";
|
||||
}
|
||||
expect: {
|
||||
foo() && bar();
|
||||
bar();
|
||||
bar() && bar();
|
||||
bar();
|
||||
"bar" && bar();
|
||||
}
|
||||
}
|
||||
|
||||
boolean_or: {
|
||||
options = {
|
||||
pure_funcs: [ "foo" ],
|
||||
side_effects :true,
|
||||
}
|
||||
input: {
|
||||
foo() || foo();
|
||||
foo() || bar();
|
||||
foo() || "bar";
|
||||
bar() || foo();
|
||||
bar() || bar();
|
||||
bar() || "bar";
|
||||
"bar" || foo();
|
||||
"bar" || bar();
|
||||
"bar" || "bar";
|
||||
}
|
||||
expect: {
|
||||
foo() || bar();
|
||||
bar();
|
||||
bar() || bar();
|
||||
bar();
|
||||
"bar" || bar();
|
||||
}
|
||||
}
|
||||
|
||||
assign: {
|
||||
options = {
|
||||
pure_funcs: [ "foo" ],
|
||||
side_effects :true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
function f(b) {
|
||||
a = foo();
|
||||
b *= 4 + foo();
|
||||
c >>= 0 | foo();
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
function f(b) {
|
||||
a = foo();
|
||||
b *= 4 + foo();
|
||||
c >>= 0 | foo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unary: {
|
||||
options = {
|
||||
pure_funcs: [ "foo" ],
|
||||
side_effects :true,
|
||||
}
|
||||
input: {
|
||||
typeof foo();
|
||||
typeof bar();
|
||||
typeof "bar";
|
||||
void foo();
|
||||
void bar();
|
||||
void "bar";
|
||||
delete a[foo()];
|
||||
delete a[bar()];
|
||||
delete a["bar"];
|
||||
a[foo()]++;
|
||||
a[bar()]++;
|
||||
a["bar"]++;
|
||||
--a[foo()];
|
||||
--a[bar()];
|
||||
--a["bar"];
|
||||
~foo();
|
||||
~bar();
|
||||
~"bar";
|
||||
}
|
||||
expect: {
|
||||
bar();
|
||||
bar();
|
||||
delete a[foo()];
|
||||
delete a[bar()];
|
||||
delete a["bar"];
|
||||
a[foo()]++;
|
||||
a[bar()]++;
|
||||
a["bar"]++;
|
||||
--a[foo()];
|
||||
--a[bar()];
|
||||
--a["bar"];
|
||||
bar();
|
||||
}
|
||||
}
|
||||
|
||||
issue_2629_1: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
beautify = {
|
||||
comments: "all",
|
||||
}
|
||||
input: {
|
||||
/*@__PURE__*/ a();
|
||||
/*@__PURE__*/ (b());
|
||||
(/*@__PURE__*/ c)();
|
||||
(/*@__PURE__*/ d());
|
||||
}
|
||||
expect_exact: [
|
||||
"/* */c();",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2629_2: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
beautify = {
|
||||
comments: "all",
|
||||
}
|
||||
input: {
|
||||
/*@__PURE__*/ a(1)(2)(3);
|
||||
/*@__PURE__*/ (b(1))(2)(3);
|
||||
/*@__PURE__*/ (c(1)(2))(3);
|
||||
/*@__PURE__*/ (d(1)(2)(3));
|
||||
(/*@__PURE__*/ e)(1)(2)(3);
|
||||
(/*@__PURE__*/ f(1))(2)(3);
|
||||
(/*@__PURE__*/ g(1)(2))(3);
|
||||
(/*@__PURE__*/ h(1)(2)(3));
|
||||
}
|
||||
expect_exact: [
|
||||
"/* */e(1)(2)(3);",
|
||||
"/* */f(1)(2)(3);",
|
||||
"/* */g(1)(2)(3);",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2629_3: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
beautify = {
|
||||
comments: "all",
|
||||
}
|
||||
input: {
|
||||
/*@__PURE__*/ a.x(1).y(2).z(3);
|
||||
/*@__PURE__*/ (b.x)(1).y(2).z(3);
|
||||
/*@__PURE__*/ (c.x(1)).y(2).z(3);
|
||||
/*@__PURE__*/ (d.x(1).y)(2).z(3);
|
||||
/*@__PURE__*/ (e.x(1).y(2)).z(3);
|
||||
/*@__PURE__*/ (f.x(1).y(2).z)(3);
|
||||
/*@__PURE__*/ (g.x(1).y(2).z(3));
|
||||
(/*@__PURE__*/ h).x(1).y(2).z(3);
|
||||
(/*@__PURE__*/ i.x)(1).y(2).z(3);
|
||||
(/*@__PURE__*/ j.x(1)).y(2).z(3);
|
||||
(/*@__PURE__*/ k.x(1).y)(2).z(3);
|
||||
(/*@__PURE__*/ l.x(1).y(2)).z(3);
|
||||
(/*@__PURE__*/ m.x(1).y(2).z)(3);
|
||||
(/*@__PURE__*/ n.x(1).y(2).z(3));
|
||||
}
|
||||
expect_exact: [
|
||||
"/* */h.x(1).y(2).z(3);",
|
||||
"/* */i.x(1).y(2).z(3);",
|
||||
"/* */j.x(1).y(2).z(3);",
|
||||
"/* */k.x(1).y(2).z(3);",
|
||||
"/* */l.x(1).y(2).z(3);",
|
||||
"/* */m.x(1).y(2).z(3);",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2629_4: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(/*@__PURE__*/ x(), y());
|
||||
(w(), /*@__PURE__*/ x(), y());
|
||||
}
|
||||
expect: {
|
||||
y();
|
||||
w(), y();
|
||||
}
|
||||
}
|
||||
|
||||
issue_2629_5: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
[ /*@__PURE__*/ x() ];
|
||||
[ /*@__PURE__*/ x(), y() ];
|
||||
[ w(), /*@__PURE__*/ x(), y() ];
|
||||
}
|
||||
expect: {
|
||||
y();
|
||||
w(), y();
|
||||
}
|
||||
}
|
||||
|
||||
issue_2638: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
beautify = {
|
||||
comments: "all",
|
||||
}
|
||||
input: {
|
||||
/*@__PURE__*/(g() || h())(x(), y());
|
||||
(/*@__PURE__*/ (a() || b()))(c(), d());
|
||||
}
|
||||
expect_exact: [
|
||||
"/* */x(),y();",
|
||||
"/* */(a()||b())(c(),d());",
|
||||
]
|
||||
}
|
||||
613
test/compress/pure_getters.js
Normal file
613
test/compress/pure_getters.js
Normal file
@@ -0,0 +1,613 @@
|
||||
strict: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
reduce_funcs: false,
|
||||
reduce_vars: false,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a, b = null, c = {};
|
||||
a.prop;
|
||||
b.prop;
|
||||
c.prop;
|
||||
d.prop;
|
||||
null.prop;
|
||||
(void 0).prop;
|
||||
undefined.prop;
|
||||
}
|
||||
expect: {
|
||||
var a, b = null, c = {};
|
||||
a.prop;
|
||||
b.prop;
|
||||
c.prop;
|
||||
d.prop;
|
||||
null.prop;
|
||||
(void 0).prop;
|
||||
(void 0).prop;
|
||||
}
|
||||
}
|
||||
|
||||
strict_reduce_vars: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a, b = null, c = {};
|
||||
a.prop;
|
||||
b.prop;
|
||||
c.prop;
|
||||
d.prop;
|
||||
null.prop;
|
||||
(void 0).prop;
|
||||
undefined.prop;
|
||||
}
|
||||
expect: {
|
||||
var a, b = null, c = {};
|
||||
a.prop;
|
||||
b.prop;
|
||||
d.prop;
|
||||
null.prop;
|
||||
(void 0).prop;
|
||||
(void 0).prop;
|
||||
}
|
||||
}
|
||||
|
||||
unsafe: {
|
||||
options = {
|
||||
pure_getters: true,
|
||||
reduce_funcs: false,
|
||||
reduce_vars: false,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a, b = null, c = {};
|
||||
a.prop;
|
||||
b.prop;
|
||||
c.prop;
|
||||
d.prop;
|
||||
null.prop;
|
||||
(void 0).prop;
|
||||
undefined.prop;
|
||||
}
|
||||
expect: {
|
||||
var a, b = null, c = {};
|
||||
d;
|
||||
null.prop;
|
||||
(void 0).prop;
|
||||
(void 0).prop;
|
||||
}
|
||||
}
|
||||
|
||||
unsafe_reduce_vars: {
|
||||
options = {
|
||||
pure_getters: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a, b = null, c = {};
|
||||
a.prop;
|
||||
b.prop;
|
||||
c.prop;
|
||||
d.prop;
|
||||
null.prop;
|
||||
(void 0).prop;
|
||||
undefined.prop;
|
||||
}
|
||||
expect: {
|
||||
var a, b = null, c = {};
|
||||
d;
|
||||
null.prop;
|
||||
(void 0).prop;
|
||||
(void 0).prop;
|
||||
}
|
||||
}
|
||||
|
||||
chained: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
a.b.c;
|
||||
}
|
||||
expect: {
|
||||
a.b.c;
|
||||
}
|
||||
}
|
||||
|
||||
impure_getter_1: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
({
|
||||
get a() {
|
||||
console.log(1);
|
||||
},
|
||||
b: 1
|
||||
}).a;
|
||||
({
|
||||
get a() {
|
||||
console.log(1);
|
||||
},
|
||||
b: 1
|
||||
}).b;
|
||||
}
|
||||
expect: {
|
||||
({
|
||||
get a() {
|
||||
console.log(1);
|
||||
},
|
||||
b: 1
|
||||
}).a;
|
||||
({
|
||||
get a() {
|
||||
console.log(1);
|
||||
},
|
||||
b: 1
|
||||
}).b;
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
impure_getter_2: {
|
||||
options = {
|
||||
pure_getters: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
// will produce incorrect output because getter is not pure
|
||||
({
|
||||
get a() {
|
||||
console.log(1);
|
||||
},
|
||||
b: 1
|
||||
}).a;
|
||||
({
|
||||
get a() {
|
||||
console.log(1);
|
||||
},
|
||||
b: 1
|
||||
}).b;
|
||||
}
|
||||
expect: {}
|
||||
}
|
||||
|
||||
issue_2110_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: "strict",
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
function f() {}
|
||||
function g() {
|
||||
return this;
|
||||
}
|
||||
f.g = g;
|
||||
return f.g();
|
||||
}
|
||||
console.log(typeof f());
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
function f() {}
|
||||
return f.g = function() {
|
||||
return this;
|
||||
}, f.g();
|
||||
}
|
||||
console.log(typeof f());
|
||||
}
|
||||
expect_stdout: "function"
|
||||
}
|
||||
|
||||
issue_2110_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: "strict",
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
function f() {}
|
||||
function g() {
|
||||
return this;
|
||||
}
|
||||
f.g = g;
|
||||
return f.g();
|
||||
}
|
||||
console.log(typeof f());
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
function f() {}
|
||||
f.g = function() {
|
||||
return this;
|
||||
};
|
||||
return f.g();
|
||||
}
|
||||
console.log(typeof f());
|
||||
}
|
||||
expect_stdout: "function"
|
||||
}
|
||||
|
||||
set_immutable_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
pure_getters: "strict",
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 1;
|
||||
a.foo += "";
|
||||
if (a.foo) console.log("FAIL");
|
||||
else console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
1..foo += "";
|
||||
if (1..foo) console.log("FAIL");
|
||||
else console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
set_immutable_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
pure_getters: "strict",
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = 1;
|
||||
a.foo += "";
|
||||
if (a.foo) console.log("FAIL");
|
||||
else console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
var a = 1;
|
||||
a.foo += "", a.foo ? console.log("FAIL") : console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
set_immutable_3: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
pure_getters: "strict",
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var a = 1;
|
||||
a.foo += "";
|
||||
if (a.foo) console.log("FAIL");
|
||||
else console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
1..foo += "";
|
||||
if (1..foo) console.log("FAIL");
|
||||
else console.log("PASS");
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
set_immutable_4: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
pure_getters: "strict",
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var a = 1;
|
||||
a.foo += "";
|
||||
if (a.foo) console.log("FAIL");
|
||||
else console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var a = 1;
|
||||
a.foo += "", a.foo ? console.log("FAIL") : console.log("PASS");
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
set_mutable_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
pure_getters: "strict",
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
!function a() {
|
||||
a.foo += "";
|
||||
if (a.foo) console.log("PASS");
|
||||
else console.log("FAIL");
|
||||
}();
|
||||
}
|
||||
expect: {
|
||||
!function a() {
|
||||
if (a.foo += "") console.log("PASS");
|
||||
else console.log("FAIL");
|
||||
}();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
set_mutable_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
pure_getters: "strict",
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
!function a() {
|
||||
a.foo += "";
|
||||
if (a.foo) console.log("PASS");
|
||||
else console.log("FAIL");
|
||||
}();
|
||||
}
|
||||
expect: {
|
||||
!function a() {
|
||||
(a.foo += "") ? console.log("PASS") : console.log("FAIL");
|
||||
}();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_2313_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
pure_getters: "strict",
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function x() {
|
||||
console.log(1);
|
||||
return {
|
||||
y: function() {
|
||||
console.log(2);
|
||||
return {
|
||||
z: 0
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
x().y().z++;
|
||||
if (x().y().z) {
|
||||
console.log(3);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function x() {
|
||||
return console.log(1), {
|
||||
y: function() {
|
||||
return console.log(2), {
|
||||
z: 0
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
x().y().z++,
|
||||
x().y().z && console.log(3);
|
||||
}
|
||||
expect_stdout: [
|
||||
"1",
|
||||
"2",
|
||||
"1",
|
||||
"2",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2313_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
pure_getters: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function x() {
|
||||
console.log(1);
|
||||
return {
|
||||
y: function() {
|
||||
console.log(2);
|
||||
return {
|
||||
z: 0
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
x().y().z++;
|
||||
if (x().y().z) {
|
||||
console.log(3);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function x() {
|
||||
return console.log(1), {
|
||||
y: function() {
|
||||
return console.log(2), {
|
||||
z: 0
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
x().y().z++,
|
||||
x().y().z && console.log(3);
|
||||
}
|
||||
expect_stdout: [
|
||||
"1",
|
||||
"2",
|
||||
"1",
|
||||
"2",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2313_3: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
pure_getters: "strict",
|
||||
}
|
||||
input: {
|
||||
function x() {
|
||||
console.log(1);
|
||||
return {
|
||||
y: function() {
|
||||
console.log(2);
|
||||
return {
|
||||
z: 0
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
x().y().z++;
|
||||
if (x().y().z) {
|
||||
console.log(3);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function x() {
|
||||
console.log(1);
|
||||
return {
|
||||
y: function() {
|
||||
console.log(2);
|
||||
return {
|
||||
z: 0
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
x().y().z++;
|
||||
x().y().z && console.log(3);
|
||||
}
|
||||
expect_stdout: [
|
||||
"1",
|
||||
"2",
|
||||
"1",
|
||||
"2",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2313_4: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
pure_getters: true,
|
||||
}
|
||||
input: {
|
||||
function x() {
|
||||
console.log(1);
|
||||
return {
|
||||
y: function() {
|
||||
console.log(2);
|
||||
return {
|
||||
z: 0
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
x().y().z++;
|
||||
if (x().y().z) {
|
||||
console.log(3);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function x() {
|
||||
console.log(1);
|
||||
return {
|
||||
y: function() {
|
||||
console.log(2);
|
||||
return {
|
||||
z: 0
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
x().y().z++;
|
||||
x().y().z && console.log(3);
|
||||
}
|
||||
expect_stdout: [
|
||||
"1",
|
||||
"2",
|
||||
"1",
|
||||
"2",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2313_5: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
x().y++;
|
||||
x().y;
|
||||
}
|
||||
expect: {
|
||||
x().y++;
|
||||
x().y;
|
||||
}
|
||||
}
|
||||
|
||||
issue_2313_6: {
|
||||
options = {
|
||||
pure_getters: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
x().y++;
|
||||
x().y;
|
||||
}
|
||||
expect: {
|
||||
x().y++;
|
||||
x();
|
||||
}
|
||||
}
|
||||
4956
test/compress/reduce_vars.js
Normal file
4956
test/compress/reduce_vars.js
Normal file
File diff suppressed because it is too large
Load Diff
536
test/compress/rename.js
Normal file
536
test/compress/rename.js
Normal file
@@ -0,0 +1,536 @@
|
||||
mangle_catch: {
|
||||
rename = true
|
||||
options = {
|
||||
ie8: false,
|
||||
toplevel: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL";
|
||||
try {
|
||||
throw 1;
|
||||
} catch (args) {
|
||||
a = "PASS";
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'var a="FAIL";try{throw 1}catch(o){a="PASS"}console.log(a);'
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
mangle_catch_ie8: {
|
||||
rename = true
|
||||
options = {
|
||||
ie8: true,
|
||||
toplevel: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL";
|
||||
try {
|
||||
throw 1;
|
||||
} catch (args) {
|
||||
a = "PASS";
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'var a="FAIL";try{throw 1}catch(args){a="PASS"}console.log(a);'
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
mangle_catch_var: {
|
||||
rename = true
|
||||
options = {
|
||||
ie8: false,
|
||||
toplevel: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL";
|
||||
try {
|
||||
throw 1;
|
||||
} catch (args) {
|
||||
var a = "PASS";
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'var a="FAIL";try{throw 1}catch(o){var a="PASS"}console.log(a);'
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
mangle_catch_var_ie8: {
|
||||
rename = true
|
||||
options = {
|
||||
ie8: true,
|
||||
toplevel: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL";
|
||||
try {
|
||||
throw 1;
|
||||
} catch (args) {
|
||||
var a = "PASS";
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'var a="FAIL";try{throw 1}catch(args){var a="PASS"}console.log(a);'
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
mangle_catch_toplevel: {
|
||||
rename = true
|
||||
options = {
|
||||
ie8: false,
|
||||
toplevel: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL";
|
||||
try {
|
||||
throw 1;
|
||||
} catch (args) {
|
||||
a = "PASS";
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'var o="FAIL";try{throw 1}catch(c){o="PASS"}console.log(o);'
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
mangle_catch_ie8_toplevel: {
|
||||
rename = true
|
||||
options = {
|
||||
ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL";
|
||||
try {
|
||||
throw 1;
|
||||
} catch (args) {
|
||||
a = "PASS";
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'var o="FAIL";try{throw 1}catch(c){o="PASS"}console.log(o);'
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
mangle_catch_var_toplevel: {
|
||||
rename = true
|
||||
options = {
|
||||
ie8: false,
|
||||
toplevel: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL";
|
||||
try {
|
||||
throw 1;
|
||||
} catch (args) {
|
||||
var a = "PASS";
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'var o="FAIL";try{throw 1}catch(r){var o="PASS"}console.log(o);'
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
mangle_catch_var_ie8_toplevel: {
|
||||
rename = true
|
||||
options = {
|
||||
ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL";
|
||||
try {
|
||||
throw 1;
|
||||
} catch (args) {
|
||||
var a = "PASS";
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'var o="FAIL";try{throw 1}catch(r){var o="PASS"}console.log(o);'
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
mangle_catch_redef_1: {
|
||||
rename = true
|
||||
options = {
|
||||
ie8: false,
|
||||
toplevel: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
try {
|
||||
throw "FAIL1";
|
||||
} catch (a) {
|
||||
var a = "FAIL2";
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'var a="PASS";try{throw"FAIL1"}catch(a){var a="FAIL2"}console.log(a);'
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
mangle_catch_redef_1_ie8: {
|
||||
rename = true
|
||||
options = {
|
||||
ie8: true,
|
||||
toplevel: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
try {
|
||||
throw "FAIL1";
|
||||
} catch (a) {
|
||||
var a = "FAIL2";
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'var a="PASS";try{throw"FAIL1"}catch(a){var a="FAIL2"}console.log(a);'
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
mangle_catch_redef_1_toplevel: {
|
||||
rename = true
|
||||
options = {
|
||||
ie8: false,
|
||||
toplevel: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
try {
|
||||
throw "FAIL1";
|
||||
} catch (a) {
|
||||
var a = "FAIL2";
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'var o="PASS";try{throw"FAIL1"}catch(o){var o="FAIL2"}console.log(o);'
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
mangle_catch_redef_1_ie8_toplevel: {
|
||||
rename = true
|
||||
options = {
|
||||
ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
try {
|
||||
throw "FAIL1";
|
||||
} catch (a) {
|
||||
var a = "FAIL2";
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'var o="PASS";try{throw"FAIL1"}catch(o){var o="FAIL2"}console.log(o);'
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
mangle_catch_redef_2: {
|
||||
rename = true
|
||||
options = {
|
||||
ie8: false,
|
||||
toplevel: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
try {
|
||||
throw "FAIL1";
|
||||
} catch (a) {
|
||||
var a = "FAIL2";
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'try{throw"FAIL1"}catch(a){var a="FAIL2"}console.log(a);'
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
mangle_catch_redef_2_ie8: {
|
||||
rename = true
|
||||
options = {
|
||||
ie8: true,
|
||||
toplevel: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
try {
|
||||
throw "FAIL1";
|
||||
} catch (a) {
|
||||
var a = "FAIL2";
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'try{throw"FAIL1"}catch(a){var a="FAIL2"}console.log(a);'
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
mangle_catch_redef_2_toplevel: {
|
||||
rename = true
|
||||
options = {
|
||||
ie8: false,
|
||||
toplevel: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
try {
|
||||
throw "FAIL1";
|
||||
} catch (a) {
|
||||
var a = "FAIL2";
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'try{throw"FAIL1"}catch(o){var o="FAIL2"}console.log(o);'
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
mangle_catch_redef_2_ie8_toplevel: {
|
||||
rename = true
|
||||
options = {
|
||||
ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
try {
|
||||
throw "FAIL1";
|
||||
} catch (a) {
|
||||
var a = "FAIL2";
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'try{throw"FAIL1"}catch(o){var o="FAIL2"}console.log(o);'
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
issue_2120_1: {
|
||||
rename = true
|
||||
mangle = {
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
"aaaaaaaa";
|
||||
var a = 1, b = "FAIL";
|
||||
try {
|
||||
throw 1;
|
||||
} catch (c) {
|
||||
try {
|
||||
throw 0;
|
||||
} catch (a) {
|
||||
if (c) b = "PASS";
|
||||
}
|
||||
}
|
||||
console.log(b);
|
||||
}
|
||||
expect: {
|
||||
"aaaaaaaa";
|
||||
var a = 1, b = "FAIL";
|
||||
try {
|
||||
throw 1;
|
||||
} catch (t) {
|
||||
try {
|
||||
throw 0;
|
||||
} catch (a) {
|
||||
if (t) b = "PASS";
|
||||
}
|
||||
}
|
||||
console.log(b);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_2120_2: {
|
||||
rename = true
|
||||
mangle = {
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
"aaaaaaaa";
|
||||
var a = 1, b = "FAIL";
|
||||
try {
|
||||
throw 1;
|
||||
} catch (c) {
|
||||
try {
|
||||
throw 0;
|
||||
} catch (a) {
|
||||
if (c) b = "PASS";
|
||||
}
|
||||
}
|
||||
console.log(b);
|
||||
}
|
||||
expect: {
|
||||
"aaaaaaaa";
|
||||
var a = 1, b = "FAIL";
|
||||
try {
|
||||
throw 1;
|
||||
} catch (c) {
|
||||
try {
|
||||
throw 0;
|
||||
} catch (a) {
|
||||
if (c) b = "PASS";
|
||||
}
|
||||
}
|
||||
console.log(b);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
function_iife_catch: {
|
||||
rename = true
|
||||
mangle = {
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
function f(n) {
|
||||
!function() {
|
||||
try {
|
||||
throw 0;
|
||||
} catch (n) {
|
||||
var a = 1;
|
||||
console.log(n, a);
|
||||
}
|
||||
}();
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect_exact: "function f(o){!function(){try{throw 0}catch(c){var o=1;console.log(c,o)}}()}f();"
|
||||
expect_stdout: "0 1"
|
||||
}
|
||||
|
||||
function_iife_catch_ie8: {
|
||||
rename = true
|
||||
mangle = {
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
function f(n) {
|
||||
!function() {
|
||||
try {
|
||||
throw 0;
|
||||
} catch (n) {
|
||||
var a = 1;
|
||||
console.log(n, a);
|
||||
}
|
||||
}();
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect_exact: "function f(o){!function(){try{throw 0}catch(o){var c=1;console.log(o,c)}}()}f();"
|
||||
expect_stdout: "0 1"
|
||||
}
|
||||
|
||||
function_catch_catch: {
|
||||
rename = true
|
||||
mangle = {
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
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(c){try{throw 2}catch(o){var o=3;console.log(o)}}console.log(o)}f();"
|
||||
expect_stdout: [
|
||||
"3",
|
||||
"undefined",
|
||||
]
|
||||
}
|
||||
|
||||
function_catch_catch_ie8: {
|
||||
rename = true
|
||||
mangle = {
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
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(c){try{throw 2}catch(o){var o=3;console.log(o)}}console.log(o)}f();"
|
||||
expect_stdout: [
|
||||
"3",
|
||||
"undefined",
|
||||
]
|
||||
}
|
||||
@@ -17,7 +17,6 @@ return_undefined: {
|
||||
keep_fnames : false,
|
||||
hoist_vars : true,
|
||||
join_vars : true,
|
||||
cascade : true,
|
||||
negate_iife : true
|
||||
};
|
||||
input: {
|
||||
@@ -122,3 +121,25 @@ return_undefined: {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return_void: {
|
||||
options = {
|
||||
if_return: true,
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
function g() {
|
||||
h();
|
||||
}
|
||||
return g();
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
h();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
14
test/compress/sandbox.js
Normal file
14
test/compress/sandbox.js
Normal file
@@ -0,0 +1,14 @@
|
||||
console_log: {
|
||||
input: {
|
||||
console.log("%% %s");
|
||||
console.log("%% %s", "%s");
|
||||
}
|
||||
expect: {
|
||||
console.log("%% %s");
|
||||
console.log("%% %s", "%s");
|
||||
}
|
||||
expect_stdout: [
|
||||
"%% %s",
|
||||
"% %s",
|
||||
]
|
||||
}
|
||||
@@ -1,18 +1,394 @@
|
||||
do_screw: {
|
||||
options = { screw_ie8: true };
|
||||
options = {
|
||||
ie8: false,
|
||||
}
|
||||
beautify = {
|
||||
screw_ie8: true,
|
||||
ascii_only: true
|
||||
};
|
||||
|
||||
input: f("\v");
|
||||
expect_exact: 'f("\\v");';
|
||||
ie8: false,
|
||||
ascii_only: true,
|
||||
}
|
||||
input: {
|
||||
f("\v");
|
||||
}
|
||||
expect_exact: 'f("\\v");'
|
||||
}
|
||||
|
||||
dont_screw: {
|
||||
options = { screw_ie8: false };
|
||||
beautify = { screw_ie8: false, ascii_only: true };
|
||||
options = {
|
||||
ie8: true,
|
||||
}
|
||||
beautify = {
|
||||
ie8: true,
|
||||
ascii_only: true,
|
||||
}
|
||||
input: {
|
||||
f("\v");
|
||||
}
|
||||
expect_exact: 'f("\\x0B");'
|
||||
}
|
||||
|
||||
input: f("\v");
|
||||
expect_exact: 'f("\\x0B");';
|
||||
}
|
||||
do_screw_constants: {
|
||||
options = {
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
f(undefined, Infinity);
|
||||
}
|
||||
expect_exact: "f(void 0,1/0);"
|
||||
}
|
||||
|
||||
dont_screw_constants: {
|
||||
options = {
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
f(undefined, Infinity);
|
||||
}
|
||||
expect_exact: "f(undefined,Infinity);"
|
||||
}
|
||||
|
||||
do_screw_try_catch: {
|
||||
options = {
|
||||
ie8: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
}
|
||||
beautify = {
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
good = function(e){
|
||||
return function(error){
|
||||
try{
|
||||
e()
|
||||
} catch(e) {
|
||||
error(e)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
expect: {
|
||||
good = function(n){
|
||||
return function(t){
|
||||
try{
|
||||
n()
|
||||
} catch(n) {
|
||||
t(n)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
dont_screw_try_catch: {
|
||||
options = {
|
||||
ie8: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
}
|
||||
beautify = {
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
bad = function(e){
|
||||
return function(error){
|
||||
try{
|
||||
e()
|
||||
} catch(e) {
|
||||
error(e)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
expect: {
|
||||
bad = function(n){
|
||||
return function(t){
|
||||
try{
|
||||
n()
|
||||
} catch(n) {
|
||||
t(n)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
do_screw_try_catch_undefined: {
|
||||
options = {
|
||||
ie8: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
}
|
||||
beautify = {
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
function a(b){
|
||||
try {
|
||||
throw 'Stuff';
|
||||
} catch (undefined) {
|
||||
console.log('caught: ' + undefined);
|
||||
}
|
||||
console.log('undefined is ' + undefined);
|
||||
return b === undefined;
|
||||
};
|
||||
}
|
||||
expect: {
|
||||
function a(o){
|
||||
try{
|
||||
throw "Stuff"
|
||||
} catch (o) {
|
||||
console.log("caught: "+o)
|
||||
}
|
||||
console.log("undefined is " + void 0);
|
||||
return void 0===o
|
||||
}
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
dont_screw_try_catch_undefined: {
|
||||
options = {
|
||||
ie8: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
}
|
||||
beautify = {
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
function a(b){
|
||||
try {
|
||||
throw 'Stuff';
|
||||
} catch (undefined) {
|
||||
console.log('caught: ' + undefined);
|
||||
}
|
||||
console.log('undefined is ' + undefined);
|
||||
return b === undefined;
|
||||
};
|
||||
}
|
||||
expect: {
|
||||
function a(n){
|
||||
try{
|
||||
throw "Stuff"
|
||||
} catch (undefined) {
|
||||
console.log("caught: " + undefined)
|
||||
}
|
||||
console.log("undefined is " + undefined);
|
||||
return n === undefined
|
||||
}
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
reduce_vars: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
ie8: true,
|
||||
unused: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
var a;
|
||||
try {
|
||||
x();
|
||||
} catch (a) {
|
||||
y();
|
||||
}
|
||||
alert(a);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
var t;
|
||||
try {
|
||||
x();
|
||||
} catch (t) {
|
||||
y();
|
||||
}
|
||||
alert(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_1586_1: {
|
||||
options = {
|
||||
ie8: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
try {
|
||||
x();
|
||||
} catch (err) {
|
||||
console.log(err.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
expect_exact: "function f(){try{x()}catch(c){console.log(c.message)}}"
|
||||
}
|
||||
|
||||
issue_1586_2: {
|
||||
options = {
|
||||
ie8: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
try {
|
||||
x();
|
||||
} catch (err) {
|
||||
console.log(err.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
expect_exact: "function f(){try{x()}catch(c){console.log(c.message)}}"
|
||||
}
|
||||
|
||||
issue_2120_1: {
|
||||
mangle = {
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
"aaaaaaaa";
|
||||
var a = 1, b = "FAIL";
|
||||
try {
|
||||
throw 1;
|
||||
} catch (c) {
|
||||
try {
|
||||
throw 0;
|
||||
} catch (a) {
|
||||
if (c) b = "PASS";
|
||||
}
|
||||
}
|
||||
console.log(b);
|
||||
}
|
||||
expect: {
|
||||
"aaaaaaaa";
|
||||
var a = 1, b = "FAIL";
|
||||
try {
|
||||
throw 1;
|
||||
} catch (t) {
|
||||
try {
|
||||
throw 0;
|
||||
} catch (a) {
|
||||
if (t) b = "PASS";
|
||||
}
|
||||
}
|
||||
console.log(b);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_2120_2: {
|
||||
mangle = {
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
"aaaaaaaa";
|
||||
var a = 1, b = "FAIL";
|
||||
try {
|
||||
throw 1;
|
||||
} catch (c) {
|
||||
try {
|
||||
throw 0;
|
||||
} catch (a) {
|
||||
if (c) b = "PASS";
|
||||
}
|
||||
}
|
||||
console.log(b);
|
||||
}
|
||||
expect: {
|
||||
"aaaaaaaa";
|
||||
var a = 1, b = "FAIL";
|
||||
try {
|
||||
throw 1;
|
||||
} catch (c) {
|
||||
try {
|
||||
throw 0;
|
||||
} catch (a) {
|
||||
if (c) b = "PASS";
|
||||
}
|
||||
}
|
||||
console.log(b);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_2254_1: {
|
||||
mangle = {
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
"eeeeee";
|
||||
try {
|
||||
console.log(f("PASS"));
|
||||
} catch (e) {}
|
||||
function f(s) {
|
||||
try {
|
||||
throw "FAIL";
|
||||
} catch (e) {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"eeeeee";
|
||||
try {
|
||||
console.log(f("PASS"));
|
||||
} catch (e) {}
|
||||
function f(e) {
|
||||
try {
|
||||
throw "FAIL";
|
||||
} catch (t) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_2254_2: {
|
||||
mangle = {
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
"eeeeee";
|
||||
try {
|
||||
console.log(f("PASS"));
|
||||
} catch (e) {}
|
||||
function f(s) {
|
||||
try {
|
||||
throw "FAIL";
|
||||
} catch (e) {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"eeeeee";
|
||||
try {
|
||||
console.log(f("PASS"));
|
||||
} catch (e) {}
|
||||
function f(t) {
|
||||
try {
|
||||
throw "FAIL";
|
||||
} catch (e) {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -86,6 +86,7 @@ make_sequences_4: {
|
||||
switch (x = 5, y) {}
|
||||
with (x = 5, obj);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
lift_sequences_1: {
|
||||
@@ -103,15 +104,18 @@ lift_sequences_1: {
|
||||
lift_sequences_2: {
|
||||
options = { sequences: true, evaluate: true };
|
||||
input: {
|
||||
var foo, bar;
|
||||
var foo = 1, bar;
|
||||
foo.x = (foo = {}, 10);
|
||||
bar = (bar = {}, 10);
|
||||
console.log(foo, bar);
|
||||
}
|
||||
expect: {
|
||||
var foo, bar;
|
||||
var foo = 1, bar;
|
||||
foo.x = (foo = {}, 10),
|
||||
bar = {}, bar = 10;
|
||||
bar = {}, bar = 10,
|
||||
console.log(foo, bar);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
lift_sequences_3: {
|
||||
@@ -138,6 +142,23 @@ lift_sequences_4: {
|
||||
}
|
||||
}
|
||||
|
||||
lift_sequences_5: {
|
||||
options = {
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
var a = 2, b;
|
||||
a *= (b, a = 4, 3);
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = 2, b;
|
||||
b, a *= (a = 4, 3),
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "6"
|
||||
}
|
||||
|
||||
for_sequences: {
|
||||
options = { sequences: true };
|
||||
input: {
|
||||
@@ -155,6 +176,11 @@ for_sequences: {
|
||||
// 4
|
||||
x = (foo in bar);
|
||||
for (y = 5; false;);
|
||||
// 5
|
||||
x = function() {
|
||||
foo in bar;
|
||||
};
|
||||
for (y = 5; false;);
|
||||
}
|
||||
expect: {
|
||||
// 1
|
||||
@@ -167,5 +193,606 @@ for_sequences: {
|
||||
// 4
|
||||
x = (foo in bar);
|
||||
for (y = 5; false;);
|
||||
// 5
|
||||
for (x = function() {
|
||||
foo in bar;
|
||||
}, y = 5; false;);
|
||||
}
|
||||
}
|
||||
|
||||
limit_1: {
|
||||
options = {
|
||||
sequences: 3,
|
||||
};
|
||||
input: {
|
||||
a;
|
||||
b;
|
||||
c;
|
||||
d;
|
||||
e;
|
||||
f;
|
||||
g;
|
||||
h;
|
||||
i;
|
||||
j;
|
||||
k;
|
||||
}
|
||||
expect: {
|
||||
a, b, c;
|
||||
d, e, f;
|
||||
g, h, i;
|
||||
j, k;
|
||||
}
|
||||
}
|
||||
|
||||
limit_2: {
|
||||
options = {
|
||||
sequences: 3,
|
||||
};
|
||||
input: {
|
||||
a, b;
|
||||
c, d;
|
||||
e, f;
|
||||
g, h;
|
||||
i, j;
|
||||
k;
|
||||
}
|
||||
expect: {
|
||||
a, b, c, d;
|
||||
e, f, g, h;
|
||||
i, j, k;
|
||||
}
|
||||
}
|
||||
|
||||
negate_iife_for: {
|
||||
options = {
|
||||
sequences: true,
|
||||
negate_iife: true,
|
||||
};
|
||||
input: {
|
||||
(function() {})();
|
||||
for (i = 0; i < 5; i++) console.log(i);
|
||||
(function() {})();
|
||||
for (; i < 10; i++) console.log(i);
|
||||
}
|
||||
expect: {
|
||||
for (!function() {}(), i = 0; i < 5; i++) console.log(i);
|
||||
for (!function() {}(); i < 10; i++) console.log(i);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
iife: {
|
||||
options = {
|
||||
sequences: true,
|
||||
};
|
||||
input: {
|
||||
x = 42;
|
||||
(function a() {})();
|
||||
!function b() {}();
|
||||
~function c() {}();
|
||||
+function d() {}();
|
||||
-function e() {}();
|
||||
void function f() {}();
|
||||
typeof function g() {}();
|
||||
}
|
||||
expect: {
|
||||
x = 42, function a() {}(), function b() {}(), function c() {}(),
|
||||
function d() {}(), function e() {}(), function f() {}(), function g() {}();
|
||||
}
|
||||
}
|
||||
|
||||
unsafe_undefined: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
function f(undefined) {
|
||||
if (a)
|
||||
return b;
|
||||
if (c)
|
||||
return d;
|
||||
}
|
||||
function g(undefined) {
|
||||
if (a)
|
||||
return b;
|
||||
if (c)
|
||||
return d;
|
||||
e();
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(undefined) {
|
||||
return a ? b : c ? d : undefined;
|
||||
}
|
||||
function g(undefined) {
|
||||
return a ? b : c ? d : void e();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_1685: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var a = 100, b = 10;
|
||||
function f() {
|
||||
var a = (a--, delete a && --b);
|
||||
}
|
||||
f();
|
||||
console.log(a, b);
|
||||
}
|
||||
expect: {
|
||||
var a = 100, b = 10;
|
||||
function f() {
|
||||
var a = (a--, delete a && --b);
|
||||
}
|
||||
f();
|
||||
console.log(a, b);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
func_def_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
return f = 0, !!f;
|
||||
}
|
||||
console.log(f());
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
return !!(f = 0);
|
||||
}
|
||||
console.log(f());
|
||||
}
|
||||
expect_stdout: "false"
|
||||
}
|
||||
|
||||
func_def_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function f() {
|
||||
return f = 0, !!f;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function f() {
|
||||
return f = 0, !!f;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
func_def_3: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
function g() {}
|
||||
return g = 0, !!g;
|
||||
}
|
||||
console.log(f());
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
function g() {}
|
||||
return !!(g = 0);
|
||||
}
|
||||
console.log(f());
|
||||
}
|
||||
expect_stdout: "false"
|
||||
}
|
||||
|
||||
func_def_4: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
function g() {
|
||||
return g = 0, !!g;
|
||||
}
|
||||
return g();
|
||||
}
|
||||
console.log(f());
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
function g() {
|
||||
return !!(g = 0);
|
||||
}
|
||||
return g();
|
||||
}
|
||||
console.log(f());
|
||||
}
|
||||
expect_stdout: "false"
|
||||
}
|
||||
|
||||
func_def_5: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
return function g(){
|
||||
return g = 0, !!g;
|
||||
}();
|
||||
}
|
||||
console.log(f());
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
return function g(){
|
||||
return g = 0, !!g;
|
||||
}();
|
||||
}
|
||||
console.log(f());
|
||||
}
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
issue_1758: {
|
||||
options = {
|
||||
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 function() {
|
||||
return c--, c--, void c.toString();
|
||||
}();
|
||||
}());
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
delete_seq_1: {
|
||||
options = {
|
||||
booleans: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
console.log(delete (1, undefined));
|
||||
console.log(delete (1, void 0));
|
||||
console.log(delete (1, Infinity));
|
||||
console.log(delete (1, 1 / 0));
|
||||
console.log(delete (1, NaN));
|
||||
console.log(delete (1, 0 / 0));
|
||||
}
|
||||
expect: {
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
delete_seq_2: {
|
||||
options = {
|
||||
booleans: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
console.log(delete (1, 2, undefined));
|
||||
console.log(delete (1, 2, void 0));
|
||||
console.log(delete (1, 2, Infinity));
|
||||
console.log(delete (1, 2, 1 / 0));
|
||||
console.log(delete (1, 2, NaN));
|
||||
console.log(delete (1, 2, 0 / 0));
|
||||
}
|
||||
expect: {
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
delete_seq_3: {
|
||||
options = {
|
||||
booleans: true,
|
||||
keep_infinity: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
console.log(delete (1, 2, undefined));
|
||||
console.log(delete (1, 2, void 0));
|
||||
console.log(delete (1, 2, Infinity));
|
||||
console.log(delete (1, 2, 1 / 0));
|
||||
console.log(delete (1, 2, NaN));
|
||||
console.log(delete (1, 2, 0 / 0));
|
||||
}
|
||||
expect: {
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
console.log(!0);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
delete_seq_4: {
|
||||
options = {
|
||||
booleans: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function f() {}
|
||||
console.log(delete (f(), undefined));
|
||||
console.log(delete (f(), void 0));
|
||||
console.log(delete (f(), Infinity));
|
||||
console.log(delete (f(), 1 / 0));
|
||||
console.log(delete (f(), NaN));
|
||||
console.log(delete (f(), 0 / 0));
|
||||
}
|
||||
expect: {
|
||||
function f() {}
|
||||
console.log((f(), !0)),
|
||||
console.log((f(), !0)),
|
||||
console.log((f(), !0)),
|
||||
console.log((f(), !0)),
|
||||
console.log((f(), !0)),
|
||||
console.log((f(), !0));
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
delete_seq_5: {
|
||||
options = {
|
||||
booleans: true,
|
||||
keep_infinity: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function f() {}
|
||||
console.log(delete (f(), undefined));
|
||||
console.log(delete (f(), void 0));
|
||||
console.log(delete (f(), Infinity));
|
||||
console.log(delete (f(), 1 / 0));
|
||||
console.log(delete (f(), NaN));
|
||||
console.log(delete (f(), 0 / 0));
|
||||
}
|
||||
expect: {
|
||||
function f() {}
|
||||
console.log((f(), !0)),
|
||||
console.log((f(), !0)),
|
||||
console.log((f(), !0)),
|
||||
console.log((f(), !0)),
|
||||
console.log((f(), !0)),
|
||||
console.log((f(), !0));
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
delete_seq_6: {
|
||||
options = {
|
||||
booleans: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
console.log(delete (1, a));
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
console.log(!0);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
side_effects: {
|
||||
options = {
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
0, a(), 1, b(), 2, c(), 3;
|
||||
}
|
||||
expect: {
|
||||
a(), b(), c();
|
||||
}
|
||||
}
|
||||
|
||||
side_effects_cascade_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b) {
|
||||
a -= 42;
|
||||
if (a < 0) a = 0;
|
||||
b.a = a;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(a, b) {
|
||||
(a -= 42) < 0 && (a = 0), b.a = a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
side_effects_cascade_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b) {
|
||||
b = a,
|
||||
!a + (b += a) || (b += a),
|
||||
b = a,
|
||||
b;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(a, b) {
|
||||
b = a,
|
||||
!a + (b += a) || (b += a),
|
||||
b = a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
side_effects_cascade_3: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b) {
|
||||
"foo" ^ (b += a),
|
||||
b ? false : (b = a) ? -1 : (b -= a) - (b ^= a),
|
||||
a-- || !a,
|
||||
a;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(a, b) {
|
||||
!(b += a) && ((b = a) || (b -= a, b ^= a)),
|
||||
a--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_27: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
passes: 2,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(jQuery) {
|
||||
var $;
|
||||
$ = jQuery;
|
||||
$("body").addClass("foo");
|
||||
})(jQuery);
|
||||
}
|
||||
expect: {
|
||||
(function(jQuery) {
|
||||
jQuery("body").addClass("foo");
|
||||
})(jQuery);
|
||||
}
|
||||
}
|
||||
|
||||
issue_2062: {
|
||||
options = {
|
||||
booleans: true,
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var a = 1;
|
||||
if ([ a || a++ + a--, a++ + a--, a && a.var ]);
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = 1;
|
||||
a || (a++, a--), a++, --a && a.var;
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_2313: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var a = 0, b = 0;
|
||||
var foo = {
|
||||
get c() {
|
||||
a++;
|
||||
return 42;
|
||||
},
|
||||
set c(c) {
|
||||
b++;
|
||||
},
|
||||
d: function() {
|
||||
this.c++;
|
||||
if (this.c) console.log(a, b);
|
||||
}
|
||||
}
|
||||
foo.d();
|
||||
}
|
||||
expect: {
|
||||
var a = 0, b = 0;
|
||||
var foo = {
|
||||
get c() {
|
||||
return a++, 42;
|
||||
},
|
||||
set c(c) {
|
||||
b++;
|
||||
},
|
||||
d: function() {
|
||||
if (this.c++, this.c) console.log(a, b);
|
||||
}
|
||||
}
|
||||
foo.d();
|
||||
}
|
||||
expect_stdout: "2 1"
|
||||
}
|
||||
|
||||
cascade_assignment_in_return: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b) {
|
||||
return a = x(), b(a);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(a, b) {
|
||||
return b(x());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
19
test/compress/string-literal.js
Normal file
19
test/compress/string-literal.js
Normal file
@@ -0,0 +1,19 @@
|
||||
octal_escape_sequence: {
|
||||
input: {
|
||||
var boundaries = "\0\7\00\07\70\77\000\077\300\377";
|
||||
var border_check = "\400\700\0000\3000";
|
||||
}
|
||||
expect: {
|
||||
var boundaries = "\x00\x07\x00\x07\x38\x3f\x00\x3f\xc0\xff";
|
||||
var border_check = "\x20\x30\x38\x30\x00\x30\xc0\x30";
|
||||
}
|
||||
}
|
||||
|
||||
issue_1929: {
|
||||
input: {
|
||||
function f(s) {
|
||||
return s.split(/[\\/]/);
|
||||
}
|
||||
}
|
||||
expect_exact: "function f(s){return s.split(/[\\\\/]/)}"
|
||||
}
|
||||
@@ -1,5 +1,10 @@
|
||||
constant_switch_1: {
|
||||
options = { dead_code: true, evaluate: true };
|
||||
options = {
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
switch (1+1) {
|
||||
case 1: foo(); break;
|
||||
@@ -13,7 +18,12 @@ constant_switch_1: {
|
||||
}
|
||||
|
||||
constant_switch_2: {
|
||||
options = { dead_code: true, evaluate: true };
|
||||
options = {
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
switch (1) {
|
||||
case 1: foo();
|
||||
@@ -28,7 +38,12 @@ constant_switch_2: {
|
||||
}
|
||||
|
||||
constant_switch_3: {
|
||||
options = { dead_code: true, evaluate: true };
|
||||
options = {
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
switch (10) {
|
||||
case 1: foo();
|
||||
@@ -44,7 +59,12 @@ constant_switch_3: {
|
||||
}
|
||||
|
||||
constant_switch_4: {
|
||||
options = { dead_code: true, evaluate: true };
|
||||
options = {
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
switch (2) {
|
||||
case 1:
|
||||
@@ -65,7 +85,12 @@ constant_switch_4: {
|
||||
}
|
||||
|
||||
constant_switch_5: {
|
||||
options = { dead_code: true, evaluate: true };
|
||||
options = {
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
switch (1) {
|
||||
case 1:
|
||||
@@ -94,7 +119,12 @@ constant_switch_5: {
|
||||
}
|
||||
|
||||
constant_switch_6: {
|
||||
options = { dead_code: true, evaluate: true };
|
||||
options = {
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
OUT: {
|
||||
foo();
|
||||
@@ -123,7 +153,12 @@ constant_switch_6: {
|
||||
}
|
||||
|
||||
constant_switch_7: {
|
||||
options = { dead_code: true, evaluate: true };
|
||||
options = {
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
OUT: {
|
||||
foo();
|
||||
@@ -161,7 +196,12 @@ constant_switch_7: {
|
||||
}
|
||||
|
||||
constant_switch_8: {
|
||||
options = { dead_code: true, evaluate: true };
|
||||
options = {
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
OUT: switch (1) {
|
||||
case 1:
|
||||
@@ -185,7 +225,12 @@ constant_switch_8: {
|
||||
}
|
||||
|
||||
constant_switch_9: {
|
||||
options = { dead_code: true, evaluate: true };
|
||||
options = {
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
OUT: switch (1) {
|
||||
case 1:
|
||||
@@ -210,7 +255,10 @@ constant_switch_9: {
|
||||
}
|
||||
|
||||
drop_default_1: {
|
||||
options = { dead_code: true };
|
||||
options = {
|
||||
dead_code: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
switch (foo) {
|
||||
case 'bar': baz();
|
||||
@@ -225,7 +273,10 @@ drop_default_1: {
|
||||
}
|
||||
|
||||
drop_default_2: {
|
||||
options = { dead_code: true };
|
||||
options = {
|
||||
dead_code: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
switch (foo) {
|
||||
case 'bar': baz(); break;
|
||||
@@ -241,7 +292,10 @@ drop_default_2: {
|
||||
}
|
||||
|
||||
keep_default: {
|
||||
options = { dead_code: true };
|
||||
options = {
|
||||
dead_code: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
switch (foo) {
|
||||
case 'bar': baz();
|
||||
@@ -258,3 +312,555 @@ keep_default: {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_1663: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
var a = 100, b = 10;
|
||||
function f() {
|
||||
switch (1) {
|
||||
case 1:
|
||||
b = a++;
|
||||
return ++b;
|
||||
default:
|
||||
var b;
|
||||
}
|
||||
}
|
||||
f();
|
||||
console.log(a, b);
|
||||
}
|
||||
expect: {
|
||||
var a = 100, b = 10;
|
||||
function f() {
|
||||
var b;
|
||||
b = a++;
|
||||
return ++b;
|
||||
}
|
||||
f();
|
||||
console.log(a, b);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
drop_case: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
switch (foo) {
|
||||
case 'bar': baz(); break;
|
||||
case 'moo':
|
||||
break;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
switch (foo) {
|
||||
case 'bar': baz();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
keep_case: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
switch (foo) {
|
||||
case 'bar': baz(); break;
|
||||
case moo:
|
||||
break;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
switch (foo) {
|
||||
case 'bar': baz(); break;
|
||||
case moo:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_376: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
switch (true) {
|
||||
case boolCondition:
|
||||
console.log(1);
|
||||
break;
|
||||
case false:
|
||||
console.log(2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
switch (true) {
|
||||
case boolCondition:
|
||||
console.log(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_441_1: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
switch (foo) {
|
||||
case bar:
|
||||
qux();
|
||||
break;
|
||||
case baz:
|
||||
qux();
|
||||
break;
|
||||
default:
|
||||
qux();
|
||||
break;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
switch (foo) {
|
||||
case bar:
|
||||
case baz:
|
||||
default:
|
||||
qux();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_441_2: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
switch (foo) {
|
||||
case bar:
|
||||
// TODO: Fold into the case below
|
||||
qux();
|
||||
break;
|
||||
case fall:
|
||||
case baz:
|
||||
qux();
|
||||
break;
|
||||
default:
|
||||
qux();
|
||||
break;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
switch (foo) {
|
||||
case bar:
|
||||
qux();
|
||||
break;
|
||||
case fall:
|
||||
case baz:
|
||||
default:
|
||||
qux();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_1674: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
switch (0) {
|
||||
default:
|
||||
console.log("FAIL");
|
||||
break;
|
||||
case 0:
|
||||
console.log("PASS");
|
||||
break;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_1679: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
var a = 100, b = 10;
|
||||
function f() {
|
||||
switch (--b) {
|
||||
default:
|
||||
case !function x() {}:
|
||||
break;
|
||||
case b--:
|
||||
switch (0) {
|
||||
default:
|
||||
case a--:
|
||||
}
|
||||
break;
|
||||
case (a++):
|
||||
break;
|
||||
}
|
||||
}
|
||||
f();
|
||||
console.log(a, b);
|
||||
}
|
||||
expect: {
|
||||
var a = 100, b = 10;
|
||||
function f() {
|
||||
switch (--b) {
|
||||
default:
|
||||
case !function x() {}:
|
||||
break;
|
||||
case b--:
|
||||
switch (0) {
|
||||
default:
|
||||
case a--:
|
||||
}
|
||||
break;
|
||||
case (a++):
|
||||
}
|
||||
}
|
||||
f();
|
||||
console.log(a, b);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1680_1: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
function f(x) {
|
||||
console.log(x);
|
||||
return x + 1;
|
||||
}
|
||||
switch (2) {
|
||||
case f(0):
|
||||
case f(1):
|
||||
f(2);
|
||||
case 2:
|
||||
case f(3):
|
||||
case f(4):
|
||||
f(5);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(x) {
|
||||
console.log(x);
|
||||
return x + 1;
|
||||
}
|
||||
switch (2) {
|
||||
case f(0):
|
||||
case f(1):
|
||||
f(2);
|
||||
case 2:
|
||||
f(5);
|
||||
}
|
||||
}
|
||||
expect_stdout: [
|
||||
"0",
|
||||
"1",
|
||||
"2",
|
||||
"5",
|
||||
]
|
||||
}
|
||||
|
||||
issue_1680_2: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
var a = 100, b = 10;
|
||||
switch (b) {
|
||||
case a--:
|
||||
break;
|
||||
case b:
|
||||
var c;
|
||||
break;
|
||||
case a:
|
||||
break;
|
||||
case a--:
|
||||
break;
|
||||
}
|
||||
console.log(a, b);
|
||||
}
|
||||
expect: {
|
||||
var a = 100, b = 10;
|
||||
switch (b) {
|
||||
case a--:
|
||||
break;
|
||||
case b:
|
||||
var c;
|
||||
break;
|
||||
case a:
|
||||
case a--:
|
||||
}
|
||||
console.log(a, b);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1690_1: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
switch (console.log("PASS")) {}
|
||||
}
|
||||
expect: {
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_1690_2: {
|
||||
options = {
|
||||
dead_code: false,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
switch (console.log("PASS")) {}
|
||||
}
|
||||
expect: {
|
||||
switch (console.log("PASS")) {}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
if_switch_typeof: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
side_effects: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
if (a) switch(typeof b) {}
|
||||
}
|
||||
expect: {
|
||||
a;
|
||||
}
|
||||
}
|
||||
|
||||
issue_1698: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
var a = 1;
|
||||
!function() {
|
||||
switch (a++) {}
|
||||
}();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = 1;
|
||||
!function() {
|
||||
switch (a++) {}
|
||||
}();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "2"
|
||||
}
|
||||
|
||||
issue_1705_1: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
var a = 0;
|
||||
switch (a) {
|
||||
default:
|
||||
console.log("FAIL");
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var a = 0;
|
||||
switch (a) {
|
||||
default:
|
||||
console.log("FAIL");
|
||||
case 0:
|
||||
}
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1705_2: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
switches: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 0;
|
||||
switch (a) {
|
||||
default:
|
||||
console.log("FAIL");
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1705_3: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
switch (a) {
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
a;
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
beautify: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
}
|
||||
input: {
|
||||
switch (a) {
|
||||
case 0:
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
default:
|
||||
}
|
||||
switch (b) {
|
||||
case 3:
|
||||
foo();
|
||||
bar();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
expect_exact: [
|
||||
"switch (a) {",
|
||||
" case 0:",
|
||||
" case 1:",
|
||||
" break;",
|
||||
"",
|
||||
" case 2:",
|
||||
" default:",
|
||||
"}",
|
||||
"",
|
||||
"switch (b) {",
|
||||
" case 3:",
|
||||
" foo();",
|
||||
" bar();",
|
||||
"",
|
||||
" default:",
|
||||
" break;",
|
||||
"}",
|
||||
]
|
||||
}
|
||||
|
||||
issue_1758: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
var a = 1, b = 2;
|
||||
switch (a--) {
|
||||
default:
|
||||
b++;
|
||||
}
|
||||
console.log(a, b);
|
||||
}
|
||||
expect: {
|
||||
var a = 1, b = 2;
|
||||
a--;
|
||||
b++;
|
||||
console.log(a, b);
|
||||
}
|
||||
expect_stdout: "0 3"
|
||||
}
|
||||
|
||||
issue_2535: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
dead_code: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
switch(w(), 42) {
|
||||
case 13: x();
|
||||
case 42: y();
|
||||
default: z();
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
w(), 42;
|
||||
42;
|
||||
y();
|
||||
z();
|
||||
}
|
||||
}
|
||||
|
||||
issue_1750: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
var a = 0, b = 1;
|
||||
switch (true) {
|
||||
case a, true:
|
||||
default:
|
||||
b = 2;
|
||||
case true:
|
||||
}
|
||||
console.log(a, b);
|
||||
}
|
||||
expect: {
|
||||
var a = 0, b = 1;
|
||||
true;
|
||||
a, true;
|
||||
b = 2;
|
||||
console.log(a, b);
|
||||
}
|
||||
expect_stdout: "0 2"
|
||||
}
|
||||
|
||||
131
test/compress/transform.js
Normal file
131
test/compress/transform.js
Normal file
@@ -0,0 +1,131 @@
|
||||
booleans_evaluate: {
|
||||
options = {
|
||||
booleans: true,
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
console.log(typeof void 0 != "undefined");
|
||||
console.log(1 == 1, 1 === 1)
|
||||
console.log(1 != 1, 1 !== 1)
|
||||
}
|
||||
expect: {
|
||||
console.log(!1);
|
||||
console.log(!0, !0);
|
||||
console.log(!1, !1);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
booleans_global_defs: {
|
||||
options = {
|
||||
booleans: true,
|
||||
evaluate: true,
|
||||
global_defs: {
|
||||
A: true,
|
||||
},
|
||||
}
|
||||
input: {
|
||||
console.log(A == 1);
|
||||
}
|
||||
expect: {
|
||||
console.log(!0);
|
||||
}
|
||||
}
|
||||
|
||||
condition_evaluate: {
|
||||
options = {
|
||||
booleans: true,
|
||||
dead_code: false,
|
||||
evaluate: true,
|
||||
loops: false,
|
||||
}
|
||||
input: {
|
||||
while (1 === 2);
|
||||
for (; 1 == true;);
|
||||
if (void 0 == null);
|
||||
}
|
||||
expect: {
|
||||
while (0);
|
||||
for (; 1;);
|
||||
if (1);
|
||||
}
|
||||
}
|
||||
|
||||
if_else_empty: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
if ({} ? a : b); else {}
|
||||
}
|
||||
expect: {
|
||||
!{} ? b : a;
|
||||
}
|
||||
}
|
||||
|
||||
label_if_break: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
L: if (true) {
|
||||
a;
|
||||
break L;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
a;
|
||||
}
|
||||
}
|
||||
|
||||
while_if_break: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
loops: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
while (a) {
|
||||
if (b) if(c) d;
|
||||
if (e) break;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
for(; a && (b && c && d, !e););
|
||||
}
|
||||
}
|
||||
|
||||
if_return: {
|
||||
options = {
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
function f(w, x, y, z) {
|
||||
if (x) return;
|
||||
if (w) {
|
||||
if (y) return;
|
||||
} else if (z) return;
|
||||
if (x == y) return true;
|
||||
|
||||
if (x) w();
|
||||
if (y) z();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(w, x, y, z) {
|
||||
if (!x) {
|
||||
if (w) {
|
||||
if (y) return;
|
||||
} else if (z) return;
|
||||
return x == y || (x && w(), y && z(), !0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
typeof_evaluation: {
|
||||
options = {
|
||||
evaluate: true
|
||||
evaluate: true,
|
||||
typeofs: true,
|
||||
};
|
||||
input: {
|
||||
a = typeof 1;
|
||||
@@ -23,3 +24,117 @@ typeof_evaluation: {
|
||||
h='undefined';
|
||||
}
|
||||
}
|
||||
|
||||
typeof_in_boolean_context: {
|
||||
options = {
|
||||
booleans : true,
|
||||
evaluate : true,
|
||||
conditionals : true,
|
||||
side_effects : true,
|
||||
};
|
||||
input: {
|
||||
function f1(x) { return typeof x ? "yes" : "no"; }
|
||||
function f2() { return typeof g()? "Yes" : "No"; }
|
||||
typeof 0 ? foo() : bar();
|
||||
!typeof console.log(1);
|
||||
var a = !typeof console.log(2);
|
||||
if (typeof (1 + foo()));
|
||||
}
|
||||
expect: {
|
||||
function f1(x) { return "yes"; }
|
||||
function f2() { return g(), "Yes"; }
|
||||
foo();
|
||||
console.log(1);
|
||||
var a = !(console.log(2), 1);
|
||||
foo();
|
||||
}
|
||||
}
|
||||
|
||||
issue_1668: {
|
||||
options = {
|
||||
booleans: true,
|
||||
}
|
||||
input: {
|
||||
if (typeof bar);
|
||||
}
|
||||
expect: {
|
||||
if (1);
|
||||
}
|
||||
}
|
||||
|
||||
typeof_defun_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
typeofs: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
console.log("YES");
|
||||
}
|
||||
function g() {
|
||||
h = 42;
|
||||
console.log("NOPE");
|
||||
}
|
||||
function h() {
|
||||
console.log("YUP");
|
||||
}
|
||||
g = 42;
|
||||
"function" == typeof f && f();
|
||||
"function" == typeof g && g();
|
||||
"function" == typeof h && h();
|
||||
}
|
||||
expect: {
|
||||
function g() {
|
||||
h = 42;
|
||||
console.log("NOPE");
|
||||
}
|
||||
function h() {
|
||||
console.log("YUP");
|
||||
}
|
||||
g = 42;
|
||||
console.log("YES");
|
||||
"function" == typeof g && g();
|
||||
h();
|
||||
}
|
||||
expect_stdout: [
|
||||
"YES",
|
||||
"YUP",
|
||||
]
|
||||
}
|
||||
|
||||
typeof_defun_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
typeofs: true,
|
||||
}
|
||||
input: {
|
||||
var f = function() {
|
||||
console.log(x);
|
||||
};
|
||||
var x = 0;
|
||||
x++ < 2 && typeof f == "function" && f();
|
||||
x++ < 2 && typeof f == "function" && f();
|
||||
x++ < 2 && typeof f == "function" && f();
|
||||
}
|
||||
expect: {
|
||||
var f = function() {
|
||||
console.log(x);
|
||||
};
|
||||
var x = 0;
|
||||
x++ < 2 && f();
|
||||
x++ < 2 && f();
|
||||
x++ < 2 && f();
|
||||
}
|
||||
expect_stdout: [
|
||||
"1",
|
||||
"2",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -15,3 +15,50 @@ unicode_parse_variables: {
|
||||
var l০ = 3;
|
||||
}
|
||||
}
|
||||
|
||||
issue_2242_1: {
|
||||
beautify = {
|
||||
ascii_only: false,
|
||||
}
|
||||
input: {
|
||||
console.log("\ud83d", "\ude00", "\ud83d\ude00", "\ud83d@\ude00");
|
||||
}
|
||||
expect_exact: 'console.log("\\ud83d","\\ude00","\ud83d\ude00","\\ud83d@\\ude00");'
|
||||
}
|
||||
|
||||
issue_2242_2: {
|
||||
beautify = {
|
||||
ascii_only: true,
|
||||
}
|
||||
input: {
|
||||
console.log("\ud83d", "\ude00", "\ud83d\ude00", "\ud83d@\ude00");
|
||||
}
|
||||
expect_exact: 'console.log("\\ud83d","\\ude00","\\ud83d\\ude00","\\ud83d@\\ude00");'
|
||||
}
|
||||
|
||||
issue_2242_3: {
|
||||
options = {
|
||||
evaluate: false,
|
||||
}
|
||||
input: {
|
||||
console.log("\ud83d" + "\ude00", "\ud83d" + "@" + "\ude00");
|
||||
}
|
||||
expect_exact: 'console.log("\\ud83d"+"\\ude00","\\ud83d"+"@"+"\\ude00");'
|
||||
}
|
||||
|
||||
issue_2242_4: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
console.log("\ud83d" + "\ude00", "\ud83d" + "@" + "\ude00");
|
||||
}
|
||||
expect_exact: 'console.log("\ud83d\ude00","\\ud83d@\\ude00");'
|
||||
}
|
||||
|
||||
issue_2569: {
|
||||
input: {
|
||||
new RegExp("[\udc42-\udcaa\udd74-\udd96\ude45-\ude4f\udea3-\udecc]");
|
||||
}
|
||||
expect_exact: 'new RegExp("[\\udc42-\\udcaa\\udd74-\\udd96\\ude45-\\ude4f\\udea3-\\udecc]");'
|
||||
}
|
||||
|
||||
48
test/compress/wrap_iife.js
Normal file
48
test/compress/wrap_iife.js
Normal file
@@ -0,0 +1,48 @@
|
||||
wrap_iife: {
|
||||
options = {
|
||||
negate_iife: false,
|
||||
}
|
||||
beautify = {
|
||||
wrap_iife: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
return function() {
|
||||
console.log('test')
|
||||
};
|
||||
})()();
|
||||
}
|
||||
expect_exact: '(function(){return function(){console.log("test")}})()();'
|
||||
}
|
||||
|
||||
wrap_iife_in_expression: {
|
||||
options = {
|
||||
negate_iife: false,
|
||||
}
|
||||
beautify = {
|
||||
wrap_iife: true,
|
||||
}
|
||||
input: {
|
||||
foo = (function () {
|
||||
return bar();
|
||||
})();
|
||||
}
|
||||
expect_exact: 'foo=(function(){return bar()})();'
|
||||
}
|
||||
|
||||
wrap_iife_in_return_call: {
|
||||
options = {
|
||||
negate_iife: false,
|
||||
}
|
||||
beautify = {
|
||||
wrap_iife: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
return (function() {
|
||||
console.log('test')
|
||||
})();
|
||||
})()();
|
||||
}
|
||||
expect_exact: '(function(){return(function(){console.log("test")})()})()();'
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user