Compare commits
554 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
01d6e0f223 | ||
|
|
ab050e7a94 | ||
|
|
75aa6ef848 | ||
|
|
519a00bd8a | ||
|
|
3ff0feddee | ||
|
|
74396acc86 | ||
|
|
036bca980c | ||
|
|
18c2b1841b | ||
|
|
fe19ab7c57 | ||
|
|
9074f05129 | ||
|
|
04fbb1f949 | ||
|
|
bf7e4ca1a3 | ||
|
|
d68ddc31f9 | ||
|
|
500e31e03b | ||
|
|
bef856addb | ||
|
|
9a6faf365b | ||
|
|
e915832a36 | ||
|
|
0593892d6e | ||
|
|
b866a23671 | ||
|
|
1283d73853 | ||
|
|
1b61a81b5d | ||
|
|
5a88c30d65 | ||
|
|
168ae747ad | ||
|
|
d4b7010678 | ||
|
|
e27493f3c2 | ||
|
|
292d1de363 | ||
|
|
6768e6578f | ||
|
|
48a0f6fe41 | ||
|
|
81caadb709 | ||
|
|
d959e0b86f | ||
|
|
67278e76c8 | ||
|
|
c289ba1139 | ||
|
|
02cc4a0d03 | ||
|
|
4e06e1ca34 | ||
|
|
644f65feca | ||
|
|
8504a4ea0e | ||
|
|
10c1a78772 | ||
|
|
a6a0319f1c | ||
|
|
d1b2ecec27 | ||
|
|
552be61c4d | ||
|
|
dcfc4aca5b | ||
|
|
4027f87717 | ||
|
|
910799ca99 | ||
|
|
4bd36dc8da | ||
|
|
ab15c40770 | ||
|
|
fe65ce9658 | ||
|
|
d6fd18d0b0 | ||
|
|
0d17c5b0fa | ||
|
|
5b20bad4b3 | ||
|
|
765a06340f | ||
|
|
5045e140b1 | ||
|
|
10648c9af6 | ||
|
|
87e67ec299 | ||
|
|
61a0dad9fe | ||
|
|
3e2c51a4da | ||
|
|
0e29ad5eb9 | ||
|
|
0f2687ecfc | ||
|
|
1c0defdc03 | ||
|
|
dcbf2236c7 | ||
|
|
24bb288832 | ||
|
|
6ad8e1081f | ||
|
|
815eff1f7c | ||
|
|
1e9b576ee9 | ||
|
|
3797458365 | ||
|
|
1858c2018c | ||
|
|
ec7f071272 | ||
|
|
f1eb03f2c0 | ||
|
|
0f4cfa877a | ||
|
|
1d5c2becbd | ||
|
|
22a09ea7c5 | ||
|
|
bad664c632 | ||
|
|
8a191c0a84 | ||
|
|
83fb8b4ca1 | ||
|
|
f38e31bd1e | ||
|
|
24e8b47977 | ||
|
|
95618793a4 | ||
|
|
2f3b460212 | ||
|
|
06e135e35f | ||
|
|
ebbf3d4a51 | ||
|
|
a270ba6b59 | ||
|
|
37f35e4ac2 | ||
|
|
50a578c1f6 | ||
|
|
85237b08d4 | ||
|
|
27b159e711 | ||
|
|
82b3eed5ef | ||
|
|
0f7aa41e33 | ||
|
|
370c8e0385 | ||
|
|
4240fba9b8 | ||
|
|
267bc70d33 | ||
|
|
a53ab99378 | ||
|
|
02308a7b56 | ||
|
|
0b3705e82f | ||
|
|
da5a21b240 | ||
|
|
5bd0cf8633 | ||
|
|
9199ab5846 | ||
|
|
ca6dce43fe | ||
|
|
543dd7d3d7 | ||
|
|
6b4886c908 | ||
|
|
0201cb4b52 | ||
|
|
cd072317d0 | ||
|
|
0785a15ace | ||
|
|
b1279a46d9 | ||
|
|
b571619d31 | ||
|
|
7b5350b459 | ||
|
|
1549db70e6 | ||
|
|
8ff9a3c8fb | ||
|
|
91cae51d8f | ||
|
|
8af2f5fbcf | ||
|
|
86a8016323 | ||
|
|
009dcdae01 | ||
|
|
f86f615d83 | ||
|
|
d3d1d11926 | ||
|
|
736019b767 | ||
|
|
a39bdb5840 | ||
|
|
e8ab0a44b2 | ||
|
|
c3ca293e6b | ||
|
|
516b67a43b | ||
|
|
eba3a37bb5 | ||
|
|
6d57ca1a59 | ||
|
|
3320251b4b | ||
|
|
33c94d3bd9 | ||
|
|
b18f717b46 | ||
|
|
a0d4b648bb | ||
|
|
6db880e16d | ||
|
|
a82003d6ac | ||
|
|
da9f1622fc | ||
|
|
8a4c7077bb | ||
|
|
0a63f2f2b0 | ||
|
|
931ac66638 | ||
|
|
35338a100f | ||
|
|
d57b606e73 | ||
|
|
00ada04111 | ||
|
|
a31c477fea | ||
|
|
bde7418ce1 | ||
|
|
70bb304a0a | ||
|
|
9d3b1efd86 | ||
|
|
482e1baea3 | ||
|
|
e4f5ba1d29 | ||
|
|
b9053c7a25 | ||
|
|
d357a7aabc | ||
|
|
ae77ebe5a5 | ||
|
|
04439edcec | ||
|
|
a246195412 | ||
|
|
8939a36bc7 | ||
|
|
a21c348d93 | ||
|
|
1f0def10eb | ||
|
|
f87caac9d8 | ||
|
|
d538a73250 | ||
|
|
2e4fbdeb08 | ||
|
|
3bc7cc82bb | ||
|
|
45fbdbc2dc | ||
|
|
54cb678055 | ||
|
|
e88c439eac | ||
|
|
9fc8cd4076 | ||
|
|
5476cb8f05 | ||
|
|
6a30e1d6be | ||
|
|
e4881245d9 | ||
|
|
354fec8a9c | ||
|
|
11cdab745d | ||
|
|
a89d424a0b | ||
|
|
429d2b56b7 | ||
|
|
2ea96549c5 | ||
|
|
fba008e298 | ||
|
|
c37a8e927e | ||
|
|
413bbe0480 | ||
|
|
34075fc4c4 | ||
|
|
e5436ca566 | ||
|
|
cfde686eab | ||
|
|
a206964c0a | ||
|
|
c56d89f804 | ||
|
|
c215706350 | ||
|
|
d3b93ec682 | ||
|
|
6fe20dbe33 | ||
|
|
7ccdf3337b | ||
|
|
dafed54764 | ||
|
|
a84beafd1b | ||
|
|
f01cc1e413 | ||
|
|
338dd144b8 | ||
|
|
c719552317 | ||
|
|
855964a87a | ||
|
|
a438e2fca9 | ||
|
|
00833e893a | ||
|
|
f1a77e4fc0 | ||
|
|
b55a2fd531 | ||
|
|
e8a2c0b5bf | ||
|
|
21cd7e3f57 | ||
|
|
5172ba5f2a | ||
|
|
a57b069409 | ||
|
|
4454656c3b | ||
|
|
fa43768ce0 | ||
|
|
a74e600fa0 | ||
|
|
4b21526310 | ||
|
|
a7a7b1daed | ||
|
|
7436977aa5 | ||
|
|
e3c565b46f | ||
|
|
54b0b49b68 | ||
|
|
65648d84a5 | ||
|
|
fd788590f6 | ||
|
|
143f9054da | ||
|
|
f2286c33f1 | ||
|
|
b9615f7a62 | ||
|
|
c520e99eda | ||
|
|
615ae37ca3 | ||
|
|
7aa7f21872 | ||
|
|
4430a436eb | ||
|
|
9707ccdc9f | ||
|
|
cb8f3a2a31 | ||
|
|
8b3259e0c2 | ||
|
|
b66f47b8dd | ||
|
|
8d2e6f333e | ||
|
|
b3ef5e514d | ||
|
|
627f5fb41e | ||
|
|
d90777b724 | ||
|
|
e49297e5eb | ||
|
|
ebd82b3fb6 | ||
|
|
d074aa6e27 | ||
|
|
b052f62710 | ||
|
|
d4ac84b255 | ||
|
|
e250396d7e | ||
|
|
c6fa39b482 | ||
|
|
9aae4f2424 | ||
|
|
008c236137 | ||
|
|
b1c0664066 | ||
|
|
ea999b0e92 | ||
|
|
ce7e220de4 | ||
|
|
2bdaca10ae | ||
|
|
aa0029204e | ||
|
|
f352bcec3a | ||
|
|
08514030f4 | ||
|
|
694ca5d045 | ||
|
|
57fb58b263 | ||
|
|
18c1c9b38a | ||
|
|
5c1ae3662d | ||
|
|
cfebeb2f63 | ||
|
|
fc78423f1d | ||
|
|
2a5277b391 | ||
|
|
d47547dc71 | ||
|
|
304db15a20 | ||
|
|
7cf72b8d66 | ||
|
|
cea685f8d9 | ||
|
|
8d4b5344f4 | ||
|
|
34a0ab6f2c | ||
|
|
bcebacbb9e | ||
|
|
018a5a750a | ||
|
|
b468103f26 | ||
|
|
66c126ffde | ||
|
|
fdee083465 | ||
|
|
5ffc17d4aa | ||
|
|
6aa750010f | ||
|
|
76df77c08c | ||
|
|
957d5537a8 | ||
|
|
88c8f4e363 | ||
|
|
ab36b9b10a | ||
|
|
28330913d8 | ||
|
|
766a4147d4 | ||
|
|
915c7e234d | ||
|
|
e54ddcbb8a | ||
|
|
9e19e63551 | ||
|
|
bce7ee5f6a | ||
|
|
b39043f3ab | ||
|
|
caf96acb08 | ||
|
|
c76749084b | ||
|
|
5843494ee2 | ||
|
|
efa21ae3e6 | ||
|
|
24d9633a35 | ||
|
|
7963b96681 | ||
|
|
8c62d854ce | ||
|
|
69931574e1 | ||
|
|
b5af8a1914 | ||
|
|
c14d09ba84 | ||
|
|
4fc39d8dad | ||
|
|
0b7c70f726 | ||
|
|
f72d3029dd | ||
|
|
1a0d6edc81 | ||
|
|
7b59b2f5b2 | ||
|
|
7bc7704edf | ||
|
|
14e712ee80 | ||
|
|
f83adcc995 | ||
|
|
df8a99439a | ||
|
|
6b91d12ec3 | ||
|
|
f37b91879f | ||
|
|
d835c72c80 | ||
|
|
c4cebb4b01 | ||
|
|
d51a00a450 | ||
|
|
fc0f168a0c | ||
|
|
a0ca595c2c | ||
|
|
1a314e9f60 | ||
|
|
6fcbd5e217 | ||
|
|
22cea023d1 | ||
|
|
70d4477e05 | ||
|
|
838f837379 | ||
|
|
82a8b6f612 | ||
|
|
69fc7ca8da | ||
|
|
0a79496e0a | ||
|
|
9e87edfc2e | ||
|
|
27211cf2d5 | ||
|
|
b5ce199711 | ||
|
|
c71ed91e63 | ||
|
|
f7545d0f1c | ||
|
|
59eecb6bf5 | ||
|
|
d83c6490ab | ||
|
|
7362f57966 | ||
|
|
eaa2c1f6af | ||
|
|
6a916523d4 | ||
|
|
ba7069d52b | ||
|
|
4dd7d0e39b | ||
|
|
90199d0a96 | ||
|
|
b82fd0ad41 | ||
|
|
183da16896 | ||
|
|
87857b0f1b | ||
|
|
e5f6a88233 | ||
|
|
8d0b00317e | ||
|
|
db49daf365 | ||
|
|
923deeff35 | ||
|
|
0b62a28b47 | ||
|
|
44116c6d2b | ||
|
|
b5bab254ce | ||
|
|
81603ecd15 | ||
|
|
e67553fa55 | ||
|
|
fcf542f262 | ||
|
|
8adfc29f91 | ||
|
|
02f47e1713 | ||
|
|
07f64d4050 | ||
|
|
6982a0554c | ||
|
|
fa3250199a | ||
|
|
06b9894c19 | ||
|
|
9f9db504d7 | ||
|
|
82ae95c334 | ||
|
|
9a5e2052c4 | ||
|
|
b1410be443 | ||
|
|
12985d86c2 | ||
|
|
49bfc6b555 | ||
|
|
d1c6bb8c7c | ||
|
|
5c169615a8 | ||
|
|
73d77f4f64 | ||
|
|
ccf0e2ef4f | ||
|
|
20ca0f5906 | ||
|
|
b29d435bb5 | ||
|
|
90585e29c2 | ||
|
|
d8fc281915 | ||
|
|
188c39e8d5 | ||
|
|
5429234138 | ||
|
|
b9f72a4a81 | ||
|
|
fc6ebd04a5 | ||
|
|
7e00a12741 | ||
|
|
10b3752b1e | ||
|
|
fe51a91395 | ||
|
|
951d87ca94 | ||
|
|
798fc21530 | ||
|
|
a75a046abb | ||
|
|
38f2b4579f | ||
|
|
56e2a369d0 | ||
|
|
0daa199fa8 | ||
|
|
73e98dcda4 | ||
|
|
36bca6934d | ||
|
|
ace5811691 | ||
|
|
ba7bad0dbd | ||
|
|
b8b2ac5230 | ||
|
|
ea2359381b | ||
|
|
52de64cf16 | ||
|
|
455790202a | ||
|
|
f40f5eb228 | ||
|
|
604caa09e7 | ||
|
|
29a71d3aae | ||
|
|
39a907bde3 | ||
|
|
70474310f3 | ||
|
|
b5f0f4f3a1 | ||
|
|
2905fd625a | ||
|
|
4facd94029 | ||
|
|
4b5993ff15 | ||
|
|
2351a672ea | ||
|
|
4a528c469c | ||
|
|
82d1ef0242 | ||
|
|
7fdd2082a6 | ||
|
|
e529f54e90 | ||
|
|
d626e9bf19 | ||
|
|
a2a9459684 | ||
|
|
a3dfeea144 | ||
|
|
d316fb139d | ||
|
|
83d8aa8b12 | ||
|
|
4f1c12b6fd | ||
|
|
d8e0e34354 | ||
|
|
0c4f315c02 | ||
|
|
0809699bdc | ||
|
|
2088e1c19d | ||
|
|
bf1d47180c | ||
|
|
0cfbd79aa1 | ||
|
|
d66d86f20b | ||
|
|
905325d3e2 | ||
|
|
dea0cc0662 | ||
|
|
d69d8007d6 | ||
|
|
c0b8f2a16d | ||
|
|
cb0257dbbf | ||
|
|
9637f51b68 | ||
|
|
3026bd8975 | ||
|
|
78a44d5ab0 | ||
|
|
7e13c0db40 | ||
|
|
e6a2e9e4d0 | ||
|
|
e773f03927 | ||
|
|
b16380d669 | ||
|
|
334b07a3db | ||
|
|
3cc1527f00 | ||
|
|
525a61fb55 | ||
|
|
c3a002ff97 | ||
|
|
fad6766a90 | ||
|
|
aa664dea0a | ||
|
|
102f994b9d | ||
|
|
2a4c68be4f | ||
|
|
541e6011af | ||
|
|
6fa3fbeae8 | ||
|
|
4eb4cb656c | ||
|
|
193612ac67 | ||
|
|
95cfce68ea | ||
|
|
ec4202590d | ||
|
|
5e2cd07d6f | ||
|
|
06166df999 | ||
|
|
e2dc9cf091 | ||
|
|
069df27bf1 | ||
|
|
3e7873217c | ||
|
|
e21bab7ce6 | ||
|
|
ac9a168fba | ||
|
|
81b64549ce | ||
|
|
082e004b87 | ||
|
|
983e69128b | ||
|
|
b335912e86 | ||
|
|
cc07f3b806 | ||
|
|
07e4b64f3a | ||
|
|
d3ce2bc9e7 | ||
|
|
cff3bf4914 | ||
|
|
79cfac77bd | ||
|
|
224c14d49d | ||
|
|
7857354d85 | ||
|
|
b4aef753e7 | ||
|
|
424173d311 | ||
|
|
ec7cd1dcf7 | ||
|
|
7def684730 | ||
|
|
10f961c27b | ||
|
|
b483678ca7 | ||
|
|
cbbe6fad60 | ||
|
|
f96929c031 | ||
|
|
2b6657e967 | ||
|
|
7c0c92943f | ||
|
|
62a66dfff4 | ||
|
|
2cab348341 | ||
|
|
460218a3f8 | ||
|
|
e49416e4aa | ||
|
|
d4d7d99b70 | ||
|
|
6a696d0a7b | ||
|
|
1c9e13f47d | ||
|
|
b757450cd8 | ||
|
|
23ec484806 | ||
|
|
f1e1bb419a | ||
|
|
6a0af85c8b | ||
|
|
09269be974 | ||
|
|
bf832cde16 | ||
|
|
2972d58dbb | ||
|
|
2e22d38a02 | ||
|
|
ce27bcd69a | ||
|
|
9336cc8247 | ||
|
|
9809567dfc | ||
|
|
1ee8be8d91 | ||
|
|
8430c2f9f8 | ||
|
|
659c8a7632 | ||
|
|
3564b4f20d | ||
|
|
3505a3604a | ||
|
|
9b1bc6c014 | ||
|
|
9f23185f2b | ||
|
|
b82feb9302 | ||
|
|
7f2a591c7e | ||
|
|
afbcebddf6 | ||
|
|
484e484571 | ||
|
|
6f3f21233f | ||
|
|
a6873a3859 | ||
|
|
7a6d452b54 | ||
|
|
9b58b54e2d | ||
|
|
c598a12af9 | ||
|
|
cfe3a98ce5 | ||
|
|
14778e049b | ||
|
|
446fb0198b | ||
|
|
7d3cddf9d6 | ||
|
|
6dead95eb3 | ||
|
|
cc931b3ad8 | ||
|
|
d838b4b52e | ||
|
|
2f3bddbaca | ||
|
|
673b071637 | ||
|
|
da82fa59a7 | ||
|
|
333792352e | ||
|
|
e2ec270b04 | ||
|
|
ed7a0a454e | ||
|
|
d819559a01 | ||
|
|
8ca49155a8 | ||
|
|
b95e3338d9 | ||
|
|
e40a0ee9c6 | ||
|
|
cb62bd98d3 | ||
|
|
f30790b11b | ||
|
|
5205dbcbf4 | ||
|
|
3ff625de7e | ||
|
|
4832bc5d88 | ||
|
|
7f342cb3e3 | ||
|
|
05e7d34ed4 | ||
|
|
86607156e3 | ||
|
|
0fe259e9c5 | ||
|
|
8701a99a15 | ||
|
|
1476c78b53 | ||
|
|
cb6a92892f | ||
|
|
f1556cb945 | ||
|
|
efffb81735 | ||
|
|
202f90ef8f | ||
|
|
c07ea17c01 | ||
|
|
edb4e3bd52 | ||
|
|
4113609dd4 | ||
|
|
7ac7b0872f | ||
|
|
86ae5881b7 | ||
|
|
fac003c64f | ||
|
|
2273655c17 | ||
|
|
01057cf76d | ||
|
|
032f096b7f | ||
|
|
4b334edf49 | ||
|
|
8ddcbc39e6 | ||
|
|
0b0eac1d5d | ||
|
|
b29fc8b27c | ||
|
|
5de369fa67 | ||
|
|
7918a50d52 | ||
|
|
21794c9b8d | ||
|
|
6c686ce593 | ||
|
|
db902af4c6 | ||
|
|
7d6907cb99 | ||
|
|
092d9affb8 | ||
|
|
8f681b1d17 | ||
|
|
90313875f7 | ||
|
|
3f18a61532 | ||
|
|
02a6ce07eb | ||
|
|
738fd52bc4 | ||
|
|
d18979bb23 | ||
|
|
8266993c6e | ||
|
|
9a137e8613 | ||
|
|
ef618332ea | ||
|
|
7f418978c9 | ||
|
|
04cc395c35 | ||
|
|
e008dc1bde | ||
|
|
ddf96cfda2 | ||
|
|
ebfd5c5c74 | ||
|
|
f2ad542679 | ||
|
|
c43118be4f | ||
|
|
93f3b2b114 | ||
|
|
bf000beae7 | ||
|
|
0e16d92786 | ||
|
|
2441827408 | ||
|
|
0aff037a35 | ||
|
|
74a2f53683 | ||
|
|
e20935c3f2 | ||
|
|
3e34f62a1c | ||
|
|
d21cb84696 | ||
|
|
3dd495ecdd |
10
.github/ISSUE_TEMPLATE.md
vendored
10
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,11 +1,7 @@
|
||||
**Bug report or feature request?**
|
||||
**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**
|
||||
@@ -24,6 +20,6 @@
|
||||
**JavaScript output or error produced.**
|
||||
|
||||
<!--
|
||||
Note: `uglify-js` only supports ES5.
|
||||
Those wishing to minify ES6 should use `uglify-es`.
|
||||
Note: `uglify-js` only supports JavaScript.
|
||||
Those wishing to minify ES6+ should transpile first.
|
||||
-->
|
||||
|
||||
31
.github/workflows/ci.yml
vendored
Normal file
31
.github/workflows/ci.yml
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
name: CI
|
||||
on: [ push, pull_request ]
|
||||
jobs:
|
||||
test:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ ubuntu-latest, windows-latest ]
|
||||
node: [ "0.10", 0.12, 4, 6, 8, 10, latest ]
|
||||
script: [ compress, mocha, release/benchmark, release/jetstream ]
|
||||
name: ${{ matrix.os }} ${{ matrix.node }} ${{ matrix.script }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
NODE: ${{ matrix.node }}
|
||||
TYPE: ${{ matrix.script }}
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/cache@v1
|
||||
with:
|
||||
path: tmp
|
||||
key: tmp ${{ matrix.script }}
|
||||
- name: Perform tests
|
||||
shell: bash
|
||||
run: |
|
||||
git clone --branch v1.5.3 --depth 1 https://github.com/jasongin/nvs.git ~/.nvs
|
||||
. ~/.nvs/nvs.sh --version
|
||||
nvs add $NODE
|
||||
nvs use $NODE
|
||||
node --version
|
||||
npm --version --no-update-notifier
|
||||
npm install --no-audit --no-optional --no-save --no-update-notifier
|
||||
node test/$TYPE
|
||||
25
.github/workflows/ufuzz.yml
vendored
Normal file
25
.github/workflows/ufuzz.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
name: Fuzzing
|
||||
on:
|
||||
schedule:
|
||||
- cron: "*/15 * * * *"
|
||||
jobs:
|
||||
ufuzz:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ ubuntu-latest, windows-latest ]
|
||||
name: ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Perform fuzzing
|
||||
shell: bash
|
||||
run: |
|
||||
git clone --branch v1.5.3 --depth 1 https://github.com/jasongin/nvs.git ~/.nvs
|
||||
. ~/.nvs/nvs.sh --version
|
||||
nvs add 10
|
||||
nvs use 10
|
||||
node --version
|
||||
npm --version --no-update-notifier
|
||||
npm install --no-audit --no-optional --no-save --no-update-notifier
|
||||
node test/ufuzz/job 3600000
|
||||
14
.travis.yml
14
.travis.yml
@@ -1,14 +0,0 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "0.10"
|
||||
- "0.12"
|
||||
- "4"
|
||||
- "6"
|
||||
- "8"
|
||||
env:
|
||||
- UGLIFYJS_TEST_ALL=1
|
||||
matrix:
|
||||
fast_finish: true
|
||||
sudo: false
|
||||
cache:
|
||||
directories: tmp
|
||||
61
CONTRIBUTING.md
Normal file
61
CONTRIBUTING.md
Normal file
@@ -0,0 +1,61 @@
|
||||
Contributing
|
||||
============
|
||||
|
||||
## Documentation
|
||||
|
||||
Every new feature and API change should be accompanied by a README additon.
|
||||
|
||||
## Testing
|
||||
|
||||
All features and bugs should have tests that verify the fix. You can run all
|
||||
tests using `npm test`.
|
||||
|
||||
The most common type of test are tests that verify input and output of the
|
||||
Uglify transforms. These tests exist in `test/compress`. New tests can be added
|
||||
either to an existing file or in a new file `issue-xxx.js`.
|
||||
|
||||
Tests that cannot be expressed as a simple AST can be found in `test/mocha`.
|
||||
|
||||
## Code style
|
||||
|
||||
- File encoding must be `UTF-8`.
|
||||
- `LF` is always used as a line ending.
|
||||
- Statements end with semicolons.
|
||||
- Indentation uses 4 spaces, switch `case` 2 spaces.
|
||||
- Identifiers use `snake_case`.
|
||||
- Strings use double quotes (`"`).
|
||||
- Use a trailing comma for multiline array and object literals to minimize diffs.
|
||||
- The Uglify code only uses ES5, even in the `harmony` branch.
|
||||
- Line length should be at most 80 cols, except when it is easier to read a
|
||||
longer line.
|
||||
- If both sides of a comparison are of the same type, `==` and `!=` are used.
|
||||
- Multiline conditions place `&&` and `||` first on the line.
|
||||
|
||||
**Example feature**
|
||||
|
||||
```js
|
||||
OPT(AST_Debugger, function(self, compressor) {
|
||||
if (compressor.option("drop_debugger"))
|
||||
return make_node(AST_EmptyStatement, self);
|
||||
return self;
|
||||
});
|
||||
```
|
||||
|
||||
**Example test case**
|
||||
|
||||
```js
|
||||
drop_debugger: {
|
||||
options = {
|
||||
drop_debugger: true,
|
||||
}
|
||||
input: {
|
||||
debugger;
|
||||
if (foo) debugger;
|
||||
}
|
||||
expect: {
|
||||
if (foo);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
UglifyJS is released under the BSD license:
|
||||
|
||||
Copyright 2012-2013 (c) Mihai Bazon <mihai.bazon@gmail.com>
|
||||
Copyright 2012-2019 (c) Mihai Bazon <mihai.bazon@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
|
||||
159
README.md
159
README.md
@@ -6,9 +6,8 @@ UglifyJS is a JavaScript parser, minifier, compressor and beautifier toolkit.
|
||||
#### Note:
|
||||
- **`uglify-js@3` has a simplified [API](#api-reference) and [CLI](#command-line-usage) that is not backwards compatible with [`uglify-js@2`](https://github.com/mishoo/UglifyJS2/tree/v2.x)**.
|
||||
- **Documentation for UglifyJS `2.x` releases can be found [here](https://github.com/mishoo/UglifyJS2/tree/v2.x)**.
|
||||
- `uglify-js` only supports ECMAScript 5 (ES5).
|
||||
- Those wishing to minify
|
||||
ES2015+ (ES6+) should use the `npm` package [**uglify-es**](https://github.com/mishoo/UglifyJS2/tree/harmony).
|
||||
- `uglify-js` only supports JavaScript (ECMAScript 5).
|
||||
- To minify ECMAScript 2015 or above, transpile using tools like [Babel](https://babeljs.io/).
|
||||
|
||||
Install
|
||||
-------
|
||||
@@ -70,7 +69,7 @@ a double dash to prevent input files being used as option arguments:
|
||||
`debug` Add debug prefix and suffix.
|
||||
`domprops` Mangle property names that overlaps
|
||||
with DOM properties.
|
||||
`keep_quoted` Only mangle unquoted properies.
|
||||
`keep_quoted` Only mangle unquoted properties.
|
||||
`regex` Only mangle matched property names.
|
||||
`reserved` List of names that should not be mangled.
|
||||
-b, --beautify [options] Beautify output/specify output options:
|
||||
@@ -105,6 +104,8 @@ a double dash to prevent input files being used as option arguments:
|
||||
sequences.
|
||||
--config-file <file> Read `minify()` options from JSON file.
|
||||
-d, --define <expr>[=value] Global definitions.
|
||||
-e, --enclose [arg[:value]] Embed everything in a big function, with configurable
|
||||
argument(s) & value(s).
|
||||
--ie8 Support non-standard Internet Explorer 8.
|
||||
Equivalent to setting `ie8: true` in `minify()`
|
||||
for `compress`, `mangle` and `output` options.
|
||||
@@ -119,7 +120,8 @@ a double dash to prevent input files being used as option arguments:
|
||||
JS that was generated from some other original
|
||||
code. Specify "inline" if the source map is
|
||||
included within the sources.
|
||||
`filename` Name and/or location of the output source.
|
||||
`filename` Filename and/or location of the output source
|
||||
(sets `file` attribute in source map).
|
||||
`includeSources` Pass this flag if you want to include
|
||||
the content of source files in the
|
||||
source map as sourcesContent property.
|
||||
@@ -150,7 +152,9 @@ debugging your compressed JavaScript. To get a source map, pass
|
||||
|
||||
Additional options:
|
||||
|
||||
- `--source-map "filename='<NAME>'"` to specify the name of the source map.
|
||||
- `--source-map "filename='<NAME>'"` to specify the name of the source map. The value of
|
||||
`filename` is only used to set `file` attribute (see [the spec][sm-spec])
|
||||
in source map file.
|
||||
|
||||
- `--source-map "root='<URL>'"` to pass the URL where the original files can be found.
|
||||
|
||||
@@ -474,42 +478,42 @@ if (result.error) throw result.error;
|
||||
|
||||
## Minify options
|
||||
|
||||
- `warnings` (default `false`) — pass `true` to return compressor warnings
|
||||
in `result.warnings`. Use the value `"verbose"` for more detailed warnings.
|
||||
|
||||
- `parse` (default `{}`) — pass an object if you wish to specify some
|
||||
additional [parse options](#parse-options).
|
||||
|
||||
- `compress` (default `{}`) — pass `false` to skip compressing entirely.
|
||||
Pass an object to specify custom [compress options](#compress-options).
|
||||
|
||||
- `ie8` (default `false`) -- set to `true` to support IE8.
|
||||
|
||||
- `keep_fnames` (default: `false`) -- pass `true` to prevent discarding or mangling
|
||||
of function names. Useful for code relying on `Function.prototype.name`.
|
||||
|
||||
- `mangle` (default `true`) — pass `false` to skip mangling names, or pass
|
||||
an object to specify [mangle options](#mangle-options) (see below).
|
||||
|
||||
- `mangle.properties` (default `false`) — a subcategory of the mangle option.
|
||||
Pass an object to specify custom [mangle property options](#mangle-properties-options).
|
||||
|
||||
- `output` (default `null`) — pass an object if you wish to specify
|
||||
additional [output options](#output-options). The defaults are optimized
|
||||
for best compression.
|
||||
|
||||
- `sourceMap` (default `false`) - pass an object if you wish to specify
|
||||
[source map options](#source-map-options).
|
||||
|
||||
- `toplevel` (default `false`) - set to `true` if you wish to enable top level
|
||||
variable and function name mangling and to drop unused variables and functions.
|
||||
|
||||
- `nameCache` (default `null`) - pass an empty object `{}` or a previously
|
||||
- `nameCache` (default `null`) -- pass an empty object `{}` or a previously
|
||||
used `nameCache` object if you wish to cache mangled variable and
|
||||
property names across multiple invocations of `minify()`. Note: this is
|
||||
a read/write property. `minify()` will read the name cache state of this
|
||||
object and update it during minification so that it may be
|
||||
reused or externally persisted by the user.
|
||||
|
||||
- `ie8` (default `false`) - set to `true` to support IE8.
|
||||
- `output` (default `null`) — pass an object if you wish to specify
|
||||
additional [output options](#output-options). The defaults are optimized
|
||||
for best compression.
|
||||
|
||||
- `keep_fnames` (default: `false`) - pass `true` to prevent discarding or mangling
|
||||
of function names. Useful for code relying on `Function.prototype.name`.
|
||||
- `parse` (default `{}`) — pass an object if you wish to specify some
|
||||
additional [parse options](#parse-options).
|
||||
|
||||
- `sourceMap` (default `false`) -- pass an object if you wish to specify
|
||||
[source map options](#source-map-options).
|
||||
|
||||
- `toplevel` (default `false`) -- set to `true` if you wish to enable top level
|
||||
variable and function name mangling and to drop unused variables and functions.
|
||||
|
||||
- `warnings` (default `false`) — pass `true` to return compressor warnings
|
||||
in `result.warnings`. Use the value `"verbose"` for more detailed warnings.
|
||||
|
||||
## Minify options structure
|
||||
|
||||
@@ -598,24 +602,28 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
||||
|
||||
## Compress options
|
||||
|
||||
- `arguments` (default: `true`) -- replace `arguments[index]` with function
|
||||
parameter name whenever possible.
|
||||
|
||||
- `assignments` (default: `true`) -- apply optimizations to assignment expressions.
|
||||
|
||||
- `booleans` (default: `true`) -- various optimizations for boolean context,
|
||||
for example `!!a ? b : c → a ? b : c`
|
||||
|
||||
- `cascade` (default: `true`) -- small optimization for sequences, transform
|
||||
`x, x` into `x` and `x = something(), x` into `x = something()`
|
||||
|
||||
- `collapse_vars` (default: `true`) -- Collapse single-use non-constant variables,
|
||||
side effects permitting.
|
||||
|
||||
- `comparisons` (default: `true`) -- apply certain optimizations to binary nodes,
|
||||
e.g. `!(a <= b) → a > b` (only when `unsafe_comps`), attempts to negate binary
|
||||
nodes, e.g. `a = !b && !c && !d && !e → a=!(b||c||d||e)` etc.
|
||||
e.g. `!(a <= b) → a > b`, attempts to negate binary nodes, e.g.
|
||||
`a = !b && !c && !d && !e → a=!(b||c||d||e)` etc.
|
||||
|
||||
- `conditionals` (default: `true`) -- apply optimizations for `if`-s and conditional
|
||||
expressions
|
||||
|
||||
- `dead_code` (default: `true`) -- remove unreachable code
|
||||
|
||||
- `directives` (default: `true`) -- remove redundant or non-standard directives
|
||||
|
||||
- `drop_console` (default: `false`) -- Pass `true` to discard calls to
|
||||
`console.*` functions. If you wish to drop a specific function call
|
||||
such as `console.info` and/or retain side effects from function arguments
|
||||
@@ -623,14 +631,20 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
||||
|
||||
- `drop_debugger` (default: `true`) -- remove `debugger;` statements
|
||||
|
||||
- `evaluate` (default: `true`) -- attempt to evaluate constant expressions
|
||||
- `evaluate` (default: `true`) -- Evaluate expression for shorter constant
|
||||
representation. Pass `"eager"` to always replace function calls whenever
|
||||
possible, or a positive integer to specify an upper bound for each individual
|
||||
evaluation in number of characters.
|
||||
|
||||
- `expression` (default: `false`) -- Pass `true` to preserve completion values
|
||||
from terminal statements without `return`, e.g. in bookmarklets.
|
||||
|
||||
- `functions` (default: `true`) -- convert declarations from `var`to `function`
|
||||
whenever possible.
|
||||
|
||||
- `global_defs` (default: `{}`) -- see [conditional compilation](#conditional-compilation)
|
||||
|
||||
- `hoist_funs` (default: `true`) -- hoist function declarations
|
||||
- `hoist_funs` (default: `false`) -- hoist function declarations
|
||||
|
||||
- `hoist_props` (default: `true`) -- hoist properties from constant object and
|
||||
array literals into regular variables subject to a set of constraints. For example:
|
||||
@@ -643,16 +657,23 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
||||
|
||||
- `if_return` (default: `true`) -- optimizations for if/return and if/continue
|
||||
|
||||
- `inline` (default: `true`) -- embed simple functions
|
||||
- `inline` (default: `true`) -- inline calls to function with simple/`return` statement:
|
||||
- `false` -- same as `0`
|
||||
- `0` -- disabled inlining
|
||||
- `1` -- inline simple functions
|
||||
- `2` -- inline functions with arguments
|
||||
- `3` -- inline functions with arguments and variables
|
||||
- `true` -- same as `3`
|
||||
|
||||
- `join_vars` (default: `true`) -- join consecutive `var` statements
|
||||
|
||||
- `keep_fargs` (default: `true`) -- Prevents the compressor from discarding unused
|
||||
function arguments. You need this for code which relies on `Function.length`.
|
||||
- `keep_fargs` (default: `strict`) -- Discard unused function arguments. Code
|
||||
which relies on `Function.length` will break if this is done indiscriminately,
|
||||
i.e. when passing `true`. Pass `false` to always retain function arguments.
|
||||
|
||||
- `keep_fnames` (default: `false`) -- Pass `true` to prevent the
|
||||
compressor from discarding function names. Useful for code relying on
|
||||
`Function.prototype.name`. See also: the `keep_fnames` [mangle option](#mangle).
|
||||
`Function.prototype.name`. See also: the `keep_fnames` [mangle option](#mangle-options).
|
||||
|
||||
- `keep_infinity` (default: `false`) -- Pass `true` to prevent `Infinity` from
|
||||
being compressed into `1/0`, which may cause performance issues on Chrome.
|
||||
@@ -664,6 +685,8 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
||||
where the return value is discarded, to avoid the parens that the
|
||||
code generator would insert.
|
||||
|
||||
- `objects` (default: `true`) -- compact duplicate keys in object literals.
|
||||
|
||||
- `passes` (default: `1`) -- The maximum number of times to run compress.
|
||||
In some cases more than one pass leads to further compressed code. Keep in
|
||||
mind more passes will take more time.
|
||||
@@ -680,7 +703,8 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
||||
pass `pure_funcs: [ 'Math.floor' ]` to let it know that this
|
||||
function won't produce any side effect, in which case the whole
|
||||
statement would get discarded. The current implementation adds some
|
||||
overhead (compression will be slower).
|
||||
overhead (compression will be slower). Make sure symbols under `pure_funcs`
|
||||
are also under `mangle.reserved` to avoid mangling.
|
||||
|
||||
- `pure_getters` (default: `"strict"`) -- If you pass `true` for
|
||||
this, UglifyJS will assume that object property access
|
||||
@@ -727,14 +751,10 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
||||
|
||||
- `unsafe` (default: `false`) -- apply "unsafe" transformations (discussion below)
|
||||
|
||||
- `unsafe_comps` (default: `false`) -- Reverse `<` and `<=` to `>` and `>=` to
|
||||
allow improved compression. This might be unsafe when an at least one of two
|
||||
operands is an object with computed values due the use of methods like `get`,
|
||||
or `valueOf`. This could cause change in execution order after operands in the
|
||||
comparison are switching. Compression only works if both `comparisons` and
|
||||
`unsafe_comps` are both set to true.
|
||||
- `unsafe_comps` (default: `false`) -- compress expressions like `a <= b` assuming
|
||||
none of the operands can be (coerced to) `NaN`.
|
||||
|
||||
- `unsafe_Func` (default: `false`) -- compress and mangle `Function(args, code)`
|
||||
- `unsafe_Function` (default: `false`) -- compress and mangle `Function(args, code)`
|
||||
when both `args` and `code` are string literals.
|
||||
|
||||
- `unsafe_math` (default: `false`) -- optimize numerical expressions like
|
||||
@@ -746,12 +766,13 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
||||
- `unsafe_regexp` (default: `false`) -- enable substitutions of variables with
|
||||
`RegExp` values the same way as if they are constants.
|
||||
|
||||
- `unsafe_undefined` (default: `false`) -- substitute `void 0` if there is a
|
||||
variable named `undefined` in scope (variable name will be mangled, typically
|
||||
reduced to a single character)
|
||||
|
||||
- `unused` (default: `true`) -- drop unreferenced functions and variables (simple
|
||||
direct variable assignments do not count as references unless set to `"keep_assign"`)
|
||||
|
||||
- `warnings` (default: `false`) -- display warnings when dropping unreachable
|
||||
code or unused declarations etc.
|
||||
|
||||
## Mangle options
|
||||
|
||||
- `eval` (default `false`) -- Pass `true` to mangle names visible in scopes
|
||||
@@ -819,7 +840,7 @@ can pass additional arguments that control the code output:
|
||||
when you want to generate minified code, in order to specify additional
|
||||
arguments, so you can use `-b beautify=false` to override it.
|
||||
|
||||
- `bracketize` (default `false`) -- always insert brackets in `if`, `for`,
|
||||
- `braces` (default `false`) -- always insert braces in `if`, `for`,
|
||||
`do`, `while` or `with` statements, even if their body is a single
|
||||
statement.
|
||||
|
||||
@@ -831,8 +852,8 @@ can pass additional arguments that control the code output:
|
||||
|
||||
- `indent_start` (default `0`) -- prefix all lines by that many spaces
|
||||
|
||||
- `inline_script` (default `false`) -- escape the slash in occurrences of
|
||||
`</script` in strings
|
||||
- `inline_script` (default `true`) -- escape HTML comments and the slash in
|
||||
occurrences of `</script>` in strings
|
||||
|
||||
- `keep_quoted_props` (default `false`) -- when turned on, prevents stripping
|
||||
quotes from property names in object literals.
|
||||
@@ -844,8 +865,8 @@ can pass additional arguments that control the code output:
|
||||
adjust for this text. Can be used to insert a comment containing
|
||||
licensing information, for example.
|
||||
|
||||
- `preserve_line` (default `false`) -- pass `true` to preserve lines, but it
|
||||
only works if `beautify` is set to `false`.
|
||||
- `preserve_line` (default `false`) -- pass `true` to retain line numbering on
|
||||
a best effort basis.
|
||||
|
||||
- `quote_keys` (default `false`) -- pass `true` to quote all keys in literal
|
||||
objects
|
||||
@@ -919,9 +940,6 @@ when this flag is on:
|
||||
- `new Object()` → `{}`
|
||||
- `String(exp)` or `exp.toString()` → `"" + exp`
|
||||
- `new Object/RegExp/Function/Error/Array (...)` → we discard the `new`
|
||||
- `void 0` → `undefined` (if there is a variable named "undefined" in
|
||||
scope; we do it because the variable name will be mangled, typically
|
||||
reduced to a single character)
|
||||
|
||||
### Conditional compilation
|
||||
|
||||
@@ -1038,8 +1056,9 @@ var result = UglifyJS.minify(ast, {
|
||||
### Working with Uglify AST
|
||||
|
||||
Transversal and transformation of the native AST can be performed through
|
||||
[`TreeWalker`](http://lisperator.net/uglifyjs/walk) and
|
||||
[`TreeTransformer`](http://lisperator.net/uglifyjs/transform) respectively.
|
||||
[`TreeWalker`](https://github.com/mishoo/UglifyJS2/blob/master/lib/ast.js) and
|
||||
[`TreeTransformer`](https://github.com/mishoo/UglifyJS2/blob/master/lib/transform.js)
|
||||
respectively.
|
||||
|
||||
### ESTree / SpiderMonkey AST
|
||||
|
||||
@@ -1098,3 +1117,27 @@ To enable fast minify mode with the API use:
|
||||
```js
|
||||
UglifyJS.minify(code, { compress: false, mangle: true });
|
||||
```
|
||||
|
||||
#### Source maps and debugging
|
||||
|
||||
Various `compress` transforms that simplify, rearrange, inline and remove code
|
||||
are known to have an adverse effect on debugging with source maps. This is
|
||||
expected as code is optimized and mappings are often simply not possible as
|
||||
some code no longer exists. For highest fidelity in source map debugging
|
||||
disable the Uglify `compress` option and just use `mangle`.
|
||||
|
||||
### Compiler assumptions
|
||||
|
||||
To allow for better optimizations, the compiler makes various assumptions:
|
||||
|
||||
- `.toString()` and `.valueOf()` don't have side effects, and for built-in
|
||||
objects they have not been overridden.
|
||||
- `undefined`, `NaN` and `Infinity` have not been externally redefined.
|
||||
- `arguments.callee`, `arguments.caller` and `Function.prototype.caller` are not used.
|
||||
- The code doesn't expect the contents of `Function.prototype.toString()` or
|
||||
`Error.prototype.stack` to be anything in particular.
|
||||
- Getting and setting properties on a plain object does not cause other side effects
|
||||
(using `.watch()` or `Proxy`).
|
||||
- Object properties can be added, removed and modified (not prevented with
|
||||
`Object.defineProperty()`, `Object.defineProperties()`, `Object.freeze()`,
|
||||
`Object.preventExtensions()` or `Object.seal()`).
|
||||
|
||||
23
appveyor.yml
23
appveyor.yml
@@ -1,24 +1,5 @@
|
||||
environment:
|
||||
matrix:
|
||||
- nodejs_version: "0.10"
|
||||
- nodejs_version: "0.12"
|
||||
- nodejs_version: "4.0"
|
||||
- nodejs_version: "6.0"
|
||||
|
||||
build: off
|
||||
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
|
||||
- echo No longer in use
|
||||
|
||||
149
bin/uglifyjs
149
bin/uglifyjs
@@ -3,11 +3,7 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
// 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);
|
||||
});
|
||||
require("../tools/exit");
|
||||
|
||||
var fs = require("fs");
|
||||
var info = require("../package.json");
|
||||
@@ -15,7 +11,7 @@ var path = require("path");
|
||||
var program = require("commander");
|
||||
var UglifyJS = require("../tools/node");
|
||||
|
||||
var skip_keys = [ "cname", "enclosed", "inlined", "parent_scope", "scope", "thedef", "uses_eval", "uses_with" ];
|
||||
var skip_keys = [ "cname", "inlined", "parent_scope", "scope", "uses_eval", "uses_with" ];
|
||||
var files = {};
|
||||
var options = {
|
||||
compress: false,
|
||||
@@ -44,13 +40,15 @@ 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("-e, --enclose [arg[,...][:value[,...]]]", "Embed everything in a big function, with configurable argument(s) & value(s).");
|
||||
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("--rename", "Force symbol expansion.");
|
||||
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("--source-map [options]", "Enable source map/specify source map options.", parse_js());
|
||||
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.");
|
||||
@@ -58,24 +56,37 @@ program.option("--wrap <name>", "Embed everything as a function with “exports
|
||||
program.arguments("[files...]").parseArgv(process.argv);
|
||||
if (program.configFile) {
|
||||
options = JSON.parse(read_file(program.configFile));
|
||||
if (options.mangle && options.mangle.properties && options.mangle.properties.regex) {
|
||||
options.mangle.properties.regex = UglifyJS.parse(options.mangle.properties.regex, {
|
||||
expression: true
|
||||
}).getValue();
|
||||
}
|
||||
}
|
||||
if (!program.output && program.sourceMap && program.sourceMap.url != "inline") {
|
||||
fatal("ERROR: cannot write source map to STDOUT");
|
||||
fatal("cannot write source map to STDOUT");
|
||||
}
|
||||
[
|
||||
"compress",
|
||||
"enclose",
|
||||
"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.verbose) {
|
||||
options.warnings = "verbose";
|
||||
} else if (program.warn) {
|
||||
options.warnings = true;
|
||||
}
|
||||
if (options.warnings) {
|
||||
UglifyJS.AST_Node.log_function(print_error, options.warnings == "verbose");
|
||||
delete options.warnings;
|
||||
}
|
||||
if (program.beautify) {
|
||||
options.output = typeof program.beautify == "object" ? program.beautify : {};
|
||||
if (!("beautify" in options.output)) {
|
||||
@@ -103,7 +114,7 @@ if (program.mangleProps) {
|
||||
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);
|
||||
UglifyJS.push_uniq(program.mangleProps.reserved, name);
|
||||
});
|
||||
}
|
||||
if (typeof options.mangle != "object") options.mangle = {};
|
||||
@@ -122,9 +133,14 @@ 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");
|
||||
fatal("inline source map only works with built-in parser");
|
||||
}
|
||||
}
|
||||
if (~program.rawArgs.indexOf("--rename")) {
|
||||
options.rename = true;
|
||||
} else if (!program.rename) {
|
||||
options.rename = false;
|
||||
}
|
||||
var convert_path = function(name) {
|
||||
return name;
|
||||
};
|
||||
@@ -137,15 +153,8 @@ if (typeof program.sourceMap == "object" && "base" in program.sourceMap) {
|
||||
};
|
||||
}();
|
||||
}
|
||||
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");
|
||||
}
|
||||
if (program.args.length) UglifyJS.AST_Node.warn("Ignoring input files since --self was passed");
|
||||
if (!options.wrap) options.wrap = "UglifyJS";
|
||||
simple_glob(UglifyJS.FILES).forEach(function(name) {
|
||||
files[convert_path(name)] = read_file(name);
|
||||
@@ -173,9 +182,11 @@ function convert_ast(fn) {
|
||||
}
|
||||
|
||||
function run() {
|
||||
UglifyJS.AST_Node.warn_function = function(msg) {
|
||||
print_error("WARN: " + msg);
|
||||
};
|
||||
var content = program.sourceMap && program.sourceMap.content;
|
||||
if (content && content != "inline") {
|
||||
UglifyJS.AST_Node.info("Using input source map: " + content);
|
||||
options.sourceMap.content = read_file(content, content);
|
||||
}
|
||||
if (program.timings) options.timings = true;
|
||||
try {
|
||||
if (program.parse) {
|
||||
@@ -204,30 +215,45 @@ function run() {
|
||||
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;
|
||||
var file = files[ex.filename];
|
||||
if (file) {
|
||||
var col = ex.col;
|
||||
var lines = file.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;
|
||||
}
|
||||
print_error(line.slice(0, 80));
|
||||
print_error(line.slice(0, col).replace(/\S/g, " ") + "^");
|
||||
}
|
||||
print_error(line.slice(0, 80));
|
||||
print_error(line.slice(0, col).replace(/\S/g, " ") + "^");
|
||||
}
|
||||
}
|
||||
if (ex.defs) {
|
||||
} else if (ex.defs) {
|
||||
print_error("Supported options:");
|
||||
print_error(format_object(ex.defs));
|
||||
}
|
||||
fatal(ex);
|
||||
} else if (program.output == "ast") {
|
||||
if (!options.compress && !options.mangle) {
|
||||
result.ast.figure_out_scope({});
|
||||
}
|
||||
print(JSON.stringify(result.ast, function(key, value) {
|
||||
if (value) switch (key) {
|
||||
case "thedef":
|
||||
return symdef(value);
|
||||
case "enclosed":
|
||||
return value.length ? value.map(symdef) : undefined;
|
||||
case "variables":
|
||||
case "functions":
|
||||
case "globals":
|
||||
return value.size() ? value.map(symdef) : undefined;
|
||||
}
|
||||
if (skip_key(key)) return;
|
||||
if (value instanceof UglifyJS.AST_Token) return;
|
||||
if (value instanceof UglifyJS.Dictionary) return;
|
||||
@@ -268,7 +294,11 @@ function run() {
|
||||
}
|
||||
|
||||
function fatal(message) {
|
||||
if (message instanceof Error) message = message.stack.replace(/^\S*?Error:/, "ERROR:")
|
||||
if (message instanceof Error) {
|
||||
message = message.stack.replace(/^\S*?Error:/, "ERROR:")
|
||||
} else {
|
||||
message = "ERROR: " + message;
|
||||
}
|
||||
print_error(message);
|
||||
process.exit(1);
|
||||
}
|
||||
@@ -317,17 +347,9 @@ 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) {
|
||||
UglifyJS.parse(value, {
|
||||
expression: true
|
||||
}).walk(new UglifyJS.TreeWalker(function(node) {
|
||||
if (node instanceof UglifyJS.AST_Assign) {
|
||||
var name = node.left.print_to_string();
|
||||
var value = node.right;
|
||||
@@ -353,9 +375,9 @@ function parse_js(flag) {
|
||||
});
|
||||
}
|
||||
}));
|
||||
} catch(ex) {
|
||||
} catch (ex) {
|
||||
if (flag) {
|
||||
fatal("Error parsing arguments for '" + flag + "': " + value);
|
||||
fatal("cannot parse arguments for '" + flag + "': " + value);
|
||||
} else {
|
||||
options[value] = null;
|
||||
}
|
||||
@@ -364,23 +386,16 @@ function parse_js(flag) {
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
function skip_key(key) {
|
||||
return skip_keys.indexOf(key) >= 0;
|
||||
}
|
||||
|
||||
function symdef(def) {
|
||||
var ret = (1e6 + def.id) + " " + def.name;
|
||||
if (def.mangled_name) ret += " " + def.mangled_name;
|
||||
return ret;
|
||||
}
|
||||
|
||||
function format_object(obj) {
|
||||
var lines = [];
|
||||
var padding = "";
|
||||
|
||||
276
lib/ast.js
276
lib/ast.js
@@ -44,21 +44,21 @@
|
||||
"use strict";
|
||||
|
||||
function DEFNODE(type, props, methods, base) {
|
||||
if (arguments.length < 4) base = AST_Node;
|
||||
if (!props) props = [];
|
||||
else props = props.split(/\s+/);
|
||||
if (typeof base === "undefined") base = AST_Node;
|
||||
props = props ? props.split(/\s+/) : [];
|
||||
var self_props = props;
|
||||
if (base && base.PROPS)
|
||||
props = props.concat(base.PROPS);
|
||||
var code = "return function AST_" + type + "(props){ if (props) { ";
|
||||
for (var i = props.length; --i >= 0;) {
|
||||
code += "this." + props[i] + " = props." + props[i] + ";";
|
||||
}
|
||||
if (base && base.PROPS) props = props.concat(base.PROPS);
|
||||
var code = [
|
||||
"return function AST_", type, "(props){",
|
||||
"if(props){",
|
||||
];
|
||||
props.forEach(function(prop) {
|
||||
code.push("this.", prop, "=props.", prop, ";");
|
||||
});
|
||||
var proto = base && new base;
|
||||
if (proto && proto.initialize || (methods && methods.initialize))
|
||||
code += "this.initialize();";
|
||||
code += "}}";
|
||||
var ctor = new Function(code)();
|
||||
if (proto && proto.initialize || methods && methods.initialize) code.push("this.initialize();");
|
||||
code.push("}}");
|
||||
var ctor = new Function(code.join(""))();
|
||||
if (proto) {
|
||||
ctor.prototype = proto;
|
||||
ctor.BASE = base;
|
||||
@@ -71,11 +71,11 @@ function DEFNODE(type, props, methods, base) {
|
||||
if (type) {
|
||||
ctor.prototype.TYPE = ctor.TYPE = type;
|
||||
}
|
||||
if (methods) for (i in methods) if (HOP(methods, i)) {
|
||||
if (/^\$/.test(i)) {
|
||||
ctor[i.substr(1)] = methods[i];
|
||||
if (methods) for (var name in methods) if (HOP(methods, name)) {
|
||||
if (/^\$/.test(name)) {
|
||||
ctor[name.substr(1)] = methods[name];
|
||||
} else {
|
||||
ctor.prototype[i] = methods[i];
|
||||
ctor.prototype[name] = methods[name];
|
||||
}
|
||||
}
|
||||
ctor.DEFMETHOD = function(name, method) {
|
||||
@@ -85,9 +85,9 @@ function DEFNODE(type, props, methods, base) {
|
||||
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", {
|
||||
@@ -118,11 +118,25 @@ var AST_Node = DEFNODE("Node", "start end", {
|
||||
}
|
||||
}, null);
|
||||
|
||||
AST_Node.warn_function = null;
|
||||
AST_Node.warn = function(txt, props) {
|
||||
if (AST_Node.warn_function)
|
||||
AST_Node.warn_function(string_template(txt, props));
|
||||
};
|
||||
(AST_Node.log_function = function(fn, verbose) {
|
||||
var printed = Object.create(null);
|
||||
if (fn) {
|
||||
AST_Node.info = verbose ? function(text, props) {
|
||||
log("INFO: " + string_template(text, props));
|
||||
} : noop;
|
||||
AST_Node.warn = function(text, props) {
|
||||
log("WARN: " + string_template(text, props));
|
||||
};
|
||||
} else {
|
||||
AST_Node.info = AST_Node.warn = noop;
|
||||
}
|
||||
|
||||
function log(msg) {
|
||||
if (printed[msg]) return;
|
||||
printed[msg] = true;
|
||||
fn(msg);
|
||||
}
|
||||
})();
|
||||
|
||||
/* -----[ statements ]----- */
|
||||
|
||||
@@ -148,7 +162,7 @@ var AST_SimpleStatement = DEFNODE("SimpleStatement", "body", {
|
||||
body: "[AST_Node] an expression node (should not be instanceof AST_Statement)"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
this.body._walk(visitor);
|
||||
});
|
||||
}
|
||||
@@ -158,19 +172,18 @@ function walk_body(node, 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 body.forEach(function(node) {
|
||||
node._walk(visitor);
|
||||
});
|
||||
}
|
||||
|
||||
var AST_Block = DEFNODE("Block", "body", {
|
||||
$documentation: "A body of statements (usually bracketed)",
|
||||
$documentation: "A body of statements (usually braced)",
|
||||
$propdoc: {
|
||||
body: "[AST_Statement*] an array of statements"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
walk_body(this, visitor);
|
||||
});
|
||||
}
|
||||
@@ -197,7 +210,7 @@ var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", {
|
||||
label: "[AST_Label] a label definition"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
this.label._walk(visitor);
|
||||
this.body._walk(visitor);
|
||||
});
|
||||
@@ -208,8 +221,7 @@ var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", {
|
||||
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) {
|
||||
if (node instanceof AST_LoopControl && node.label && node.label.thedef === def) {
|
||||
node.label.thedef = label;
|
||||
label.references.push(node);
|
||||
}
|
||||
@@ -233,7 +245,7 @@ var AST_DWLoop = DEFNODE("DWLoop", "condition", {
|
||||
var AST_Do = DEFNODE("Do", null, {
|
||||
$documentation: "A `do` statement",
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
this.body._walk(visitor);
|
||||
this.condition._walk(visitor);
|
||||
});
|
||||
@@ -243,7 +255,7 @@ var AST_Do = DEFNODE("Do", null, {
|
||||
var AST_While = DEFNODE("While", null, {
|
||||
$documentation: "A `while` statement",
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
this.condition._walk(visitor);
|
||||
this.body._walk(visitor);
|
||||
});
|
||||
@@ -258,7 +270,7 @@ var AST_For = DEFNODE("For", "init condition step", {
|
||||
step: "[AST_Node?] the `for` update clause, or null if empty"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
if (this.init) this.init._walk(visitor);
|
||||
if (this.condition) this.condition._walk(visitor);
|
||||
if (this.step) this.step._walk(visitor);
|
||||
@@ -267,15 +279,14 @@ var AST_For = DEFNODE("For", "init condition step", {
|
||||
}
|
||||
}, AST_IterationStatement);
|
||||
|
||||
var AST_ForIn = DEFNODE("ForIn", "init name object", {
|
||||
var AST_ForIn = DEFNODE("ForIn", "init object", {
|
||||
$documentation: "A `for ... in` statement",
|
||||
$propdoc: {
|
||||
init: "[AST_Node] the `for/in` initialization code",
|
||||
name: "[AST_SymbolRef?] the loop variable, only if `init` is AST_Var",
|
||||
object: "[AST_Node] the object that we're looping through"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
this.init._walk(visitor);
|
||||
this.object._walk(visitor);
|
||||
this.body._walk(visitor);
|
||||
@@ -289,7 +300,7 @@ var AST_With = DEFNODE("With", "expression", {
|
||||
expression: "[AST_Node] the `with` expression"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
this.expression._walk(visitor);
|
||||
this.body._walk(visitor);
|
||||
});
|
||||
@@ -309,6 +320,16 @@ var AST_Scope = DEFNODE("Scope", "variables functions uses_with uses_eval parent
|
||||
enclosed: "[SymbolDef*/S] a list of all symbol definitions that are accessed from this scope or any subscopes",
|
||||
cname: "[integer/S] current index for mangling variables (used internally by the mangler)",
|
||||
},
|
||||
clone: function(deep) {
|
||||
var node = this._clone(deep);
|
||||
if (this.variables) node.variables = this.variables.clone();
|
||||
if (this.functions) node.functions = this.functions.clone();
|
||||
if (this.enclosed) node.enclosed = this.enclosed.slice();
|
||||
return node;
|
||||
},
|
||||
pinned: function() {
|
||||
return this.uses_eval || this.uses_with;
|
||||
}
|
||||
}, AST_Block);
|
||||
|
||||
var AST_Toplevel = DEFNODE("Toplevel", "globals", {
|
||||
@@ -316,20 +337,46 @@ var AST_Toplevel = DEFNODE("Toplevel", "globals", {
|
||||
$propdoc: {
|
||||
globals: "[Object/S] a map of name -> SymbolDef for all undeclared names",
|
||||
},
|
||||
wrap_commonjs: function(name) {
|
||||
wrap: 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){
|
||||
return parse([
|
||||
"(function(exports){'$ORIG';})(typeof ",
|
||||
name,
|
||||
"=='undefined'?(",
|
||||
name,
|
||||
"={}):",
|
||||
name,
|
||||
");"
|
||||
].join(""), {
|
||||
filename: "wrap=" + JSON.stringify(name)
|
||||
}).transform(new TreeTransformer(function(node) {
|
||||
if (node instanceof AST_Directive && node.value == "$ORIG") {
|
||||
return MAP.splice(body);
|
||||
}
|
||||
}));
|
||||
},
|
||||
enclose: function(args_values) {
|
||||
if (typeof args_values != "string") args_values = "";
|
||||
var index = args_values.indexOf(":");
|
||||
if (index < 0) index = args_values.length;
|
||||
var body = this.body;
|
||||
return parse([
|
||||
"(function(",
|
||||
args_values.slice(0, index),
|
||||
'){"$ORIG"})(',
|
||||
args_values.slice(index + 1),
|
||||
")"
|
||||
].join(""), {
|
||||
filename: "enclose=" + JSON.stringify(args_values)
|
||||
}).transform(new TreeTransformer(function(node) {
|
||||
if (node instanceof AST_Directive && node.value == "$ORIG") {
|
||||
return MAP.splice(body);
|
||||
}
|
||||
}));
|
||||
return wrapped_tl;
|
||||
}
|
||||
}, AST_Scope);
|
||||
|
||||
var AST_Lambda = DEFNODE("Lambda", "name argnames uses_arguments", {
|
||||
var AST_Lambda = DEFNODE("Lambda", "name argnames uses_arguments length_read", {
|
||||
$documentation: "Base class for functions",
|
||||
$propdoc: {
|
||||
name: "[AST_SymbolDeclaration?] the name of this function",
|
||||
@@ -337,12 +384,11 @@ var AST_Lambda = DEFNODE("Lambda", "name argnames uses_arguments", {
|
||||
uses_arguments: "[boolean/S] tells whether this function accesses the arguments array"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
if (this.name) this.name._walk(visitor);
|
||||
var argnames = this.argnames;
|
||||
for (var i = 0, len = argnames.length; i < len; i++) {
|
||||
argnames[i]._walk(visitor);
|
||||
}
|
||||
this.argnames.forEach(function(argname) {
|
||||
argname._walk(visitor);
|
||||
});
|
||||
walk_body(this, visitor);
|
||||
});
|
||||
}
|
||||
@@ -372,7 +418,7 @@ var AST_Exit = DEFNODE("Exit", "value", {
|
||||
value: "[AST_Node?] the value returned or thrown by this statement; could be null for AST_Return"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, this.value && function(){
|
||||
return visitor._visit(this, this.value && function() {
|
||||
this.value._walk(visitor);
|
||||
});
|
||||
}
|
||||
@@ -392,7 +438,7 @@ var AST_LoopControl = DEFNODE("LoopControl", "label", {
|
||||
label: "[AST_LabelRef?] the label, or null if none",
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, this.label && function(){
|
||||
return visitor._visit(this, this.label && function() {
|
||||
this.label._walk(visitor);
|
||||
});
|
||||
}
|
||||
@@ -415,7 +461,7 @@ var AST_If = DEFNODE("If", "condition alternative", {
|
||||
alternative: "[AST_Statement?] the `else` part, or null if not present"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
this.condition._walk(visitor);
|
||||
this.body._walk(visitor);
|
||||
if (this.alternative) this.alternative._walk(visitor);
|
||||
@@ -431,7 +477,7 @@ var AST_Switch = DEFNODE("Switch", "expression", {
|
||||
expression: "[AST_Node] the `switch` “discriminant”"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
this.expression._walk(visitor);
|
||||
walk_body(this, visitor);
|
||||
});
|
||||
@@ -452,7 +498,7 @@ var AST_Case = DEFNODE("Case", "expression", {
|
||||
expression: "[AST_Node] the `case` expression"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
this.expression._walk(visitor);
|
||||
walk_body(this, visitor);
|
||||
});
|
||||
@@ -468,7 +514,7 @@ var AST_Try = DEFNODE("Try", "bcatch bfinally", {
|
||||
bfinally: "[AST_Finally?] the finally block, or null if not present"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
walk_body(this, visitor);
|
||||
if (this.bcatch) this.bcatch._walk(visitor);
|
||||
if (this.bfinally) this.bfinally._walk(visitor);
|
||||
@@ -482,7 +528,7 @@ var AST_Catch = DEFNODE("Catch", "argname", {
|
||||
argname: "[AST_SymbolCatch] symbol for the exception"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
this.argname._walk(visitor);
|
||||
walk_body(this, visitor);
|
||||
});
|
||||
@@ -501,11 +547,10 @@ var AST_Definitions = DEFNODE("Definitions", "definitions", {
|
||||
definitions: "[AST_VarDef*] array of variable definitions"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
var definitions = this.definitions;
|
||||
for (var i = 0, len = definitions.length; i < len; i++) {
|
||||
definitions[i]._walk(visitor);
|
||||
}
|
||||
return visitor._visit(this, function() {
|
||||
this.definitions.forEach(function(defn) {
|
||||
defn._walk(visitor);
|
||||
});
|
||||
});
|
||||
}
|
||||
}, AST_Statement);
|
||||
@@ -521,7 +566,7 @@ var AST_VarDef = DEFNODE("VarDef", "name value", {
|
||||
value: "[AST_Node?] initializer, or null of there's no initializer"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
this.name._walk(visitor);
|
||||
if (this.value) this.value._walk(visitor);
|
||||
});
|
||||
@@ -537,12 +582,11 @@ var AST_Call = DEFNODE("Call", "expression args", {
|
||||
args: "[AST_Node*] array of arguments"
|
||||
},
|
||||
_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);
|
||||
}
|
||||
return visitor._visit(this, function() {
|
||||
this.expression._walk(visitor);
|
||||
this.args.forEach(function(node) {
|
||||
node._walk(visitor);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -557,7 +601,7 @@ var AST_Sequence = DEFNODE("Sequence", "expressions", {
|
||||
expressions: "[AST_Node*] array of expressions (at least two)"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
this.expressions.forEach(function(node) {
|
||||
node._walk(visitor);
|
||||
});
|
||||
@@ -570,13 +614,25 @@ var AST_PropAccess = DEFNODE("PropAccess", "expression property", {
|
||||
$propdoc: {
|
||||
expression: "[AST_Node] the “container” expression",
|
||||
property: "[AST_Node|string] the property to access. For AST_Dot this is always a plain string, while for AST_Sub it's an arbitrary AST_Node"
|
||||
},
|
||||
getProperty: function() {
|
||||
var p = this.property;
|
||||
if (p instanceof AST_Constant) {
|
||||
return p.getValue();
|
||||
}
|
||||
if (p instanceof AST_UnaryPrefix
|
||||
&& p.operator == "void"
|
||||
&& p.expression instanceof AST_Constant) {
|
||||
return;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
});
|
||||
|
||||
var AST_Dot = DEFNODE("Dot", null, {
|
||||
$documentation: "A dotted property access expression",
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
this.expression._walk(visitor);
|
||||
});
|
||||
}
|
||||
@@ -585,7 +641,7 @@ var AST_Dot = DEFNODE("Dot", null, {
|
||||
var AST_Sub = DEFNODE("Sub", null, {
|
||||
$documentation: "Index-style property access, i.e. `a[\"foo\"]`",
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
this.expression._walk(visitor);
|
||||
this.property._walk(visitor);
|
||||
});
|
||||
@@ -599,7 +655,7 @@ var AST_Unary = DEFNODE("Unary", "operator expression", {
|
||||
expression: "[AST_Node] expression that this unary operator applies to"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
this.expression._walk(visitor);
|
||||
});
|
||||
}
|
||||
@@ -621,7 +677,7 @@ var AST_Binary = DEFNODE("Binary", "operator left right", {
|
||||
right: "[AST_Node] right-hand side expression"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
this.left._walk(visitor);
|
||||
this.right._walk(visitor);
|
||||
});
|
||||
@@ -636,7 +692,7 @@ var AST_Conditional = DEFNODE("Conditional", "condition consequent alternative",
|
||||
alternative: "[AST_Node]"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
this.condition._walk(visitor);
|
||||
this.consequent._walk(visitor);
|
||||
this.alternative._walk(visitor);
|
||||
@@ -656,11 +712,10 @@ var AST_Array = DEFNODE("Array", "elements", {
|
||||
elements: "[AST_Node*] array of elements"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
var elements = this.elements;
|
||||
for (var i = 0, len = elements.length; i < len; i++) {
|
||||
elements[i]._walk(visitor);
|
||||
}
|
||||
return visitor._visit(this, function() {
|
||||
this.elements.forEach(function(element) {
|
||||
element._walk(visitor);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -671,11 +726,10 @@ var AST_Object = DEFNODE("Object", "properties", {
|
||||
properties: "[AST_ObjectProperty*] array of properties"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
var properties = this.properties;
|
||||
for (var i = 0, len = properties.length; i < len; i++) {
|
||||
properties[i]._walk(visitor);
|
||||
}
|
||||
return visitor._visit(this, function() {
|
||||
this.properties.forEach(function(prop) {
|
||||
prop._walk(visitor);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -683,11 +737,11 @@ 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 AST_SymbolAccessor.",
|
||||
value: "[AST_Node] property value. For setters and getters this is an AST_Accessor."
|
||||
key: "[string|AST_SymbolAccessor] property name. For ObjectKeyVal this is a string. For getters and setters this is an AST_SymbolAccessor.",
|
||||
value: "[AST_Node] property value. For getters and setters this is an AST_Accessor."
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
this.value._walk(visitor);
|
||||
});
|
||||
}
|
||||
@@ -756,7 +810,7 @@ var AST_Label = DEFNODE("Label", "references", {
|
||||
}
|
||||
}, AST_Symbol);
|
||||
|
||||
var AST_SymbolRef = DEFNODE("SymbolRef", null, {
|
||||
var AST_SymbolRef = DEFNODE("SymbolRef", "fixed", {
|
||||
$documentation: "Reference to some symbol (not definition/declaration)",
|
||||
}, AST_Symbol);
|
||||
|
||||
@@ -783,11 +837,10 @@ var AST_String = DEFNODE("String", "value quote", {
|
||||
}
|
||||
}, AST_Constant);
|
||||
|
||||
var AST_Number = DEFNODE("Number", "value literal", {
|
||||
var AST_Number = DEFNODE("Number", "value", {
|
||||
$documentation: "A number literal",
|
||||
$propdoc: {
|
||||
value: "[number] the numeric value",
|
||||
literal: "[string] numeric value as string (optional)"
|
||||
}
|
||||
}, AST_Constant);
|
||||
|
||||
@@ -814,12 +867,12 @@ var AST_NaN = DEFNODE("NaN", null, {
|
||||
|
||||
var AST_Undefined = DEFNODE("Undefined", null, {
|
||||
$documentation: "The `undefined` value",
|
||||
value: (function(){}())
|
||||
value: function(){}()
|
||||
}, AST_Atom);
|
||||
|
||||
var AST_Hole = DEFNODE("Hole", null, {
|
||||
$documentation: "A hole in an array",
|
||||
value: (function(){}())
|
||||
value: function(){}()
|
||||
}, AST_Atom);
|
||||
|
||||
var AST_Infinity = DEFNODE("Infinity", null, {
|
||||
@@ -847,11 +900,11 @@ function TreeWalker(callback) {
|
||||
this.visit = callback;
|
||||
this.stack = [];
|
||||
this.directives = Object.create(null);
|
||||
};
|
||||
}
|
||||
TreeWalker.prototype = {
|
||||
_visit: function(node, descend) {
|
||||
this.push(node);
|
||||
var ret = this.visit(node, descend ? function(){
|
||||
var ret = this.visit(node, descend ? function() {
|
||||
descend.call(node);
|
||||
} : noop);
|
||||
if (!ret && descend) {
|
||||
@@ -910,5 +963,34 @@ TreeWalker.prototype = {
|
||||
|| node instanceof AST_Break && x instanceof AST_Switch)
|
||||
return x;
|
||||
}
|
||||
},
|
||||
in_boolean_context: function() {
|
||||
var self = this.self();
|
||||
for (var i = 0, p; p = this.parent(i); i++) {
|
||||
if (p instanceof AST_SimpleStatement
|
||||
|| p instanceof AST_Conditional && p.condition === self
|
||||
|| p instanceof AST_DWLoop && p.condition === self
|
||||
|| p instanceof AST_For && p.condition === self
|
||||
|| p instanceof AST_If && p.condition === self
|
||||
|| p instanceof AST_UnaryPrefix && p.operator == "!" && p.expression === self) {
|
||||
return true;
|
||||
}
|
||||
if (p instanceof AST_Binary && (p.operator == "&&" || p.operator == "||")
|
||||
|| p instanceof AST_Conditional
|
||||
|| p.tail_node() === self) {
|
||||
self = p;
|
||||
} else if (p instanceof AST_Return) {
|
||||
var fn;
|
||||
do {
|
||||
fn = this.parent(++i);
|
||||
if (!fn) return false;
|
||||
} while (!(fn instanceof AST_Lambda));
|
||||
if (fn.name) return false;
|
||||
self = this.parent(++i);
|
||||
if (!self || self.TYPE != "Call" || self.expression !== fn) return false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
6718
lib/compress.js
6718
lib/compress.js
File diff suppressed because it is too large
Load Diff
122
lib/minify.js
122
lib/minify.js
@@ -1,19 +1,47 @@
|
||||
"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;
|
||||
var to_ascii, to_base64;
|
||||
if (typeof Buffer == "undefined") {
|
||||
to_ascii = atob;
|
||||
to_base64 = btoa;
|
||||
} else if (typeof Buffer.alloc == "undefined") {
|
||||
to_ascii = function(b64) {
|
||||
return new Buffer(b64, "base64").toString();
|
||||
};
|
||||
to_base64 = function(str) {
|
||||
return new Buffer(str).toString("base64");
|
||||
};
|
||||
} else {
|
||||
to_ascii = function(b64) {
|
||||
return Buffer.from(b64, "base64").toString();
|
||||
};
|
||||
to_base64 = function(str) {
|
||||
return Buffer.from(str).toString("base64");
|
||||
};
|
||||
}
|
||||
|
||||
function read_source_map(code) {
|
||||
var match = /\n\/\/# sourceMappingURL=data:application\/json(;.*?)?;base64,(.*)/.exec(code);
|
||||
if (!match) {
|
||||
AST_Node.warn("inline source map not found");
|
||||
return null;
|
||||
function read_source_map(name, toplevel) {
|
||||
var comments = toplevel.end.comments_after;
|
||||
for (var i = comments.length; --i >= 0;) {
|
||||
var comment = comments[i];
|
||||
if (comment.type != "comment1") break;
|
||||
var match = /^# ([^\s=]+)=(\S+)\s*$/.exec(comment.value);
|
||||
if (!match) break;
|
||||
if (match[1] == "sourceMappingURL") {
|
||||
match = /^data:application\/json(;.*?)?;base64,(\S+)$/.exec(match[2]);
|
||||
if (!match) break;
|
||||
return to_ascii(match[2]);
|
||||
}
|
||||
}
|
||||
AST_Node.warn("inline source map not found: " + name);
|
||||
}
|
||||
|
||||
function parse_source_map(content) {
|
||||
try {
|
||||
return JSON.parse(content);
|
||||
} catch (ex) {
|
||||
throw new Error("invalid input source map: " + content);
|
||||
}
|
||||
return to_ascii(match[2]);
|
||||
}
|
||||
|
||||
function set_shorthand(name, options, keys) {
|
||||
@@ -29,7 +57,6 @@ function set_shorthand(name, options, keys) {
|
||||
|
||||
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)) {
|
||||
@@ -39,16 +66,15 @@ function init_cache(cache) {
|
||||
|
||||
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: {},
|
||||
enclose: false,
|
||||
ie8: false,
|
||||
keep_fnames: false,
|
||||
mangle: {},
|
||||
@@ -71,7 +97,6 @@ function minify(files, options) {
|
||||
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, {
|
||||
@@ -109,13 +134,11 @@ function minify(files, options) {
|
||||
}, true);
|
||||
}
|
||||
var warnings = [];
|
||||
if (options.warnings && !AST_Node.warn_function) {
|
||||
AST_Node.warn_function = function(warning) {
|
||||
warnings.push(warning);
|
||||
};
|
||||
}
|
||||
if (options.warnings) AST_Node.log_function(function(warning) {
|
||||
warnings.push(warning);
|
||||
}, options.warnings == "verbose");
|
||||
if (timings) timings.parse = Date.now();
|
||||
var toplevel;
|
||||
var source_maps, toplevel;
|
||||
if (files instanceof AST_Toplevel) {
|
||||
toplevel = files;
|
||||
} else {
|
||||
@@ -124,23 +147,36 @@ function minify(files, options) {
|
||||
}
|
||||
options.parse = options.parse || {};
|
||||
options.parse.toplevel = null;
|
||||
var source_map_content = options.sourceMap && options.sourceMap.content;
|
||||
if (typeof source_map_content == "string" && source_map_content != "inline") {
|
||||
source_map_content = parse_source_map(source_map_content);
|
||||
}
|
||||
source_maps = source_map_content && Object.create(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]);
|
||||
options.parse.toplevel = toplevel = parse(files[name], options.parse);
|
||||
if (source_maps) {
|
||||
if (source_map_content == "inline") {
|
||||
var inlined_content = read_source_map(name, toplevel);
|
||||
if (inlined_content) {
|
||||
source_maps[name] = parse_source_map(inlined_content);
|
||||
}
|
||||
} else {
|
||||
source_maps[name] = source_map_content;
|
||||
}
|
||||
}
|
||||
}
|
||||
toplevel = options.parse.toplevel;
|
||||
}
|
||||
if (quoted_props) {
|
||||
reserve_quoted_keys(toplevel, quoted_props);
|
||||
}
|
||||
if (options.wrap) {
|
||||
toplevel = toplevel.wrap_commonjs(options.wrap);
|
||||
}
|
||||
[ "enclose", "wrap" ].forEach(function(action) {
|
||||
var option = options[action];
|
||||
if (!option) return;
|
||||
var orig = toplevel.print_to_string().slice(0, -1);
|
||||
toplevel = toplevel[action](option);
|
||||
files[toplevel.start.file] = toplevel.print_to_string().replace(orig, "");
|
||||
});
|
||||
if (timings) timings.rename = Date.now();
|
||||
if (options.rename) {
|
||||
toplevel.figure_out_scope(options.mangle);
|
||||
@@ -152,7 +188,6 @@ function minify(files, options) {
|
||||
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);
|
||||
}
|
||||
@@ -167,12 +202,9 @@ function minify(files, options) {
|
||||
}
|
||||
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,
|
||||
orig: source_maps,
|
||||
root: options.sourceMap.root
|
||||
});
|
||||
if (options.sourceMap.includeSources) {
|
||||
@@ -181,6 +213,8 @@ function minify(files, options) {
|
||||
} else for (var name in files) if (HOP(files, name)) {
|
||||
options.output.source_map.get().setSourceContent(name, files[name]);
|
||||
}
|
||||
} else {
|
||||
options.output.source_map.get()._sourcesContents = null;
|
||||
}
|
||||
}
|
||||
delete options.output.ast;
|
||||
@@ -190,10 +224,14 @@ function minify(files, options) {
|
||||
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;
|
||||
var url = options.sourceMap.url;
|
||||
if (url) {
|
||||
result.code = result.code.replace(/\n\/\/# sourceMappingURL=\S+\s*$/, "");
|
||||
if (url == "inline") {
|
||||
result.code += "\n//# sourceMappingURL=data:application/json;charset=utf-8;base64," + to_base64(result.map);
|
||||
} else {
|
||||
result.code += "\n//# sourceMappingURL=" + url;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -214,7 +252,7 @@ function minify(files, options) {
|
||||
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;
|
||||
@@ -222,7 +260,5 @@ function minify(files, options) {
|
||||
return result;
|
||||
} catch (ex) {
|
||||
return { error: ex };
|
||||
} finally {
|
||||
AST_Node.warn_function = warn_function;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,11 +43,9 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
(function(){
|
||||
|
||||
var normalize_directives = function(body) {
|
||||
(function() {
|
||||
function normalize_directives(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({
|
||||
@@ -59,9 +57,8 @@
|
||||
in_directive = false;
|
||||
}
|
||||
}
|
||||
|
||||
return body;
|
||||
};
|
||||
}
|
||||
|
||||
var MOZ_TO_ME = {
|
||||
Program: function(M) {
|
||||
@@ -129,7 +126,7 @@
|
||||
return new AST_Array({
|
||||
start : my_start_token(M),
|
||||
end : my_end_token(M),
|
||||
elements : M.elements.map(function(elem){
|
||||
elements : M.elements.map(function(elem) {
|
||||
return elem === null ? new AST_Hole() : from_moz(elem);
|
||||
})
|
||||
});
|
||||
@@ -138,7 +135,7 @@
|
||||
return new AST_Object({
|
||||
start : my_start_token(M),
|
||||
end : my_end_token(M),
|
||||
properties : M.properties.map(function(prop){
|
||||
properties : M.properties.map(function(prop) {
|
||||
prop.type = "Property";
|
||||
return from_moz(prop)
|
||||
})
|
||||
@@ -180,6 +177,17 @@
|
||||
end : my_end_token(M)
|
||||
};
|
||||
if (val === null) return new AST_Null(args);
|
||||
var rx = M.regex;
|
||||
if (rx && rx.pattern) {
|
||||
// RegExpLiteral as per ESTree AST spec
|
||||
args.value = new RegExp(rx.pattern, rx.flags);
|
||||
args.value.raw_source = rx.pattern;
|
||||
return new AST_RegExp(args);
|
||||
} else if (rx) {
|
||||
// support legacy RegExp
|
||||
args.value = M.regex && M.raw ? M.raw : val;
|
||||
return new AST_RegExp(args);
|
||||
}
|
||||
switch (typeof val) {
|
||||
case "string":
|
||||
args.value = val;
|
||||
@@ -189,16 +197,6 @@
|
||||
return new AST_Number(args);
|
||||
case "boolean":
|
||||
return new (val ? AST_True : AST_False)(args);
|
||||
default:
|
||||
var rx = M.regex;
|
||||
if (rx && rx.pattern) {
|
||||
// RegExpLiteral as per ESTree AST spec
|
||||
args.value = new RegExp(rx.pattern, rx.flags).toString();
|
||||
} else {
|
||||
// support legacy RegExp
|
||||
args.value = M.regex && M.raw ? M.raw : val;
|
||||
}
|
||||
return new AST_RegExp(args);
|
||||
}
|
||||
},
|
||||
Identifier: function(M) {
|
||||
@@ -405,19 +403,20 @@
|
||||
var def = M.definition();
|
||||
return {
|
||||
type: "Identifier",
|
||||
name: def ? def.mangled_name || def.name : M.name
|
||||
name: def && def.mangled_name || M.name
|
||||
};
|
||||
});
|
||||
|
||||
def_to_moz(AST_RegExp, function To_Moz_RegExpLiteral(M) {
|
||||
var value = M.value;
|
||||
var flags = M.value.toString().match(/[gimuy]*$/)[0];
|
||||
var value = "/" + M.value.raw_source + "/" + flags;
|
||||
return {
|
||||
type: "Literal",
|
||||
value: value,
|
||||
raw: value.toString(),
|
||||
raw: value,
|
||||
regex: {
|
||||
pattern: value.source,
|
||||
flags: value.toString().match(/[gimuy]*$/)[0]
|
||||
pattern: M.value.raw_source,
|
||||
flags: flags
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -478,7 +477,7 @@
|
||||
endpos : range ? range[0] : moznode.start,
|
||||
raw : raw_token(moznode),
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function my_end_token(moznode) {
|
||||
var loc = moznode.loc, end = loc && loc.end;
|
||||
@@ -493,7 +492,7 @@
|
||||
endpos : range ? range[1] : moznode.end,
|
||||
raw : raw_token(moznode),
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function map(moztype, mytype, propmap) {
|
||||
var moz_to_me = "function From_Moz_" + moztype + "(M){\n";
|
||||
@@ -505,7 +504,7 @@
|
||||
me_to_moz += "return {\n" +
|
||||
"type: " + JSON.stringify(moztype);
|
||||
|
||||
if (propmap) propmap.split(/\s*,\s*/).forEach(function(prop){
|
||||
if (propmap) propmap.split(/\s*,\s*/).forEach(function(prop) {
|
||||
var m = /([a-z0-9$_]+)(=|@|>|%)([a-z0-9$_]+)/i.exec(prop);
|
||||
if (!m) throw new Error("Can't understand property map: " + prop);
|
||||
var moz = m[1], how = m[2], my = m[3];
|
||||
@@ -548,7 +547,7 @@
|
||||
);
|
||||
MOZ_TO_ME[moztype] = moz_to_me;
|
||||
def_to_moz(mytype, me_to_moz);
|
||||
};
|
||||
}
|
||||
|
||||
var FROM_MOZ_STACK = null;
|
||||
|
||||
@@ -557,13 +556,28 @@
|
||||
var ret = node != null ? MOZ_TO_ME[node.type](node) : null;
|
||||
FROM_MOZ_STACK.pop();
|
||||
return ret;
|
||||
};
|
||||
}
|
||||
|
||||
AST_Node.from_mozilla_ast = function(node){
|
||||
AST_Node.from_mozilla_ast = function(node) {
|
||||
var save_stack = FROM_MOZ_STACK;
|
||||
FROM_MOZ_STACK = [];
|
||||
var ast = from_moz(node);
|
||||
FROM_MOZ_STACK = save_stack;
|
||||
ast.walk(new TreeWalker(function(node) {
|
||||
if (node instanceof AST_LabelRef) {
|
||||
for (var level = 0, parent; parent = this.parent(level); level++) {
|
||||
if (parent instanceof AST_Scope) break;
|
||||
if (parent instanceof AST_LabeledStatement && parent.label.name == node.name) {
|
||||
node.thedef = parent.label;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!node.thedef) {
|
||||
var s = node.start;
|
||||
js_error("Undefined label " + node.name, s.file, s.line, s.col, s.pos);
|
||||
}
|
||||
}
|
||||
}));
|
||||
return ast;
|
||||
};
|
||||
|
||||
@@ -583,24 +597,24 @@
|
||||
}
|
||||
}
|
||||
return moznode;
|
||||
};
|
||||
}
|
||||
|
||||
function def_to_moz(mytype, handler) {
|
||||
mytype.DEFMETHOD("to_mozilla_ast", function() {
|
||||
return set_moz_loc(this, handler(this));
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function to_moz(node) {
|
||||
return node != null ? node.to_mozilla_ast() : null;
|
||||
};
|
||||
}
|
||||
|
||||
function to_moz_block(node) {
|
||||
return {
|
||||
type: "BlockStatement",
|
||||
body: node.body.map(to_moz)
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
function to_moz_scope(type, node) {
|
||||
var body = node.body.map(to_moz);
|
||||
@@ -611,5 +625,5 @@
|
||||
type: type,
|
||||
body: body
|
||||
};
|
||||
};
|
||||
}
|
||||
})();
|
||||
|
||||
1031
lib/output.js
1031
lib/output.js
File diff suppressed because it is too large
Load Diff
504
lib/parse.js
504
lib/parse.js
File diff suppressed because it is too large
Load Diff
@@ -53,25 +53,30 @@ function find_builtins(reserved) {
|
||||
"-Infinity",
|
||||
"undefined",
|
||||
].forEach(add);
|
||||
[ Object, Array, Function, Number,
|
||||
String, Boolean, Error, Math,
|
||||
Date, RegExp
|
||||
].forEach(function(ctor){
|
||||
[
|
||||
Array,
|
||||
Boolean,
|
||||
Date,
|
||||
Error,
|
||||
Function,
|
||||
Math,
|
||||
Number,
|
||||
Object,
|
||||
RegExp,
|
||||
String,
|
||||
].forEach(function(ctor) {
|
||||
Object.getOwnPropertyNames(ctor).map(add);
|
||||
if (ctor.prototype) {
|
||||
Object.getOwnPropertyNames(ctor.prototype).map(add);
|
||||
}
|
||||
});
|
||||
|
||||
function add(name) {
|
||||
push_uniq(reserved, name);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -79,6 +84,10 @@ function reserve_quoted_keys(ast, reserved) {
|
||||
addStrings(node.property, add);
|
||||
}
|
||||
}));
|
||||
|
||||
function add(name) {
|
||||
push_uniq(reserved, name);
|
||||
}
|
||||
}
|
||||
|
||||
function addStrings(node, add) {
|
||||
@@ -110,12 +119,15 @@ function mangle_properties(ast, options) {
|
||||
if (!Array.isArray(reserved)) reserved = [];
|
||||
if (!options.builtins) find_builtins(reserved);
|
||||
|
||||
var cache = options.cache;
|
||||
if (cache == null) {
|
||||
cache = {
|
||||
cname: -1,
|
||||
props: new Dictionary()
|
||||
};
|
||||
var cname = -1;
|
||||
var cache;
|
||||
if (options.cache) {
|
||||
cache = options.cache.props;
|
||||
cache.each(function(mangled_name) {
|
||||
push_uniq(reserved, mangled_name);
|
||||
});
|
||||
} else {
|
||||
cache = new Dictionary();
|
||||
}
|
||||
|
||||
var regex = options.regex;
|
||||
@@ -124,45 +136,43 @@ function mangle_properties(ast, options) {
|
||||
// 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 debug_suffix;
|
||||
if (debug) debug_suffix = options.debug === true ? "" : options.debug;
|
||||
|
||||
var names_to_mangle = [];
|
||||
var unmangleable = [];
|
||||
|
||||
// step 1: find candidates to mangle
|
||||
ast.walk(new TreeWalker(function(node){
|
||||
ast.walk(new TreeWalker(function(node) {
|
||||
if (node instanceof AST_ObjectKeyVal) {
|
||||
add(node.key);
|
||||
}
|
||||
else if (node instanceof AST_ObjectProperty) {
|
||||
} else if (node instanceof AST_ObjectProperty) {
|
||||
// setter or getter, since KeyVal is handled above
|
||||
add(node.key.name);
|
||||
}
|
||||
else if (node instanceof AST_Dot) {
|
||||
} else if (node instanceof AST_Dot) {
|
||||
add(node.property);
|
||||
}
|
||||
else if (node instanceof AST_Sub) {
|
||||
} else if (node instanceof AST_Sub) {
|
||||
addStrings(node.property, add);
|
||||
} else if (node instanceof AST_Call
|
||||
&& node.expression.print_to_string() == "Object.defineProperty") {
|
||||
addStrings(node.args[1], add);
|
||||
}
|
||||
}));
|
||||
|
||||
// step 2: transform the tree, renaming properties
|
||||
return ast.transform(new TreeTransformer(function(node){
|
||||
return ast.transform(new TreeTransformer(function(node) {
|
||||
if (node instanceof AST_ObjectKeyVal) {
|
||||
node.key = mangle(node.key);
|
||||
}
|
||||
else if (node instanceof AST_ObjectProperty) {
|
||||
} else if (node instanceof AST_ObjectProperty) {
|
||||
// setter or getter
|
||||
node.key.name = mangle(node.key.name);
|
||||
}
|
||||
else if (node instanceof AST_Dot) {
|
||||
} else if (node instanceof AST_Dot) {
|
||||
node.property = mangle(node.property);
|
||||
}
|
||||
else if (!options.keep_quoted && node instanceof AST_Sub) {
|
||||
} else if (!options.keep_quoted && node instanceof AST_Sub) {
|
||||
node.property = mangleStrings(node.property);
|
||||
} else if (node instanceof AST_Call
|
||||
&& node.expression.print_to_string() == "Object.defineProperty") {
|
||||
node.args[1] = mangleStrings(node.args[1]);
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -171,9 +181,7 @@ function mangle_properties(ast, options) {
|
||||
function can_mangle(name) {
|
||||
if (unmangleable.indexOf(name) >= 0) return false;
|
||||
if (reserved.indexOf(name) >= 0) return false;
|
||||
if (options.only_cache) {
|
||||
return cache.props.has(name);
|
||||
}
|
||||
if (options.only_cache) return cache.has(name);
|
||||
if (/^-?[0-9]+(\.[0-9]+)?(e[+-][0-9]+)?$/.test(name)) return false;
|
||||
return true;
|
||||
}
|
||||
@@ -181,57 +189,42 @@ function mangle_properties(ast, options) {
|
||||
function should_mangle(name) {
|
||||
if (regex && !regex.test(name)) return false;
|
||||
if (reserved.indexOf(name) >= 0) return false;
|
||||
return cache.props.has(name)
|
||||
|| names_to_mangle.indexOf(name) >= 0;
|
||||
return cache.has(name) || names_to_mangle.indexOf(name) >= 0;
|
||||
}
|
||||
|
||||
function add(name) {
|
||||
if (can_mangle(name))
|
||||
push_uniq(names_to_mangle, name);
|
||||
|
||||
if (!should_mangle(name)) {
|
||||
push_uniq(unmangleable, name);
|
||||
}
|
||||
if (can_mangle(name)) push_uniq(names_to_mangle, name);
|
||||
if (!should_mangle(name)) push_uniq(unmangleable, name);
|
||||
}
|
||||
|
||||
function mangle(name) {
|
||||
if (!should_mangle(name)) {
|
||||
return name;
|
||||
}
|
||||
|
||||
var mangled = cache.props.get(name);
|
||||
var mangled = cache.get(name);
|
||||
if (!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;
|
||||
}
|
||||
var debug_mangled = "_$" + name + "$" + debug_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);
|
||||
if (!mangled) do {
|
||||
mangled = base54(++cname);
|
||||
} while (!can_mangle(mangled));
|
||||
cache.set(name, mangled);
|
||||
}
|
||||
return mangled;
|
||||
}
|
||||
|
||||
function mangleStrings(node) {
|
||||
return node.transform(new TreeTransformer(function(node){
|
||||
return node.transform(new TreeTransformer(function(node) {
|
||||
if (node instanceof AST_Sequence) {
|
||||
var last = node.expressions.length - 1;
|
||||
node.expressions[last] = mangleStrings(node.expressions[last]);
|
||||
}
|
||||
else if (node instanceof AST_String) {
|
||||
} else if (node instanceof AST_String) {
|
||||
node.value = mangle(node.value);
|
||||
}
|
||||
else if (node instanceof AST_Conditional) {
|
||||
} else if (node instanceof AST_Conditional) {
|
||||
node.consequent = mangleStrings(node.consequent);
|
||||
node.alternative = mangleStrings(node.alternative);
|
||||
}
|
||||
|
||||
439
lib/scope.js
439
lib/scope.js
@@ -43,9 +43,10 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
function SymbolDef(scope, orig) {
|
||||
function SymbolDef(scope, orig, init) {
|
||||
this.name = orig.name;
|
||||
this.orig = [ orig ];
|
||||
this.init = init;
|
||||
this.eliminated = 0;
|
||||
this.scope = scope;
|
||||
this.references = [];
|
||||
@@ -54,36 +55,31 @@ function SymbolDef(scope, orig) {
|
||||
this.mangled_name = null;
|
||||
this.undeclared = false;
|
||||
this.id = SymbolDef.next_id++;
|
||||
};
|
||||
this.lambda = orig instanceof AST_SymbolLambda;
|
||||
}
|
||||
|
||||
SymbolDef.next_id = 1;
|
||||
|
||||
SymbolDef.prototype = {
|
||||
unmangleable: function(options) {
|
||||
if (!options) options = {};
|
||||
|
||||
return (this.global && !options.toplevel)
|
||||
return this.global && !options.toplevel
|
||||
|| this.undeclared
|
||||
|| (!options.eval && (this.scope.uses_eval || this.scope.uses_with))
|
||||
|| (options.keep_fnames
|
||||
|| !options.eval && this.scope.pinned()
|
||||
|| options.keep_fnames
|
||||
&& (this.orig[0] instanceof AST_SymbolLambda
|
||||
|| this.orig[0] instanceof AST_SymbolDefun));
|
||||
|| this.orig[0] instanceof AST_SymbolDefun);
|
||||
},
|
||||
mangle: function(options) {
|
||||
var cache = options.cache && options.cache.props;
|
||||
if (this.global && cache && cache.has(this.name)) {
|
||||
this.mangled_name = cache.get(this.name);
|
||||
}
|
||||
else if (!this.mangled_name && !this.unmangleable(options)) {
|
||||
var s = this.scope;
|
||||
var sym = this.orig[0];
|
||||
if (options.ie8 && sym instanceof AST_SymbolLambda)
|
||||
s = s.parent_scope;
|
||||
} else if (!this.mangled_name && !this.unmangleable(options)) {
|
||||
var def;
|
||||
if (def = this.redefined()) {
|
||||
this.mangled_name = def.mangled_name || def.name;
|
||||
} else
|
||||
this.mangled_name = s.next_mangled(options, this);
|
||||
} else {
|
||||
this.mangled_name = next_mangled_name(this.scope, options, this);
|
||||
}
|
||||
if (this.global && cache) {
|
||||
cache.set(this.name, this.mangled_name);
|
||||
}
|
||||
@@ -94,7 +90,7 @@ SymbolDef.prototype = {
|
||||
}
|
||||
};
|
||||
|
||||
AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||
AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
||||
options = defaults(options, {
|
||||
cache: null,
|
||||
ie8: false,
|
||||
@@ -103,9 +99,8 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||
// pass 1: setup scope chaining and handle definitions
|
||||
var self = this;
|
||||
var scope = self.parent_scope = null;
|
||||
var labels = new Dictionary();
|
||||
var defun = null;
|
||||
var tw = new TreeWalker(function(node, descend){
|
||||
var tw = new TreeWalker(function(node, descend) {
|
||||
if (node instanceof AST_Catch) {
|
||||
var save_scope = scope;
|
||||
scope = new AST_Scope(node);
|
||||
@@ -118,28 +113,14 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||
node.init_scope_vars(scope);
|
||||
var save_scope = scope;
|
||||
var save_defun = defun;
|
||||
var save_labels = labels;
|
||||
defun = scope = node;
|
||||
labels = new Dictionary();
|
||||
descend();
|
||||
scope = save_scope;
|
||||
defun = save_defun;
|
||||
labels = save_labels;
|
||||
return true; // don't descend again in TreeWalker
|
||||
}
|
||||
if (node instanceof AST_LabeledStatement) {
|
||||
var l = node.label;
|
||||
if (labels.has(l.name)) {
|
||||
throw new Error(string_template("Label {name} defined twice", l));
|
||||
}
|
||||
labels.set(l.name, l);
|
||||
descend();
|
||||
labels.del(l.name);
|
||||
return true; // no descend again
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_With) {
|
||||
for (var s = scope; s; s = s.parent_scope)
|
||||
s.uses_with = true;
|
||||
for (var s = scope; s; s = s.parent_scope) s.uses_with = true;
|
||||
return;
|
||||
}
|
||||
if (node instanceof AST_Symbol) {
|
||||
@@ -149,48 +130,34 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||
node.thedef = node;
|
||||
node.references = [];
|
||||
}
|
||||
if (node instanceof AST_SymbolLambda) {
|
||||
defun.def_function(node);
|
||||
}
|
||||
else if (node instanceof AST_SymbolDefun) {
|
||||
// Careful here, the scope where this should be defined is
|
||||
// the parent scope. The reason is that we enter a new
|
||||
// scope when we encounter the AST_Defun node (which is
|
||||
// instanceof AST_Scope) but we get to the symbol a bit
|
||||
// later.
|
||||
(node.scope = defun.parent_scope).def_function(node);
|
||||
}
|
||||
else if (node instanceof AST_SymbolVar) {
|
||||
defun.def_variable(node);
|
||||
if (node instanceof AST_SymbolDefun) {
|
||||
// This should be defined in the parent scope, as we encounter the
|
||||
// AST_Defun node before getting to its AST_Symbol.
|
||||
(node.scope = defun.parent_scope.resolve()).def_function(node, defun);
|
||||
} else if (node instanceof AST_SymbolLambda) {
|
||||
var def = defun.def_function(node, node.name == "arguments" ? undefined : defun);
|
||||
if (options.ie8) def.defun = defun.parent_scope.resolve();
|
||||
} else if (node instanceof AST_SymbolVar) {
|
||||
defun.def_variable(node, node.TYPE == "SymbolVar" ? null : undefined);
|
||||
if (defun !== scope) {
|
||||
node.mark_enclosed(options);
|
||||
var def = scope.find_variable(node);
|
||||
if (node.thedef !== def) {
|
||||
node.thedef = def;
|
||||
node.reference(options);
|
||||
}
|
||||
node.reference(options);
|
||||
}
|
||||
}
|
||||
else if (node instanceof AST_SymbolCatch) {
|
||||
} else if (node instanceof AST_SymbolCatch) {
|
||||
scope.def_variable(node).defun = defun;
|
||||
}
|
||||
else if (node instanceof AST_LabelRef) {
|
||||
var sym = labels.get(node.name);
|
||||
if (!sym) throw new Error(string_template("Undefined label {name} [{line},{col}]", {
|
||||
name: node.name,
|
||||
line: node.start.line,
|
||||
col: node.start.col
|
||||
}));
|
||||
node.thedef = sym;
|
||||
}
|
||||
});
|
||||
self.walk(tw);
|
||||
|
||||
// pass 2: find back references and eval
|
||||
self.globals = new Dictionary();
|
||||
var tw = new TreeWalker(function(node, descend){
|
||||
if (node instanceof AST_LoopControl && node.label) {
|
||||
node.label.thedef.references.push(node);
|
||||
var tw = new TreeWalker(function(node) {
|
||||
if (node instanceof AST_LoopControl) {
|
||||
if (node.label) node.label.thedef.references.push(node);
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_SymbolRef) {
|
||||
@@ -211,43 +178,59 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(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) {
|
||||
if (node instanceof AST_SymbolCatch) {
|
||||
var def = node.definition().redefined();
|
||||
if (def) for (var s = node.scope; s; s = s.parent_scope) {
|
||||
push_uniq(s.enclosed, def);
|
||||
if (s === def.scope) break;
|
||||
s = s.parent_scope;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
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.ie8) self.walk(new TreeWalker(function(node) {
|
||||
if (node instanceof AST_SymbolCatch) {
|
||||
var scope = node.thedef.defun;
|
||||
if (scope.name instanceof AST_SymbolLambda && scope.name.name == node.name) {
|
||||
scope = scope.parent_scope.resolve();
|
||||
}
|
||||
}));
|
||||
}
|
||||
redefine(node, scope);
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_SymbolLambda) {
|
||||
var def = node.thedef;
|
||||
redefine(node, node.scope.parent_scope.resolve());
|
||||
if (typeof node.thedef.init !== "undefined") {
|
||||
node.thedef.init = false;
|
||||
} else if (def.init) {
|
||||
node.thedef.init = def.init;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}));
|
||||
|
||||
if (options.cache) {
|
||||
this.cname = options.cache.cname;
|
||||
function redefine(node, scope) {
|
||||
var name = node.name;
|
||||
var old_def = node.thedef;
|
||||
var new_def = scope.find_variable(name);
|
||||
if (new_def) {
|
||||
var redef;
|
||||
while (redef = new_def.redefined()) new_def = redef;
|
||||
} else {
|
||||
new_def = self.globals.get(name) || scope.def_variable(node);
|
||||
}
|
||||
old_def.orig.concat(old_def.references).forEach(function(node) {
|
||||
node.thedef = new_def;
|
||||
node.reference(options);
|
||||
});
|
||||
if (old_def.lambda) new_def.lambda = true;
|
||||
if (new_def.undeclared) self.variables.set(name, new_def);
|
||||
}
|
||||
});
|
||||
|
||||
AST_Toplevel.DEFMETHOD("def_global", function(node){
|
||||
AST_Toplevel.DEFMETHOD("def_global", function(node) {
|
||||
var globals = this.globals, name = node.name;
|
||||
if (globals.has(name)) {
|
||||
return globals.get(name);
|
||||
@@ -260,7 +243,7 @@ AST_Toplevel.DEFMETHOD("def_global", function(node){
|
||||
}
|
||||
});
|
||||
|
||||
AST_Scope.DEFMETHOD("init_scope_vars", function(parent_scope){
|
||||
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
|
||||
@@ -270,7 +253,7 @@ AST_Scope.DEFMETHOD("init_scope_vars", function(parent_scope){
|
||||
this.cname = -1; // the current index for mangling functions/variables
|
||||
});
|
||||
|
||||
AST_Lambda.DEFMETHOD("init_scope_vars", function(){
|
||||
AST_Lambda.DEFMETHOD("init_scope_vars", function() {
|
||||
AST_Scope.prototype.init_scope_vars.apply(this, arguments);
|
||||
this.uses_arguments = false;
|
||||
this.def_variable(new AST_SymbolFunarg({
|
||||
@@ -282,8 +265,7 @@ AST_Lambda.DEFMETHOD("init_scope_vars", function(){
|
||||
|
||||
AST_Symbol.DEFMETHOD("mark_enclosed", function(options) {
|
||||
var def = this.definition();
|
||||
var s = this.scope;
|
||||
while (s) {
|
||||
for (var s = this.scope; s; s = s.parent_scope) {
|
||||
push_uniq(s.enclosed, def);
|
||||
if (options.keep_fnames) {
|
||||
s.functions.each(function(d) {
|
||||
@@ -291,7 +273,6 @@ AST_Symbol.DEFMETHOD("mark_enclosed", function(options) {
|
||||
});
|
||||
}
|
||||
if (s === def.scope) break;
|
||||
s = s.parent_scope;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -300,69 +281,89 @@ AST_Symbol.DEFMETHOD("reference", function(options) {
|
||||
this.mark_enclosed(options);
|
||||
});
|
||||
|
||||
AST_Scope.DEFMETHOD("find_variable", function(name){
|
||||
AST_Scope.DEFMETHOD("find_variable", function(name) {
|
||||
if (name instanceof AST_Symbol) name = name.name;
|
||||
return this.variables.get(name)
|
||||
|| (this.parent_scope && this.parent_scope.find_variable(name));
|
||||
});
|
||||
|
||||
AST_Scope.DEFMETHOD("def_function", function(symbol){
|
||||
this.functions.set(symbol.name, this.def_variable(symbol));
|
||||
AST_Scope.DEFMETHOD("def_function", function(symbol, init) {
|
||||
var def = this.def_variable(symbol, init);
|
||||
if (!def.init || def.init instanceof AST_Defun) def.init = init;
|
||||
this.functions.set(symbol.name, def);
|
||||
return def;
|
||||
});
|
||||
|
||||
AST_Scope.DEFMETHOD("def_variable", function(symbol){
|
||||
var def;
|
||||
if (!this.variables.has(symbol.name)) {
|
||||
def = new SymbolDef(this, symbol);
|
||||
AST_Scope.DEFMETHOD("def_variable", function(symbol, init) {
|
||||
var def = this.variables.get(symbol.name);
|
||||
if (def) {
|
||||
def.orig.push(symbol);
|
||||
if (def.init instanceof AST_Function) def.init = init;
|
||||
} else {
|
||||
def = new SymbolDef(this, symbol, init);
|
||||
this.variables.set(symbol.name, def);
|
||||
def.global = !this.parent_scope;
|
||||
} else {
|
||||
def = this.variables.get(symbol.name);
|
||||
def.orig.push(symbol);
|
||||
}
|
||||
return symbol.thedef = def;
|
||||
});
|
||||
|
||||
AST_Scope.DEFMETHOD("next_mangled", function(options){
|
||||
var ext = this.enclosed;
|
||||
out: while (true) {
|
||||
var m = base54(++this.cname);
|
||||
if (!is_identifier(m)) continue; // skip over "do"
|
||||
|
||||
// https://github.com/mishoo/UglifyJS2/issues/242 -- do not
|
||||
// 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
|
||||
// inner scopes.
|
||||
for (var i = ext.length; --i >= 0;) {
|
||||
var sym = ext[i];
|
||||
var name = sym.mangled_name || (sym.unmangleable(options) && sym.name);
|
||||
if (m == name) continue out;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
AST_Lambda.DEFMETHOD("resolve", return_this);
|
||||
AST_Scope.DEFMETHOD("resolve", function() {
|
||||
return this.parent_scope.resolve();
|
||||
});
|
||||
AST_Toplevel.DEFMETHOD("resolve", return_this);
|
||||
|
||||
AST_Function.DEFMETHOD("next_mangled", function(options, def){
|
||||
// #179, #326
|
||||
// in Safari strict mode, something like (function x(x){...}) is a syntax error;
|
||||
// a function expression's argument cannot shadow the function expression's name
|
||||
|
||||
var tricky_def = def.orig[0] instanceof AST_SymbolFunarg && this.name && this.name.definition();
|
||||
|
||||
// the function's mangled_name is null when keep_fnames is true
|
||||
var tricky_name = tricky_def ? tricky_def.mangled_name || tricky_def.name : null;
|
||||
function names_in_use(scope, options) {
|
||||
var names = scope.names_in_use;
|
||||
if (!names) {
|
||||
scope.names_in_use = names = Object.create(scope.mangled_names || null);
|
||||
scope.cname_holes = [];
|
||||
var cache = options.cache && options.cache.props;
|
||||
scope.enclosed.forEach(function(def) {
|
||||
if (def.unmangleable(options)) names[def.name] = true;
|
||||
if (def.global && cache && cache.has(def.name)) {
|
||||
names[cache.get(def.name)] = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
function next_mangled_name(scope, options, def) {
|
||||
var in_use = names_in_use(scope, options);
|
||||
var holes = scope.cname_holes;
|
||||
var names = Object.create(null);
|
||||
var scopes = [ scope ];
|
||||
def.references.forEach(function(sym) {
|
||||
var scope = sym.scope;
|
||||
do {
|
||||
if (scopes.indexOf(scope) < 0) {
|
||||
for (var name in names_in_use(scope, options)) {
|
||||
names[name] = true;
|
||||
}
|
||||
scopes.push(scope);
|
||||
} else break;
|
||||
} while (scope = scope.parent_scope);
|
||||
});
|
||||
var name;
|
||||
for (var i = 0; i < holes.length; i++) {
|
||||
name = base54(holes[i]);
|
||||
if (names[name]) continue;
|
||||
holes.splice(i, 1);
|
||||
scope.names_in_use[name] = true;
|
||||
return name;
|
||||
}
|
||||
while (true) {
|
||||
var name = AST_Lambda.prototype.next_mangled.call(this, options, def);
|
||||
if (!tricky_name || tricky_name != name)
|
||||
return name;
|
||||
name = base54(++scope.cname);
|
||||
if (in_use[name] || RESERVED_WORDS[name] || options.reserved.has[name]) continue;
|
||||
if (!names[name]) break;
|
||||
holes.push(scope.cname);
|
||||
}
|
||||
});
|
||||
scope.names_in_use[name] = true;
|
||||
return name;
|
||||
}
|
||||
|
||||
AST_Symbol.DEFMETHOD("unmangleable", function(options){
|
||||
AST_Symbol.DEFMETHOD("unmangleable", function(options) {
|
||||
var def = this.definition();
|
||||
return !def || def.unmangleable(options);
|
||||
});
|
||||
@@ -370,20 +371,19 @@ AST_Symbol.DEFMETHOD("unmangleable", function(options){
|
||||
// labels are always mangleable
|
||||
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("unreferenced", function() {
|
||||
return !this.definition().references.length && !this.scope.pinned();
|
||||
});
|
||||
|
||||
AST_Symbol.DEFMETHOD("definition", function(){
|
||||
AST_Symbol.DEFMETHOD("definition", function() {
|
||||
return this.thedef;
|
||||
});
|
||||
|
||||
AST_Symbol.DEFMETHOD("global", function(){
|
||||
AST_Symbol.DEFMETHOD("global", function() {
|
||||
return this.definition().global;
|
||||
});
|
||||
|
||||
AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options) {
|
||||
function _default_mangler_options(options) {
|
||||
options = defaults(options, {
|
||||
eval : false,
|
||||
ie8 : false,
|
||||
@@ -394,118 +394,140 @@ AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options) {
|
||||
if (!Array.isArray(options.reserved)) options.reserved = [];
|
||||
// Never mangle arguments
|
||||
push_uniq(options.reserved, "arguments");
|
||||
options.reserved.has = makePredicate(options.reserved);
|
||||
return options;
|
||||
});
|
||||
}
|
||||
|
||||
AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
||||
options = this._default_mangler_options(options);
|
||||
AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
|
||||
options = _default_mangler_options(options);
|
||||
|
||||
// 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
|
||||
// the AST_SymbolDeclaration that it points to).
|
||||
var lname = -1;
|
||||
var to_mangle = [];
|
||||
|
||||
if (options.cache) {
|
||||
this.globals.each(collect);
|
||||
if (options.cache && options.cache.props) {
|
||||
var mangled_names = this.mangled_names = Object.create(null);
|
||||
options.cache.props.each(function(mangled_name) {
|
||||
mangled_names[mangled_name] = true;
|
||||
});
|
||||
}
|
||||
|
||||
var tw = new TreeWalker(function(node, descend){
|
||||
var redefined = [];
|
||||
var tw = new TreeWalker(function(node, descend) {
|
||||
if (node instanceof AST_LabeledStatement) {
|
||||
// lname is incremented when we get to the AST_Label
|
||||
var save_nesting = lname;
|
||||
descend();
|
||||
lname = save_nesting;
|
||||
return true; // don't descend again in TreeWalker
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_Scope) {
|
||||
node.variables.each(collect);
|
||||
return;
|
||||
descend();
|
||||
if (options.cache && node instanceof AST_Toplevel) {
|
||||
node.globals.each(mangle);
|
||||
}
|
||||
node.variables.each(function(def) {
|
||||
if (!defer_redef(def)) mangle(def);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_Label) {
|
||||
var name;
|
||||
do name = base54(++lname); while (!is_identifier(name));
|
||||
do {
|
||||
name = base54(++lname);
|
||||
} while (RESERVED_WORDS[name]);
|
||||
node.mangled_name = name;
|
||||
return true;
|
||||
}
|
||||
if (!options.ie8 && node instanceof AST_SymbolCatch) {
|
||||
to_mangle.push(node.definition());
|
||||
return;
|
||||
if (!options.ie8 && node instanceof AST_Catch) {
|
||||
var def = node.argname.definition();
|
||||
var redef = defer_redef(def, node.argname);
|
||||
descend();
|
||||
if (!redef) mangle(def);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
this.walk(tw);
|
||||
to_mangle.forEach(function(def){ def.mangle(options) });
|
||||
redefined.forEach(mangle);
|
||||
|
||||
if (options.cache) {
|
||||
options.cache.cname = this.cname;
|
||||
function mangle(def) {
|
||||
if (options.reserved.has[def.name]) return;
|
||||
def.mangle(options);
|
||||
}
|
||||
|
||||
function collect(symbol) {
|
||||
if (!member(symbol.name, options.reserved)) {
|
||||
to_mangle.push(symbol);
|
||||
function defer_redef(def, node) {
|
||||
var redef = def.redefined();
|
||||
if (!redef) return false;
|
||||
redefined.push(def);
|
||||
def.references.forEach(reference);
|
||||
if (node) reference(node);
|
||||
return true;
|
||||
|
||||
function reference(sym) {
|
||||
sym.thedef = redef;
|
||||
sym.reference(options);
|
||||
sym.thedef = def;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
AST_Toplevel.DEFMETHOD("find_unique_prefix", function(options) {
|
||||
var letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_";
|
||||
AST_Toplevel.DEFMETHOD("find_colliding_names", function(options) {
|
||||
var cache = options.cache && options.cache.props;
|
||||
var prefixes = Object.create(null);
|
||||
options.reserved.forEach(add_prefix);
|
||||
var avoid = Object.create(null);
|
||||
options.reserved.forEach(to_avoid);
|
||||
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;
|
||||
return avoid;
|
||||
|
||||
function add_prefix(name) {
|
||||
if (/[0-9]$/.test(name)) {
|
||||
prefixes[name.replace(/[0-9]+$/, "")] = true;
|
||||
}
|
||||
function to_avoid(name) {
|
||||
avoid[name] = 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;
|
||||
to_avoid(name);
|
||||
}
|
||||
});
|
||||
|
||||
AST_Toplevel.DEFMETHOD("expand_names", function(options) {
|
||||
options = this._default_mangler_options(options);
|
||||
var prefix = this.find_unique_prefix(options);
|
||||
base54.reset();
|
||||
base54.sort();
|
||||
options = _default_mangler_options(options);
|
||||
var avoid = this.find_colliding_names(options);
|
||||
var cname = 0;
|
||||
this.globals.each(rename);
|
||||
this.walk(new TreeWalker(function(node) {
|
||||
if (node instanceof AST_Scope) node.variables.each(rename);
|
||||
if (node instanceof AST_SymbolCatch) rename(node.definition());
|
||||
}));
|
||||
|
||||
function next_name() {
|
||||
var name;
|
||||
do {
|
||||
name = base54(cname++);
|
||||
} while (avoid[name] || RESERVED_WORDS[name]);
|
||||
return name;
|
||||
}
|
||||
|
||||
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;
|
||||
if (def.global && options.cache) return;
|
||||
if (def.unmangleable(options)) return;
|
||||
if (options.reserved.has[def.name]) return;
|
||||
var redef = def.redefined();
|
||||
var name = redef ? redef.rename || redef.name : next_name();
|
||||
def.rename = name;
|
||||
def.orig.forEach(function(sym) {
|
||||
sym.name = def.name;
|
||||
sym.name = name;
|
||||
});
|
||||
def.references.forEach(function(sym) {
|
||||
sym.name = def.name;
|
||||
sym.name = name;
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -515,8 +537,9 @@ 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);
|
||||
AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options) {
|
||||
options = _default_mangler_options(options);
|
||||
base54.reset();
|
||||
try {
|
||||
AST_Node.prototype.print = function(stream, force_parens) {
|
||||
this._print(stream, force_parens);
|
||||
@@ -549,17 +572,21 @@ AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options){
|
||||
});
|
||||
|
||||
var base54 = (function() {
|
||||
var leading = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_".split("");
|
||||
var digits = "0123456789".split("");
|
||||
var freq = Object.create(null);
|
||||
function init(chars) {
|
||||
var array = [];
|
||||
for (var i = 0; i < chars.length; i++) {
|
||||
var ch = chars[i];
|
||||
array.push(ch);
|
||||
freq[ch] = -1e-2 * i;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
var digits = init("0123456789");
|
||||
var leading = init("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_");
|
||||
var chars, frequency;
|
||||
function reset() {
|
||||
frequency = Object.create(null);
|
||||
leading.forEach(function(ch) {
|
||||
frequency[ch] = 0;
|
||||
});
|
||||
digits.forEach(function(ch) {
|
||||
frequency[ch] = 0;
|
||||
});
|
||||
frequency = Object.create(freq);
|
||||
}
|
||||
base54.consider = function(str, delta) {
|
||||
for (var i = str.length; --i >= 0;) {
|
||||
@@ -570,7 +597,7 @@ var base54 = (function() {
|
||||
return frequency[b] - frequency[a];
|
||||
}
|
||||
base54.sort = function() {
|
||||
chars = mergeSort(leading, compare).concat(mergeSort(digits, compare));
|
||||
chars = leading.sort(compare).concat(digits.sort(compare));
|
||||
};
|
||||
base54.reset = reset;
|
||||
reset();
|
||||
@@ -584,6 +611,6 @@ var base54 = (function() {
|
||||
base = 64;
|
||||
} while (num > 0);
|
||||
return ret;
|
||||
};
|
||||
}
|
||||
return base54;
|
||||
})();
|
||||
|
||||
@@ -46,52 +46,59 @@
|
||||
// a small wrapper around fitzgen's source-map library
|
||||
function SourceMap(options) {
|
||||
options = defaults(options, {
|
||||
file : null,
|
||||
root : null,
|
||||
orig : null,
|
||||
|
||||
orig_line_diff : 0,
|
||||
dest_line_diff : 0,
|
||||
});
|
||||
file: null,
|
||||
root: null,
|
||||
orig: null,
|
||||
orig_line_diff: 0,
|
||||
dest_line_diff: 0,
|
||||
}, true);
|
||||
var generator = new MOZ_SourceMap.SourceMapGenerator({
|
||||
file : options.file,
|
||||
sourceRoot : options.root
|
||||
file: options.file,
|
||||
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({
|
||||
line: orig_line,
|
||||
column: orig_col
|
||||
var maps = options.orig && Object.create(null);
|
||||
if (maps) for (var source in options.orig) {
|
||||
var map = new MOZ_SourceMap.SourceMapConsumer(options.orig[source]);
|
||||
if (Array.isArray(options.orig[source].sources)) {
|
||||
map._sources.toArray().forEach(function(source) {
|
||||
var sourceContent = map.sourceContentFor(source, true);
|
||||
if (sourceContent) generator.setSourceContent(source, sourceContent);
|
||||
});
|
||||
if (info.source === null) {
|
||||
return;
|
||||
}
|
||||
source = info.source;
|
||||
orig_line = info.line;
|
||||
orig_col = info.column;
|
||||
name = info.name || name;
|
||||
}
|
||||
generator.addMapping({
|
||||
generated : { line: gen_line + options.dest_line_diff, column: gen_col },
|
||||
original : { line: orig_line + options.orig_line_diff, column: orig_col },
|
||||
source : source,
|
||||
name : name
|
||||
});
|
||||
};
|
||||
maps[source] = map;
|
||||
}
|
||||
return {
|
||||
add : add,
|
||||
get : function() { return generator },
|
||||
toString : function() { return JSON.stringify(generator.toJSON()); }
|
||||
add: function(source, gen_line, gen_col, orig_line, orig_col, name) {
|
||||
var map = maps && maps[source];
|
||||
if (map) {
|
||||
var info = map.originalPositionFor({
|
||||
line: orig_line,
|
||||
column: orig_col
|
||||
});
|
||||
if (info.source === null) return;
|
||||
source = info.source;
|
||||
orig_line = info.line;
|
||||
orig_col = info.column;
|
||||
name = info.name || name;
|
||||
}
|
||||
generator.addMapping({
|
||||
name: name,
|
||||
source: source,
|
||||
generated: {
|
||||
line: gen_line + options.dest_line_diff,
|
||||
column: gen_col
|
||||
},
|
||||
original: {
|
||||
line: orig_line + options.orig_line_diff,
|
||||
column: orig_col
|
||||
}
|
||||
});
|
||||
},
|
||||
get: function() {
|
||||
return generator;
|
||||
},
|
||||
toString: function() {
|
||||
return JSON.stringify(generator.toJSON());
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
136
lib/transform.js
136
lib/transform.js
@@ -43,8 +43,6 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
// Tree transformer helpers.
|
||||
|
||||
function TreeTransformer(before, after) {
|
||||
TreeWalker.call(this);
|
||||
this.before = before;
|
||||
@@ -52,166 +50,136 @@ function TreeTransformer(before, after) {
|
||||
}
|
||||
TreeTransformer.prototype = new TreeWalker;
|
||||
|
||||
(function(undefined){
|
||||
|
||||
function _(node, descend) {
|
||||
node.DEFMETHOD("transform", function(tw, in_list){
|
||||
var x, y;
|
||||
tw.push(this);
|
||||
if (tw.before) x = tw.before(this, descend, in_list);
|
||||
if (x === undefined) {
|
||||
if (!tw.after) {
|
||||
x = this;
|
||||
descend(x, tw);
|
||||
} else {
|
||||
tw.stack[tw.stack.length - 1] = x = this;
|
||||
descend(x, tw);
|
||||
y = tw.after(x, in_list);
|
||||
if (y !== undefined) x = y;
|
||||
}
|
||||
}
|
||||
tw.pop();
|
||||
return x;
|
||||
});
|
||||
};
|
||||
|
||||
(function(DEF) {
|
||||
function do_list(list, tw) {
|
||||
return MAP(list, function(node){
|
||||
return MAP(list, function(node) {
|
||||
return node.transform(tw, true);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
_(AST_Node, noop);
|
||||
|
||||
_(AST_LabeledStatement, function(self, tw){
|
||||
DEF(AST_Node, noop);
|
||||
DEF(AST_LabeledStatement, function(self, tw) {
|
||||
self.label = self.label.transform(tw);
|
||||
self.body = self.body.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_SimpleStatement, function(self, tw){
|
||||
DEF(AST_SimpleStatement, function(self, tw) {
|
||||
self.body = self.body.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_Block, function(self, tw){
|
||||
DEF(AST_Block, function(self, tw) {
|
||||
self.body = do_list(self.body, tw);
|
||||
});
|
||||
|
||||
_(AST_DWLoop, function(self, tw){
|
||||
DEF(AST_Do, function(self, tw) {
|
||||
self.body = self.body.transform(tw);
|
||||
self.condition = self.condition.transform(tw);
|
||||
});
|
||||
DEF(AST_While, function(self, tw) {
|
||||
self.condition = self.condition.transform(tw);
|
||||
self.body = self.body.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_For, function(self, tw){
|
||||
DEF(AST_For, function(self, tw) {
|
||||
if (self.init) self.init = self.init.transform(tw);
|
||||
if (self.condition) self.condition = self.condition.transform(tw);
|
||||
if (self.step) self.step = self.step.transform(tw);
|
||||
self.body = self.body.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_ForIn, function(self, tw){
|
||||
DEF(AST_ForIn, function(self, tw) {
|
||||
self.init = self.init.transform(tw);
|
||||
self.object = self.object.transform(tw);
|
||||
self.body = self.body.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_With, function(self, tw){
|
||||
DEF(AST_With, function(self, tw) {
|
||||
self.expression = self.expression.transform(tw);
|
||||
self.body = self.body.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_Exit, function(self, tw){
|
||||
DEF(AST_Exit, function(self, tw) {
|
||||
if (self.value) self.value = self.value.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_LoopControl, function(self, tw){
|
||||
DEF(AST_LoopControl, function(self, tw) {
|
||||
if (self.label) self.label = self.label.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_If, function(self, tw){
|
||||
DEF(AST_If, function(self, tw) {
|
||||
self.condition = self.condition.transform(tw);
|
||||
self.body = self.body.transform(tw);
|
||||
if (self.alternative) self.alternative = self.alternative.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_Switch, function(self, tw){
|
||||
DEF(AST_Switch, function(self, tw) {
|
||||
self.expression = self.expression.transform(tw);
|
||||
self.body = do_list(self.body, tw);
|
||||
});
|
||||
|
||||
_(AST_Case, function(self, tw){
|
||||
DEF(AST_Case, function(self, tw) {
|
||||
self.expression = self.expression.transform(tw);
|
||||
self.body = do_list(self.body, tw);
|
||||
});
|
||||
|
||||
_(AST_Try, function(self, tw){
|
||||
DEF(AST_Try, function(self, tw) {
|
||||
self.body = do_list(self.body, tw);
|
||||
if (self.bcatch) self.bcatch = self.bcatch.transform(tw);
|
||||
if (self.bfinally) self.bfinally = self.bfinally.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_Catch, function(self, tw){
|
||||
DEF(AST_Catch, function(self, tw) {
|
||||
self.argname = self.argname.transform(tw);
|
||||
self.body = do_list(self.body, tw);
|
||||
});
|
||||
|
||||
_(AST_Definitions, function(self, tw){
|
||||
DEF(AST_Definitions, function(self, tw) {
|
||||
self.definitions = do_list(self.definitions, tw);
|
||||
});
|
||||
|
||||
_(AST_VarDef, function(self, tw){
|
||||
DEF(AST_VarDef, function(self, tw) {
|
||||
self.name = self.name.transform(tw);
|
||||
if (self.value) self.value = self.value.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_Lambda, function(self, tw){
|
||||
DEF(AST_Lambda, function(self, tw) {
|
||||
if (self.name) self.name = self.name.transform(tw);
|
||||
self.argnames = do_list(self.argnames, tw);
|
||||
self.body = do_list(self.body, tw);
|
||||
});
|
||||
|
||||
_(AST_Call, function(self, tw){
|
||||
DEF(AST_Call, function(self, tw) {
|
||||
self.expression = self.expression.transform(tw);
|
||||
self.args = do_list(self.args, tw);
|
||||
});
|
||||
|
||||
_(AST_Sequence, function(self, tw){
|
||||
DEF(AST_Sequence, function(self, tw) {
|
||||
self.expressions = do_list(self.expressions, tw);
|
||||
});
|
||||
|
||||
_(AST_Dot, function(self, tw){
|
||||
DEF(AST_Dot, function(self, tw) {
|
||||
self.expression = self.expression.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_Sub, function(self, tw){
|
||||
DEF(AST_Sub, function(self, tw) {
|
||||
self.expression = self.expression.transform(tw);
|
||||
self.property = self.property.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_Unary, function(self, tw){
|
||||
DEF(AST_Unary, function(self, tw) {
|
||||
self.expression = self.expression.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_Binary, function(self, tw){
|
||||
DEF(AST_Binary, function(self, tw) {
|
||||
self.left = self.left.transform(tw);
|
||||
self.right = self.right.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_Conditional, function(self, tw){
|
||||
DEF(AST_Conditional, function(self, tw) {
|
||||
self.condition = self.condition.transform(tw);
|
||||
self.consequent = self.consequent.transform(tw);
|
||||
self.alternative = self.alternative.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_Array, function(self, tw){
|
||||
DEF(AST_Array, function(self, tw) {
|
||||
self.elements = do_list(self.elements, tw);
|
||||
});
|
||||
|
||||
_(AST_Object, function(self, tw){
|
||||
DEF(AST_Object, function(self, tw) {
|
||||
self.properties = do_list(self.properties, tw);
|
||||
});
|
||||
|
||||
_(AST_ObjectProperty, function(self, tw){
|
||||
DEF(AST_ObjectProperty, function(self, tw) {
|
||||
self.value = self.value.transform(tw);
|
||||
});
|
||||
|
||||
})();
|
||||
})(function(node, descend) {
|
||||
node.DEFMETHOD("transform", function(tw, in_list) {
|
||||
var x, y;
|
||||
tw.push(this);
|
||||
if (tw.before) x = tw.before(this, descend, in_list);
|
||||
if (typeof x === "undefined") {
|
||||
x = this;
|
||||
descend(x, tw);
|
||||
if (tw.after) {
|
||||
y = tw.after(x, in_list);
|
||||
if (typeof y !== "undefined") x = y;
|
||||
}
|
||||
}
|
||||
tw.pop();
|
||||
return x;
|
||||
});
|
||||
});
|
||||
|
||||
204
lib/utils.js
204
lib/utils.js
@@ -43,33 +43,25 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
function slice(a, start) {
|
||||
return Array.prototype.slice.call(a, start || 0);
|
||||
};
|
||||
|
||||
function characters(str) {
|
||||
return str.split("");
|
||||
};
|
||||
}
|
||||
|
||||
function member(name, array) {
|
||||
return array.indexOf(name) >= 0;
|
||||
};
|
||||
}
|
||||
|
||||
function find_if(func, array) {
|
||||
for (var i = 0, n = array.length; i < n; ++i) {
|
||||
if (func(array[i]))
|
||||
return array[i];
|
||||
}
|
||||
};
|
||||
for (var i = array.length; --i >= 0;) if (func(array[i])) return array[i];
|
||||
}
|
||||
|
||||
function repeat_string(str, i) {
|
||||
if (i <= 0) return "";
|
||||
if (i == 1) return str;
|
||||
var d = repeat_string(str, i >> 1);
|
||||
d += d;
|
||||
if (i & 1) d += str;
|
||||
return d;
|
||||
};
|
||||
return i & 1 ? d + str : d;
|
||||
}
|
||||
|
||||
function configure_error_stack(fn) {
|
||||
Object.defineProperty(fn.prototype, "stack", {
|
||||
@@ -78,7 +70,7 @@ function configure_error_stack(fn) {
|
||||
err.name = this.name;
|
||||
try {
|
||||
throw err;
|
||||
} catch(e) {
|
||||
} catch (e) {
|
||||
return e.stack;
|
||||
}
|
||||
}
|
||||
@@ -88,27 +80,23 @@ function configure_error_stack(fn) {
|
||||
function DefaultsError(msg, defs) {
|
||||
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);
|
||||
};
|
||||
|
||||
function defaults(args, defs, croak) {
|
||||
if (args === true)
|
||||
args = {};
|
||||
if (args === true) args = {};
|
||||
var ret = args || {};
|
||||
if (croak) for (var i in ret) if (HOP(ret, i) && !HOP(defs, i))
|
||||
DefaultsError.croak("`" + i + "` is not a supported option", defs);
|
||||
if (croak) for (var i in ret) if (HOP(ret, i) && !HOP(defs, i)) {
|
||||
throw new DefaultsError("`" + i + "` is not a supported option", defs);
|
||||
}
|
||||
for (var i in defs) if (HOP(defs, i)) {
|
||||
ret[i] = (args && HOP(args, i)) ? args[i] : defs[i];
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
}
|
||||
|
||||
function merge(obj, ext) {
|
||||
var count = 0;
|
||||
@@ -117,7 +105,7 @@ function merge(obj, ext) {
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
};
|
||||
}
|
||||
|
||||
function noop() {}
|
||||
function return_false() { return false; }
|
||||
@@ -125,7 +113,7 @@ function return_true() { return true; }
|
||||
function return_this() { return this; }
|
||||
function return_null() { return null; }
|
||||
|
||||
var MAP = (function(){
|
||||
var MAP = (function() {
|
||||
function MAP(a, f, backwards) {
|
||||
var ret = [], top = [], i;
|
||||
function doit() {
|
||||
@@ -139,8 +127,7 @@ var MAP = (function(){
|
||||
} else {
|
||||
top.push(val);
|
||||
}
|
||||
}
|
||||
else if (val !== skip) {
|
||||
} else if (val !== skip) {
|
||||
if (val instanceof Splice) {
|
||||
ret.push.apply(ret, backwards ? val.v.slice().reverse() : val.v);
|
||||
} else {
|
||||
@@ -148,8 +135,8 @@ var MAP = (function(){
|
||||
}
|
||||
}
|
||||
return is_last;
|
||||
};
|
||||
if (a instanceof Array) {
|
||||
}
|
||||
if (Array.isArray(a)) {
|
||||
if (backwards) {
|
||||
for (i = a.length; --i >= 0;) if (doit()) break;
|
||||
ret.reverse();
|
||||
@@ -157,132 +144,56 @@ var MAP = (function(){
|
||||
} else {
|
||||
for (i = 0; i < a.length; ++i) if (doit()) break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
for (i in a) if (HOP(a, i)) if (doit()) break;
|
||||
}
|
||||
return top.concat(ret);
|
||||
};
|
||||
}
|
||||
MAP.at_top = function(val) { return new AtTop(val) };
|
||||
MAP.splice = function(val) { return new Splice(val) };
|
||||
MAP.last = function(val) { return new Last(val) };
|
||||
var skip = MAP.skip = {};
|
||||
function AtTop(val) { this.v = val };
|
||||
function Splice(val) { this.v = val };
|
||||
function Last(val) { this.v = val };
|
||||
function AtTop(val) { this.v = val }
|
||||
function Splice(val) { this.v = val }
|
||||
function Last(val) { this.v = val }
|
||||
return MAP;
|
||||
})();
|
||||
|
||||
function push_uniq(array, el) {
|
||||
if (array.indexOf(el) < 0)
|
||||
array.push(el);
|
||||
};
|
||||
if (array.indexOf(el) < 0) return array.push(el);
|
||||
}
|
||||
|
||||
function string_template(text, props) {
|
||||
return text.replace(/\{(.+?)\}/g, function(str, p){
|
||||
return text.replace(/\{(.+?)\}/g, function(str, p) {
|
||||
return props && props[p];
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function remove(array, el) {
|
||||
for (var i = array.length; --i >= 0;) {
|
||||
if (array[i] === el) array.splice(i, 1);
|
||||
}
|
||||
};
|
||||
var index = array.indexOf(el);
|
||||
if (index >= 0) array.splice(index, 1);
|
||||
}
|
||||
|
||||
function mergeSort(array, cmp) {
|
||||
if (array.length < 2) return array.slice();
|
||||
function merge(a, b) {
|
||||
var r = [], ai = 0, bi = 0, i = 0;
|
||||
while (ai < a.length && bi < b.length) {
|
||||
cmp(a[ai], b[bi]) <= 0
|
||||
? r[i++] = a[ai++]
|
||||
: r[i++] = b[bi++];
|
||||
}
|
||||
if (ai < a.length) r.push.apply(r, a.slice(ai));
|
||||
if (bi < b.length) r.push.apply(r, b.slice(bi));
|
||||
return r;
|
||||
};
|
||||
function _ms(a) {
|
||||
if (a.length <= 1)
|
||||
return a;
|
||||
var m = Math.floor(a.length / 2), left = a.slice(0, m), right = a.slice(m);
|
||||
left = _ms(left);
|
||||
right = _ms(right);
|
||||
return merge(left, right);
|
||||
};
|
||||
return _ms(array);
|
||||
};
|
||||
|
||||
function set_difference(a, b) {
|
||||
return a.filter(function(el){
|
||||
return b.indexOf(el) < 0;
|
||||
});
|
||||
};
|
||||
|
||||
function set_intersection(a, b) {
|
||||
return a.filter(function(el){
|
||||
return b.indexOf(el) >= 0;
|
||||
});
|
||||
};
|
||||
|
||||
// this function is taken from Acorn [1], written by Marijn Haverbeke
|
||||
// [1] https://github.com/marijnh/acorn
|
||||
function makePredicate(words) {
|
||||
if (!(words instanceof Array)) words = words.split(" ");
|
||||
var f = "", cats = [];
|
||||
out: for (var i = 0; i < words.length; ++i) {
|
||||
for (var j = 0; j < cats.length; ++j)
|
||||
if (cats[j][0].length == words[i].length) {
|
||||
cats[j].push(words[i]);
|
||||
continue out;
|
||||
}
|
||||
cats.push([words[i]]);
|
||||
}
|
||||
function quote(word) {
|
||||
return JSON.stringify(word).replace(/[\u2028\u2029]/g, function(s) {
|
||||
switch (s) {
|
||||
case "\u2028": return "\\u2028";
|
||||
case "\u2029": return "\\u2029";
|
||||
}
|
||||
return s;
|
||||
});
|
||||
}
|
||||
function compareTo(arr) {
|
||||
if (arr.length == 1) return f += "return str === " + quote(arr[0]) + ";";
|
||||
f += "switch(str){";
|
||||
for (var i = 0; i < arr.length; ++i) f += "case " + quote(arr[i]) + ":";
|
||||
f += "return true}return false;";
|
||||
}
|
||||
// When there are more than three length categories, an outer
|
||||
// switch first dispatches on the lengths, to save on comparisons.
|
||||
if (cats.length > 3) {
|
||||
cats.sort(function(a, b) {return b.length - a.length;});
|
||||
f += "switch(str.length){";
|
||||
for (var i = 0; i < cats.length; ++i) {
|
||||
var cat = cats[i];
|
||||
f += "case " + cat[0].length + ":";
|
||||
compareTo(cat);
|
||||
}
|
||||
f += "}";
|
||||
// Otherwise, simply generate a flat `switch` statement.
|
||||
} else {
|
||||
compareTo(words);
|
||||
}
|
||||
return new Function("str", f);
|
||||
};
|
||||
if (!Array.isArray(words)) words = words.split(" ");
|
||||
var map = Object.create(null);
|
||||
words.forEach(function(word) {
|
||||
map[word] = true;
|
||||
});
|
||||
return map;
|
||||
}
|
||||
|
||||
function all(array, predicate) {
|
||||
for (var i = array.length; --i >= 0;)
|
||||
if (!predicate(array[i]))
|
||||
return false;
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
function Dictionary() {
|
||||
this._values = Object.create(null);
|
||||
this._size = 0;
|
||||
};
|
||||
}
|
||||
Dictionary.prototype = {
|
||||
set: function(key, val) {
|
||||
if (!this.has(key)) ++this._size;
|
||||
@@ -319,6 +230,13 @@ Dictionary.prototype = {
|
||||
ret.push(f(this._values[i], i.substr(1)));
|
||||
return ret;
|
||||
},
|
||||
clone: function() {
|
||||
var ret = new Dictionary();
|
||||
for (var i in this._values)
|
||||
ret._values[i] = this._values[i];
|
||||
ret._size = this._size;
|
||||
return ret;
|
||||
},
|
||||
toObject: function() { return this._values }
|
||||
};
|
||||
Dictionary.fromObject = function(obj) {
|
||||
@@ -336,20 +254,22 @@ function HOP(obj, prop) {
|
||||
// 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 instanceof AST_Call && p.expression === node && !(p instanceof AST_New) ) ||
|
||||
(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;
|
||||
for (var i = 0, p; p = stack.parent(i++); node = p) {
|
||||
if (p.TYPE == "Call") {
|
||||
if (p.expression === node) continue;
|
||||
} else if (p instanceof AST_Binary) {
|
||||
if (p.left === node) continue;
|
||||
} else if (p instanceof AST_Conditional) {
|
||||
if (p.condition === node) continue;
|
||||
} else if (p instanceof AST_PropAccess) {
|
||||
if (p.expression === node) continue;
|
||||
} else if (p instanceof AST_Sequence) {
|
||||
if (p.expressions[0] === node) continue;
|
||||
} else if (p instanceof AST_Statement) {
|
||||
return p.body === node;
|
||||
} else if (p instanceof AST_UnaryPostfix) {
|
||||
if (p.expression === node) continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
46
package.json
46
package.json
@@ -1,23 +1,17 @@
|
||||
{
|
||||
"name": "uglify-js",
|
||||
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
||||
"homepage": "http://lisperator.net/uglifyjs",
|
||||
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
||||
"license": "BSD-2-Clause",
|
||||
"version": "3.2.1",
|
||||
"version": "3.7.3",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
},
|
||||
"maintainers": [
|
||||
"Alex Lam <alexlamsl@gmail.com>",
|
||||
"Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/mishoo/UglifyJS2.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/mishoo/UglifyJS2/issues"
|
||||
},
|
||||
"repository": "mishoo/UglifyJS2",
|
||||
"main": "tools/node.js",
|
||||
"bin": {
|
||||
"uglifyjs": "bin/uglifyjs"
|
||||
@@ -29,16 +23,38 @@
|
||||
"LICENSE"
|
||||
],
|
||||
"dependencies": {
|
||||
"commander": "~2.12.1",
|
||||
"commander": "~2.20.3",
|
||||
"source-map": "~0.6.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"acorn": "~5.2.1",
|
||||
"mocha": "~3.5.1",
|
||||
"semver": "~5.4.1"
|
||||
"acorn": "~7.1.0",
|
||||
"semver": "~6.3.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "node test/run-tests.js"
|
||||
"test": "node test/compress.js && node test/mocha.js"
|
||||
},
|
||||
"keywords": ["uglify", "uglify-js", "minify", "minifier", "es5"]
|
||||
"keywords": [
|
||||
"cli",
|
||||
"compress",
|
||||
"compressor",
|
||||
"ecma",
|
||||
"ecmascript",
|
||||
"es",
|
||||
"es5",
|
||||
"javascript",
|
||||
"js",
|
||||
"jsmin",
|
||||
"min",
|
||||
"minification",
|
||||
"minifier",
|
||||
"minify",
|
||||
"optimize",
|
||||
"optimizer",
|
||||
"pack",
|
||||
"packer",
|
||||
"parse",
|
||||
"parser",
|
||||
"uglifier",
|
||||
"uglify"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -13,20 +13,22 @@ if (!args.length) {
|
||||
}
|
||||
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://code.jquery.com/jquery-3.4.1.js",
|
||||
"https://code.angularjs.org/1.7.8/angular.js",
|
||||
"https://unpkg.com/mathjs@6.2.3/dist/math.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://cdnjs.cloudflare.com/ajax/libs/d3/5.12.0/d3.js",
|
||||
"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.js",
|
||||
"https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js",
|
||||
"https://cdnjs.cloudflare.com/ajax/libs/ember.js/2.12.2/ember.prod.js",
|
||||
"https://raw.githubusercontent.com/kangax/html-minifier/v4.0.0/dist/htmlminifier.js",
|
||||
];
|
||||
var results = {};
|
||||
var remaining = 2 * urls.length;
|
||||
function done() {
|
||||
if (!--remaining) {
|
||||
var failures = [];
|
||||
var sum = { input: 0, output: 0, gzip: 0 };
|
||||
urls.forEach(function(url) {
|
||||
var info = results[url];
|
||||
console.log();
|
||||
@@ -39,6 +41,9 @@ function done() {
|
||||
if (info.code) {
|
||||
failures.push(url);
|
||||
}
|
||||
sum.input += info.input;
|
||||
sum.output += info.output;
|
||||
sum.gzip += info.gzip;
|
||||
});
|
||||
if (failures.length) {
|
||||
console.error("Benchmark failed:");
|
||||
@@ -46,6 +51,13 @@ function done() {
|
||||
console.error(url);
|
||||
});
|
||||
process.exit(1);
|
||||
} else {
|
||||
console.log();
|
||||
console.log("Subtotal");
|
||||
console.log();
|
||||
console.log("Original:", sum.input, "bytes");
|
||||
console.log("Uglified:", sum.output, "bytes");
|
||||
console.log("GZipped: ", sum.gzip, "bytes");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
454
test/compress.js
Normal file
454
test/compress.js
Normal file
@@ -0,0 +1,454 @@
|
||||
"use strict";
|
||||
|
||||
require("../tools/exit");
|
||||
|
||||
var assert = require("assert");
|
||||
var child_process = require("child_process");
|
||||
var fs = require("fs");
|
||||
var path = require("path");
|
||||
var sandbox = require("./sandbox");
|
||||
var semver = require("semver");
|
||||
var U = require("./node");
|
||||
|
||||
var file = process.argv[2];
|
||||
var dir = path.resolve(path.dirname(module.filename), "compress");
|
||||
if (file) {
|
||||
var minify_options = require("./ufuzz/options.json").map(JSON.stringify);
|
||||
log("--- {file}", { file: file });
|
||||
var tests = parse_test(path.resolve(dir, file));
|
||||
process.exit(Object.keys(tests).filter(function(name) {
|
||||
return !test_case(tests[name]);
|
||||
}).length);
|
||||
} else {
|
||||
var files = fs.readdirSync(dir).filter(function(name) {
|
||||
return /\.js$/i.test(name);
|
||||
});
|
||||
var failures = 0;
|
||||
var failed_files = Object.create(null);
|
||||
(function next() {
|
||||
var file = files.shift();
|
||||
if (file) {
|
||||
child_process.spawn(process.argv[0], [ process.argv[1], file ], {
|
||||
stdio: [ "ignore", 1, 2 ]
|
||||
}).on("exit", function(code) {
|
||||
if (code) {
|
||||
failures += code;
|
||||
failed_files[file] = code;
|
||||
}
|
||||
next();
|
||||
});
|
||||
} else if (failures) {
|
||||
console.error();
|
||||
console.error("!!! Failed " + failures + " test case(s).");
|
||||
console.error("!!! " + Object.keys(failed_files).join(", "));
|
||||
process.exit(1);
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
function evaluate(code) {
|
||||
if (code instanceof U.AST_Node) code = make_code(code, { beautify: true });
|
||||
return new Function("return(" + code + ")")();
|
||||
}
|
||||
|
||||
function log() {
|
||||
console.log("%s", tmpl.apply(null, arguments));
|
||||
}
|
||||
|
||||
function make_code(ast, options) {
|
||||
var stream = U.OutputStream(options);
|
||||
ast.print(stream);
|
||||
return stream.get();
|
||||
}
|
||||
|
||||
function parse_test(file) {
|
||||
var script = fs.readFileSync(file, "utf8");
|
||||
// TODO try/catch can be removed after fixing https://github.com/mishoo/UglifyJS2/issues/348
|
||||
try {
|
||||
var ast = U.parse(script, {
|
||||
filename: file
|
||||
});
|
||||
} catch (e) {
|
||||
console.error("Caught error while parsing tests in " + file);
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
}
|
||||
var tests = Object.create(null);
|
||||
var tw = new U.TreeWalker(function(node, descend) {
|
||||
if (node instanceof U.AST_LabeledStatement
|
||||
&& tw.parent() instanceof U.AST_Toplevel) {
|
||||
var name = node.label.name;
|
||||
if (name in tests) {
|
||||
throw new Error('Duplicated test name "' + name + '" in ' + file);
|
||||
}
|
||||
tests[name] = get_one_test(name, node.body);
|
||||
return true;
|
||||
}
|
||||
if (!(node instanceof U.AST_Toplevel)) croak(node);
|
||||
});
|
||||
ast.walk(tw);
|
||||
return tests;
|
||||
|
||||
function croak(node) {
|
||||
throw new Error(tmpl("Can't understand test file {file} [{line},{col}]\n{code}", {
|
||||
file: file,
|
||||
line: node.start.line,
|
||||
col: node.start.col,
|
||||
code: make_code(node, { beautify: false })
|
||||
}));
|
||||
}
|
||||
|
||||
function read_string(stat) {
|
||||
if (stat.TYPE == "SimpleStatement") {
|
||||
var body = stat.body;
|
||||
switch(body.TYPE) {
|
||||
case "String":
|
||||
return body.value;
|
||||
case "Array":
|
||||
return body.elements.map(function(element) {
|
||||
if (element.TYPE !== "String")
|
||||
throw new Error("Should be array of strings");
|
||||
return element.value;
|
||||
}).join("\n");
|
||||
}
|
||||
}
|
||||
throw new Error("Should be string or array of strings");
|
||||
}
|
||||
|
||||
function get_one_test(name, block) {
|
||||
var test = { name: name, options: {} };
|
||||
var tw = new U.TreeWalker(function(node, descend) {
|
||||
if (node instanceof U.AST_Assign) {
|
||||
if (!(node.left instanceof U.AST_SymbolRef)) {
|
||||
croak(node);
|
||||
}
|
||||
var name = node.left.name;
|
||||
test[name] = evaluate(node.right);
|
||||
return true;
|
||||
}
|
||||
if (node instanceof U.AST_LabeledStatement) {
|
||||
var label = node.label;
|
||||
assert.ok([
|
||||
"input",
|
||||
"expect",
|
||||
"expect_exact",
|
||||
"expect_warnings",
|
||||
"expect_stdout",
|
||||
"node_version",
|
||||
].indexOf(label.name) >= 0, tmpl("Unsupported label {name} [{line},{col}]", {
|
||||
name: label.name,
|
||||
line: label.start.line,
|
||||
col: label.start.col
|
||||
}));
|
||||
var stat = node.body;
|
||||
if (label.name == "expect_exact" || label.name == "node_version") {
|
||||
test[label.name] = read_string(stat);
|
||||
} else if (label.name == "expect_stdout") {
|
||||
var body = stat.body;
|
||||
if (body instanceof U.AST_Boolean) {
|
||||
test[label.name] = body.value;
|
||||
} else if (body instanceof U.AST_Call) {
|
||||
var ctor = global[body.expression.name];
|
||||
assert.ok(ctor === Error || ctor.prototype instanceof Error, tmpl("Unsupported expect_stdout format [{line},{col}]", {
|
||||
line: label.start.line,
|
||||
col: label.start.col
|
||||
}));
|
||||
test[label.name] = ctor.apply(null, body.args.map(function(node) {
|
||||
assert.ok(node instanceof U.AST_Constant, tmpl("Unsupported expect_stdout format [{line},{col}]", {
|
||||
line: label.start.line,
|
||||
col: label.start.col
|
||||
}));
|
||||
return node.value;
|
||||
}));
|
||||
} else {
|
||||
test[label.name] = read_string(stat) + "\n";
|
||||
}
|
||||
} else {
|
||||
test[label.name] = stat;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
block.walk(tw);
|
||||
return test;
|
||||
}
|
||||
}
|
||||
|
||||
// Try to reminify original input with standard options
|
||||
// to see if it matches expect_stdout.
|
||||
function reminify(orig_options, input_code, input_formatted, stdout) {
|
||||
for (var i = 0; i < minify_options.length; i++) {
|
||||
var options = JSON.parse(minify_options[i]);
|
||||
if (options.compress) [
|
||||
"keep_fargs",
|
||||
"keep_fnames",
|
||||
].forEach(function(name) {
|
||||
if (name in orig_options) {
|
||||
options.compress[name] = orig_options[name];
|
||||
}
|
||||
});
|
||||
var options_formatted = JSON.stringify(options, null, 4);
|
||||
var result = U.minify(input_code, options);
|
||||
if (result.error) {
|
||||
log([
|
||||
"!!! failed input reminify",
|
||||
"---INPUT---",
|
||||
"{input}",
|
||||
"---OPTIONS---",
|
||||
"{options}",
|
||||
"--ERROR---",
|
||||
"{error}",
|
||||
"",
|
||||
"",
|
||||
].join("\n"), {
|
||||
input: input_formatted,
|
||||
options: options_formatted,
|
||||
error: result.error,
|
||||
});
|
||||
return false;
|
||||
} else {
|
||||
var expected = stdout[options.toplevel ? 1 : 0];
|
||||
var actual = run_code(result.code, options.toplevel);
|
||||
if (typeof expected != "string" && typeof actual != "string" && expected.name == actual.name) {
|
||||
actual = expected;
|
||||
}
|
||||
if (!sandbox.same_stdout(expected, actual)) {
|
||||
log([
|
||||
"!!! failed running reminified input",
|
||||
"---INPUT---",
|
||||
"{input}",
|
||||
"---OPTIONS---",
|
||||
"{options}",
|
||||
"---OUTPUT---",
|
||||
"{output}",
|
||||
"---EXPECTED {expected_type}---",
|
||||
"{expected}",
|
||||
"---ACTUAL {actual_type}---",
|
||||
"{actual}",
|
||||
"",
|
||||
"",
|
||||
].join("\n"), {
|
||||
input: input_formatted,
|
||||
options: options_formatted,
|
||||
output: result.code,
|
||||
expected_type: typeof expected == "string" ? "STDOUT" : "ERROR",
|
||||
expected: expected,
|
||||
actual_type: typeof actual == "string" ? "STDOUT" : "ERROR",
|
||||
actual: actual,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function run_code(code, toplevel) {
|
||||
var result = sandbox.run_code(code, toplevel);
|
||||
return typeof result == "string" ? result.replace(/\u001b\[\d+m/g, "") : result;
|
||||
}
|
||||
|
||||
function test_case(test) {
|
||||
log(" Running test [{name}]", { name: test.name });
|
||||
var output_options = test.beautify || {};
|
||||
var expect;
|
||||
if (test.expect) {
|
||||
expect = make_code(to_toplevel(test.expect, test.mangle), output_options);
|
||||
} else {
|
||||
expect = test.expect_exact;
|
||||
}
|
||||
var input = to_toplevel(test.input, test.mangle);
|
||||
var input_code = make_code(input);
|
||||
var input_formatted = make_code(test.input, {
|
||||
beautify: true,
|
||||
comments: "all",
|
||||
keep_quoted_props: true,
|
||||
quote_style: 3,
|
||||
});
|
||||
try {
|
||||
U.parse(input_code);
|
||||
} catch (ex) {
|
||||
log([
|
||||
"!!! Cannot parse input",
|
||||
"---INPUT---",
|
||||
"{input}",
|
||||
"--PARSE ERROR--",
|
||||
"{error}",
|
||||
"",
|
||||
"",
|
||||
].join("\n"), {
|
||||
input: input_formatted,
|
||||
error: ex,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
var warnings_emitted = [];
|
||||
if (test.expect_warnings) {
|
||||
var expected_warnings = make_code(test.expect_warnings, {
|
||||
beautify: false,
|
||||
quote_style: 2, // force double quote to match JSON
|
||||
});
|
||||
U.AST_Node.log_function(function(text) {
|
||||
warnings_emitted.push(text);
|
||||
}, /"INFO: /.test(expected_warnings));
|
||||
}
|
||||
if (test.mangle && test.mangle.properties && test.mangle.properties.keep_quoted) {
|
||||
var quoted_props = test.mangle.properties.reserved;
|
||||
if (!Array.isArray(quoted_props)) quoted_props = [];
|
||||
test.mangle.properties.reserved = quoted_props;
|
||||
U.reserve_quoted_keys(input, quoted_props);
|
||||
}
|
||||
if (test.rename) {
|
||||
input.figure_out_scope(test.mangle);
|
||||
input.expand_names(test.mangle);
|
||||
}
|
||||
var cmp = new U.Compressor(test.options, true);
|
||||
var output = cmp.compress(input);
|
||||
output.figure_out_scope(test.mangle);
|
||||
if (test.mangle) {
|
||||
output.compute_char_frequency(test.mangle);
|
||||
output.mangle_names(test.mangle);
|
||||
if (test.mangle.properties) {
|
||||
output = U.mangle_properties(output, test.mangle.properties);
|
||||
}
|
||||
}
|
||||
output = make_code(output, output_options);
|
||||
if (expect != output) {
|
||||
log([
|
||||
"!!! failed",
|
||||
"---INPUT---",
|
||||
"{input}",
|
||||
"---OUTPUT---",
|
||||
"{output}",
|
||||
"---EXPECTED---",
|
||||
"{expected}",
|
||||
"",
|
||||
"",
|
||||
].join("\n"), {
|
||||
input: input_formatted,
|
||||
output: output,
|
||||
expected: expect
|
||||
});
|
||||
return false;
|
||||
}
|
||||
// expect == output
|
||||
try {
|
||||
U.parse(output);
|
||||
} catch (ex) {
|
||||
log([
|
||||
"!!! Test matched expected result but cannot parse output",
|
||||
"---INPUT---",
|
||||
"{input}",
|
||||
"---OUTPUT---",
|
||||
"{output}",
|
||||
"--REPARSE ERROR--",
|
||||
"{error}",
|
||||
"",
|
||||
"",
|
||||
].join("\n"), {
|
||||
input: input_formatted,
|
||||
output: output,
|
||||
error: ex,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (test.expect_warnings) {
|
||||
warnings_emitted = warnings_emitted.map(function(input) {
|
||||
return input.split(process.cwd() + path.sep).join("").split(path.sep).join("/");
|
||||
});
|
||||
var actual_warnings = JSON.stringify(warnings_emitted);
|
||||
if (expected_warnings != actual_warnings) {
|
||||
log([
|
||||
"!!! failed",
|
||||
"---INPUT---",
|
||||
"{input}",
|
||||
"---EXPECTED WARNINGS---",
|
||||
"{expected_warnings}",
|
||||
"---ACTUAL WARNINGS---",
|
||||
"{actual_warnings}",
|
||||
"",
|
||||
"",
|
||||
].join("\n"), {
|
||||
input: input_formatted,
|
||||
expected_warnings: expected_warnings,
|
||||
actual_warnings: actual_warnings,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (test.expect_stdout && (!test.node_version || semver.satisfies(process.version, test.node_version))) {
|
||||
var stdout = [ run_code(input_code), run_code(input_code, true) ];
|
||||
var toplevel = test.options.toplevel;
|
||||
var actual = stdout[toplevel ? 1 : 0];
|
||||
if (test.expect_stdout === true) {
|
||||
test.expect_stdout = actual;
|
||||
}
|
||||
if (!sandbox.same_stdout(test.expect_stdout, actual)) {
|
||||
log([
|
||||
"!!! Invalid input or expected stdout",
|
||||
"---INPUT---",
|
||||
"{input}",
|
||||
"---EXPECTED {expected_type}---",
|
||||
"{expected}",
|
||||
"---ACTUAL {actual_type}---",
|
||||
"{actual}",
|
||||
"",
|
||||
"",
|
||||
].join("\n"), {
|
||||
input: input_formatted,
|
||||
expected_type: typeof test.expect_stdout == "string" ? "STDOUT" : "ERROR",
|
||||
expected: test.expect_stdout,
|
||||
actual_type: typeof actual == "string" ? "STDOUT" : "ERROR",
|
||||
actual: actual,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
actual = run_code(output, toplevel);
|
||||
if (!sandbox.same_stdout(test.expect_stdout, actual)) {
|
||||
log([
|
||||
"!!! failed",
|
||||
"---INPUT---",
|
||||
"{input}",
|
||||
"---EXPECTED {expected_type}---",
|
||||
"{expected}",
|
||||
"---ACTUAL {actual_type}---",
|
||||
"{actual}",
|
||||
"",
|
||||
"",
|
||||
].join("\n"), {
|
||||
input: input_formatted,
|
||||
expected_type: typeof test.expect_stdout == "string" ? "STDOUT" : "ERROR",
|
||||
expected: test.expect_stdout,
|
||||
actual_type: typeof actual == "string" ? "STDOUT" : "ERROR",
|
||||
actual: actual,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!reminify(test.options, input_code, input_formatted, stdout)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function tmpl() {
|
||||
return U.string_template.apply(null, arguments);
|
||||
}
|
||||
|
||||
function to_toplevel(input, mangle_options) {
|
||||
if (!(input instanceof U.AST_BlockStatement)) throw new Error("Unsupported input syntax");
|
||||
var directive = true;
|
||||
var offset = input.start.line;
|
||||
var tokens = [];
|
||||
var toplevel = new U.AST_Toplevel(input.transform(new U.TreeTransformer(function(node) {
|
||||
if (U.push_uniq(tokens, node.start)) node.start.line -= offset;
|
||||
if (!directive || node === input) return;
|
||||
if (node instanceof U.AST_SimpleStatement && node.body instanceof U.AST_String) {
|
||||
return new U.AST_Directive(node.body);
|
||||
} else {
|
||||
directive = false;
|
||||
}
|
||||
})));
|
||||
toplevel.figure_out_scope(mangle_options);
|
||||
return toplevel;
|
||||
}
|
||||
778
test/compress/arguments.js
Normal file
778
test/compress/arguments.js
Normal file
@@ -0,0 +1,778 @@
|
||||
replace_index: {
|
||||
options = {
|
||||
arguments: true,
|
||||
evaluate: true,
|
||||
properties: true,
|
||||
}
|
||||
input: {
|
||||
var arguments = [];
|
||||
console.log(arguments[0]);
|
||||
(function() {
|
||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||
})("bar", 42);
|
||||
(function(a, b) {
|
||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||
})("bar", 42);
|
||||
(function(arguments) {
|
||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||
})("bar", 42);
|
||||
(function() {
|
||||
var arguments;
|
||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||
})("bar", 42);
|
||||
}
|
||||
expect: {
|
||||
var arguments = [];
|
||||
console.log(arguments[0]);
|
||||
(function() {
|
||||
console.log(arguments[1], arguments[1], arguments.foo);
|
||||
})("bar", 42);
|
||||
(function(a, b) {
|
||||
console.log(b, b, arguments.foo);
|
||||
})("bar", 42);
|
||||
(function(arguments) {
|
||||
console.log(arguments[1], arguments[1], arguments.foo);
|
||||
})("bar", 42);
|
||||
(function() {
|
||||
var arguments;
|
||||
console.log(arguments[1], arguments[1], arguments.foo);
|
||||
})("bar", 42);
|
||||
}
|
||||
expect_stdout: [
|
||||
"undefined",
|
||||
"42 42 undefined",
|
||||
"42 42 undefined",
|
||||
"a a undefined",
|
||||
"42 42 undefined",
|
||||
]
|
||||
}
|
||||
|
||||
replace_index_strict: {
|
||||
options = {
|
||||
arguments: true,
|
||||
evaluate: true,
|
||||
properties: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
(function() {
|
||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||
})("bar", 42);
|
||||
(function(a, b) {
|
||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||
})("bar", 42);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
(function() {
|
||||
console.log(arguments[1], arguments[1], arguments.foo);
|
||||
})("bar", 42);
|
||||
(function(a, b) {
|
||||
console.log(b, b, arguments.foo);
|
||||
})("bar", 42);
|
||||
}
|
||||
expect_stdout: [
|
||||
"42 42 undefined",
|
||||
"42 42 undefined",
|
||||
]
|
||||
}
|
||||
|
||||
replace_index_keep_fargs: {
|
||||
options = {
|
||||
arguments: true,
|
||||
evaluate: true,
|
||||
keep_fargs: false,
|
||||
properties: true,
|
||||
}
|
||||
input: {
|
||||
var arguments = [];
|
||||
console.log(arguments[0]);
|
||||
(function() {
|
||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||
})("bar", 42);
|
||||
(function(a, b) {
|
||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||
})("bar", 42);
|
||||
(function(arguments) {
|
||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||
})("bar", 42);
|
||||
(function() {
|
||||
var arguments;
|
||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||
})("bar", 42);
|
||||
}
|
||||
expect: {
|
||||
var arguments = [];
|
||||
console.log(arguments[0]);
|
||||
(function(argument_0, argument_1) {
|
||||
console.log(argument_1, argument_1, arguments.foo);
|
||||
})("bar", 42);
|
||||
(function(a, b) {
|
||||
console.log(b, b, arguments.foo);
|
||||
})("bar", 42);
|
||||
(function(arguments) {
|
||||
console.log(arguments[1], arguments[1], arguments.foo);
|
||||
})("bar", 42);
|
||||
(function() {
|
||||
var arguments;
|
||||
console.log(arguments[1], arguments[1], arguments.foo);
|
||||
})("bar", 42);
|
||||
}
|
||||
expect_stdout: [
|
||||
"undefined",
|
||||
"42 42 undefined",
|
||||
"42 42 undefined",
|
||||
"a a undefined",
|
||||
"42 42 undefined",
|
||||
]
|
||||
}
|
||||
|
||||
replace_index_keep_fargs_strict: {
|
||||
options = {
|
||||
arguments: true,
|
||||
evaluate: true,
|
||||
keep_fargs: false,
|
||||
properties: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
(function() {
|
||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||
})("bar", 42);
|
||||
(function(a, b) {
|
||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||
})("bar", 42);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
(function(argument_0, argument_1) {
|
||||
console.log(argument_1, argument_1, arguments.foo);
|
||||
})("bar", 42);
|
||||
(function(a, b) {
|
||||
console.log(b, b, arguments.foo);
|
||||
})("bar", 42);
|
||||
}
|
||||
expect_stdout: [
|
||||
"42 42 undefined",
|
||||
"42 42 undefined",
|
||||
]
|
||||
}
|
||||
|
||||
modified: {
|
||||
options = {
|
||||
arguments: true,
|
||||
}
|
||||
input: {
|
||||
(function(a, b) {
|
||||
var c = arguments[0];
|
||||
var d = arguments[1];
|
||||
var a = "foo";
|
||||
b++;
|
||||
arguments[0] = "moo";
|
||||
arguments[1] *= 2;
|
||||
console.log(a, b, c, d, arguments[0], arguments[1]);
|
||||
})("bar", 42);
|
||||
}
|
||||
expect: {
|
||||
(function(a, b) {
|
||||
var c = a;
|
||||
var d = b;
|
||||
var a = "foo";
|
||||
b++;
|
||||
a = "moo";
|
||||
b *= 2;
|
||||
console.log(a, b, c, d, a, b);
|
||||
})("bar", 42);
|
||||
}
|
||||
expect_stdout: "moo 86 bar 42 moo 86"
|
||||
}
|
||||
|
||||
modified_strict: {
|
||||
options = {
|
||||
arguments: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
(function(a, b) {
|
||||
var c = arguments[0];
|
||||
var d = arguments[1];
|
||||
var a = "foo";
|
||||
b++;
|
||||
arguments[0] = "moo";
|
||||
arguments[1] *= 2;
|
||||
console.log(a, b, c, d, arguments[0], arguments[1]);
|
||||
})("bar", 42);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
(function(a, b) {
|
||||
var c = arguments[0];
|
||||
var d = arguments[1];
|
||||
var a = "foo";
|
||||
b++;
|
||||
arguments[0] = "moo";
|
||||
arguments[1] *= 2;
|
||||
console.log(a, b, c, d, arguments[0], arguments[1]);
|
||||
})("bar", 42);
|
||||
}
|
||||
expect_stdout: "foo 43 bar 42 moo 84"
|
||||
}
|
||||
|
||||
duplicate_argname: {
|
||||
options = {
|
||||
arguments: true,
|
||||
}
|
||||
input: {
|
||||
(function(a, b, a) {
|
||||
console.log(a, b, arguments[0], arguments[1], arguments[2]);
|
||||
})("foo", 42, "bar");
|
||||
}
|
||||
expect: {
|
||||
(function(a, b, a) {
|
||||
console.log(a, b, arguments[0], b, a);
|
||||
})("foo", 42, "bar");
|
||||
}
|
||||
expect_stdout: "bar 42 foo 42 bar"
|
||||
}
|
||||
|
||||
issue_3273: {
|
||||
options = {
|
||||
arguments: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
console.log(arguments[0], a);
|
||||
arguments[0]++;
|
||||
console.log(arguments[0], a);
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
console.log(a, a);
|
||||
a++;
|
||||
console.log(a, a);
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect_stdout: [
|
||||
"0 0",
|
||||
"1 1",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3273_reduce_vars: {
|
||||
options = {
|
||||
arguments: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
console.log(arguments[0], a);
|
||||
arguments[0]++;
|
||||
console.log(arguments[0], a);
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
console.log(a, a);
|
||||
a++;
|
||||
console.log(a, a);
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect_stdout: [
|
||||
"0 0",
|
||||
"1 1",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3273_local_strict: {
|
||||
options = {
|
||||
arguments: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
"use strict";
|
||||
console.log(arguments[0], a);
|
||||
arguments[0]++;
|
||||
console.log(arguments[0], a);
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
"use strict";
|
||||
console.log(arguments[0], a);
|
||||
arguments[0]++;
|
||||
console.log(arguments[0], a);
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect_stdout: [
|
||||
"0 0",
|
||||
"1 0",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3273_local_strict_reduce_vars: {
|
||||
options = {
|
||||
arguments: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
"use strict";
|
||||
console.log(arguments[0], a);
|
||||
arguments[0]++;
|
||||
console.log(arguments[0], a);
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
"use strict";
|
||||
console.log(arguments[0], a);
|
||||
arguments[0]++;
|
||||
console.log(arguments[0], a);
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect_stdout: [
|
||||
"0 0",
|
||||
"1 0",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3273_global_strict: {
|
||||
options = {
|
||||
arguments: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
console.log(arguments[0], a);
|
||||
arguments[0]++;
|
||||
console.log(arguments[0], a);
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
console.log(arguments[0], a);
|
||||
arguments[0]++;
|
||||
console.log(arguments[0], a);
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect_stdout: [
|
||||
"0 0",
|
||||
"1 0",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3273_global_strict_reduce_vars: {
|
||||
options = {
|
||||
arguments: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
console.log(arguments[0], a);
|
||||
arguments[0]++;
|
||||
console.log(arguments[0], a);
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
console.log(arguments[0], a);
|
||||
arguments[0]++;
|
||||
console.log(arguments[0], a);
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect_stdout: [
|
||||
"0 0",
|
||||
"1 0",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3273_keep_fargs_false: {
|
||||
options = {
|
||||
arguments: true,
|
||||
keep_fargs: false,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
"use strict";
|
||||
arguments[0]++;
|
||||
console.log(arguments[0]);
|
||||
})(0);
|
||||
}
|
||||
expect: {
|
||||
(function(argument_0) {
|
||||
"use strict";
|
||||
argument_0++;
|
||||
console.log(argument_0);
|
||||
})(0);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_3273_keep_fargs_strict: {
|
||||
options = {
|
||||
arguments: true,
|
||||
keep_fargs: "strict",
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
"use strict";
|
||||
arguments[0]++;
|
||||
console.log(arguments[0]);
|
||||
})(0);
|
||||
}
|
||||
expect: {
|
||||
(function(argument_0) {
|
||||
"use strict";
|
||||
argument_0++;
|
||||
console.log(argument_0);
|
||||
})(0);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_3282_1: {
|
||||
options = {
|
||||
arguments: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
keep_fargs: false,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(t) {
|
||||
return function() {
|
||||
t();
|
||||
};
|
||||
})(function() {
|
||||
'use strict';
|
||||
function e() {
|
||||
return arguments[0];
|
||||
}
|
||||
e();
|
||||
e();
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
return function() {
|
||||
(function() {
|
||||
"use strict";
|
||||
function e() {
|
||||
return arguments[0];
|
||||
}
|
||||
e();
|
||||
e();
|
||||
})();
|
||||
};
|
||||
})()();
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_3282_1_passes: {
|
||||
options = {
|
||||
arguments: true,
|
||||
passes: 2,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
keep_fargs: false,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(t) {
|
||||
return function() {
|
||||
t();
|
||||
};
|
||||
})(function() {
|
||||
'use strict';
|
||||
function e() {
|
||||
return arguments[0];
|
||||
}
|
||||
e();
|
||||
e();
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
return function() {
|
||||
(function() {
|
||||
"use strict";
|
||||
function e(argument_0) {
|
||||
return argument_0;
|
||||
}
|
||||
e();
|
||||
e();
|
||||
})();
|
||||
};
|
||||
})()();
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_3282_2: {
|
||||
options = {
|
||||
arguments: true,
|
||||
reduce_vars: true,
|
||||
keep_fargs: false,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(f) {
|
||||
f();
|
||||
})(function() {
|
||||
return (function(t) {
|
||||
return function() {
|
||||
t();
|
||||
};
|
||||
})(function() {
|
||||
'use strict';
|
||||
function e() {
|
||||
return arguments[0];
|
||||
}
|
||||
e();
|
||||
e();
|
||||
})();
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
(function() {
|
||||
return function(t) {
|
||||
return function() {
|
||||
t();
|
||||
};
|
||||
}(function() {
|
||||
"use strict";
|
||||
function e() {
|
||||
return arguments[0];
|
||||
}
|
||||
e();
|
||||
e();
|
||||
})();
|
||||
})();
|
||||
})();
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_3282_2_passes: {
|
||||
options = {
|
||||
arguments: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
keep_fargs: false,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(f) {
|
||||
f();
|
||||
})(function() {
|
||||
return (function(t) {
|
||||
return function() {
|
||||
t();
|
||||
};
|
||||
})(function() {
|
||||
'use strict';
|
||||
function e() {
|
||||
return arguments[0];
|
||||
}
|
||||
e();
|
||||
e();
|
||||
})();
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
(function() {
|
||||
return function(t) {
|
||||
return function() {
|
||||
t();
|
||||
};
|
||||
}(function() {
|
||||
"use strict";
|
||||
function e(argument_0) {
|
||||
return argument_0;
|
||||
}
|
||||
e();
|
||||
e();
|
||||
})();
|
||||
})();
|
||||
})();
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_3420_1: {
|
||||
options = {
|
||||
arguments: true,
|
||||
keep_fargs: "strict",
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
return function() {
|
||||
return arguments[0];
|
||||
};
|
||||
}().length);
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
return function() {
|
||||
return arguments[0];
|
||||
};
|
||||
}().length);
|
||||
}
|
||||
expect_stdout: "0"
|
||||
}
|
||||
|
||||
issue_3420_2: {
|
||||
options = {
|
||||
arguments: true,
|
||||
keep_fargs: "strict",
|
||||
}
|
||||
input: {
|
||||
var foo = function() {
|
||||
delete arguments[0];
|
||||
};
|
||||
foo();
|
||||
}
|
||||
expect: {
|
||||
var foo = function() {
|
||||
delete arguments[0];
|
||||
};
|
||||
foo();
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_3420_3: {
|
||||
options = {
|
||||
arguments: true,
|
||||
keep_fargs: "strict",
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var foo = function() {
|
||||
delete arguments[0];
|
||||
};
|
||||
foo();
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var foo = function() {
|
||||
delete arguments[0];
|
||||
};
|
||||
foo();
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_3420_4: {
|
||||
options = {
|
||||
arguments: true,
|
||||
keep_fargs: "strict",
|
||||
}
|
||||
input: {
|
||||
!function() {
|
||||
console.log(arguments[0]);
|
||||
delete arguments[0];
|
||||
console.log(arguments[0]);
|
||||
}(42);
|
||||
}
|
||||
expect: {
|
||||
!function(argument_0) {
|
||||
console.log(argument_0);
|
||||
delete arguments[0];
|
||||
console.log(arguments[0]);
|
||||
}(42);
|
||||
}
|
||||
expect_stdout: [
|
||||
"42",
|
||||
"undefined",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3420_5: {
|
||||
options = {
|
||||
arguments: true,
|
||||
keep_fargs: "strict",
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
!function() {
|
||||
console.log(arguments[0]);
|
||||
delete arguments[0];
|
||||
console.log(arguments[0]);
|
||||
}(42);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
!function(argument_0) {
|
||||
console.log(argument_0);
|
||||
delete arguments[0];
|
||||
console.log(arguments[0]);
|
||||
}(42);
|
||||
}
|
||||
expect_stdout: [
|
||||
"42",
|
||||
"undefined",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3420_6: {
|
||||
options = {
|
||||
arguments: true,
|
||||
keep_fargs: "strict",
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
return delete arguments[0];
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
return delete arguments[0];
|
||||
}());
|
||||
}
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
issue_3420_7: {
|
||||
options = {
|
||||
arguments: true,
|
||||
keep_fargs: "strict",
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
console.log(function() {
|
||||
return delete arguments[0];
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
console.log(function() {
|
||||
return delete arguments[0];
|
||||
}());
|
||||
}
|
||||
expect_stdout: "true"
|
||||
}
|
||||
@@ -15,9 +15,9 @@ holes_and_undefined: {
|
||||
|
||||
constant_join: {
|
||||
options = {
|
||||
unsafe : true,
|
||||
evaluate : true
|
||||
};
|
||||
evaluate: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
var a = [ "foo", "bar", "baz" ].join("");
|
||||
var a1 = [ "foo", "bar", "baz" ].join();
|
||||
@@ -64,9 +64,9 @@ constant_join: {
|
||||
|
||||
constant_join_2: {
|
||||
options = {
|
||||
unsafe : true,
|
||||
evaluate : true
|
||||
};
|
||||
evaluate: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
var a = [ "foo", "bar", boo(), "baz", "x", "y" ].join("");
|
||||
var b = [ "foo", "bar", boo(), "baz", "x", "y" ].join("-");
|
||||
@@ -93,9 +93,9 @@ constant_join_2: {
|
||||
|
||||
constant_join_3: {
|
||||
options = {
|
||||
unsafe: true,
|
||||
evaluate: true,
|
||||
};
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
var a = [ null ].join();
|
||||
var b = [ , ].join();
|
||||
@@ -133,7 +133,7 @@ for_loop: {
|
||||
reduce_vars: true,
|
||||
unsafe: true,
|
||||
unused: true,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
function f0() {
|
||||
var a = [1, 2, 3];
|
||||
@@ -239,3 +239,113 @@ index_length: {
|
||||
}
|
||||
expect_stdout: "1 2"
|
||||
}
|
||||
|
||||
constructor_bad: {
|
||||
options = {
|
||||
unsafe: true
|
||||
}
|
||||
input: {
|
||||
try {
|
||||
Array(NaN);
|
||||
console.log("FAIL1");
|
||||
} catch (ex) {
|
||||
try {
|
||||
new Array(NaN);
|
||||
console.log("FAIL2");
|
||||
} catch (ex) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
try {
|
||||
Array(3.14);
|
||||
console.log("FAIL1");
|
||||
} catch (ex) {
|
||||
try {
|
||||
new Array(3.14);
|
||||
console.log("FAIL2");
|
||||
} catch (ex) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
try {
|
||||
Array(NaN);
|
||||
console.log("FAIL1");
|
||||
} catch (ex) {
|
||||
try {
|
||||
Array(NaN);
|
||||
console.log("FAIL2");
|
||||
} catch (ex) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
try {
|
||||
Array(3.14);
|
||||
console.log("FAIL1");
|
||||
} catch (ex) {
|
||||
try {
|
||||
Array(3.14);
|
||||
console.log("FAIL2");
|
||||
} catch (ex) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"PASS",
|
||||
]
|
||||
expect_warnings: [
|
||||
"WARN: Invalid array length: 3.14 [test/compress/arrays.js:13,12]",
|
||||
"WARN: Invalid array length: 3.14 [test/compress/arrays.js:17,16]",
|
||||
]
|
||||
}
|
||||
|
||||
constructor_good: {
|
||||
options = {
|
||||
unsafe: true
|
||||
}
|
||||
input: {
|
||||
console.log(Array());
|
||||
console.log(Array(0));
|
||||
console.log(Array(1));
|
||||
console.log(Array(6));
|
||||
console.log(Array(7));
|
||||
console.log(Array(1, 2));
|
||||
console.log(Array(false));
|
||||
console.log(Array("foo"));
|
||||
console.log(Array(Array));
|
||||
console.log(new Array());
|
||||
console.log(new Array(0));
|
||||
console.log(new Array(1));
|
||||
console.log(new Array(6));
|
||||
console.log(new Array(7));
|
||||
console.log(new Array(1, 2));
|
||||
console.log(new Array(false));
|
||||
console.log(new Array("foo"));
|
||||
console.log(new Array(Array));
|
||||
}
|
||||
expect: {
|
||||
console.log([]);
|
||||
console.log([]);
|
||||
console.log([,]);
|
||||
console.log([,,,,,,]);
|
||||
console.log(Array(7));
|
||||
console.log([ 1, 2 ]);
|
||||
console.log([ false ]);
|
||||
console.log([ "foo" ]);
|
||||
console.log(Array(Array));
|
||||
console.log([]);
|
||||
console.log([]);
|
||||
console.log([,]);
|
||||
console.log([,,,,,,]);
|
||||
console.log(Array(7));
|
||||
console.log([ 1, 2 ]);
|
||||
console.log([ false ]);
|
||||
console.log([ "foo" ]);
|
||||
console.log(Array(Array));
|
||||
}
|
||||
expect_stdout: true
|
||||
expect_warnings: []
|
||||
}
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
asm_mixed: {
|
||||
options = {
|
||||
sequences : true,
|
||||
properties : true,
|
||||
dead_code : true,
|
||||
drop_debugger : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
loops : true,
|
||||
unused : true,
|
||||
hoist_funs : true,
|
||||
keep_fargs : true,
|
||||
keep_fnames : false,
|
||||
hoist_vars : true,
|
||||
if_return : true,
|
||||
join_vars : true,
|
||||
cascade : true,
|
||||
side_effects : true,
|
||||
negate_iife : true
|
||||
};
|
||||
assignments: true,
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
drop_debugger: true,
|
||||
evaluate: true,
|
||||
hoist_funs: true,
|
||||
hoist_vars: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
keep_fnames: false,
|
||||
loops: true,
|
||||
negate_iife: true,
|
||||
properties: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
// adapted from http://asmjs.org/spec/latest/
|
||||
function asm_GeometricMean(stdlib, foreign, buffer) {
|
||||
@@ -96,7 +96,7 @@ asm_mixed: {
|
||||
return +sum;
|
||||
}
|
||||
function geometricMean(start, end) {
|
||||
return start |= 0, end |= 0, +exp(+logSum(start, end) / +(end - start | 0));
|
||||
return start |= 0, end |= 0, +exp(logSum(start, end) / (end - start | 0));
|
||||
}
|
||||
var exp = stdlib.Math.exp, log = stdlib.Math.log, values = new stdlib.Float64Array(buffer);
|
||||
return { geometricMean: geometricMean };
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
op_equals_left_local_var: {
|
||||
options = {
|
||||
assignments: true,
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
@@ -60,6 +61,7 @@ op_equals_left_local_var: {
|
||||
|
||||
op_equals_right_local_var: {
|
||||
options = {
|
||||
assignments: true,
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
@@ -123,6 +125,7 @@ op_equals_right_local_var: {
|
||||
}
|
||||
op_equals_left_global_var: {
|
||||
options = {
|
||||
assignments: true,
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
@@ -179,6 +182,7 @@ op_equals_left_global_var: {
|
||||
|
||||
op_equals_right_global_var: {
|
||||
options = {
|
||||
assignments: true,
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
@@ -236,3 +240,170 @@ op_equals_right_global_var: {
|
||||
x = g() & x;
|
||||
}
|
||||
}
|
||||
|
||||
increment_decrement_1: {
|
||||
options = {
|
||||
assignments: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a) {
|
||||
a += 1;
|
||||
a -= 1;
|
||||
return a;
|
||||
}(42));
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a){
|
||||
++a;
|
||||
--a;
|
||||
return a;
|
||||
}(42));
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
increment_decrement_2: {
|
||||
options = {
|
||||
assignments: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a) {
|
||||
a = a + 1;
|
||||
a = a - 1;
|
||||
a += 1;
|
||||
a -= 1;
|
||||
return a;
|
||||
}(42));
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a){
|
||||
++a;
|
||||
--a;
|
||||
++a;
|
||||
--a;
|
||||
return a;
|
||||
}(42));
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
issue_3375_1: {
|
||||
options = {
|
||||
assignments: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
function p(o) {
|
||||
console.log(typeof o, o);
|
||||
}
|
||||
p(function(b) {
|
||||
var a = b += 1;
|
||||
--b;
|
||||
return a;
|
||||
}("object"));
|
||||
}
|
||||
expect: {
|
||||
function p(o) {
|
||||
console.log(typeof o, o);
|
||||
}
|
||||
p(function(b) {
|
||||
var a = b += 1;
|
||||
--b;
|
||||
return a;
|
||||
}("object"));
|
||||
}
|
||||
expect_stdout: "string object1"
|
||||
}
|
||||
|
||||
issue_3375_2: {
|
||||
options = {
|
||||
assignments: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
function p(o) {
|
||||
console.log(typeof o, o);
|
||||
}
|
||||
p(function(b) {
|
||||
var a = b -= 1;
|
||||
--b;
|
||||
return a;
|
||||
}("object"));
|
||||
}
|
||||
expect: {
|
||||
function p(o) {
|
||||
console.log(typeof o, o);
|
||||
}
|
||||
p(function(b) {
|
||||
var a = --b;
|
||||
--b;
|
||||
return a;
|
||||
}("object"));
|
||||
}
|
||||
expect_stdout: "number NaN"
|
||||
}
|
||||
|
||||
issue_3427: {
|
||||
options = {
|
||||
assignments: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
var a;
|
||||
a || (a = {});
|
||||
})();
|
||||
}
|
||||
expect: {}
|
||||
}
|
||||
|
||||
issue_3429_1: {
|
||||
options = {
|
||||
assignments: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
(function(b) {
|
||||
b && (b = a = "FAIL");
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
(function(b) {
|
||||
b = b && (a = "FAIL");
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3429_2: {
|
||||
options = {
|
||||
assignments: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
(function(b) {
|
||||
b || (b = a = "FAIL");
|
||||
})(42);
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
(function(b) {
|
||||
b = b || (a = "FAIL");
|
||||
})(42);
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
88
test/compress/booleans.js
Normal file
88
test/compress/booleans.js
Normal file
@@ -0,0 +1,88 @@
|
||||
iife_boolean_context: {
|
||||
options = {
|
||||
booleans: true,
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
return Object(1) || false;
|
||||
}() ? "PASS" : "FAIL");
|
||||
console.log(function() {
|
||||
return [].length || true;
|
||||
}() ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
return Object(1);
|
||||
}() ? "PASS" : "FAIL");
|
||||
console.log(function() {
|
||||
return [].length, 1;
|
||||
}() ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"PASS",
|
||||
]
|
||||
expect_warnings: [
|
||||
"WARN: Dropping side-effect-free || [test/compress/booleans.js:2,19]",
|
||||
"WARN: Boolean || always true [test/compress/booleans.js:5,19]",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3465_1: {
|
||||
options = {
|
||||
booleans: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a) {
|
||||
return typeof a;
|
||||
}() ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a) {
|
||||
return 1;
|
||||
}() ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3465_2: {
|
||||
options = {
|
||||
booleans: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function f(a) {
|
||||
if (!a) console.log(f(42));
|
||||
return typeof a;
|
||||
}() ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
console.log(function f(a) {
|
||||
if (!a) console.log(f(42));
|
||||
return typeof a;
|
||||
}() ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: [
|
||||
"number",
|
||||
"PASS",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3465_3: {
|
||||
options = {
|
||||
booleans: true,
|
||||
passes: 2,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function f(a) {
|
||||
return typeof a;
|
||||
}() ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a) {
|
||||
return 1;
|
||||
}() ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,114 +0,0 @@
|
||||
keep_comparisons: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
unsafe_comps: false
|
||||
}
|
||||
input: {
|
||||
var obj1 = {
|
||||
valueOf: function() {triggeredFirst();}
|
||||
}
|
||||
var obj2 = {
|
||||
valueOf: function() {triggeredSecond();}
|
||||
}
|
||||
var result1 = obj1 <= obj2;
|
||||
var result2 = obj1 < obj2;
|
||||
var result3 = obj1 >= obj2;
|
||||
var result4 = obj1 > obj2;
|
||||
}
|
||||
expect: {
|
||||
var obj1 = {
|
||||
valueOf: function() {triggeredFirst();}
|
||||
}
|
||||
var obj2 = {
|
||||
valueOf: function() {triggeredSecond();}
|
||||
}
|
||||
var result1 = obj1 <= obj2;
|
||||
var result2 = obj1 < obj2;
|
||||
var result3 = obj1 >= obj2;
|
||||
var result4 = obj1 > obj2;
|
||||
}
|
||||
}
|
||||
|
||||
keep_comparisons_with_unsafe_comps: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
unsafe_comps: true
|
||||
}
|
||||
input: {
|
||||
var obj1 = {
|
||||
valueOf: function() {triggeredFirst();}
|
||||
}
|
||||
var obj2 = {
|
||||
valueOf: function() {triggeredSecond();}
|
||||
}
|
||||
var result1 = obj1 <= obj2;
|
||||
var result2 = obj1 < obj2;
|
||||
var result3 = obj1 >= obj2;
|
||||
var result4 = obj1 > obj2;
|
||||
}
|
||||
expect: {
|
||||
var obj1 = {
|
||||
valueOf: function() {triggeredFirst();}
|
||||
}
|
||||
var obj2 = {
|
||||
valueOf: function() {triggeredSecond();}
|
||||
}
|
||||
var result1 = obj2 >= obj1;
|
||||
var result2 = obj2 > obj1;
|
||||
var result3 = obj1 >= obj2;
|
||||
var result4 = obj1 > obj2;
|
||||
}
|
||||
}
|
||||
|
||||
dont_change_in_or_instanceof_expressions: {
|
||||
input: {
|
||||
1 in 1;
|
||||
null in null;
|
||||
1 instanceof 1;
|
||||
null instanceof null;
|
||||
}
|
||||
expect: {
|
||||
1 in 1;
|
||||
null in null;
|
||||
1 instanceof 1;
|
||||
null instanceof null;
|
||||
}
|
||||
}
|
||||
|
||||
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"
|
||||
}
|
||||
442
test/compress/comparisons.js
Normal file
442
test/compress/comparisons.js
Normal file
@@ -0,0 +1,442 @@
|
||||
comparisons: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
var obj1, obj2;
|
||||
var result1 = obj1 <= obj2;
|
||||
var result2 = obj1 < obj2;
|
||||
var result3 = obj1 >= obj2;
|
||||
var result4 = obj1 > obj2;
|
||||
}
|
||||
expect: {
|
||||
var obj1, obj2;
|
||||
var result1 = obj1 <= obj2;
|
||||
var result2 = obj1 < obj2;
|
||||
var result3 = obj2 <= obj1;
|
||||
var result4 = obj2 < obj1;
|
||||
}
|
||||
}
|
||||
|
||||
unsafe_comps: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
unsafe_comps: true,
|
||||
}
|
||||
input: {
|
||||
var obj1, obj2;
|
||||
obj1 <= obj2 ? f1() : g1();
|
||||
obj1 < obj2 ? f2() : g2();
|
||||
obj1 >= obj2 ? f3() : g3();
|
||||
obj1 > obj2 ? f4() : g4();
|
||||
}
|
||||
expect: {
|
||||
var obj1, obj2;
|
||||
(obj2 < obj1 ? g1 : f1)();
|
||||
(obj1 < obj2 ? f2 : g2)();
|
||||
(obj1 < obj2 ? g3 : f3)();
|
||||
(obj2 < obj1 ? f4 : g4)();
|
||||
}
|
||||
}
|
||||
|
||||
dont_change_in_or_instanceof_expressions: {
|
||||
input: {
|
||||
1 in 1;
|
||||
null in null;
|
||||
1 instanceof 1;
|
||||
null instanceof null;
|
||||
}
|
||||
expect: {
|
||||
1 in 1;
|
||||
null in null;
|
||||
1 instanceof 1;
|
||||
null instanceof null;
|
||||
}
|
||||
}
|
||||
|
||||
self_comparison_1: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
a === a;
|
||||
a !== b;
|
||||
b.c === a.c;
|
||||
b.c !== b.c;
|
||||
}
|
||||
expect: {
|
||||
a == a;
|
||||
a !== b;
|
||||
b.c === a.c;
|
||||
b.c != b.c;
|
||||
}
|
||||
}
|
||||
|
||||
self_comparison_2: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
function f() {}
|
||||
var o = {};
|
||||
console.log(f != f, o === o);
|
||||
}
|
||||
expect: {
|
||||
function f() {}
|
||||
var o = {};
|
||||
console.log(false, true);
|
||||
}
|
||||
expect_stdout: "false true"
|
||||
}
|
||||
|
||||
issue_2857_1: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
function f1(a) {
|
||||
a === undefined || a === null;
|
||||
a === undefined || a !== null;
|
||||
a !== undefined || a === null;
|
||||
a !== undefined || a !== null;
|
||||
a === undefined && a === null;
|
||||
a === undefined && a !== null;
|
||||
a !== undefined && a === null;
|
||||
a !== undefined && a !== null;
|
||||
}
|
||||
function f2(a) {
|
||||
a === null || a === undefined;
|
||||
a === null || a !== undefined;
|
||||
a !== null || a === undefined;
|
||||
a !== null || a !== undefined;
|
||||
a === null && a === undefined;
|
||||
a === null && a !== undefined;
|
||||
a !== null && a === undefined;
|
||||
a !== null && a !== undefined;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f1(a) {
|
||||
null == a;
|
||||
void 0 === a || null !== a;
|
||||
void 0 !== a || null === a;
|
||||
void 0 !== a || null !== a;
|
||||
void 0 === a && null === a;
|
||||
void 0 === a && null !== a;
|
||||
void 0 !== a && null === a;
|
||||
null != a;
|
||||
}
|
||||
function f2(a) {
|
||||
null == a;
|
||||
null === a || void 0 !== a;
|
||||
null !== a || void 0 === a;
|
||||
null !== a || void 0 !== a;
|
||||
null === a && void 0 === a;
|
||||
null === a && void 0 !== a;
|
||||
null !== a && void 0 === a;
|
||||
null != a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_2857_2: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, p) {
|
||||
a === undefined || a === null || p;
|
||||
a === undefined || a !== null || p;
|
||||
a !== undefined || a === null || p;
|
||||
a !== undefined || a !== null || p;
|
||||
a === undefined && a === null || p;
|
||||
a === undefined && a !== null || p;
|
||||
a !== undefined && a === null || p;
|
||||
a !== undefined && a !== null || p;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(a, p) {
|
||||
null == a || p;
|
||||
void 0 === a || null !== a || p;
|
||||
void 0 !== a || null === a || p;
|
||||
void 0 !== a || null !== a || p;
|
||||
void 0 === a && null === a || p;
|
||||
void 0 === a && null !== a || p;
|
||||
void 0 !== a && null === a || p;
|
||||
null != a || p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_2857_3: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, p) {
|
||||
a === undefined || a === null && p;
|
||||
a === undefined || a !== null && p;
|
||||
a !== undefined || a === null && p;
|
||||
a !== undefined || a !== null && p;
|
||||
a === undefined && a === null && p;
|
||||
a === undefined && a !== null && p;
|
||||
a !== undefined && a === null && p;
|
||||
a !== undefined && a !== null && p;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(a, p) {
|
||||
void 0 === a || null === a && p;
|
||||
void 0 === a || null !== a && p;
|
||||
void 0 !== a || null === a && p;
|
||||
void 0 !== a || null !== a && p;
|
||||
void 0 === a && null === a && p;
|
||||
void 0 === a && null !== a && p;
|
||||
void 0 !== a && null === a && p;
|
||||
null != a && p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_2857_4: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, p) {
|
||||
p || a === undefined || a === null;
|
||||
p || a === undefined || a !== null;
|
||||
p || a !== undefined || a === null;
|
||||
p || a !== undefined || a !== null;
|
||||
p || a === undefined && a === null;
|
||||
p || a === undefined && a !== null;
|
||||
p || a !== undefined && a === null;
|
||||
p || a !== undefined && a !== null;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(a, p) {
|
||||
p || null == a;
|
||||
p || void 0 === a || null !== a;
|
||||
p || void 0 !== a || null === a;
|
||||
p || void 0 !== a || null !== a;
|
||||
p || void 0 === a && null === a;
|
||||
p || void 0 === a && null !== a;
|
||||
p || void 0 !== a && null === a;
|
||||
p || null != a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_2857_5: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, p) {
|
||||
p && a === undefined || a === null;
|
||||
p && a === undefined || a !== null;
|
||||
p && a !== undefined || a === null;
|
||||
p && a !== undefined || a !== null;
|
||||
p && a === undefined && a === null;
|
||||
p && a === undefined && a !== null;
|
||||
p && a !== undefined && a === null;
|
||||
p && a !== undefined && a !== null;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(a, p) {
|
||||
p && void 0 === a || null === a;
|
||||
p && void 0 === a || null !== a;
|
||||
p && void 0 !== a || null === a;
|
||||
p && void 0 !== a || null !== a;
|
||||
p && void 0 === a && null === a;
|
||||
p && void 0 === a && null !== a;
|
||||
p && void 0 !== a && null === a;
|
||||
p && null != a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_2857_6: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
if (({}).b === undefined || {}.b === null)
|
||||
return a.b !== undefined && a.b !== null;
|
||||
}
|
||||
console.log(f({
|
||||
a: [ null ],
|
||||
get b() {
|
||||
return this.a.shift();
|
||||
}
|
||||
}));
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
if (null == {}.b)
|
||||
return void 0 !== a.b && null !== a.b;
|
||||
}
|
||||
console.log(f({
|
||||
a: [ null ],
|
||||
get b() {
|
||||
return this.a.shift();
|
||||
}
|
||||
}));
|
||||
}
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
is_boolean_unsafe: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
console.log(/foo/.test("bar") === [].isPrototypeOf({}));
|
||||
}
|
||||
expect: {
|
||||
console.log(/foo/.test("bar") == [].isPrototypeOf({}));
|
||||
}
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
is_number_unsafe: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
console.log(Math.acos(42) !== "foo".charCodeAt(4));
|
||||
}
|
||||
expect: {
|
||||
console.log(Math.acos(42) != "foo".charCodeAt(4));
|
||||
}
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
is_boolean_var: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a, b) {
|
||||
for (var i = 0, c = !b; i < a.length; i++)
|
||||
if (!a[i] === c)
|
||||
return i;
|
||||
}([ false, true ], 42));
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a, b) {
|
||||
for (var i = 0, c = !b; i < a.length; i++)
|
||||
if (!a[i] == c)
|
||||
return i;
|
||||
}([ false, true ], 42));
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
is_defined: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function a() {
|
||||
return void 0 === a;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function a() {
|
||||
return a, false;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "false"
|
||||
expect_warnings: [
|
||||
"WARN: Expression always defined [test/compress/comparisons.js:2,19]",
|
||||
]
|
||||
}
|
||||
|
||||
unsafe_indexOf: {
|
||||
options = {
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
var a = Object.keys({ foo: 42 });
|
||||
if (a.indexOf("bar") < 0) console.log("PASS");
|
||||
if (0 > a.indexOf("bar")) console.log("PASS");
|
||||
if (a.indexOf("foo") >= 0) console.log("PASS");
|
||||
if (0 <= a.indexOf("foo")) console.log("PASS");
|
||||
if (a.indexOf("foo") > -1) console.log("PASS");
|
||||
if (-1 < a.indexOf("foo")) console.log("PASS");
|
||||
if (a.indexOf("bar") == -1) console.log("PASS");
|
||||
if (-1 == a.indexOf("bar")) console.log("PASS");
|
||||
if (a.indexOf("bar") === -1) console.log("PASS");
|
||||
if (-1 === a.indexOf("bar")) console.log("PASS");
|
||||
if (a.indexOf("foo") != -1) console.log("PASS");
|
||||
if (-1 != a.indexOf("foo")) console.log("PASS");
|
||||
if (a.indexOf("foo") !== -1) console.log("PASS");
|
||||
if (-1 !== a.indexOf("foo")) console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
var a = Object.keys({ foo: 42 });
|
||||
if (!~a.indexOf("bar")) console.log("PASS");
|
||||
if (!~a.indexOf("bar")) console.log("PASS");
|
||||
if (~a.indexOf("foo")) console.log("PASS");
|
||||
if (~a.indexOf("foo")) console.log("PASS");
|
||||
if (~a.indexOf("foo")) console.log("PASS");
|
||||
if (~a.indexOf("foo")) console.log("PASS");
|
||||
if (!~a.indexOf("bar")) console.log("PASS");
|
||||
if (!~a.indexOf("bar")) console.log("PASS");
|
||||
if (!~a.indexOf("bar")) console.log("PASS");
|
||||
if (!~a.indexOf("bar")) console.log("PASS");
|
||||
if (~a.indexOf("foo")) console.log("PASS");
|
||||
if (~a.indexOf("foo")) console.log("PASS");
|
||||
if (~a.indexOf("foo")) console.log("PASS");
|
||||
if (~a.indexOf("foo")) console.log("PASS");
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3413: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var b;
|
||||
void 0 !== ("" < b || void 0) || console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
var b;
|
||||
void 0 !== ("" < b || void 0) || console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
concat_1: {
|
||||
options = {
|
||||
evaluate: true
|
||||
};
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
var a = "foo" + "bar" + x() + "moo" + "foo" + y() + "x" + "y" + "z" + q();
|
||||
var b = "foo" + 1 + x() + 2 + "boo";
|
||||
@@ -26,7 +26,7 @@ concat_1: {
|
||||
}
|
||||
|
||||
concat_2: {
|
||||
options = {};
|
||||
options = {}
|
||||
input: {
|
||||
console.log(
|
||||
1 + (2 + 3),
|
||||
@@ -55,7 +55,7 @@ concat_2: {
|
||||
}
|
||||
|
||||
concat_3: {
|
||||
options = {};
|
||||
options = {}
|
||||
input: {
|
||||
console.log(
|
||||
1 + 2 + (3 + 4 + 5),
|
||||
@@ -84,7 +84,7 @@ concat_3: {
|
||||
}
|
||||
|
||||
concat_4: {
|
||||
options = {};
|
||||
options = {}
|
||||
input: {
|
||||
console.log(
|
||||
1 + "2" + (3 + 4 + 5),
|
||||
@@ -113,7 +113,7 @@ concat_4: {
|
||||
}
|
||||
|
||||
concat_5: {
|
||||
options = {};
|
||||
options = {}
|
||||
input: {
|
||||
console.log(
|
||||
"1" + 2 + (3 + 4 + 5),
|
||||
@@ -142,7 +142,7 @@ concat_5: {
|
||||
}
|
||||
|
||||
concat_6: {
|
||||
options = {};
|
||||
options = {}
|
||||
input: {
|
||||
console.log(
|
||||
"1" + "2" + (3 + 4 + 5),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
ifs_1: {
|
||||
options = {
|
||||
conditionals: true
|
||||
};
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
if (foo) bar();
|
||||
if (!foo); else bar();
|
||||
@@ -18,8 +18,8 @@ ifs_1: {
|
||||
|
||||
ifs_2: {
|
||||
options = {
|
||||
conditionals: true
|
||||
};
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
if (foo) {
|
||||
x();
|
||||
@@ -41,18 +41,18 @@ ifs_2: {
|
||||
}
|
||||
expect: {
|
||||
foo ? x() : bar ? y() : baz && z();
|
||||
foo ? x() : bar ? y() : baz ? z() : t();
|
||||
(foo ? x : bar ? y : baz ? z : t)();
|
||||
}
|
||||
}
|
||||
|
||||
ifs_3_should_warn: {
|
||||
options = {
|
||||
conditionals : true,
|
||||
dead_code : true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
side_effects : true,
|
||||
};
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var x, y;
|
||||
if (x && !(x + "1") && y) { // 1
|
||||
@@ -78,8 +78,8 @@ ifs_3_should_warn: {
|
||||
|
||||
ifs_4: {
|
||||
options = {
|
||||
conditionals: true
|
||||
};
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
if (foo && bar) {
|
||||
x(foo)[10].bar.baz = something();
|
||||
@@ -95,10 +95,10 @@ ifs_4: {
|
||||
|
||||
ifs_5: {
|
||||
options = {
|
||||
if_return: true,
|
||||
conditionals: true,
|
||||
comparisons: true,
|
||||
};
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
if (foo) return;
|
||||
@@ -132,9 +132,9 @@ ifs_5: {
|
||||
|
||||
ifs_6: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
comparisons: true
|
||||
};
|
||||
}
|
||||
input: {
|
||||
var x, y;
|
||||
if (!foo && !bar && !baz && !boo) {
|
||||
@@ -161,52 +161,74 @@ ifs_6: {
|
||||
}
|
||||
}
|
||||
|
||||
ifs_7: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
if (A); else;
|
||||
if (A) while (B); else;
|
||||
if (A); else while (C);
|
||||
if (A) while (B); else while (C);
|
||||
}
|
||||
expect: {
|
||||
A;
|
||||
if (A) while (B);
|
||||
if (!A) while (C);
|
||||
if (A) while (B); else while (C);
|
||||
}
|
||||
}
|
||||
|
||||
cond_1: {
|
||||
options = {
|
||||
conditionals: true
|
||||
};
|
||||
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);
|
||||
}
|
||||
if (some_condition()) {
|
||||
side_effects(x);
|
||||
} else {
|
||||
side_effects(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);
|
||||
some_condition() ? side_effects(x) : side_effects(y);
|
||||
function foo(do_something, some_condition) {
|
||||
do_something(some_condition ? x : y);
|
||||
some_condition ? side_effects(x) : side_effects(y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cond_2: {
|
||||
options = {
|
||||
conditionals: true
|
||||
};
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cond_3: {
|
||||
options = {
|
||||
conditionals: true
|
||||
};
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
var FooBar;
|
||||
if (some_condition()) {
|
||||
@@ -223,8 +245,8 @@ cond_3: {
|
||||
|
||||
cond_4: {
|
||||
options = {
|
||||
conditionals: true
|
||||
};
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
var do_something;
|
||||
if (some_condition()) {
|
||||
@@ -247,8 +269,8 @@ cond_4: {
|
||||
|
||||
cond_5: {
|
||||
options = {
|
||||
conditionals: true
|
||||
};
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
if (some_condition()) {
|
||||
if (some_other_condition()) {
|
||||
@@ -267,7 +289,7 @@ cond_5: {
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
some_condition() && some_other_condition() ? do_something() : alternate();
|
||||
(some_condition() && some_other_condition() ? do_something : alternate)();
|
||||
some_condition() && some_other_condition() && do_something();
|
||||
}
|
||||
}
|
||||
@@ -275,9 +297,9 @@ cond_5: {
|
||||
cond_7: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
evaluate : true,
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
var x, y, z, a, b;
|
||||
// compress these
|
||||
@@ -328,7 +350,7 @@ cond_7: {
|
||||
x = 'foo';
|
||||
x = 'foo';
|
||||
x = (condition(), 20);
|
||||
x = z ? 'fuji' : (condition(), 'fuji');
|
||||
x = (z || condition(), 'fuji');
|
||||
x = (condition(), 'foobar');
|
||||
x = y ? a : b;
|
||||
x = y ? 'foo' : 'fo';
|
||||
@@ -338,8 +360,8 @@ cond_7: {
|
||||
cond_7_1: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
evaluate : true
|
||||
};
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
var x;
|
||||
// access to global should be assumed to have side effects
|
||||
@@ -357,10 +379,10 @@ cond_7_1: {
|
||||
|
||||
cond_8: {
|
||||
options = {
|
||||
booleans: false,
|
||||
conditionals: true,
|
||||
evaluate : true,
|
||||
booleans : false
|
||||
};
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
// compress these
|
||||
@@ -441,10 +463,10 @@ cond_8: {
|
||||
|
||||
cond_8b: {
|
||||
options = {
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
evaluate : true,
|
||||
booleans : true
|
||||
};
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
// compress these
|
||||
@@ -524,10 +546,10 @@ cond_8b: {
|
||||
|
||||
cond_8c: {
|
||||
options = {
|
||||
booleans: false,
|
||||
conditionals: true,
|
||||
evaluate : false,
|
||||
booleans : false
|
||||
};
|
||||
evaluate: false,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
// compress these
|
||||
@@ -605,11 +627,122 @@ cond_8c: {
|
||||
}
|
||||
}
|
||||
|
||||
cond_9: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
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: {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cond_10: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
if (1 == a) return "foo";
|
||||
if (2 == a) return "foo";
|
||||
if (3 == a) return "foo";
|
||||
if (4 == a) return 42;
|
||||
if (5 == a) return "foo";
|
||||
if (6 == a) return "foo";
|
||||
return "bar";
|
||||
}
|
||||
console.log(f(1), f(2), f(3), f(4), f(5), f(6), f(7));
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
return 1 == a || 2 == a || 3 == a ? "foo" : 4 == a ? 42 : 5 == a || 6 == a ? "foo" : "bar";
|
||||
}
|
||||
console.log(f(1), f(2), f(3), f(4), f(5), f(6), f(7));
|
||||
}
|
||||
expect_stdout: "foo foo foo 42 foo foo bar"
|
||||
}
|
||||
|
||||
cond_11: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
p: "foo",
|
||||
q: function() {
|
||||
return this.p;
|
||||
}
|
||||
};
|
||||
function f() {
|
||||
return "bar";
|
||||
}
|
||||
function g(a) {
|
||||
return a ? f() : o.q();
|
||||
}
|
||||
console.log(g(0), g(1));
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
p: "foo",
|
||||
q: function() {
|
||||
return this.p;
|
||||
}
|
||||
};
|
||||
function f() {
|
||||
return "bar";
|
||||
}
|
||||
function g(a) {
|
||||
return a ? f() : o.q();
|
||||
}
|
||||
console.log(g(0), g(1));
|
||||
}
|
||||
expect_stdout: "foo bar"
|
||||
}
|
||||
|
||||
ternary_boolean_consequent: {
|
||||
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, cascade:true, side_effects:true
|
||||
booleans: true,
|
||||
collapse_vars: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_funs: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
properties: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f1() { return a == b ? true : x; }
|
||||
@@ -635,9 +768,21 @@ ternary_boolean_consequent: {
|
||||
|
||||
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, cascade:true, side_effects:true
|
||||
booleans: true,
|
||||
collapse_vars: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_funs: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
properties: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f1() { return a == b ? x : true; }
|
||||
@@ -663,10 +808,11 @@ ternary_boolean_alternative: {
|
||||
|
||||
trivial_boolean_ternary_expressions : {
|
||||
options = {
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
evaluate : true,
|
||||
booleans : true
|
||||
};
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
f('foo' in m ? true : false);
|
||||
f('foo' in m ? false : true);
|
||||
@@ -737,11 +883,11 @@ trivial_boolean_ternary_expressions : {
|
||||
|
||||
issue_1154: {
|
||||
options = {
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
function f1(x) { return x ? -1 : -1; }
|
||||
function f2(x) { return x ? +2 : +2; }
|
||||
@@ -777,7 +923,7 @@ issue_1154: {
|
||||
no_evaluate: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
evaluate : false,
|
||||
evaluate: false,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
@@ -1115,3 +1261,320 @@ issue_2535_2: {
|
||||
"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",
|
||||
]
|
||||
}
|
||||
|
||||
hoist_decl: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
join_vars: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
if (x()) {
|
||||
var a;
|
||||
y();
|
||||
} else {
|
||||
z();
|
||||
var b;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var a, b;
|
||||
x() ? y() : z();
|
||||
}
|
||||
}
|
||||
|
||||
to_and_or: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
var values = [
|
||||
0,
|
||||
null,
|
||||
true,
|
||||
"foo",
|
||||
false,
|
||||
-1 / 0,
|
||||
void 0,
|
||||
];
|
||||
values.forEach(function(x) {
|
||||
values.forEach(function(y) {
|
||||
values.forEach(function(z) {
|
||||
console.log(x ? y || z : z);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
var values = [
|
||||
0,
|
||||
null,
|
||||
true,
|
||||
"foo",
|
||||
false,
|
||||
-1 / 0,
|
||||
void 0,
|
||||
];
|
||||
values.forEach(function(x) {
|
||||
values.forEach(function(y) {
|
||||
values.forEach(function(z) {
|
||||
console.log(x && y || z);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
cond_seq_assign_1: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
var t;
|
||||
if (a) {
|
||||
t = "foo";
|
||||
t = "bar";
|
||||
} else {
|
||||
console.log(t);
|
||||
t = 42;
|
||||
}
|
||||
console.log(t);
|
||||
}
|
||||
f(f);
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
var t;
|
||||
t = a ? (t = "foo", "bar") : (console.log(t), 42),
|
||||
console.log(t);
|
||||
}
|
||||
f(f),
|
||||
f();
|
||||
}
|
||||
expect_stdout: [
|
||||
"bar",
|
||||
"undefined",
|
||||
"42",
|
||||
]
|
||||
}
|
||||
|
||||
cond_seq_assign_2: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
var t;
|
||||
if (a) {
|
||||
t = "foo";
|
||||
a = "bar";
|
||||
} else {
|
||||
console.log(t);
|
||||
t = 42;
|
||||
}
|
||||
console.log(t);
|
||||
}
|
||||
f(f);
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
var t;
|
||||
a ? (t = "foo", a = "bar") : (console.log(t), t = 42),
|
||||
console.log(t);
|
||||
}
|
||||
f(f),
|
||||
f();
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"undefined",
|
||||
"42",
|
||||
]
|
||||
}
|
||||
|
||||
cond_seq_assign_3: {
|
||||
options = {
|
||||
assignments: true,
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
var c = 0;
|
||||
if (this)
|
||||
c = 1 + c, c = c + 1;
|
||||
else
|
||||
c = 1 + c, c = c + 1;
|
||||
console.log(c);
|
||||
}
|
||||
expect: {
|
||||
var c = 0;
|
||||
this, c = 1 + c, c += 1;
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: "2"
|
||||
}
|
||||
|
||||
issue_3271: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
var i = 0, b = [];
|
||||
if (a) {
|
||||
b[i++] = 4,
|
||||
b[i++] = 1;
|
||||
} else {
|
||||
b[i++] = 3,
|
||||
b[i++] = 2,
|
||||
b[i++] = 1;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
console.log(f(0).pop(), f(1).pop());
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
var i = 0, b = [];
|
||||
a ? b[i++] = 4 : (b[i++] = 3, b[i++] = 2),
|
||||
b[i++] = 1;
|
||||
return b;
|
||||
}
|
||||
console.log(f(0).pop(), f(1).pop());
|
||||
}
|
||||
expect_stdout: "1 1"
|
||||
}
|
||||
|
||||
iife_condition: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
if (function() {
|
||||
return console;
|
||||
}())
|
||||
console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
!function() {
|
||||
return console;
|
||||
}() || console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
angularjs_chain: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
passes: 2,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function nonComputedMember(left, right, context, create) {
|
||||
var lhs = left();
|
||||
if (create && create !== 1) {
|
||||
if (lhs && lhs[right] == null) {
|
||||
lhs[right] = {};
|
||||
}
|
||||
}
|
||||
var value = lhs != null ? lhs[right] : undefined;
|
||||
if (context) {
|
||||
return { context: lhs, name: right, value: value };
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function nonComputedMember(left, right, context, create) {
|
||||
var lhs = left();
|
||||
create && 1 !== create && lhs && null == lhs[right] && (lhs[right] = {});
|
||||
var value = null != lhs ? lhs[right] : void 0;
|
||||
return context ? {
|
||||
context: lhs,
|
||||
name: right,
|
||||
value: value
|
||||
} : value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_3576: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
var c = "FAIL";
|
||||
(function(a) {
|
||||
(a = -1) ? (a && (a.a = 0)) : (a && (a.a = 0));
|
||||
a && a[c = "PASS"]++;
|
||||
})();
|
||||
console.log(c);
|
||||
}
|
||||
expect: {
|
||||
var c = "FAIL";
|
||||
(function(a) {
|
||||
a = -1, a, a.a = 0;
|
||||
a, a[c = "PASS"]++;
|
||||
})();
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
dead_code_1: {
|
||||
options = {
|
||||
dead_code: true
|
||||
};
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
a();
|
||||
@@ -25,8 +25,8 @@ dead_code_1: {
|
||||
|
||||
dead_code_2_should_warn: {
|
||||
options = {
|
||||
dead_code: true
|
||||
};
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
g();
|
||||
@@ -62,55 +62,15 @@ dead_code_2_should_warn: {
|
||||
node_version: "<=4"
|
||||
}
|
||||
|
||||
dead_code_2_should_warn_strict: {
|
||||
options = {
|
||||
dead_code: true
|
||||
};
|
||||
input: {
|
||||
"use strict";
|
||||
function f() {
|
||||
g();
|
||||
x = 10;
|
||||
throw new Error("foo");
|
||||
// completely discarding the `if` would introduce some
|
||||
// bugs. UglifyJS v1 doesn't deal with this issue; in v2
|
||||
// we copy any declarations to the upper scope.
|
||||
if (x) {
|
||||
y();
|
||||
var x;
|
||||
function g(){};
|
||||
// but nested declarations should not be kept.
|
||||
(function(){
|
||||
var q;
|
||||
function y(){};
|
||||
})();
|
||||
}
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function f() {
|
||||
g();
|
||||
x = 10;
|
||||
throw new Error("foo");
|
||||
var x;
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
dead_code_constant_boolean_should_warn_more: {
|
||||
options = {
|
||||
dead_code : true,
|
||||
loops : true,
|
||||
booleans : true,
|
||||
conditionals : true,
|
||||
evaluate : true,
|
||||
side_effects : true,
|
||||
};
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
while (!((foo && bar) || (x + "0"))) {
|
||||
console.log("unreachable");
|
||||
@@ -137,42 +97,6 @@ dead_code_constant_boolean_should_warn_more: {
|
||||
node_version: "<=4"
|
||||
}
|
||||
|
||||
dead_code_constant_boolean_should_warn_more_strict: {
|
||||
options = {
|
||||
dead_code : true,
|
||||
loops : true,
|
||||
booleans : true,
|
||||
conditionals : true,
|
||||
evaluate : true,
|
||||
side_effects : true,
|
||||
};
|
||||
input: {
|
||||
"use strict";
|
||||
while (!((foo && bar) || (x + "0"))) {
|
||||
console.log("unreachable");
|
||||
var foo;
|
||||
function bar() {}
|
||||
}
|
||||
for (var x = 10, y; x && (y || x) && (!typeof x); ++x) {
|
||||
asdf();
|
||||
foo();
|
||||
var moo;
|
||||
}
|
||||
bar();
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var foo;
|
||||
// nothing for the while
|
||||
// as for the for, it should keep:
|
||||
var moo;
|
||||
var x = 10, y;
|
||||
bar();
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
try_catch_finally: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
@@ -417,3 +341,789 @@ global_fns: {
|
||||
"RangeError",
|
||||
]
|
||||
}
|
||||
|
||||
collapse_vars_assignment: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
dead_code: true,
|
||||
passes: 2,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f0(c) {
|
||||
var a = 3 / c;
|
||||
return a = a;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f0(c) {
|
||||
return 3 / c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
collapse_vars_lvalues_drop_assign: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
dead_code: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f0(x) { var i = ++x; return x += i; }
|
||||
function f1(x) { var a = (x -= 3); return x += a; }
|
||||
function f2(x) { var z = x, a = ++z; return z += a; }
|
||||
}
|
||||
expect: {
|
||||
function f0(x) { var i = ++x; return x + i; }
|
||||
function f1(x) { var a = (x -= 3); return x + a; }
|
||||
function f2(x) { var z = x, a = ++z; return z + a; }
|
||||
}
|
||||
}
|
||||
|
||||
collapse_vars_misc1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
dead_code: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f10(x) { var a = 5, b = 3; return a += b; }
|
||||
function f11(x) { var a = 5, b = 3; return a += --b; }
|
||||
}
|
||||
expect: {
|
||||
function f10(x) { return 5 + 3; }
|
||||
function f11(x) { var b = 3; return 5 + --b; }
|
||||
}
|
||||
}
|
||||
|
||||
return_assignment: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f1(a, b, c) {
|
||||
return a = x(), b = y(), b = a && (c >>= 5);
|
||||
}
|
||||
function f2() {
|
||||
return e = x();
|
||||
}
|
||||
function f3(e) {
|
||||
return e = x();
|
||||
}
|
||||
function f4() {
|
||||
var e;
|
||||
return e = x();
|
||||
}
|
||||
function f5(a) {
|
||||
try {
|
||||
return a = x();
|
||||
} catch (b) {
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
function f6(a) {
|
||||
try {
|
||||
return a = x();
|
||||
} finally {
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
function y() {
|
||||
console.log("y");
|
||||
}
|
||||
function test(inc) {
|
||||
var counter = 0;
|
||||
x = function() {
|
||||
counter += inc;
|
||||
if (inc < 0) throw counter;
|
||||
return counter;
|
||||
};
|
||||
[ f1, f2, f3, f4, f5, f6 ].forEach(function(f, i) {
|
||||
e = null;
|
||||
try {
|
||||
i += 1;
|
||||
console.log("result " + f(10 * i, 100 * i, 1000 * i));
|
||||
} catch (x) {
|
||||
console.log("caught " + x);
|
||||
}
|
||||
if (null !== e) console.log("e: " + e);
|
||||
});
|
||||
}
|
||||
var x, e;
|
||||
test(1);
|
||||
test(-1);
|
||||
}
|
||||
expect: {
|
||||
function f1(a, b, c) {
|
||||
return a = x(), y(), a && (c >> 5);
|
||||
}
|
||||
function f2() {
|
||||
return e = x();
|
||||
}
|
||||
function f3(e) {
|
||||
return x();
|
||||
}
|
||||
function f4() {
|
||||
return x();
|
||||
}
|
||||
function f5(a) {
|
||||
try {
|
||||
return x();
|
||||
} catch (b) {
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
function f6(a) {
|
||||
try {
|
||||
return a = x();
|
||||
} finally {
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
function y() {
|
||||
console.log("y");
|
||||
}
|
||||
function test(inc) {
|
||||
var counter = 0;
|
||||
x = function() {
|
||||
counter += inc;
|
||||
if (inc < 0) throw counter;
|
||||
return counter;
|
||||
};
|
||||
[ f1, f2, f3, f4, f5, f6 ].forEach(function(f, i) {
|
||||
e = null;
|
||||
try {
|
||||
i += 1;
|
||||
console.log("result " + f(10 * i, 100 * i, 1000 * i));
|
||||
} catch (x) {
|
||||
console.log("caught " + x);
|
||||
}
|
||||
if (null !== e) console.log("e: " + e);
|
||||
});
|
||||
}
|
||||
var x, e;
|
||||
test(1);
|
||||
test(-1);
|
||||
}
|
||||
expect_stdout: [
|
||||
"y",
|
||||
"result 31",
|
||||
"result 2",
|
||||
"e: 2",
|
||||
"result 3",
|
||||
"result 4",
|
||||
"result 5",
|
||||
"6",
|
||||
"result 6",
|
||||
"caught -1",
|
||||
"caught -2",
|
||||
"caught -3",
|
||||
"caught -4",
|
||||
"50",
|
||||
"result undefined",
|
||||
"60",
|
||||
"caught -6",
|
||||
]
|
||||
}
|
||||
|
||||
throw_assignment: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f1() {
|
||||
throw a = x();
|
||||
}
|
||||
function f2(a) {
|
||||
throw a = x();
|
||||
}
|
||||
function f3() {
|
||||
var a;
|
||||
throw a = x();
|
||||
}
|
||||
function f4() {
|
||||
try {
|
||||
throw a = x();
|
||||
} catch (b) {
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
function f5(a) {
|
||||
try {
|
||||
throw a = x();
|
||||
} catch (b) {
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
function f6() {
|
||||
var a;
|
||||
try {
|
||||
throw a = x();
|
||||
} catch (b) {
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
function f7() {
|
||||
try {
|
||||
throw a = x();
|
||||
} finally {
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
function f8(a) {
|
||||
try {
|
||||
throw a = x();
|
||||
} finally {
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
function f9() {
|
||||
var a;
|
||||
try {
|
||||
throw a = x();
|
||||
} finally {
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
function test(inc) {
|
||||
var counter = 0;
|
||||
x = function() {
|
||||
counter += inc;
|
||||
if (inc < 0) throw counter;
|
||||
return counter;
|
||||
};
|
||||
[ f1, f2, f3, f4, f5, f6, f7, f8, f9 ].forEach(function(f, i) {
|
||||
a = null;
|
||||
try {
|
||||
f(10 * (1 + i));
|
||||
} catch (x) {
|
||||
console.log("caught " + x);
|
||||
}
|
||||
if (null !== a) console.log("a: " + a);
|
||||
});
|
||||
}
|
||||
var x, a;
|
||||
test(1);
|
||||
test(-1);
|
||||
}
|
||||
expect: {
|
||||
function f1() {
|
||||
throw a = x();
|
||||
}
|
||||
function f2(a) {
|
||||
throw x();
|
||||
}
|
||||
function f3() {
|
||||
throw x();
|
||||
}
|
||||
function f4() {
|
||||
try {
|
||||
throw a = x();
|
||||
} catch (b) {
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
function f5(a) {
|
||||
try {
|
||||
throw a = x();
|
||||
} catch (b) {
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
function f6() {
|
||||
var a;
|
||||
try {
|
||||
throw a = x();
|
||||
} catch (b) {
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
function f7() {
|
||||
try {
|
||||
throw a = x();
|
||||
} finally {
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
function f8(a) {
|
||||
try {
|
||||
throw a = x();
|
||||
} finally {
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
function f9() {
|
||||
var a;
|
||||
try {
|
||||
throw a = x();
|
||||
} finally {
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
function test(inc) {
|
||||
var counter = 0;
|
||||
x = function() {
|
||||
counter += inc;
|
||||
if (inc < 0) throw counter;
|
||||
return counter;
|
||||
};
|
||||
[ f1, f2, f3, f4, f5, f6, f7, f8, f9 ].forEach(function(f, i) {
|
||||
a = null;
|
||||
try {
|
||||
f(10 * (1 + i));
|
||||
} catch (x) {
|
||||
console.log("caught " + x);
|
||||
}
|
||||
if (null !== a) console.log("a: " + a);
|
||||
});
|
||||
}
|
||||
var x, a;
|
||||
test(1);
|
||||
test(-1);
|
||||
}
|
||||
expect_stdout: [
|
||||
"caught 1",
|
||||
"a: 1",
|
||||
"caught 2",
|
||||
"caught 3",
|
||||
"4",
|
||||
"a: 4",
|
||||
"5",
|
||||
"6",
|
||||
"7",
|
||||
"caught 7",
|
||||
"a: 7",
|
||||
"8",
|
||||
"caught 8",
|
||||
"9",
|
||||
"caught 9",
|
||||
"caught -1",
|
||||
"caught -2",
|
||||
"caught -3",
|
||||
"null",
|
||||
"50",
|
||||
"undefined",
|
||||
"null",
|
||||
"caught -7",
|
||||
"80",
|
||||
"caught -8",
|
||||
"undefined",
|
||||
"caught -9",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2597: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
function f(b) {
|
||||
try {
|
||||
try {
|
||||
throw "foo";
|
||||
} catch (e) {
|
||||
return b = true;
|
||||
}
|
||||
} finally {
|
||||
b && (a = "PASS");
|
||||
}
|
||||
}
|
||||
var a = "FAIL";
|
||||
f();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
function f(b) {
|
||||
try {
|
||||
try {
|
||||
throw "foo";
|
||||
} catch (e) {
|
||||
return b = true;
|
||||
}
|
||||
} finally {
|
||||
b && (a = "PASS");
|
||||
}
|
||||
}
|
||||
var a = "FAIL";
|
||||
f();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_2666: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
return a = {
|
||||
p: function() {
|
||||
return a;
|
||||
}
|
||||
};
|
||||
}
|
||||
console.log(typeof f().p());
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
return a = {
|
||||
p: function() {
|
||||
return a;
|
||||
}
|
||||
};
|
||||
}
|
||||
console.log(typeof f().p());
|
||||
}
|
||||
expect_stdout: "object"
|
||||
}
|
||||
|
||||
issue_2692: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
reduce_vars: false,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
return a = g;
|
||||
function g() {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
console.log(typeof f()());
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
return a = g;
|
||||
function g() {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
console.log(typeof f()());
|
||||
}
|
||||
expect_stdout: "function"
|
||||
}
|
||||
|
||||
issue_2701: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
inline: false,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
return a = function() {
|
||||
return function() {
|
||||
return a;
|
||||
};
|
||||
}();
|
||||
}
|
||||
console.log(typeof f()());
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
return a = function() {
|
||||
return function() {
|
||||
return a;
|
||||
};
|
||||
}();
|
||||
}
|
||||
console.log(typeof f()());
|
||||
}
|
||||
expect_stdout: "function"
|
||||
}
|
||||
|
||||
issue_2749: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
inline: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 2, c = "PASS";
|
||||
while (a--)
|
||||
(function() {
|
||||
return b ? c = "FAIL" : b = 1;
|
||||
try {
|
||||
} catch (b) {
|
||||
var b;
|
||||
}
|
||||
})();
|
||||
console.log(c);
|
||||
}
|
||||
expect: {
|
||||
var a = 2, c = "PASS";
|
||||
while (a--)
|
||||
b = void 0, b ? c = "FAIL" : b = 1;
|
||||
var b;
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
unsafe_builtin: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
(!w).constructor(x);
|
||||
Math.abs(y);
|
||||
[ 1, 2, z ].valueOf();
|
||||
}
|
||||
expect: {
|
||||
w, x;
|
||||
y;
|
||||
z;
|
||||
}
|
||||
}
|
||||
|
||||
issue_2860_1: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a) {
|
||||
return a ^= 1;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(1);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_2860_2: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a) {
|
||||
return a ^= 1;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(1);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_2929: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a) {
|
||||
try {
|
||||
return null.p = a = 1;
|
||||
} catch (e) {
|
||||
return a ? "PASS" : "FAIL";
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a) {
|
||||
try {
|
||||
return null.p = a = 1;
|
||||
} catch (e) {
|
||||
return a ? "PASS" : "FAIL";
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
unsafe_string_replace: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
"foo".replace("f", function() {
|
||||
console.log("PASS");
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
"foo".replace("f", function() {
|
||||
console.log("PASS");
|
||||
});
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3402: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
functions: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
typeofs: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var f = function f() {
|
||||
f = 42;
|
||||
console.log(typeof f);
|
||||
};
|
||||
"function" == typeof f && f();
|
||||
"function" == typeof f && f();
|
||||
console.log(typeof f);
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
console.log(typeof f);
|
||||
}
|
||||
f();
|
||||
f();
|
||||
console.log(typeof f);
|
||||
}
|
||||
expect_stdout: [
|
||||
"function",
|
||||
"function",
|
||||
"function",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3406: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function f(a) {
|
||||
return delete (f = a);
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function f(a) {
|
||||
return delete (0, a);
|
||||
}());
|
||||
}
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
function_assign: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
var a = "PASS";
|
||||
function h(c) {
|
||||
return c;
|
||||
}
|
||||
h.p = function(b) {
|
||||
return b;
|
||||
}.p = a;
|
||||
return h;
|
||||
}().p);
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
var a = "PASS";
|
||||
function h(c) {
|
||||
return c;
|
||||
}
|
||||
h.p = a;
|
||||
return h;
|
||||
}().p);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3552: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
pure_getters: "strict",
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
(function() {
|
||||
(1..p += 42) && (a = "FAIL");
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
(function() {
|
||||
(1..p += 42) && (a = "FAIL");
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
unreachable_assign: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
console.log(A = "P" + (A = "A" + (B = "S" + (A = B = "S"))), A, B);
|
||||
}
|
||||
expect: {
|
||||
console.log(A = "P" + "A" + (B = "S" + "S"), A, B);
|
||||
}
|
||||
expect_stdout: "PASS PASS SS"
|
||||
}
|
||||
|
||||
catch_return_assign: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
try {
|
||||
throw "FAIL";
|
||||
} catch (e) {
|
||||
return e = "PASS";
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
try {
|
||||
throw "FAIL";
|
||||
} catch (e) {
|
||||
return "PASS";
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3578: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL", b, c;
|
||||
try {
|
||||
b = c.p = b = 0;
|
||||
} catch (e) {
|
||||
b += 42;
|
||||
b && (a = "PASS");
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "FAIL", b, c;
|
||||
try {
|
||||
b = c.p = b = 0;
|
||||
} catch (e) {
|
||||
b += 42;
|
||||
b && (a = "PASS");
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
keep_debugger: {
|
||||
options = {
|
||||
drop_debugger: false
|
||||
};
|
||||
drop_debugger: false,
|
||||
}
|
||||
input: {
|
||||
debugger;
|
||||
}
|
||||
@@ -12,8 +12,8 @@ keep_debugger: {
|
||||
|
||||
drop_debugger: {
|
||||
options = {
|
||||
drop_debugger: true
|
||||
};
|
||||
drop_debugger: true,
|
||||
}
|
||||
input: {
|
||||
debugger;
|
||||
if (foo) debugger;
|
||||
|
||||
133
test/compress/directives.js
Normal file
133
test/compress/directives.js
Normal file
@@ -0,0 +1,133 @@
|
||||
simple_statement_is_not_a_directive: {
|
||||
input: {
|
||||
"use strict"
|
||||
.split(" ")
|
||||
.forEach(function(s) {
|
||||
console.log(s);
|
||||
});
|
||||
console.log(!this); // is strict mode?
|
||||
(function() {
|
||||
"directive"
|
||||
""
|
||||
"use strict"
|
||||
"hello world"
|
||||
.split(" ")
|
||||
.forEach(function(s) {
|
||||
console.log(s);
|
||||
});
|
||||
console.log(!this); // is strict mode?
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
"use strict".split(" ").forEach(function(s) {
|
||||
console.log(s);
|
||||
});
|
||||
console.log(!this);
|
||||
(function() {
|
||||
"directive";
|
||||
"";
|
||||
"use strict";
|
||||
"hello world".split(" ").forEach(function(s) {
|
||||
console.log(s);
|
||||
});
|
||||
console.log(!this);
|
||||
})();
|
||||
}
|
||||
expect_stdout: [
|
||||
"use",
|
||||
"strict",
|
||||
"false",
|
||||
"hello",
|
||||
"world",
|
||||
"true",
|
||||
]
|
||||
}
|
||||
|
||||
drop_lone_use_strict: {
|
||||
options = {
|
||||
directives: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function f1() {
|
||||
"use strict";
|
||||
}
|
||||
function f2() {
|
||||
"use strict";
|
||||
function f3() {
|
||||
"use strict";
|
||||
}
|
||||
}
|
||||
(function f4() {
|
||||
"use strict";
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
function f1() {
|
||||
}
|
||||
function f2() {
|
||||
"use strict";
|
||||
function f3() {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_3166: {
|
||||
options = {
|
||||
directives: true,
|
||||
}
|
||||
input: {
|
||||
"foo";
|
||||
"use strict";
|
||||
function f() {
|
||||
"use strict";
|
||||
"bar";
|
||||
"use asm";
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function f() {
|
||||
"use asm";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
valid_after_invalid_1: {
|
||||
input: {
|
||||
console.log(typeof function() {
|
||||
"use\x20strict";
|
||||
"use strict";
|
||||
return this;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(typeof function() {
|
||||
"use\x20strict";
|
||||
"use strict";
|
||||
return this;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
valid_after_invalid_2: {
|
||||
options = {
|
||||
directives: true,
|
||||
}
|
||||
input: {
|
||||
console.log(typeof function() {
|
||||
"use\x20strict";
|
||||
"use strict";
|
||||
return this;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(typeof function() {
|
||||
"use strict";
|
||||
return this;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
drop_console_1: {
|
||||
options = {};
|
||||
options = {}
|
||||
input: {
|
||||
console.log('foo');
|
||||
console.log.apply(console, arguments);
|
||||
@@ -11,7 +11,9 @@ drop_console_1: {
|
||||
}
|
||||
|
||||
drop_console_2: {
|
||||
options = { drop_console: true };
|
||||
options = {
|
||||
drop_console: true,
|
||||
}
|
||||
input: {
|
||||
console.log('foo');
|
||||
console.log.apply(console, arguments);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@ must_replace: {
|
||||
options = {
|
||||
global_defs: {
|
||||
D: "foo bar",
|
||||
}
|
||||
},
|
||||
}
|
||||
input: {
|
||||
console.log(D);
|
||||
@@ -141,9 +141,8 @@ mixed: {
|
||||
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]',
|
||||
"WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:4,22]",
|
||||
"WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:7,8]",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -197,3 +196,23 @@ issue_2167: {
|
||||
doWork();
|
||||
}
|
||||
}
|
||||
|
||||
issue_3217: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
global_defs: {
|
||||
"@o": "{fn:function(){var a=42;console.log(a)}}",
|
||||
},
|
||||
inline: true,
|
||||
properties: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
o.fn();
|
||||
}
|
||||
expect: {
|
||||
console.log(42);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
issue_2377_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
hoist_props: true,
|
||||
inline: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
@@ -33,8 +33,8 @@ issue_2377_1: {
|
||||
issue_2377_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
hoist_props: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
@@ -55,9 +55,8 @@ issue_2377_2: {
|
||||
console.log(obj.foo, obj.cube(3));
|
||||
}
|
||||
expect: {
|
||||
console.log(1, function(x) {
|
||||
return x * x * x;
|
||||
}(3));
|
||||
console.log(1, (x = 3, x * x * x));
|
||||
var x;
|
||||
}
|
||||
expect_stdout: "1 27"
|
||||
}
|
||||
@@ -65,11 +64,12 @@ issue_2377_2: {
|
||||
issue_2377_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
hoist_props: true,
|
||||
passes: 3,
|
||||
inline: true,
|
||||
passes: 4,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
@@ -239,14 +239,14 @@ name_collision_2: {
|
||||
input: {
|
||||
var o = {
|
||||
p: 1,
|
||||
0: function(x) {
|
||||
"+": function(x) {
|
||||
return x;
|
||||
},
|
||||
1: function(x) {
|
||||
"-": 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);
|
||||
console.log(o.p === o.p, o["+"](4), o["-"](5), o__$0, o__$1);
|
||||
}
|
||||
expect: {
|
||||
var o_p = 1,
|
||||
@@ -273,14 +273,14 @@ name_collision_3: {
|
||||
input: {
|
||||
var o = {
|
||||
p: 1,
|
||||
0: function(x) {
|
||||
"+": function(x) {
|
||||
return x;
|
||||
},
|
||||
1: function(x) {
|
||||
"-": function(x) {
|
||||
return x + 1;
|
||||
}
|
||||
}, o__$0 = 2, o__$1 = 3;
|
||||
console.log(o.p === o.p, o[0](4), o[1](5));
|
||||
console.log(o.p === o.p, o["+"](4), o["-"](5));
|
||||
}
|
||||
expect: {
|
||||
var o_p = 1,
|
||||
@@ -416,7 +416,10 @@ issue_2473_1: {
|
||||
options = {
|
||||
hoist_props: false,
|
||||
reduce_vars: true,
|
||||
top_retain: [ "x", "y" ],
|
||||
top_retain: [
|
||||
"x",
|
||||
"y"
|
||||
],
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
@@ -435,7 +438,10 @@ issue_2473_2: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
top_retain: [ "x", "y" ],
|
||||
top_retain: [
|
||||
"x",
|
||||
"y"
|
||||
],
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
@@ -664,3 +670,247 @@ issue_2519: {
|
||||
}
|
||||
expect_stdout: "5.5"
|
||||
}
|
||||
|
||||
undefined_key: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_props: true,
|
||||
join_vars: true,
|
||||
passes: 4,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a, o = {};
|
||||
o[a] = 1;
|
||||
o.b = 2;
|
||||
console.log(o[a] + o.b);
|
||||
}
|
||||
expect: {
|
||||
console.log(3);
|
||||
}
|
||||
expect_stdout: "3"
|
||||
}
|
||||
|
||||
issue_3021: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
var a = 1, b = 2;
|
||||
(function() {
|
||||
b = a;
|
||||
if (a++ + b--)
|
||||
return 1;
|
||||
return;
|
||||
var b = {};
|
||||
})();
|
||||
console.log(a, b);
|
||||
}
|
||||
expect: {
|
||||
var a = 1, b = 2;
|
||||
(function() {
|
||||
b = a;
|
||||
if (a++ + b--)
|
||||
return 1;
|
||||
return;
|
||||
var b = {};
|
||||
})();
|
||||
console.log(a, b);
|
||||
}
|
||||
expect_stdout: "2 2"
|
||||
}
|
||||
|
||||
issue_3046: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a) {
|
||||
do {
|
||||
var b = {
|
||||
c: a++
|
||||
};
|
||||
} while (b.c && a);
|
||||
return a;
|
||||
}(0));
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a) {
|
||||
do {
|
||||
var b_c = a++;
|
||||
} while (b_c && a);
|
||||
return a;
|
||||
}(0));
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_3071_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_props: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
passes: 3,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
var obj = {};
|
||||
obj.one = 1;
|
||||
obj.two = 2;
|
||||
console.log(obj.one);
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
console.log(1);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_3071_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_props: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
passes: 3,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
obj = {};
|
||||
obj.one = 1;
|
||||
obj.two = 2;
|
||||
console.log(obj.one);
|
||||
var obj;
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
console.log(1);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_3071_2_toplevel: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_props: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
passes: 3,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
obj = {};
|
||||
obj.one = 1;
|
||||
obj.two = 2;
|
||||
console.log(obj.one);
|
||||
var obj;
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
console.log(1);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_3071_3: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
var c = 0;
|
||||
(function(a, b) {
|
||||
(function f(o) {
|
||||
var n = 2;
|
||||
while (--b + (o = {
|
||||
p: c++,
|
||||
}) && --n > 0);
|
||||
})();
|
||||
})();
|
||||
console.log(c);
|
||||
}
|
||||
expect: {
|
||||
var c = 0;
|
||||
(function(a, b) {
|
||||
(function f(o) {
|
||||
var n = 2;
|
||||
while (--b + (o = {
|
||||
p: c++,
|
||||
}) && --n > 0);
|
||||
})();
|
||||
})();
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: "2"
|
||||
}
|
||||
|
||||
issue_3411: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
var c = 1;
|
||||
!function f() {
|
||||
var o = {
|
||||
p: --c && f()
|
||||
};
|
||||
+o || console.log("PASS");
|
||||
}();
|
||||
}
|
||||
expect: {
|
||||
var c = 1;
|
||||
!function f() {
|
||||
var o_p = --c && f();
|
||||
+{} || console.log("PASS");
|
||||
}();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3440: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
function f() {
|
||||
console.log(o.p);
|
||||
}
|
||||
var o = {
|
||||
p: "PASS",
|
||||
};
|
||||
return f;
|
||||
})()();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
var o_p = "PASS";
|
||||
return function() {
|
||||
console.log(o_p);
|
||||
};
|
||||
})()();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -1,55 +1,107 @@
|
||||
html_comment_in_expression: {
|
||||
input: {
|
||||
function f(a, b, x, y) { return a < !--b && x-- > y; }
|
||||
(function(a, b) {
|
||||
console.log(a < !--b && a-- > b, a, b);
|
||||
})(1, 2);
|
||||
}
|
||||
expect_exact: "function f(a,b,x,y){return a< !--b&&x-- >y}";
|
||||
expect_exact: "(function(a,b){console.log(a<! --b&&a-- >b,a,b)})(1,2);"
|
||||
expect_stdout: "false 1 1"
|
||||
}
|
||||
|
||||
html_comment_in_less_than: {
|
||||
input: {
|
||||
function f(a, b) { return a < !--b; }
|
||||
(function(a, b, c) {
|
||||
console.log(
|
||||
a < !--b,
|
||||
a < !--b + c,
|
||||
a + b < !--c,
|
||||
a, b, c
|
||||
);
|
||||
})(1, 2, 3);
|
||||
}
|
||||
expect_exact: "function f(a,b){return a< !--b}";
|
||||
expect_exact: "(function(a,b,c){console.log(a<! --b,a<! --b+c,a+b<! --c,a,b,c)})(1,2,3);"
|
||||
expect_stdout: "false true false 1 0 2"
|
||||
}
|
||||
|
||||
html_comment_in_left_shift: {
|
||||
input: {
|
||||
function f(a, b) { return a << !--b; }
|
||||
(function(a, b, c) {
|
||||
console.log(
|
||||
a << !--b,
|
||||
a << !--b + c,
|
||||
a + b << !--c,
|
||||
a, b, c
|
||||
);
|
||||
})(1, 2, 3);
|
||||
}
|
||||
expect_exact: "function f(a,b){return a<< !--b}";
|
||||
}
|
||||
|
||||
html_comment_in_right_shift: {
|
||||
input: {
|
||||
function f(a, b) { return a-- >> b; }
|
||||
}
|
||||
expect_exact: "function f(a,b){return a-- >>b}";
|
||||
}
|
||||
|
||||
html_comment_in_zero_fill_right_shift: {
|
||||
input: {
|
||||
function f(a, b) { return a-- >>> b; }
|
||||
}
|
||||
expect_exact: "function f(a,b){return a-- >>>b}";
|
||||
expect_exact: "(function(a,b,c){console.log(a<<! --b,a<<! --b+c,a+b<<! --c,a,b,c)})(1,2,3);"
|
||||
expect_stdout: "1 16 1 1 0 2"
|
||||
}
|
||||
|
||||
html_comment_in_greater_than: {
|
||||
input: {
|
||||
function f(a, b) { return a-- > b; }
|
||||
(function(a, b, c) {
|
||||
console.log(
|
||||
a-- > b,
|
||||
a-- > b + c,
|
||||
a + b-- > c,
|
||||
a, b, c
|
||||
);
|
||||
})(1, 2, 3);
|
||||
}
|
||||
expect_exact: "function f(a,b){return a-- >b}";
|
||||
expect_exact: "(function(a,b,c){console.log(a-- >b,a-- >b+c,a+b-- >c,a,b,c)})(1,2,3);"
|
||||
expect_stdout: "false false false -1 1 3"
|
||||
}
|
||||
|
||||
html_comment_in_greater_than_or_equal: {
|
||||
input: {
|
||||
function f(a, b) { return a-- >= b; }
|
||||
(function(a, b, c) {
|
||||
console.log(
|
||||
a-- >= b,
|
||||
a-- >= b + c,
|
||||
a + b-- >= c,
|
||||
a, b, c
|
||||
);
|
||||
})(1, 2, 3);
|
||||
}
|
||||
expect_exact: "function f(a,b){return a-- >=b}";
|
||||
expect_exact: "(function(a,b,c){console.log(a-- >=b,a-- >=b+c,a+b-- >=c,a,b,c)})(1,2,3);"
|
||||
expect_stdout: "false false false -1 1 3"
|
||||
}
|
||||
|
||||
html_comment_in_right_shift: {
|
||||
input: {
|
||||
(function(a, b, c) {
|
||||
console.log(
|
||||
a-- >> b,
|
||||
a-- >> b + c,
|
||||
a + b-- >> c,
|
||||
a, b, c
|
||||
);
|
||||
})(1, 2, 3);
|
||||
}
|
||||
expect_exact: "(function(a,b,c){console.log(a-- >>b,a-- >>b+c,a+b-- >>c,a,b,c)})(1,2,3);"
|
||||
expect_stdout: "0 0 0 -1 1 3"
|
||||
}
|
||||
|
||||
html_comment_in_zero_fill_right_shift: {
|
||||
input: {
|
||||
(function(a, b, c) {
|
||||
console.log(
|
||||
a-- >>> b,
|
||||
a-- >>> b + c,
|
||||
a + b-- >>> c,
|
||||
a, b, c
|
||||
);
|
||||
})(1, 2, 3);
|
||||
}
|
||||
expect_exact: "(function(a,b,c){console.log(a-- >>>b,a-- >>>b+c,a+b-- >>>c,a,b,c)})(1,2,3);"
|
||||
expect_stdout: "0 0 0 -1 1 3"
|
||||
}
|
||||
|
||||
html_comment_in_string_literal: {
|
||||
input: {
|
||||
function f() { return "<!--HTML-->comment in<!--string literal-->"; }
|
||||
console.log("<!--HTML-->comment in<!--string literal-->".length);
|
||||
}
|
||||
expect_exact: 'function f(){return"\\x3c!--HTML--\\x3ecomment in\\x3c!--string literal--\\x3e"}';
|
||||
expect_exact: 'console.log("\\x3c!--HTML--\\x3ecomment in\\x3c!--string literal--\\x3e".length);'
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
2363
test/compress/ie8.js
Normal file
2363
test/compress/ie8.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,14 +1,14 @@
|
||||
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,
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(x) {
|
||||
@@ -24,15 +24,15 @@ if_return_1: {
|
||||
|
||||
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,
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(x, y) {
|
||||
@@ -49,15 +49,15 @@ if_return_2: {
|
||||
|
||||
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,
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(x) {
|
||||
@@ -75,15 +75,15 @@ if_return_3: {
|
||||
|
||||
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,
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(x, y) {
|
||||
@@ -100,15 +100,15 @@ if_return_4: {
|
||||
|
||||
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,
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
@@ -126,15 +126,15 @@ if_return_5: {
|
||||
|
||||
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,
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(x) {
|
||||
@@ -150,15 +150,15 @@ if_return_6: {
|
||||
|
||||
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,
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(x) {
|
||||
@@ -176,10 +176,10 @@ if_return_7: {
|
||||
|
||||
if_return_8: {
|
||||
options = {
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
conditionals: true,
|
||||
side_effects : true,
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function f(e) {
|
||||
@@ -220,15 +220,15 @@ if_return_8: {
|
||||
|
||||
issue_1089: {
|
||||
options = {
|
||||
if_return : true,
|
||||
sequences : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
side_effects : true,
|
||||
dead_code : true,
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function x() {
|
||||
@@ -243,7 +243,7 @@ issue_1089: {
|
||||
expect: {
|
||||
function x() {
|
||||
var f = document.getElementById("fname");
|
||||
if (f.files[0].size > 12345)
|
||||
if (12345 < f.files[0].size)
|
||||
return alert("alert"), f.focus(), !1;
|
||||
}
|
||||
}
|
||||
@@ -251,9 +251,9 @@ issue_1089: {
|
||||
|
||||
issue_1437: {
|
||||
options = {
|
||||
if_return : true,
|
||||
sequences : true,
|
||||
conditionals : false
|
||||
conditionals: false,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
function x() {
|
||||
@@ -281,9 +281,9 @@ issue_1437: {
|
||||
|
||||
issue_1437_conditionals: {
|
||||
options = {
|
||||
conditionals : true,
|
||||
if_return : true,
|
||||
sequences : true
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
function x() {
|
||||
@@ -326,3 +326,250 @@ issue_512: {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if_var_return: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
var a;
|
||||
return;
|
||||
var b;
|
||||
}
|
||||
function g() {
|
||||
var a;
|
||||
if (u()) {
|
||||
var b;
|
||||
return v();
|
||||
var c;
|
||||
}
|
||||
var d;
|
||||
if (w()) {
|
||||
var e;
|
||||
return x();
|
||||
var f;
|
||||
} else {
|
||||
var g;
|
||||
y();
|
||||
var h;
|
||||
}
|
||||
var i;
|
||||
z();
|
||||
var j;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
var a, b;
|
||||
}
|
||||
function g() {
|
||||
var a, b, c, d, e, f, g, h, i, j;
|
||||
return u() ? v() : w() ? x() : (y(), z(), void 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if_if_return_return: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b) {
|
||||
if (a) {
|
||||
if (b)
|
||||
return b;
|
||||
return;
|
||||
}
|
||||
g();
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(a, b) {
|
||||
if (a)
|
||||
return b || void 0;
|
||||
g();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if_body_return_1: {
|
||||
options = {
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
var c = "PASS";
|
||||
function f(a, b) {
|
||||
if (a) {
|
||||
if (b) throw new Error(c);
|
||||
return 42;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
console.log(f(0, 0));
|
||||
console.log(f(0, 1));
|
||||
console.log(f(1, 0));
|
||||
try {
|
||||
f(1, 1);
|
||||
console.log("FAIL");
|
||||
} catch (e) {
|
||||
console.log(e.message);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var c = "PASS";
|
||||
function f(a, b) {
|
||||
if (a) {
|
||||
if (b) throw new Error(c);
|
||||
return 42;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
console.log(f(0, 0));
|
||||
console.log(f(0, 1));
|
||||
console.log(f(1, 0));
|
||||
try {
|
||||
f(1, 1);
|
||||
console.log("FAIL");
|
||||
} catch (e) {
|
||||
console.log(e.message);
|
||||
}
|
||||
}
|
||||
expect_stdout: [
|
||||
"true",
|
||||
"true",
|
||||
"42",
|
||||
"PASS",
|
||||
]
|
||||
}
|
||||
|
||||
if_body_return_2: {
|
||||
options = {
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
var c = "PASS";
|
||||
function f(a, b) {
|
||||
if (0 + a) {
|
||||
if (b) throw new Error(c);
|
||||
return 42;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
console.log(f(0, 0));
|
||||
console.log(f(0, 1));
|
||||
console.log(f(1, 0));
|
||||
try {
|
||||
f(1, 1);
|
||||
console.log("FAIL");
|
||||
} catch (e) {
|
||||
console.log(e.message);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var c = "PASS";
|
||||
function f(a, b) {
|
||||
if (0 + a) {
|
||||
if (b) throw new Error(c);
|
||||
return 42;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
console.log(f(0, 0));
|
||||
console.log(f(0, 1));
|
||||
console.log(f(1, 0));
|
||||
try {
|
||||
f(1, 1);
|
||||
console.log("FAIL");
|
||||
} catch (e) {
|
||||
console.log(e.message);
|
||||
}
|
||||
}
|
||||
expect_stdout: [
|
||||
"true",
|
||||
"true",
|
||||
"42",
|
||||
"PASS",
|
||||
]
|
||||
}
|
||||
|
||||
if_body_return_3: {
|
||||
options = {
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
var c = "PASS";
|
||||
function f(a, b) {
|
||||
if (1 == a) {
|
||||
if (b) throw new Error(c);
|
||||
return 42;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
console.log(f(0, 0));
|
||||
console.log(f(0, 1));
|
||||
console.log(f(1, 0));
|
||||
try {
|
||||
f(1, 1);
|
||||
console.log("FAIL");
|
||||
} catch (e) {
|
||||
console.log(e.message);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var c = "PASS";
|
||||
function f(a, b) {
|
||||
if (1 != a) return true;
|
||||
if (b) throw new Error(c);
|
||||
return 42;
|
||||
}
|
||||
console.log(f(0, 0));
|
||||
console.log(f(0, 1));
|
||||
console.log(f(1, 0));
|
||||
try {
|
||||
f(1, 1);
|
||||
console.log("FAIL");
|
||||
} catch (e) {
|
||||
console.log(e.message);
|
||||
}
|
||||
}
|
||||
expect_stdout: [
|
||||
"true",
|
||||
"true",
|
||||
"42",
|
||||
"PASS",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3600: {
|
||||
options = {
|
||||
if_return: true,
|
||||
inline: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var c = 0;
|
||||
(function() {
|
||||
if ([ ][c++]); else return;
|
||||
return void function() {
|
||||
var b = --b, a = c = 42;
|
||||
return c;
|
||||
}();
|
||||
})();
|
||||
console.log(c);
|
||||
}
|
||||
expect: {
|
||||
var c = 0;
|
||||
(function() {
|
||||
if ([][c++]) b = --b, c = 42;
|
||||
var b;
|
||||
})();
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
@@ -1,8 +1,17 @@
|
||||
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, cascade: true, side_effects: true
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_funs: false,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function foo(x) {
|
||||
@@ -21,25 +30,35 @@ non_hoisted_function_after_return: {
|
||||
}
|
||||
expect: {
|
||||
function foo(x) {
|
||||
return x ? bar() : baz();
|
||||
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]"
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:4,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:7,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:10,12]",
|
||||
"WARN: Dropping unused function UnusedFunction [test/compress/issue-1034.js:11,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, cascade: true, side_effects: true,
|
||||
collapse_vars: false, passes: 2, warnings: "verbose"
|
||||
booleans: true,
|
||||
collapse_vars: false,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_funs: false,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
passes: 2,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function foo(x) {
|
||||
@@ -65,28 +84,37 @@ non_hoisted_function_after_return_2a: {
|
||||
}
|
||||
}
|
||||
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",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:4,16]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:4,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:7,16]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:7,16]",
|
||||
"WARN: Dropping unused variable a [test/compress/issue-1034.js:4,20]",
|
||||
"WARN: Dropping unused function nope [test/compress/issue-1034.js:11,21]",
|
||||
"INFO: pass 0: last_count: Infinity, count: 37",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:9,12]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:9,12]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:12,12]",
|
||||
"INFO: Dropping unused variable b [test/compress/issue-1034.js:7,20]",
|
||||
"INFO: Dropping unused variable c [test/compress/issue-1034.js:9,16]",
|
||||
"INFO: pass 1: last_count: 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, cascade: true, side_effects: true,
|
||||
collapse_vars: false
|
||||
booleans: true,
|
||||
collapse_vars: false,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_funs: false,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function foo(x) {
|
||||
@@ -110,20 +138,28 @@ non_hoisted_function_after_return_2b: {
|
||||
}
|
||||
}
|
||||
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]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:6,16]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:6,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:8,12]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:8,12]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:12,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, cascade: true, side_effects: true
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_funs: false,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
@@ -145,7 +181,7 @@ non_hoisted_function_after_return_strict: {
|
||||
expect: {
|
||||
"use strict";
|
||||
function foo(x) {
|
||||
return x ? bar() : baz();
|
||||
return (x ? bar : baz)();
|
||||
function bar() { return 7 }
|
||||
function baz() { return 8 }
|
||||
}
|
||||
@@ -153,19 +189,29 @@ non_hoisted_function_after_return_strict: {
|
||||
}
|
||||
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]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:5,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:8,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:11,12]",
|
||||
"WARN: Dropping unused function UnusedFunction [test/compress/issue-1034.js:12,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, cascade: true, side_effects: true,
|
||||
collapse_vars: false, passes: 2, warnings: "verbose"
|
||||
booleans: true,
|
||||
collapse_vars: false,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_funs: false,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
passes: 2,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
@@ -196,28 +242,37 @@ non_hoisted_function_after_return_2a_strict: {
|
||||
}
|
||||
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",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:5,16]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:5,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:8,16]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:8,16]",
|
||||
"WARN: Dropping unused variable a [test/compress/issue-1034.js:5,20]",
|
||||
"WARN: Dropping unused function nope [test/compress/issue-1034.js:12,21]",
|
||||
"INFO: pass 0: last_count: Infinity, count: 48",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:10,12]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:10,12]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:13,12]",
|
||||
"INFO: Dropping unused variable b [test/compress/issue-1034.js:8,20]",
|
||||
"INFO: Dropping unused variable c [test/compress/issue-1034.js:10,16]",
|
||||
"INFO: pass 1: last_count: 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, cascade: true, side_effects: true,
|
||||
collapse_vars: false
|
||||
booleans: true,
|
||||
collapse_vars: false,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_funs: false,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
@@ -246,11 +301,10 @@ non_hoisted_function_after_return_2b_strict: {
|
||||
}
|
||||
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]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:7,16]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:7,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:9,12]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:9,12]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:13,12]",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ const_pragma: {
|
||||
evaluate: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
};
|
||||
}
|
||||
|
||||
input: {
|
||||
/** @const */ var goog = goog || {};
|
||||
@@ -19,7 +19,7 @@ not_const: {
|
||||
evaluate: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
};
|
||||
}
|
||||
|
||||
input: {
|
||||
var goog = goog || {};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
with_in_global_scope: {
|
||||
options = {
|
||||
unused: true
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = 42;
|
||||
@@ -18,7 +18,7 @@ with_in_global_scope: {
|
||||
}
|
||||
with_in_function_scope: {
|
||||
options = {
|
||||
unused: true
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function foo() {
|
||||
@@ -40,7 +40,7 @@ with_in_function_scope: {
|
||||
}
|
||||
compress_with_with_in_other_scope: {
|
||||
options = {
|
||||
unused: true
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function foo() {
|
||||
@@ -69,7 +69,7 @@ compress_with_with_in_other_scope: {
|
||||
}
|
||||
with_using_existing_variable_outside_scope: {
|
||||
options = {
|
||||
unused: true
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
@@ -99,7 +99,7 @@ with_using_existing_variable_outside_scope: {
|
||||
}
|
||||
check_drop_unused_in_peer_function: {
|
||||
options = {
|
||||
unused: true
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function outer() {
|
||||
@@ -148,7 +148,7 @@ check_drop_unused_in_peer_function: {
|
||||
|
||||
Infinity_not_in_with_scope: {
|
||||
options = {
|
||||
unused: true
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = { Infinity: 'oInfinity' };
|
||||
@@ -164,7 +164,7 @@ Infinity_not_in_with_scope: {
|
||||
|
||||
Infinity_in_with_scope: {
|
||||
options = {
|
||||
unused: true
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = { Infinity: 'oInfinity' };
|
||||
@@ -180,20 +180,19 @@ Infinity_in_with_scope: {
|
||||
|
||||
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,
|
||||
cascade: true,
|
||||
side_effects: true,
|
||||
sequences: false,
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_funs: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
keep_infinity: false,
|
||||
sequences: false,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var f = console.log;
|
||||
@@ -243,20 +242,19 @@ assorted_Infinity_NaN_undefined_in_with_scope: {
|
||||
|
||||
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,
|
||||
cascade: true,
|
||||
side_effects: true,
|
||||
sequences: false,
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_funs: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
keep_infinity: true,
|
||||
sequences: false,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var f = console.log;
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
keep_name_of_getter: {
|
||||
options = { unused: true };
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: { a = { get foo () {} } }
|
||||
expect: { a = { get foo () {} } }
|
||||
}
|
||||
|
||||
keep_name_of_setter: {
|
||||
options = { unused: true };
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: { a = { set foo () {} } }
|
||||
expect: { a = { set foo () {} } }
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
mangle_keep_fnames_false: {
|
||||
options = {
|
||||
keep_fnames : true,
|
||||
keep_fargs : true,
|
||||
keep_fargs: true,
|
||||
keep_fnames: true,
|
||||
}
|
||||
mangle = {
|
||||
keep_fnames : false,
|
||||
@@ -26,8 +26,8 @@ mangle_keep_fnames_false: {
|
||||
|
||||
mangle_keep_fnames_true: {
|
||||
options = {
|
||||
keep_fnames : true,
|
||||
keep_fargs : true,
|
||||
keep_fargs: true,
|
||||
keep_fnames: true,
|
||||
}
|
||||
mangle = {
|
||||
keep_fnames : true,
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
pure_function_calls: {
|
||||
options = {
|
||||
evaluate : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
side_effects : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
if_return : true,
|
||||
join_vars : true,
|
||||
cascade : true,
|
||||
negate_iife : true,
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
negate_iife: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
// pure top-level IIFE will be dropped
|
||||
@@ -49,29 +48,28 @@ pure_function_calls: {
|
||||
a.b(), f.g();
|
||||
}
|
||||
expect_warnings: [
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:17,8]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:17,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:30,37]",
|
||||
"WARN: Dropping unused variable iife2 [test/compress/issue-1261.js:30,16]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:28,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:38,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:39,31]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:3,8]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:3,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:16,37]",
|
||||
"WARN: Dropping unused variable iife2 [test/compress/issue-1261.js:16,16]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:14,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:24,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:25,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,
|
||||
cascade : true,
|
||||
negate_iife : true,
|
||||
toplevel : true,
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
negate_iife: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
// pure top-level IIFE will be dropped
|
||||
@@ -112,17 +110,17 @@ pure_function_calls_toplevel: {
|
||||
a.b(), f.g();
|
||||
}
|
||||
expect_warnings: [
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:79,8]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:79,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:92,37]",
|
||||
"WARN: Dropping unused variable iife2 [test/compress/issue-1261.js:92,16]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:90,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:107,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:108,31]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:84,33]",
|
||||
"WARN: Dropping unused variable iife1 [test/compress/issue-1261.js:84,12]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:100,45]",
|
||||
"WARN: Dropping unused variable MyClass [test/compress/issue-1261.js:100,12]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:3,8]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:3,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:16,37]",
|
||||
"WARN: Dropping unused variable iife2 [test/compress/issue-1261.js:16,16]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:14,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:31,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:32,31]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:8,33]",
|
||||
"WARN: Dropping unused variable iife1 [test/compress/issue-1261.js:8,12]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:24,45]",
|
||||
"WARN: Dropping unused variable MyClass [test/compress/issue-1261.js:24,12]",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -157,29 +155,29 @@ should_warn: {
|
||||
baz();
|
||||
}
|
||||
expect_warnings: [
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:137,61]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:137,23]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:137,23]",
|
||||
"WARN: Boolean || always true [test/compress/issue-1261.js:138,23]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:138,23]",
|
||||
"WARN: Condition always true [test/compress/issue-1261.js:138,23]",
|
||||
"WARN: Condition left of || always true [test/compress/issue-1261.js:139,8]",
|
||||
"WARN: Condition always true [test/compress/issue-1261.js:139,8]",
|
||||
"WARN: Boolean && always false [test/compress/issue-1261.js:140,23]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:140,23]",
|
||||
"WARN: Condition always false [test/compress/issue-1261.js:140,23]",
|
||||
"WARN: Condition left of && always false [test/compress/issue-1261.js:141,8]",
|
||||
"WARN: Condition always false [test/compress/issue-1261.js:141,8]",
|
||||
"WARN: + in boolean context always true [test/compress/issue-1261.js:142,23]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:142,23]",
|
||||
"WARN: Condition always true [test/compress/issue-1261.js:142,23]",
|
||||
"WARN: + in boolean context always true [test/compress/issue-1261.js:143,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:143,31]",
|
||||
"WARN: Condition always true [test/compress/issue-1261.js:143,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:144,23]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:145,24]",
|
||||
"WARN: Condition always true [test/compress/issue-1261.js:145,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:146,31]",
|
||||
"WARN: Condition always false [test/compress/issue-1261.js:146,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:1,61]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:1,23]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:1,23]",
|
||||
"WARN: Boolean || always true [test/compress/issue-1261.js:2,23]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:2,23]",
|
||||
"WARN: Condition always true [test/compress/issue-1261.js:2,23]",
|
||||
"WARN: Condition left of || always true [test/compress/issue-1261.js:3,8]",
|
||||
"WARN: Condition always true [test/compress/issue-1261.js:3,8]",
|
||||
"WARN: Boolean && always false [test/compress/issue-1261.js:4,23]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:4,23]",
|
||||
"WARN: Condition always false [test/compress/issue-1261.js:4,23]",
|
||||
"WARN: Condition left of && always false [test/compress/issue-1261.js:5,8]",
|
||||
"WARN: Condition always false [test/compress/issue-1261.js:5,8]",
|
||||
"WARN: + in boolean context always true [test/compress/issue-1261.js:6,23]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:6,23]",
|
||||
"WARN: Condition always true [test/compress/issue-1261.js:6,23]",
|
||||
"WARN: + in boolean context always true [test/compress/issue-1261.js:7,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:7,31]",
|
||||
"WARN: Condition always true [test/compress/issue-1261.js:7,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:8,23]",
|
||||
"WARN: Condition always true [test/compress/issue-1261.js:9,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:9,24]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:10,31]",
|
||||
"WARN: Condition always false [test/compress/issue-1261.js:10,8]",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
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,
|
||||
cascade : true,
|
||||
hoist_funs : true,
|
||||
};
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_funs: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function foo(anything) {
|
||||
function throwing_function() {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
tranformation_sort_order_equal: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
};
|
||||
}
|
||||
|
||||
input: { (a = parseInt('100')) == a }
|
||||
expect: { (a = parseInt('100')) == a }
|
||||
@@ -24,7 +24,7 @@ tranformation_sort_order_equal: {
|
||||
tranformation_sort_order_unequal: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
};
|
||||
}
|
||||
|
||||
input: { (a = parseInt('100')) != a }
|
||||
expect: { (a = parseInt('100')) != a }
|
||||
@@ -33,7 +33,7 @@ tranformation_sort_order_unequal: {
|
||||
tranformation_sort_order_lesser_or_equal: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
};
|
||||
}
|
||||
|
||||
input: { (a = parseInt('100')) <= a }
|
||||
expect: { (a = parseInt('100')) <= a }
|
||||
@@ -41,7 +41,7 @@ tranformation_sort_order_lesser_or_equal: {
|
||||
tranformation_sort_order_greater_or_equal: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
};
|
||||
}
|
||||
|
||||
input: { (a = parseInt('100')) >= a }
|
||||
expect: { (a = parseInt('100')) >= a }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
level_zero: {
|
||||
options = {
|
||||
keep_fnames: true
|
||||
keep_fnames: true,
|
||||
}
|
||||
mangle = {
|
||||
keep_fnames: true
|
||||
@@ -29,7 +29,7 @@ level_zero: {
|
||||
|
||||
level_one: {
|
||||
options = {
|
||||
keep_fnames: true
|
||||
keep_fnames: true,
|
||||
}
|
||||
mangle = {
|
||||
keep_fnames: true
|
||||
@@ -58,7 +58,7 @@ level_one: {
|
||||
|
||||
level_two: {
|
||||
options = {
|
||||
keep_fnames: true
|
||||
keep_fnames: true,
|
||||
}
|
||||
mangle = {
|
||||
keep_fnames: true
|
||||
@@ -97,7 +97,7 @@ level_two: {
|
||||
|
||||
level_three: {
|
||||
options = {
|
||||
keep_fnames: true
|
||||
keep_fnames: true,
|
||||
}
|
||||
mangle = {
|
||||
keep_fnames: true
|
||||
|
||||
@@ -4,7 +4,7 @@ unsafe_undefined: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
unsafe: true
|
||||
unsafe_undefined: true,
|
||||
}
|
||||
mangle = {}
|
||||
input: {
|
||||
@@ -30,7 +30,7 @@ keep_fnames: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
unsafe: true
|
||||
unsafe_undefined: true,
|
||||
}
|
||||
mangle = {
|
||||
keep_fnames: true
|
||||
|
||||
@@ -22,18 +22,17 @@ else_with_empty_statement: {
|
||||
|
||||
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,
|
||||
cascade : true,
|
||||
conditionals : false,
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: false,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_vars: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
for (var i = 1; i <= 4; ++i) {
|
||||
|
||||
@@ -61,7 +61,7 @@ unsafe_undefined: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
unsafe: true,
|
||||
unsafe_undefined: true,
|
||||
}
|
||||
mangle = {}
|
||||
input: {
|
||||
|
||||
@@ -52,3 +52,30 @@ chained_evaluation_2: {
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
||||
chained_evaluation_3: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: 10,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
var a = "long piece of string";
|
||||
(function() {
|
||||
var b = a, c;
|
||||
c = f(b);
|
||||
c.bar = b;
|
||||
})();
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
(function() {
|
||||
f("long piece of string").bar = "long piece of string";
|
||||
})();
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
|
||||
issue_1639_1: {
|
||||
options = {
|
||||
booleans: true,
|
||||
cascade: true,
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
join_vars: true,
|
||||
@@ -12,7 +11,6 @@ issue_1639_1: {
|
||||
}
|
||||
input: {
|
||||
var a = 100, b = 10;
|
||||
|
||||
var L1 = 5;
|
||||
while (--L1 > 0) {
|
||||
if ((--b), false) {
|
||||
@@ -21,7 +19,6 @@ issue_1639_1: {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log(a, b);
|
||||
}
|
||||
expect: {
|
||||
@@ -29,13 +26,13 @@ issue_1639_1: {
|
||||
if (--b, 0) var ignore = 0;
|
||||
console.log(a, b);
|
||||
}
|
||||
expect_stdout: true
|
||||
expect_stdout: "100 6"
|
||||
}
|
||||
|
||||
issue_1639_2: {
|
||||
options = {
|
||||
booleans: true,
|
||||
cascade: true,
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
join_vars: true,
|
||||
@@ -44,31 +41,29 @@ issue_1639_2: {
|
||||
}
|
||||
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;
|
||||
++a, 1;
|
||||
}
|
||||
f19(),
|
||||
console.log(a, b);
|
||||
}
|
||||
expect_stdout: true
|
||||
expect_stdout: "101 10"
|
||||
}
|
||||
|
||||
issue_1639_3: {
|
||||
options = {
|
||||
booleans: true,
|
||||
cascade: true,
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
sequences: true,
|
||||
@@ -84,5 +79,5 @@ issue_1639_3: {
|
||||
a++,
|
||||
console.log(a, b);
|
||||
}
|
||||
expect_stdout: true
|
||||
expect_stdout: "101 10"
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
f7: {
|
||||
options = {
|
||||
booleans: true,
|
||||
cascade: true,
|
||||
collapse_vars: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
|
||||
@@ -104,7 +104,7 @@ mangle_catch_toplevel: {
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'var o="FAIL";try{throw 1}catch(c){o="PASS"}console.log(o);'
|
||||
expect_exact: 'var c="FAIL";try{throw 1}catch(o){c="PASS"}console.log(c);'
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ mangle_catch_var_toplevel: {
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'var o="FAIL";try{throw 1}catch(r){var o="PASS"}console.log(o);'
|
||||
expect_exact: 'var r="FAIL";try{throw 1}catch(o){var r="PASS"}console.log(r);'
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -345,3 +345,95 @@ mangle_catch_redef_2_ie8_toplevel: {
|
||||
expect_exact: 'try{throw"FAIL1"}catch(o){var o="FAIL2"}console.log(o);'
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
mangle_catch_redef_3: {
|
||||
mangle = {
|
||||
ie8: false,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
var o = "PASS";
|
||||
try {
|
||||
throw 0;
|
||||
} catch (o) {
|
||||
(function() {
|
||||
function f() {
|
||||
o = "FAIL";
|
||||
}
|
||||
f(), f();
|
||||
})();
|
||||
}
|
||||
console.log(o);
|
||||
}
|
||||
expect_exact: 'var o="PASS";try{throw 0}catch(o){(function(){function c(){o="FAIL"}c(),c()})()}console.log(o);'
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
mangle_catch_redef_3_toplevel: {
|
||||
mangle = {
|
||||
ie8: false,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var o = "PASS";
|
||||
try {
|
||||
throw 0;
|
||||
} catch (o) {
|
||||
(function() {
|
||||
function f() {
|
||||
o = "FAIL";
|
||||
}
|
||||
f(), f();
|
||||
})();
|
||||
}
|
||||
console.log(o);
|
||||
}
|
||||
expect_exact: 'var c="PASS";try{throw 0}catch(c){(function(){function o(){c="FAIL"}o(),o()})()}console.log(c);'
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
mangle_catch_redef_3_ie8: {
|
||||
mangle = {
|
||||
ie8: true,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
var o = "PASS";
|
||||
try {
|
||||
throw 0;
|
||||
} catch (o) {
|
||||
(function() {
|
||||
function f() {
|
||||
o = "FAIL";
|
||||
}
|
||||
f(), f();
|
||||
})();
|
||||
}
|
||||
console.log(o);
|
||||
}
|
||||
expect_exact: 'var o="PASS";try{throw 0}catch(o){(function(){function c(){o="FAIL"}c(),c()})()}console.log(o);'
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
mangle_catch_redef_3_ie8_toplevel: {
|
||||
mangle = {
|
||||
ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var o = "PASS";
|
||||
try {
|
||||
throw 0;
|
||||
} catch (o) {
|
||||
(function() {
|
||||
function f() {
|
||||
o = "FAIL";
|
||||
}
|
||||
f(), f();
|
||||
})();
|
||||
}
|
||||
console.log(o);
|
||||
}
|
||||
expect_exact: 'var c="PASS";try{throw 0}catch(c){(function(){function o(){c="FAIL"}o(),o()})()}console.log(c);'
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ function_iife_catch: {
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect_exact: "function f(o){!function(){try{throw 0}catch(c){var o=1;console.log(c,o)}}()}f();"
|
||||
expect_exact: "function f(o){!function(){try{throw 0}catch(o){var c=1;console.log(o,c)}}()}f();"
|
||||
expect_stdout: "0 1"
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ function_iife_catch_ie8: {
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect_exact: "function f(o){!function(){try{throw 0}catch(o){var c=1;console.log(o,c)}}()}f();"
|
||||
expect_exact: "function f(c){!function(){try{throw 0}catch(c){var o=1;console.log(c,o)}}()}f();"
|
||||
expect_stdout: "0 1"
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ function_catch_catch: {
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect_exact: "var o=0;function f(){try{throw 1}catch(c){try{throw 2}catch(o){var o=3;console.log(o)}}console.log(o)}f();"
|
||||
expect_exact: "var o=0;function f(){try{throw 1}catch(o){try{throw 2}catch(c){var c=3;console.log(c)}}console.log(c)}f();"
|
||||
expect_stdout: [
|
||||
"3",
|
||||
"undefined",
|
||||
|
||||
@@ -84,12 +84,12 @@ numeric_literal: {
|
||||
' 0: 0,',
|
||||
' "-0": 1,',
|
||||
' 42: 2,',
|
||||
' "42": 3,',
|
||||
' 42: 3,',
|
||||
' 37: 4,',
|
||||
' o: 5,',
|
||||
' 1e42: 6,',
|
||||
' b: 7,',
|
||||
' "1e+42": 8',
|
||||
' 1e42: 8',
|
||||
'};',
|
||||
'',
|
||||
'console.log(obj[-0], obj[-""], obj["-0"]);',
|
||||
|
||||
@@ -125,8 +125,8 @@ label_do: {
|
||||
|
||||
label_while: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
do_not_update_lhs: {
|
||||
options = {
|
||||
global_defs: { DEBUG: 0 }
|
||||
global_defs: {
|
||||
DEBUG: 0,
|
||||
},
|
||||
}
|
||||
input: {
|
||||
DEBUG++;
|
||||
@@ -16,7 +18,9 @@ do_not_update_lhs: {
|
||||
|
||||
do_update_rhs: {
|
||||
options = {
|
||||
global_defs: { DEBUG: 0 }
|
||||
global_defs: {
|
||||
DEBUG: 0,
|
||||
},
|
||||
}
|
||||
input: {
|
||||
MY_DEBUG = DEBUG;
|
||||
@@ -35,7 +39,7 @@ mixed: {
|
||||
DEBUG: 0,
|
||||
ENV: 1,
|
||||
FOO: 2,
|
||||
}
|
||||
},
|
||||
}
|
||||
input: {
|
||||
var ENV = 3;
|
||||
@@ -60,11 +64,11 @@ mixed: {
|
||||
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]',
|
||||
"WARN: global_defs ENV redefined [test/compress/issue-208.js:1,12]",
|
||||
"WARN: global_defs FOO redefined [test/compress/issue-208.js:2,12]",
|
||||
"WARN: global_defs FOO redefined [test/compress/issue-208.js:4,10]",
|
||||
"WARN: global_defs DEBUG redefined [test/compress/issue-208.js:5,8]",
|
||||
"WARN: global_defs DEBUG redefined [test/compress/issue-208.js:6,8]",
|
||||
"WARN: global_defs DEBUG redefined [test/compress/issue-208.js:7,8]",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
return_with_no_value_in_if_body: {
|
||||
options = { conditionals: true };
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
function foo(bar) {
|
||||
if (bar) {
|
||||
|
||||
33
test/compress/issue-2652.js
Normal file
33
test/compress/issue-2652.js
Normal file
@@ -0,0 +1,33 @@
|
||||
insert_semicolon: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
comments: "all",
|
||||
}
|
||||
input: {
|
||||
var a
|
||||
/* foo */ var b
|
||||
}
|
||||
expect_exact: [
|
||||
"var a",
|
||||
"/* foo */;",
|
||||
"",
|
||||
"var b;",
|
||||
]
|
||||
}
|
||||
|
||||
unary_postfix: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
comments: "all",
|
||||
}
|
||||
input: {
|
||||
a
|
||||
/* foo */++b
|
||||
}
|
||||
expect_exact: [
|
||||
"a",
|
||||
"/* foo */;",
|
||||
"",
|
||||
"++b;",
|
||||
]
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
issue_267: {
|
||||
options = { comparisons: true };
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
x = a % b / b * c * 2;
|
||||
x = a % b * 2
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
issue_269_1: {
|
||||
options = {unsafe: true};
|
||||
options = {
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
f(
|
||||
String(x),
|
||||
@@ -20,7 +22,9 @@ issue_269_1: {
|
||||
}
|
||||
|
||||
issue_269_dangers: {
|
||||
options = {unsafe: true};
|
||||
options = {
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
f(
|
||||
String(x, x),
|
||||
@@ -34,7 +38,9 @@ issue_269_dangers: {
|
||||
}
|
||||
|
||||
issue_269_in_scope: {
|
||||
options = {unsafe: true};
|
||||
options = {
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
var String, Number, Boolean;
|
||||
f(
|
||||
@@ -50,7 +56,9 @@ issue_269_in_scope: {
|
||||
}
|
||||
|
||||
strings_concat: {
|
||||
options = {unsafe: true};
|
||||
options = {
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
f(
|
||||
String(x + 'str'),
|
||||
@@ -64,3 +72,27 @@ strings_concat: {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
regexp: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
RegExp("foo");
|
||||
RegExp("bar", "ig");
|
||||
RegExp(foo);
|
||||
RegExp("bar", ig);
|
||||
RegExp("should", "fail");
|
||||
}
|
||||
expect: {
|
||||
/foo/;
|
||||
/bar/ig;
|
||||
RegExp(foo);
|
||||
RegExp("bar", ig);
|
||||
RegExp("should", "fail");
|
||||
}
|
||||
expect_warnings: [
|
||||
'WARN: Error converting RegExp("should","fail") [test/compress/issue-269.js:5,2]',
|
||||
]
|
||||
}
|
||||
|
||||
32
test/compress/issue-2719.js
Normal file
32
test/compress/issue-2719.js
Normal file
@@ -0,0 +1,32 @@
|
||||
warn: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
properties: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
return g();
|
||||
}
|
||||
function g() {
|
||||
return g["call" + "er"].arguments;
|
||||
}
|
||||
// 3
|
||||
console.log(f(1, 2, 3).length);
|
||||
}
|
||||
expect: {
|
||||
// TypeError: Cannot read property 'arguments' of null
|
||||
console.log(function g() {
|
||||
return g.caller.arguments;
|
||||
}().length);
|
||||
}
|
||||
expect_warnings: [
|
||||
"WARN: Function.prototype.caller not supported [test/compress/issue-2719.js:5,19]",
|
||||
"WARN: Function.prototype.arguments not supported [test/compress/issue-2719.js:5,19]",
|
||||
]
|
||||
}
|
||||
@@ -186,7 +186,7 @@ negate_iife_5_off: {
|
||||
inline: true,
|
||||
negate_iife: false,
|
||||
sequences: true,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
if ((function(){ return t })()) {
|
||||
foo(true);
|
||||
@@ -245,7 +245,7 @@ negate_iife_issue_1073: {
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
unused: true,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
new (function(a) {
|
||||
return function Foo() {
|
||||
@@ -273,7 +273,7 @@ issue_1288_side_effects: {
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
if (w) ;
|
||||
else {
|
||||
@@ -399,7 +399,7 @@ wrap_iife_in_expression: {
|
||||
wrap_iife: true,
|
||||
}
|
||||
input: {
|
||||
foo = (function () {
|
||||
foo = (function() {
|
||||
return bar();
|
||||
})();
|
||||
}
|
||||
@@ -453,7 +453,7 @@ pure_annotation_2: {
|
||||
|
||||
drop_fargs: {
|
||||
options = {
|
||||
cascade: true,
|
||||
collapse_vars: true,
|
||||
inline: true,
|
||||
keep_fargs: false,
|
||||
side_effects: true,
|
||||
@@ -476,7 +476,7 @@ drop_fargs: {
|
||||
|
||||
keep_fargs: {
|
||||
options = {
|
||||
cascade: true,
|
||||
collapse_vars: true,
|
||||
inline: true,
|
||||
keep_fargs: true,
|
||||
side_effects: true,
|
||||
|
||||
37
test/compress/issue-2871.js
Normal file
37
test/compress/issue-2871.js
Normal file
@@ -0,0 +1,37 @@
|
||||
comparison_with_undefined: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
a == undefined;
|
||||
a != undefined;
|
||||
a === undefined;
|
||||
a !== undefined;
|
||||
|
||||
undefined == a;
|
||||
undefined != a;
|
||||
undefined === a;
|
||||
undefined !== a;
|
||||
|
||||
void 0 == a;
|
||||
void 0 != a;
|
||||
void 0 === a;
|
||||
void 0 !== a;
|
||||
}
|
||||
expect: {
|
||||
null == a;
|
||||
null != a;
|
||||
void 0 === a;
|
||||
void 0 !== a;
|
||||
|
||||
null == a;
|
||||
null != a;
|
||||
void 0 === a;
|
||||
void 0 !== a;
|
||||
|
||||
null == a;
|
||||
null != a;
|
||||
void 0 === a;
|
||||
void 0 !== a;
|
||||
}
|
||||
}
|
||||
21
test/compress/issue-2989.js
Normal file
21
test/compress/issue-2989.js
Normal file
@@ -0,0 +1,21 @@
|
||||
inline_script_off: {
|
||||
beautify = {
|
||||
inline_script: false,
|
||||
}
|
||||
input: {
|
||||
console.log("</sCrIpT>");
|
||||
}
|
||||
expect_exact: 'console.log("</sCrIpT>");'
|
||||
expect_stdout: "</sCrIpT>"
|
||||
}
|
||||
|
||||
inline_script_on: {
|
||||
beautify = {
|
||||
inline_script: true,
|
||||
}
|
||||
input: {
|
||||
console.log("</sCrIpT>");
|
||||
}
|
||||
expect_exact: 'console.log("<\\/sCrIpT>");'
|
||||
expect_stdout: "</sCrIpT>"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
collapse: {
|
||||
options = {
|
||||
cascade: true,
|
||||
collapse_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
@@ -41,7 +41,7 @@ collapse: {
|
||||
return void 0 !== ('function' === typeof b ? b() : b) && c();
|
||||
}
|
||||
function f2(b) {
|
||||
return b = c(), 'stirng' == typeof ('function' === typeof b ? b() : b) && d();
|
||||
return 'stirng' == typeof ('function' === typeof (b = c()) ? b() : b) && d();
|
||||
}
|
||||
function f3(c) {
|
||||
var a;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
issue_44_valid_ast_1: {
|
||||
options = { unused: true };
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function a(b) {
|
||||
for (var i = 0, e = b.qoo(); ; i++) {}
|
||||
@@ -14,7 +16,9 @@ issue_44_valid_ast_1: {
|
||||
}
|
||||
|
||||
issue_44_valid_ast_2: {
|
||||
options = { unused: true };
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function a(b) {
|
||||
if (foo) for (var i = 0, e = b.qoo(); ; i++) {}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
keep_continue: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
evaluate: true
|
||||
};
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
while (a) {
|
||||
if (b) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
NaN_and_Infinity_must_have_parens: {
|
||||
options = {};
|
||||
options = {}
|
||||
input: {
|
||||
Infinity.toString();
|
||||
NaN.toString();
|
||||
@@ -11,7 +11,7 @@ NaN_and_Infinity_must_have_parens: {
|
||||
}
|
||||
|
||||
NaN_and_Infinity_should_not_be_replaced_when_they_are_redefined: {
|
||||
options = {};
|
||||
options = {}
|
||||
input: {
|
||||
var Infinity, NaN;
|
||||
Infinity.toString();
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
issue_611: {
|
||||
options = {
|
||||
sequences: true,
|
||||
side_effects: true
|
||||
};
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
define(function() {
|
||||
function fn() {}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
wrongly_optimized: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
booleans: true,
|
||||
evaluate: true
|
||||
};
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
function func() {
|
||||
foo();
|
||||
|
||||
@@ -21,19 +21,19 @@ cond_5: {
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
some_condition() && some_other_condition() ? do_something() : alternate();
|
||||
(some_condition() && some_other_condition() ? do_something : alternate)();
|
||||
if (some_condition() && some_other_condition()) do_something();
|
||||
}
|
||||
}
|
||||
|
||||
dead_code_const_annotation_regex: {
|
||||
options = {
|
||||
booleans : true,
|
||||
conditionals : true,
|
||||
dead_code : true,
|
||||
evaluate : true,
|
||||
expression : true,
|
||||
loops : true,
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
expression: true,
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
var unused;
|
||||
@@ -82,8 +82,8 @@ drop_value: {
|
||||
|
||||
wrongly_optimized: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
expression: true,
|
||||
}
|
||||
@@ -195,7 +195,7 @@ negate_iife_5_off: {
|
||||
expression: true,
|
||||
negate_iife: false,
|
||||
sequences: true,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
if ((function(){ return t })()) {
|
||||
foo(true);
|
||||
@@ -248,7 +248,9 @@ issue_1254_negate_iife_nested: {
|
||||
conditional: {
|
||||
options = {
|
||||
expression: true,
|
||||
pure_funcs: [ "pure" ],
|
||||
pure_funcs: [
|
||||
"pure"
|
||||
],
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
negate_booleans_1: {
|
||||
options = {
|
||||
comparisons: true
|
||||
};
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
var a = !a || !b || !c || !d || !e || !f;
|
||||
}
|
||||
@@ -12,8 +12,8 @@ negate_booleans_1: {
|
||||
|
||||
negate_booleans_2: {
|
||||
options = {
|
||||
comparisons: true
|
||||
};
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
var match = !x && // should not touch this one
|
||||
(!z || c) &&
|
||||
|
||||
@@ -1,11 +1,31 @@
|
||||
remove_redundant_sequence_items: {
|
||||
options = { side_effects: true };
|
||||
remove_sequence: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(0, 1, eval)();
|
||||
(0, 1, logThis)();
|
||||
(0, 1, _decorators.logThis)();
|
||||
}
|
||||
expect: {
|
||||
eval();
|
||||
logThis();
|
||||
(0, _decorators.logThis)();
|
||||
}
|
||||
}
|
||||
|
||||
remove_redundant_sequence_items: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
(0, 1, eval)();
|
||||
(0, 1, logThis)();
|
||||
(0, 1, _decorators.logThis)();
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
(0, eval)();
|
||||
logThis();
|
||||
(0, _decorators.logThis)();
|
||||
@@ -13,13 +33,17 @@ remove_redundant_sequence_items: {
|
||||
}
|
||||
|
||||
dont_remove_this_binding_sequence: {
|
||||
options = { side_effects: true };
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
(0, eval)();
|
||||
(0, logThis)();
|
||||
(0, _decorators.logThis)();
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
(0, eval)();
|
||||
logThis();
|
||||
(0, _decorators.logThis)();
|
||||
|
||||
@@ -2,26 +2,25 @@ dont_mangle_arguments: {
|
||||
mangle = {
|
||||
};
|
||||
options = {
|
||||
sequences : true,
|
||||
properties : true,
|
||||
dead_code : true,
|
||||
drop_debugger : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
loops : true,
|
||||
unused : true,
|
||||
hoist_funs : true,
|
||||
keep_fargs : true,
|
||||
keep_fnames : false,
|
||||
hoist_vars : true,
|
||||
if_return : true,
|
||||
join_vars : true,
|
||||
cascade : true,
|
||||
side_effects : true,
|
||||
negate_iife : false
|
||||
};
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
drop_debugger: true,
|
||||
evaluate: true,
|
||||
hoist_funs: true,
|
||||
hoist_vars: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
keep_fnames: false,
|
||||
loops: true,
|
||||
negate_iife: false,
|
||||
properties: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(){
|
||||
var arguments = arguments, not_arguments = 9;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
keep_var_for_in: {
|
||||
options = {
|
||||
hoist_vars: true,
|
||||
unused: true
|
||||
};
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(obj){
|
||||
var foo = 5;
|
||||
|
||||
@@ -3,8 +3,9 @@ this_binding_conditionals: {
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
(1 && a)();
|
||||
(0 || a)();
|
||||
(0 || 1 && a)();
|
||||
@@ -26,6 +27,7 @@ this_binding_conditionals: {
|
||||
(1 ? eval : 0)();
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
a();
|
||||
a();
|
||||
a();
|
||||
@@ -53,13 +55,15 @@ this_binding_collapse_vars: {
|
||||
collapse_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var c = a; c();
|
||||
var d = a.b; d();
|
||||
var e = eval; e();
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
a();
|
||||
(0, a.b)();
|
||||
(0, eval)();
|
||||
@@ -68,32 +72,89 @@ this_binding_collapse_vars: {
|
||||
|
||||
this_binding_side_effects: {
|
||||
options = {
|
||||
side_effects : true
|
||||
};
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(function (foo) {
|
||||
(function(foo) {
|
||||
(0, foo)();
|
||||
(0, foo.bar)();
|
||||
(0, eval)('console.log(foo);');
|
||||
(0, eval)("console.log(foo);");
|
||||
}());
|
||||
(function (foo) {
|
||||
(function(foo) {
|
||||
"use strict";
|
||||
(0, foo)();
|
||||
(0, foo.bar)();
|
||||
(0, eval)("console.log(foo);");
|
||||
}());
|
||||
(function(foo) {
|
||||
var eval = console;
|
||||
(0, foo)();
|
||||
(0, foo.bar)();
|
||||
(0, eval)('console.log(foo);');
|
||||
(0, eval)("console.log(foo);");
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
(function (foo) {
|
||||
(function(foo) {
|
||||
foo();
|
||||
(0, foo.bar)();
|
||||
(0, eval)('console.log(foo);');
|
||||
eval("console.log(foo);");
|
||||
}());
|
||||
(function (foo) {
|
||||
(function(foo) {
|
||||
"use strict";
|
||||
foo();
|
||||
(0, foo.bar)();
|
||||
(0, eval)("console.log(foo);");
|
||||
}());
|
||||
(function(foo) {
|
||||
var eval = console;
|
||||
foo();
|
||||
(0, foo.bar)();
|
||||
(0, eval)('console.log(foo);');
|
||||
eval("console.log(foo);");
|
||||
}());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this_binding_sequences: {
|
||||
options = {
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
console.log(typeof function() {
|
||||
return eval("this");
|
||||
}());
|
||||
console.log(typeof function() {
|
||||
"use strict";
|
||||
return eval("this");
|
||||
}());
|
||||
console.log(typeof function() {
|
||||
return (0, eval)("this");
|
||||
}());
|
||||
console.log(typeof function() {
|
||||
"use strict";
|
||||
return (0, eval)("this");
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(typeof function() {
|
||||
return eval("this");
|
||||
}()),
|
||||
console.log(typeof function() {
|
||||
"use strict";
|
||||
return eval("this");
|
||||
}()),
|
||||
console.log(typeof function() {
|
||||
return eval("this");
|
||||
}()),
|
||||
console.log(typeof function() {
|
||||
"use strict";
|
||||
return (0, eval)("this");
|
||||
}());
|
||||
}
|
||||
expect_stdout: [
|
||||
"object",
|
||||
"undefined",
|
||||
"object",
|
||||
"object",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,9 +1,21 @@
|
||||
eval_collapse_vars: {
|
||||
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
|
||||
};
|
||||
booleans: true,
|
||||
collapse_vars: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_funs: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
properties: true,
|
||||
sequences: false,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f1() {
|
||||
var e = 7;
|
||||
@@ -46,7 +58,10 @@ eval_collapse_vars: {
|
||||
}
|
||||
|
||||
eval_unused: {
|
||||
options = { unused: true, keep_fargs: false };
|
||||
options = {
|
||||
keep_fargs: false,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f1(a, eval, c, d, e) {
|
||||
return a('c') + eval;
|
||||
|
||||
@@ -1,8 +1,19 @@
|
||||
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
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_funs: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
properties: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f1() {
|
||||
@@ -30,9 +41,20 @@ issue979_reported: {
|
||||
|
||||
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
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_funs: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
properties: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f3() {
|
||||
|
||||
1457
test/compress/keep_fargs.js
Normal file
1457
test/compress/keep_fargs.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,9 @@
|
||||
labels_1: {
|
||||
options = { if_return: true, conditionals: true, dead_code: true };
|
||||
options = {
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
out: {
|
||||
if (foo) break out;
|
||||
@@ -13,7 +17,11 @@ labels_1: {
|
||||
}
|
||||
|
||||
labels_2: {
|
||||
options = { if_return: true, conditionals: true, dead_code: true };
|
||||
options = {
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
out: {
|
||||
if (foo) print("stuff");
|
||||
@@ -30,7 +38,11 @@ labels_2: {
|
||||
}
|
||||
|
||||
labels_3: {
|
||||
options = { if_return: true, conditionals: true, dead_code: true };
|
||||
options = {
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
for (var i = 0; i < 5; ++i) {
|
||||
if (i < 3) continue;
|
||||
@@ -45,7 +57,11 @@ labels_3: {
|
||||
}
|
||||
|
||||
labels_4: {
|
||||
options = { if_return: true, conditionals: true, dead_code: true };
|
||||
options = {
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
out: for (var i = 0; i < 5; ++i) {
|
||||
if (i < 3) continue out;
|
||||
@@ -60,7 +76,11 @@ labels_4: {
|
||||
}
|
||||
|
||||
labels_5: {
|
||||
options = { if_return: true, conditionals: true, dead_code: true };
|
||||
options = {
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
if_return: true,
|
||||
}
|
||||
// should keep the break-s in the following
|
||||
input: {
|
||||
while (foo) {
|
||||
@@ -92,7 +112,11 @@ labels_6: {
|
||||
}
|
||||
|
||||
labels_7: {
|
||||
options = { if_return: true, conditionals: true, dead_code: true };
|
||||
options = {
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
while (foo) {
|
||||
x();
|
||||
@@ -109,7 +133,11 @@ labels_7: {
|
||||
}
|
||||
|
||||
labels_8: {
|
||||
options = { if_return: true, conditionals: true, dead_code: true };
|
||||
options = {
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
while (foo) {
|
||||
x();
|
||||
@@ -127,7 +155,11 @@ labels_8: {
|
||||
}
|
||||
|
||||
labels_9: {
|
||||
options = { if_return: true, conditionals: true, dead_code: true };
|
||||
options = {
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
out: while (foo) {
|
||||
x();
|
||||
@@ -146,7 +178,11 @@ labels_9: {
|
||||
}
|
||||
|
||||
labels_10: {
|
||||
options = { if_return: true, conditionals: true, dead_code: true };
|
||||
options = {
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
out: while (foo) {
|
||||
x();
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
while_becomes_for: {
|
||||
options = { loops: true };
|
||||
options = {
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
while (foo()) bar();
|
||||
}
|
||||
@@ -9,7 +11,9 @@ while_becomes_for: {
|
||||
}
|
||||
|
||||
drop_if_break_1: {
|
||||
options = { loops: true };
|
||||
options = {
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
for (;;)
|
||||
if (foo()) break;
|
||||
@@ -20,7 +24,9 @@ drop_if_break_1: {
|
||||
}
|
||||
|
||||
drop_if_break_2: {
|
||||
options = { loops: true };
|
||||
options = {
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
for (;bar();)
|
||||
if (foo()) break;
|
||||
@@ -31,7 +37,9 @@ drop_if_break_2: {
|
||||
}
|
||||
|
||||
drop_if_break_3: {
|
||||
options = { loops: true };
|
||||
options = {
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
for (;bar();) {
|
||||
if (foo()) break;
|
||||
@@ -48,7 +56,10 @@ drop_if_break_3: {
|
||||
}
|
||||
|
||||
drop_if_break_4: {
|
||||
options = { loops: true, sequences: true };
|
||||
options = {
|
||||
loops: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
for (;bar();) {
|
||||
x();
|
||||
@@ -64,7 +75,9 @@ drop_if_break_4: {
|
||||
}
|
||||
|
||||
drop_if_else_break_1: {
|
||||
options = { loops: true };
|
||||
options = {
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
for (;;) if (foo()) bar(); else break;
|
||||
}
|
||||
@@ -74,7 +87,9 @@ drop_if_else_break_1: {
|
||||
}
|
||||
|
||||
drop_if_else_break_2: {
|
||||
options = { loops: true };
|
||||
options = {
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
for (;bar();) {
|
||||
if (foo()) baz();
|
||||
@@ -87,7 +102,9 @@ drop_if_else_break_2: {
|
||||
}
|
||||
|
||||
drop_if_else_break_3: {
|
||||
options = { loops: true };
|
||||
options = {
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
for (;bar();) {
|
||||
if (foo()) baz();
|
||||
@@ -106,7 +123,10 @@ drop_if_else_break_3: {
|
||||
}
|
||||
|
||||
drop_if_else_break_4: {
|
||||
options = { loops: true, sequences: true };
|
||||
options = {
|
||||
loops: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
for (;bar();) {
|
||||
x();
|
||||
@@ -123,7 +143,9 @@ drop_if_else_break_4: {
|
||||
}
|
||||
|
||||
parse_do_while_with_semicolon: {
|
||||
options = { loops: false };
|
||||
options = {
|
||||
loops: false,
|
||||
}
|
||||
input: {
|
||||
do {
|
||||
x();
|
||||
@@ -135,7 +157,9 @@ parse_do_while_with_semicolon: {
|
||||
}
|
||||
|
||||
parse_do_while_without_semicolon: {
|
||||
options = { loops: false };
|
||||
options = {
|
||||
loops: false,
|
||||
}
|
||||
input: {
|
||||
do {
|
||||
x();
|
||||
@@ -153,7 +177,7 @@ evaluate: {
|
||||
loops: true,
|
||||
passes: 2,
|
||||
side_effects: true,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
while (true) {
|
||||
a();
|
||||
@@ -294,10 +318,10 @@ issue_186_beautify_ie8: {
|
||||
]
|
||||
}
|
||||
|
||||
issue_186_bracketize: {
|
||||
issue_186_braces: {
|
||||
beautify = {
|
||||
beautify: false,
|
||||
bracketize: true,
|
||||
braces: true,
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
@@ -314,10 +338,10 @@ issue_186_bracketize: {
|
||||
expect_exact: 'var x=3;if(foo()){do{do{alert(x)}while(--x)}while(x)}else{bar()}'
|
||||
}
|
||||
|
||||
issue_186_bracketize_ie8: {
|
||||
issue_186_braces_ie8: {
|
||||
beautify = {
|
||||
beautify: false,
|
||||
bracketize: true,
|
||||
braces: true,
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
@@ -334,10 +358,10 @@ issue_186_bracketize_ie8: {
|
||||
expect_exact: 'var x=3;if(foo()){do{do{alert(x)}while(--x)}while(x)}else{bar()}'
|
||||
}
|
||||
|
||||
issue_186_beautify_bracketize: {
|
||||
issue_186_beautify_braces: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
bracketize: true,
|
||||
braces: true,
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
@@ -366,10 +390,10 @@ issue_186_beautify_bracketize: {
|
||||
]
|
||||
}
|
||||
|
||||
issue_186_beautify_bracketize_ie8: {
|
||||
issue_186_beautify_braces_ie8: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
bracketize: true,
|
||||
braces: true,
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
@@ -457,7 +481,7 @@ 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);
|
||||
@@ -492,3 +516,414 @@ dead_code_condition: {
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_2740_1: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
for (; ; ) break;
|
||||
for (a(); ; ) break;
|
||||
for (; b(); ) break;
|
||||
for (c(); d(); ) break;
|
||||
for (; ; e()) break;
|
||||
for (f(); ; g()) break;
|
||||
for (; h(); i()) break;
|
||||
for (j(); k(); l()) break;
|
||||
}
|
||||
expect: {
|
||||
a();
|
||||
b();
|
||||
c();
|
||||
d();
|
||||
f();
|
||||
h();
|
||||
j();
|
||||
k();
|
||||
}
|
||||
}
|
||||
|
||||
issue_2740_2: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
loops: true,
|
||||
passes: 2,
|
||||
}
|
||||
input: {
|
||||
L1: while (x()) {
|
||||
break L1;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
x();
|
||||
}
|
||||
}
|
||||
|
||||
issue_2740_3: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
L1: for (var x = 0; x < 3; x++) {
|
||||
L2: for (var y = 0; y < 2; y++) {
|
||||
break L1;
|
||||
}
|
||||
}
|
||||
console.log(x, y);
|
||||
}
|
||||
expect: {
|
||||
L1: for (var x = 0; x < 3; x++) {
|
||||
var y = 0;
|
||||
if (y < 2)
|
||||
break L1;
|
||||
}
|
||||
console.log(x, y);
|
||||
}
|
||||
expect_stdout: "0 0"
|
||||
}
|
||||
|
||||
issue_2740_4: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
loops: true,
|
||||
passes: 2,
|
||||
}
|
||||
input: {
|
||||
L1: for (var x = 0; x < 3; x++) {
|
||||
L2: for (var y = 0; y < 2; y++) {
|
||||
break L2;
|
||||
}
|
||||
}
|
||||
console.log(x, y);
|
||||
}
|
||||
expect: {
|
||||
for (var x = 0; x < 3; x++) {
|
||||
var y = 0;
|
||||
y < 2;
|
||||
}
|
||||
console.log(x, y);
|
||||
}
|
||||
expect_stdout: "3 0"
|
||||
}
|
||||
|
||||
issue_2740_5: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
loops: true,
|
||||
passes: 2,
|
||||
}
|
||||
input: {
|
||||
L1: for (var x = 0; x < 3; x++) {
|
||||
break L1;
|
||||
L2: for (var y = 0; y < 2; y++) {
|
||||
break L2;
|
||||
}
|
||||
}
|
||||
console.log(x, y);
|
||||
}
|
||||
expect: {
|
||||
var x = 0;
|
||||
x < 3;
|
||||
var y;
|
||||
console.log(x,y);
|
||||
}
|
||||
expect_stdout: "0 undefined"
|
||||
}
|
||||
|
||||
issue_2904: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
var a = 1;
|
||||
do {
|
||||
console.log(a);
|
||||
} while (--a);
|
||||
}
|
||||
expect: {
|
||||
for (var a = 1; console.log(a), --a;);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_3371: {
|
||||
options = {
|
||||
functions: true,
|
||||
join_vars: true,
|
||||
loops: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
var a = function() {
|
||||
console.log("PASS");
|
||||
};
|
||||
while (a());
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
function a() {
|
||||
console.log("PASS");
|
||||
}
|
||||
for (; a(); );
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
step: {
|
||||
options = {
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
for (var i = 0; i < 42; "foo", i++, "bar");
|
||||
console.log(i);
|
||||
}
|
||||
expect: {
|
||||
for (var i = 0; i < 42; i++);
|
||||
console.log(i);
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
empty_for_in: {
|
||||
options = {
|
||||
loops: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
for (var a in [ 1, 2, 3 ]) {
|
||||
var b = a + 1;
|
||||
}
|
||||
}
|
||||
expect: {}
|
||||
expect_warnings: [
|
||||
"WARN: Dropping unused variable b [test/compress/loops.js:2,16]",
|
||||
"INFO: Dropping unused loop variable a [test/compress/loops.js:1,17]",
|
||||
]
|
||||
}
|
||||
|
||||
empty_for_in_used: {
|
||||
options = {
|
||||
loops: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
for (var a in [ 1, 2, 3 ]) {
|
||||
var b = a + 1;
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
for (var a in [ 1, 2, 3 ]);
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "2"
|
||||
expect_warnings: [
|
||||
"WARN: Dropping unused variable b [test/compress/loops.js:2,16]",
|
||||
]
|
||||
}
|
||||
|
||||
empty_for_in_side_effects: {
|
||||
options = {
|
||||
loops: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
for (var a in {
|
||||
foo: console.log("PASS")
|
||||
}) {
|
||||
var b = a + "bar";
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
expect_warnings: [
|
||||
"WARN: Dropping unused variable b [test/compress/loops.js:4,16]",
|
||||
"INFO: Dropping unused loop variable a [test/compress/loops.js:1,17]",
|
||||
"WARN: Side effects in object of for-in loop [test/compress/loops.js:1,17]",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3631_1: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
loops: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var c = 0;
|
||||
L: do {
|
||||
for (;;) continue L;
|
||||
var b = 1;
|
||||
} while (b && c++);
|
||||
console.log(c);
|
||||
}
|
||||
expect: {
|
||||
var c = 0;
|
||||
do {
|
||||
var b;
|
||||
} while (b && c++);
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: "0"
|
||||
}
|
||||
|
||||
issue_3631_2: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
loops: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
L: for (var a = 1; a--; console.log(b)) {
|
||||
for (;;) continue L;
|
||||
var b = "FAIL";
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
for (var a = 1; a--; console.log(b))
|
||||
var b;
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
loop_if_break: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b) {
|
||||
try {
|
||||
while (a) {
|
||||
if (b) {
|
||||
break;
|
||||
var c = 42;
|
||||
console.log(c);
|
||||
} else {
|
||||
var d = false;
|
||||
throw d;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.log("E:", e);
|
||||
}
|
||||
console.log(a, b, c, d);
|
||||
}
|
||||
f(0, 0);
|
||||
f(0, 1);
|
||||
f(1, 0);
|
||||
f(1, 1);
|
||||
}
|
||||
expect: {
|
||||
function f(a, b) {
|
||||
try {
|
||||
for (;a && !b;) {
|
||||
var d = false;
|
||||
throw d;
|
||||
var c;
|
||||
}
|
||||
} catch (e) {
|
||||
console.log("E:", e);
|
||||
}
|
||||
console.log(a, b, c, d);
|
||||
}
|
||||
f(0, 0);
|
||||
f(0, 1);
|
||||
f(1, 0);
|
||||
f(1, 1);
|
||||
}
|
||||
expect_stdout: [
|
||||
"0 0 undefined undefined",
|
||||
"0 1 undefined undefined",
|
||||
"E: false",
|
||||
"1 0 undefined false",
|
||||
"1 1 undefined undefined",
|
||||
]
|
||||
}
|
||||
|
||||
loop_return: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
while (a) return 42;
|
||||
return "foo";
|
||||
}
|
||||
console.log(f(0), f(1));
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
if (a) return 42;
|
||||
return "foo";
|
||||
}
|
||||
console.log(f(0), f(1));
|
||||
}
|
||||
expect_stdout: "foo 42"
|
||||
}
|
||||
|
||||
issue_3634_1: {
|
||||
options = {
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
var b = 0;
|
||||
L: while (++b < 2)
|
||||
while (1)
|
||||
if (b) break L;
|
||||
console.log(b);
|
||||
}
|
||||
expect: {
|
||||
var b = 0;
|
||||
L: for (;++b < 2;)
|
||||
for (;1;)
|
||||
if (b) break L;
|
||||
console.log(b);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_3634_2: {
|
||||
options = {
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
var b = 0;
|
||||
L: while (++b < 2)
|
||||
while (1)
|
||||
if (!b)
|
||||
continue L;
|
||||
else
|
||||
break L;
|
||||
console.log(b);
|
||||
}
|
||||
expect: {
|
||||
var b = 0;
|
||||
L: for (;++b < 2;)
|
||||
for (;1;)
|
||||
if (!b)
|
||||
continue L;
|
||||
else
|
||||
break L;
|
||||
console.log(b);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
@@ -8,14 +8,14 @@ too_short: {
|
||||
}
|
||||
}
|
||||
expect_exact: [
|
||||
'function f(a){',
|
||||
'return{',
|
||||
'c:42,',
|
||||
'd:a(),',
|
||||
'e:"foo"}}',
|
||||
"function f(",
|
||||
"a){return{",
|
||||
"c:42,d:a(",
|
||||
'),e:"foo"}',
|
||||
"}",
|
||||
]
|
||||
expect_warnings: [
|
||||
"WARN: Output exceeds 10 characters"
|
||||
"WARN: Output exceeds 10 characters",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -29,11 +29,25 @@ just_enough: {
|
||||
}
|
||||
}
|
||||
expect_exact: [
|
||||
'function f(a){',
|
||||
'return{c:42,',
|
||||
"function f(a){",
|
||||
"return{c:42,",
|
||||
'd:a(),e:"foo"}',
|
||||
'}',
|
||||
]
|
||||
expect_warnings: [
|
||||
"}",
|
||||
]
|
||||
expect_warnings: []
|
||||
}
|
||||
|
||||
issue_304: {
|
||||
beautify = {
|
||||
max_line_len: 10,
|
||||
}
|
||||
input: {
|
||||
var a = 0, b = 0, c = 0, d = 0, e = 0;
|
||||
}
|
||||
expect_exact: [
|
||||
"var a=0,",
|
||||
"b=0,c=0,",
|
||||
"d=0,e=0;",
|
||||
]
|
||||
expect_warnings: []
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
negate_iife_1: {
|
||||
options = {
|
||||
negate_iife: true
|
||||
};
|
||||
negate_iife: true,
|
||||
}
|
||||
input: {
|
||||
(function(){ stuff() })();
|
||||
}
|
||||
@@ -13,7 +13,7 @@ negate_iife_1: {
|
||||
negate_iife_1_off: {
|
||||
options = {
|
||||
negate_iife: false,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
(function(){ stuff() })();
|
||||
}
|
||||
@@ -24,7 +24,7 @@ negate_iife_2: {
|
||||
options = {
|
||||
inline: true,
|
||||
negate_iife: true,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
(function(){ return {} })().x = 10;
|
||||
}
|
||||
@@ -45,9 +45,9 @@ negate_iife_2_side_effects: {
|
||||
|
||||
negate_iife_3: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
negate_iife: true,
|
||||
conditionals: true
|
||||
};
|
||||
}
|
||||
input: {
|
||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||
}
|
||||
@@ -67,7 +67,7 @@ negate_iife_3_evaluate: {
|
||||
(function(){ return true })() ? console.log(true) : console.log(false);
|
||||
}
|
||||
expect: {
|
||||
console.log(true);
|
||||
true, console.log(true);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
@@ -88,9 +88,9 @@ negate_iife_3_side_effects: {
|
||||
|
||||
negate_iife_3_off: {
|
||||
options = {
|
||||
negate_iife: false,
|
||||
conditionals: true,
|
||||
};
|
||||
negate_iife: false,
|
||||
}
|
||||
input: {
|
||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||
}
|
||||
@@ -110,17 +110,17 @@ negate_iife_3_off_evaluate: {
|
||||
(function(){ return true })() ? console.log(true) : console.log(false);
|
||||
}
|
||||
expect: {
|
||||
console.log(true);
|
||||
true, console.log(true);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
negate_iife_4: {
|
||||
options = {
|
||||
negate_iife: true,
|
||||
conditionals: true,
|
||||
sequences: true
|
||||
};
|
||||
negate_iife: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||
(function(){
|
||||
@@ -136,11 +136,11 @@ negate_iife_4: {
|
||||
|
||||
sequence_off: {
|
||||
options = {
|
||||
negate_iife: false,
|
||||
conditionals: true,
|
||||
sequences: true,
|
||||
negate_iife: false,
|
||||
passes: 2,
|
||||
};
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||
@@ -171,10 +171,10 @@ sequence_off: {
|
||||
|
||||
negate_iife_5: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
negate_iife: true,
|
||||
sequences: true,
|
||||
conditionals: true,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
if ((function(){ return t })()) {
|
||||
foo(true);
|
||||
@@ -194,10 +194,10 @@ negate_iife_5: {
|
||||
|
||||
negate_iife_5_off: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
negate_iife: false,
|
||||
sequences: true,
|
||||
conditionals: true,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
if ((function(){ return t })()) {
|
||||
foo(true);
|
||||
@@ -217,10 +217,10 @@ negate_iife_5_off: {
|
||||
|
||||
negate_iife_nested: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
negate_iife: true,
|
||||
sequences: true,
|
||||
conditionals: true,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
function Foo(f) {
|
||||
this.f = f;
|
||||
@@ -250,10 +250,10 @@ negate_iife_nested: {
|
||||
|
||||
negate_iife_nested_off: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
negate_iife: false,
|
||||
sequences: true,
|
||||
conditionals: true,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
function Foo(f) {
|
||||
this.f = f;
|
||||
@@ -283,10 +283,10 @@ negate_iife_nested_off: {
|
||||
|
||||
negate_iife_issue_1073: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
negate_iife: true,
|
||||
sequences: true,
|
||||
conditionals: true,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
new (function(a) {
|
||||
return function Foo() {
|
||||
@@ -356,7 +356,7 @@ issue_1288: {
|
||||
conditionals: true,
|
||||
negate_iife: true,
|
||||
side_effects: false,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
if (w) ;
|
||||
else {
|
||||
|
||||
@@ -36,7 +36,9 @@ new_statements_3: {
|
||||
}
|
||||
|
||||
new_with_rewritten_true_value: {
|
||||
options = { booleans: true }
|
||||
options = {
|
||||
booleans: true,
|
||||
}
|
||||
input: {
|
||||
new true;
|
||||
}
|
||||
|
||||
@@ -1,21 +1,49 @@
|
||||
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);
|
||||
beautify = {
|
||||
beautify: true,
|
||||
}
|
||||
expect_exact: "-2;(-2).toFixed(0);2;2..toFixed(0);.2;.2.toFixed(0);2e-8;2e-8.toFixed(0);0xde0b6b3a7640080;(0xde0b6b3a7640080).toFixed(0);"
|
||||
input: {
|
||||
function f() {
|
||||
(-2);
|
||||
(-2).toFixed(0);
|
||||
|
||||
(2);
|
||||
(2).toFixed(0);
|
||||
|
||||
(0.2);
|
||||
(0.2).toFixed(0);
|
||||
|
||||
(2.34e20);
|
||||
(2.34e20).toFixed(0);
|
||||
|
||||
(0.00000002);
|
||||
(0.00000002).toFixed(0);
|
||||
|
||||
(1000000000000000128);
|
||||
(1000000000000000128).toFixed(0);
|
||||
|
||||
(-1000000000000000128);
|
||||
(-1000000000000000128).toFixed(0);
|
||||
}
|
||||
}
|
||||
expect_exact: [
|
||||
"function f() {",
|
||||
" -2;",
|
||||
" (-2).toFixed(0);",
|
||||
" 2;",
|
||||
" 2..toFixed(0);",
|
||||
" .2;",
|
||||
" .2.toFixed(0);",
|
||||
" 234e18;",
|
||||
" 234e18.toFixed(0);",
|
||||
" 2e-8;",
|
||||
" 2e-8.toFixed(0);",
|
||||
" 0xde0b6b3a7640080;",
|
||||
" (0xde0b6b3a7640080).toFixed(0);",
|
||||
" -0xde0b6b3a7640080;",
|
||||
" (-0xde0b6b3a7640080).toFixed(0);",
|
||||
"}",
|
||||
]
|
||||
}
|
||||
|
||||
comparisons: {
|
||||
@@ -23,17 +51,20 @@ comparisons: {
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
var x = "42", y = "0x30";
|
||||
console.log(
|
||||
~x === 42,
|
||||
x % n === 42
|
||||
x % y === 42
|
||||
);
|
||||
}
|
||||
expect: {
|
||||
var x = "42", y = "0x30";
|
||||
console.log(
|
||||
42 == ~x,
|
||||
x % n == 42
|
||||
x % y == 42
|
||||
);
|
||||
}
|
||||
expect_stdout: "false true"
|
||||
}
|
||||
|
||||
evaluate_1: {
|
||||
@@ -75,7 +106,7 @@ evaluate_1: {
|
||||
}
|
||||
}
|
||||
|
||||
evaluate_2: {
|
||||
evaluate_1_unsafe_math: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe_math: true,
|
||||
@@ -90,6 +121,8 @@ evaluate_2: {
|
||||
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)
|
||||
);
|
||||
@@ -98,18 +131,138 @@ evaluate_2: {
|
||||
console.log(
|
||||
x + 1 + 2,
|
||||
2 * x,
|
||||
3 + +x,
|
||||
+x + 3,
|
||||
1 + x + 2 + 3,
|
||||
3 | x,
|
||||
6 + x--,
|
||||
6 + x*y,
|
||||
x*y + 6,
|
||||
1 + (2 + x + 3),
|
||||
6 + ~x,
|
||||
5 - y + ~x,
|
||||
0 & x,
|
||||
6 + (x |= 0)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
evaluate_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe_math: false,
|
||||
}
|
||||
input: {
|
||||
var x = "42", y = null;
|
||||
[
|
||||
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),
|
||||
].forEach(function(n) {
|
||||
console.log(typeof n, n);
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
var x = "42", y = null;
|
||||
[
|
||||
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,
|
||||
2 + ~x + 3 - y,
|
||||
0 & x,
|
||||
2 + (x |= 0) + 3 + 1,
|
||||
].forEach(function(n) {
|
||||
console.log(typeof n, n);
|
||||
});
|
||||
}
|
||||
expect_stdout: [
|
||||
"string 4212",
|
||||
"number 84",
|
||||
"number 45",
|
||||
"string 14223",
|
||||
"number 43",
|
||||
"number 48",
|
||||
"number 6",
|
||||
"number 47",
|
||||
"number -36",
|
||||
"number -37",
|
||||
"number 0",
|
||||
"number 47",
|
||||
]
|
||||
}
|
||||
|
||||
evaluate_2_unsafe_math: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe_math: true,
|
||||
}
|
||||
input: {
|
||||
var x = "42", y = null;
|
||||
[
|
||||
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),
|
||||
].forEach(function(n) {
|
||||
console.log(typeof n, n);
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
var x = "42", y = null;
|
||||
[
|
||||
x + 1 + 2,
|
||||
2 * x,
|
||||
+x + 3,
|
||||
1 + x + 2 + 3,
|
||||
3 | x,
|
||||
6 + x--,
|
||||
x*y + 6,
|
||||
1 + (2 + x + 3),
|
||||
6 + ~x,
|
||||
5 + ~x - y,
|
||||
0 & x,
|
||||
6 + (x |= 0),
|
||||
].forEach(function(n) {
|
||||
console.log(typeof n, n);
|
||||
});
|
||||
}
|
||||
expect_stdout: [
|
||||
"string 4212",
|
||||
"number 84",
|
||||
"number 45",
|
||||
"string 14223",
|
||||
"number 43",
|
||||
"number 48",
|
||||
"number 6",
|
||||
"number 47",
|
||||
"number -36",
|
||||
"number -37",
|
||||
"number 0",
|
||||
"number 47",
|
||||
]
|
||||
}
|
||||
|
||||
evaluate_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
@@ -120,7 +273,7 @@ evaluate_3: {
|
||||
console.log(1 + Number(x) + 2);
|
||||
}
|
||||
expect: {
|
||||
console.log(3 + +x);
|
||||
console.log(+x + 3);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,6 +307,352 @@ evaluate_4: {
|
||||
}
|
||||
}
|
||||
|
||||
evaluate_5: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe_math: false,
|
||||
}
|
||||
input: {
|
||||
var a = "1";
|
||||
[
|
||||
+a + 2 + 3,
|
||||
+a + 2 - 3,
|
||||
+a - 2 + 3,
|
||||
+a - 2 - 3,
|
||||
2 + +a + 3,
|
||||
2 + +a - 3,
|
||||
2 - +a + 3,
|
||||
2 - +a - 3,
|
||||
2 + 3 + +a,
|
||||
2 + 3 - +a,
|
||||
2 - 3 + +a,
|
||||
2 - 3 - +a,
|
||||
].forEach(function(n) {
|
||||
console.log(typeof n, n);
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
var a = "1";
|
||||
[
|
||||
+a + 2 + 3,
|
||||
+a + 2 - 3,
|
||||
a - 2 + 3,
|
||||
a - 2 - 3,
|
||||
+a + 2 + 3,
|
||||
+a + 2 - 3,
|
||||
2 - a + 3,
|
||||
2 - a - 3,
|
||||
+a + 5,
|
||||
5 - a,
|
||||
+a - 1,
|
||||
-1 - a,
|
||||
].forEach(function(n) {
|
||||
console.log(typeof n, n);
|
||||
});
|
||||
}
|
||||
expect_stdout: [
|
||||
"number 6",
|
||||
"number 0",
|
||||
"number 2",
|
||||
"number -4",
|
||||
"number 6",
|
||||
"number 0",
|
||||
"number 4",
|
||||
"number -2",
|
||||
"number 6",
|
||||
"number 4",
|
||||
"number 0",
|
||||
"number -2",
|
||||
]
|
||||
}
|
||||
|
||||
evaluate_5_unsafe_math: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe_math: true,
|
||||
}
|
||||
input: {
|
||||
var a = "1";
|
||||
[
|
||||
+a + 2 + 3,
|
||||
+a + 2 - 3,
|
||||
+a - 2 + 3,
|
||||
+a - 2 - 3,
|
||||
2 + +a + 3,
|
||||
2 + +a - 3,
|
||||
2 - +a + 3,
|
||||
2 - +a - 3,
|
||||
2 + 3 + +a,
|
||||
2 + 3 - +a,
|
||||
2 - 3 + +a,
|
||||
2 - 3 - +a,
|
||||
].forEach(function(n) {
|
||||
console.log(typeof n, n);
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
var a = "1";
|
||||
[
|
||||
+a + 5,
|
||||
+a + -1,
|
||||
a - -1,
|
||||
a - 5,
|
||||
+a + 5,
|
||||
+a + -1,
|
||||
5 - a,
|
||||
-1 - a,
|
||||
+a + 5,
|
||||
5 - a,
|
||||
+a - 1,
|
||||
-1 - a,
|
||||
].forEach(function(n) {
|
||||
console.log(typeof n, n);
|
||||
});
|
||||
}
|
||||
expect_stdout: [
|
||||
"number 6",
|
||||
"number 0",
|
||||
"number 2",
|
||||
"number -4",
|
||||
"number 6",
|
||||
"number 0",
|
||||
"number 4",
|
||||
"number -2",
|
||||
"number 6",
|
||||
"number 4",
|
||||
"number 0",
|
||||
"number -2",
|
||||
]
|
||||
}
|
||||
|
||||
evaluate_6: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe_math: false,
|
||||
}
|
||||
input: {
|
||||
var a = "1";
|
||||
[
|
||||
-a + 2 + 3,
|
||||
-a + 2 - 3,
|
||||
-a - 2 + 3,
|
||||
-a - 2 - 3,
|
||||
2 + -a + 3,
|
||||
2 + -a - 3,
|
||||
2 - -a + 3,
|
||||
2 - -a - 3,
|
||||
2 + 3 + -a,
|
||||
2 + 3 - -a,
|
||||
2 - 3 + -a,
|
||||
2 - 3 - -a,
|
||||
].forEach(function(n) {
|
||||
console.log(typeof n, n);
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
var a = "1";
|
||||
[
|
||||
2 - a + 3,
|
||||
2 - a - 3,
|
||||
-a - 2 + 3,
|
||||
-a - 2 - 3,
|
||||
2 - a + 3,
|
||||
2 - a - 3,
|
||||
2 - -a + 3,
|
||||
2 - -a - 3,
|
||||
5 - a,
|
||||
5 - -a,
|
||||
-1 - a,
|
||||
-1 - -a,
|
||||
].forEach(function(n) {
|
||||
console.log(typeof n, n);
|
||||
});
|
||||
}
|
||||
expect_stdout: [
|
||||
"number 4",
|
||||
"number -2",
|
||||
"number 0",
|
||||
"number -6",
|
||||
"number 4",
|
||||
"number -2",
|
||||
"number 6",
|
||||
"number 0",
|
||||
"number 4",
|
||||
"number 6",
|
||||
"number -2",
|
||||
"number 0",
|
||||
]
|
||||
}
|
||||
|
||||
evaluate_6_unsafe_math: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe_math: true,
|
||||
}
|
||||
input: {
|
||||
var a = "1";
|
||||
[
|
||||
-a + 2 + 3,
|
||||
-a + 2 - 3,
|
||||
-a - 2 + 3,
|
||||
-a - 2 - 3,
|
||||
2 + -a + 3,
|
||||
2 + -a - 3,
|
||||
2 - -a + 3,
|
||||
2 - -a - 3,
|
||||
2 + 3 + -a,
|
||||
2 + 3 - -a,
|
||||
2 - 3 + -a,
|
||||
2 - 3 - -a,
|
||||
].forEach(function(n) {
|
||||
console.log(typeof n, n);
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
var a = "1";
|
||||
[
|
||||
5 - a,
|
||||
-1 - a,
|
||||
-a - -1,
|
||||
-a - 5,
|
||||
5 - a,
|
||||
-1 - a,
|
||||
5 - -a,
|
||||
-1 - -a,
|
||||
5 - a,
|
||||
5 - -a,
|
||||
-1 - a,
|
||||
-1 - -a,
|
||||
].forEach(function(n) {
|
||||
console.log(typeof n, n);
|
||||
});
|
||||
}
|
||||
expect_stdout: [
|
||||
"number 4",
|
||||
"number -2",
|
||||
"number 0",
|
||||
"number -6",
|
||||
"number 4",
|
||||
"number -2",
|
||||
"number 6",
|
||||
"number 0",
|
||||
"number 4",
|
||||
"number 6",
|
||||
"number -2",
|
||||
"number 0",
|
||||
]
|
||||
}
|
||||
|
||||
evaluate_7: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe_math: false,
|
||||
}
|
||||
input: {
|
||||
var x = "42", y;
|
||||
[
|
||||
+x + 2 + (3 + !y),
|
||||
+x + 2 + (3 - !y),
|
||||
+x + 2 - (3 + !y),
|
||||
+x + 2 - (3 - !y),
|
||||
+x - 2 + (3 + !y),
|
||||
+x - 2 + (3 - !y),
|
||||
+x - 2 - (3 + !y),
|
||||
+x - 2 - (3 - !y),
|
||||
].forEach(function(n) {
|
||||
console.log(typeof n, n);
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
var x = "42", y;
|
||||
[
|
||||
+x + 2 + (3 + !y),
|
||||
+x + 2 + (3 - !y),
|
||||
+x + 2 - (3 + !y),
|
||||
+x + 2 - (3 - !y),
|
||||
x - 2 + (3 + !y),
|
||||
x - 2 + (3 - !y),
|
||||
x - 2 - (3 + !y),
|
||||
x - 2 - (3 - !y),
|
||||
].forEach(function(n) {
|
||||
console.log(typeof n, n);
|
||||
});
|
||||
}
|
||||
expect_stdout: [
|
||||
"number 48",
|
||||
"number 46",
|
||||
"number 40",
|
||||
"number 42",
|
||||
"number 44",
|
||||
"number 42",
|
||||
"number 36",
|
||||
"number 38",
|
||||
]
|
||||
}
|
||||
|
||||
evaluate_7_unsafe_math: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe_math: true,
|
||||
}
|
||||
input: {
|
||||
var x = "42", y;
|
||||
[
|
||||
+x + 2 + (3 + !y),
|
||||
+x + 2 + (3 - !y),
|
||||
+x + 2 - (3 + !y),
|
||||
+x + 2 - (3 - !y),
|
||||
+x - 2 + (3 + !y),
|
||||
+x - 2 + (3 - !y),
|
||||
+x - 2 - (3 + !y),
|
||||
+x - 2 - (3 - !y),
|
||||
].forEach(function(n) {
|
||||
console.log(typeof n, n);
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
var x = "42", y;
|
||||
[
|
||||
+x + 5 + !y,
|
||||
+x + 5 - !y,
|
||||
+x + -1 - !y,
|
||||
+x + -1 + !y,
|
||||
x - -1 + !y,
|
||||
x - -1 - !y,
|
||||
x - 5 - !y,
|
||||
x - 5 + !y,
|
||||
].forEach(function(n) {
|
||||
console.log(typeof n, n);
|
||||
});
|
||||
}
|
||||
expect_stdout: [
|
||||
"number 48",
|
||||
"number 46",
|
||||
"number 40",
|
||||
"number 42",
|
||||
"number 44",
|
||||
"number 42",
|
||||
"number 36",
|
||||
"number 38",
|
||||
]
|
||||
}
|
||||
|
||||
NaN_redefined: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe_math: true,
|
||||
}
|
||||
input: {
|
||||
var NaN;
|
||||
console.log(1 / (0 / 0));
|
||||
}
|
||||
expect: {
|
||||
var NaN;
|
||||
console.log(0 / 0);
|
||||
}
|
||||
expect_stdout: "NaN"
|
||||
}
|
||||
|
||||
issue_1710: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
@@ -202,3 +701,281 @@ unary_binary_parenthesis: {
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_3531_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe_math: true,
|
||||
}
|
||||
input: {
|
||||
var a = "1";
|
||||
console.log(typeof (a + 1 - .1 - .1 - .1));
|
||||
}
|
||||
expect: {
|
||||
var a = "1";
|
||||
console.log(typeof (a + 1 - .3));
|
||||
}
|
||||
expect_stdout: "number"
|
||||
}
|
||||
|
||||
issue_3531_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe_math: true,
|
||||
}
|
||||
input: {
|
||||
console.log(1 - (2 - {}));
|
||||
}
|
||||
expect: {
|
||||
console.log(-1 + +{});
|
||||
}
|
||||
expect_stdout: "NaN"
|
||||
}
|
||||
|
||||
issue_3531_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe_math: true,
|
||||
}
|
||||
input: {
|
||||
var a = "3";
|
||||
console.log(1 - (2 + a));
|
||||
}
|
||||
expect: {
|
||||
var a = "3";
|
||||
console.log(1 - (2 + a));
|
||||
}
|
||||
expect_stdout: "-22"
|
||||
}
|
||||
|
||||
issue_3536: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe_math: true,
|
||||
}
|
||||
input: {
|
||||
var a = 100, b = 10;
|
||||
var c = --a + ("23" - (b++, 1));
|
||||
console.log(typeof c, a, b, c);
|
||||
}
|
||||
expect: {
|
||||
var a = 100, b = 10;
|
||||
var c = --a + ("23" - (b++, 1));
|
||||
console.log(typeof c, a, b, c);
|
||||
}
|
||||
expect_stdout: "number 99 11 121"
|
||||
}
|
||||
|
||||
issue_3539: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe_math: true,
|
||||
}
|
||||
input: {
|
||||
var a = -0 + -"";
|
||||
console.log(0/a, 1/a, -1/a);
|
||||
}
|
||||
expect: {
|
||||
var a = -0;
|
||||
console.log(0/a, 1/a, -1/a);
|
||||
}
|
||||
expect_stdout: "NaN -Infinity Infinity"
|
||||
}
|
||||
|
||||
issue_3547_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe_math: true,
|
||||
}
|
||||
input: {
|
||||
[
|
||||
1/0 + "1" + 0,
|
||||
1/0 + "1" - 0,
|
||||
1/0 - "1" + 0,
|
||||
1/0 - "1" - 0,
|
||||
].forEach(function(n) {
|
||||
console.log(typeof n, n);
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
[
|
||||
1/0 + "10",
|
||||
NaN,
|
||||
1/0,
|
||||
1/0,
|
||||
].forEach(function(n) {
|
||||
console.log(typeof n, n);
|
||||
});
|
||||
}
|
||||
expect_stdout: [
|
||||
"string Infinity10",
|
||||
"number NaN",
|
||||
"number Infinity",
|
||||
"number Infinity",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3547_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe_math: true,
|
||||
}
|
||||
input: {
|
||||
[
|
||||
"1" + 1/0 + 0,
|
||||
"1" + 1/0 - 0,
|
||||
"1" - 1/0 + 0,
|
||||
"1" - 1/0 - 0,
|
||||
].forEach(function(n) {
|
||||
console.log(typeof n, n);
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
[
|
||||
"1" + 1/0 + 0,
|
||||
NaN,
|
||||
-1/0,
|
||||
-1/0,
|
||||
].forEach(function(n) {
|
||||
console.log(typeof n, n);
|
||||
});
|
||||
}
|
||||
expect_stdout: [
|
||||
"string 1Infinity0",
|
||||
"number NaN",
|
||||
"number -Infinity",
|
||||
"number -Infinity",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3547_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe_math: true,
|
||||
}
|
||||
input: {
|
||||
var a = "3";
|
||||
[
|
||||
a + "2" + 1,
|
||||
a + "2" - 1,
|
||||
a - "2" + 1,
|
||||
a - "2" - 1,
|
||||
].forEach(function(n) {
|
||||
console.log(typeof n, n);
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
var a = "3";
|
||||
[
|
||||
a + "21",
|
||||
a + "2" - 1,
|
||||
a - 1,
|
||||
a - 3,
|
||||
].forEach(function(n) {
|
||||
console.log(typeof n, n);
|
||||
});
|
||||
}
|
||||
expect_stdout: [
|
||||
"string 321",
|
||||
"number 31",
|
||||
"number 2",
|
||||
"number 0",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3547_4: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe_math: true,
|
||||
}
|
||||
input: {
|
||||
var a = "2";
|
||||
[
|
||||
"3" + a + 1,
|
||||
"3" + a - 1,
|
||||
"3" - a + 1,
|
||||
"3" - a - 1,
|
||||
].forEach(function(n) {
|
||||
console.log(typeof n, n);
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
var a = "2";
|
||||
[
|
||||
"3" + a + 1,
|
||||
"3" + a - 1,
|
||||
4 - a,
|
||||
2 - a,
|
||||
].forEach(function(n) {
|
||||
console.log(typeof n, n);
|
||||
});
|
||||
}
|
||||
expect_stdout: [
|
||||
"string 321",
|
||||
"number 31",
|
||||
"number 2",
|
||||
"number 0",
|
||||
]
|
||||
}
|
||||
|
||||
unsafe_math_rounding: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe_math: true,
|
||||
}
|
||||
input: {
|
||||
console.log(4 / -3 + 1 === 1 / -3);
|
||||
}
|
||||
expect: {
|
||||
console.log(false);
|
||||
}
|
||||
expect_stdout: "false"
|
||||
}
|
||||
|
||||
issue_3593: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe_math: true,
|
||||
}
|
||||
input: {
|
||||
console.log((0 === this) - 1 - "1");
|
||||
}
|
||||
expect: {
|
||||
console.log((0 === this) - 2);
|
||||
}
|
||||
expect_stdout: "-2"
|
||||
}
|
||||
|
||||
unsafe_math_swap_constant: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe_math: true,
|
||||
}
|
||||
input: {
|
||||
var a = 1, b = 2;
|
||||
console.log(
|
||||
a++ + b-- + 3,
|
||||
a++ + b + 3,
|
||||
a + b-- + 3,
|
||||
a + b + 3,
|
||||
a++ - b-- + 3,
|
||||
a++ - b + 3,
|
||||
a - b-- + 3,
|
||||
a - b + 3
|
||||
);
|
||||
}
|
||||
expect: {
|
||||
var a = 1, b = 2;
|
||||
console.log(
|
||||
3 + a++ + b--,
|
||||
a++ + b + 3,
|
||||
a + b-- + 3,
|
||||
a + b + 3,
|
||||
3 + a++ - b--,
|
||||
3 + a++ - b,
|
||||
a - b-- + 3,
|
||||
a - b + 3
|
||||
);
|
||||
}
|
||||
expect_stdout: "6 6 7 6 6 8 9 10"
|
||||
}
|
||||
|
||||
223
test/compress/objects.js
Normal file
223
test/compress/objects.js
Normal file
@@ -0,0 +1,223 @@
|
||||
duplicate_key: {
|
||||
options = {
|
||||
objects: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
a: 1,
|
||||
b: 2,
|
||||
a: 3,
|
||||
};
|
||||
for (var k in o)
|
||||
console.log(k, o[k]);
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
a: 3,
|
||||
b: 2,
|
||||
};
|
||||
for (var k in o)
|
||||
console.log(k, o[k]);
|
||||
}
|
||||
expect_stdout: [
|
||||
"a 3",
|
||||
"b 2",
|
||||
]
|
||||
}
|
||||
|
||||
duplicate_key_strict: {
|
||||
options = {
|
||||
objects: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var o = {
|
||||
a: 1,
|
||||
b: 2,
|
||||
a: 3,
|
||||
};
|
||||
for (var k in o)
|
||||
console.log(k, o[k]);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var o = {
|
||||
a: 1,
|
||||
b: 2,
|
||||
a: 3,
|
||||
};
|
||||
for (var k in o)
|
||||
console.log(k, o[k]);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
duplicate_key_side_effect: {
|
||||
options = {
|
||||
objects: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
a: 1,
|
||||
b: o = 2,
|
||||
a: 3,
|
||||
};
|
||||
for (var k in o)
|
||||
console.log(k, o[k]);
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
a: 1,
|
||||
b: o = 2,
|
||||
a: 3,
|
||||
};
|
||||
for (var k in o)
|
||||
console.log(k, o[k]);
|
||||
}
|
||||
expect_stdout: [
|
||||
"a 3",
|
||||
"b 2",
|
||||
]
|
||||
}
|
||||
|
||||
duplicate_key_with_accessor: {
|
||||
options = {
|
||||
objects: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
[
|
||||
{
|
||||
a: 0,
|
||||
b: 1,
|
||||
a: 2,
|
||||
set b(v) {},
|
||||
},
|
||||
{
|
||||
a: 3,
|
||||
b: 4,
|
||||
get a() {
|
||||
return 5;
|
||||
},
|
||||
a: 6,
|
||||
b: 7,
|
||||
a: 8,
|
||||
b: 9,
|
||||
},
|
||||
].forEach(function(o) {
|
||||
for (var k in o)
|
||||
console.log(k, o[k]);
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
[
|
||||
{
|
||||
a: 2,
|
||||
b: 1,
|
||||
set b(v) {},
|
||||
},
|
||||
{
|
||||
a: 3,
|
||||
b: 4,
|
||||
get a() {
|
||||
return 5;
|
||||
},
|
||||
a: 8,
|
||||
b: 9,
|
||||
},
|
||||
].forEach(function(o) {
|
||||
for (var k in o)
|
||||
console.log(k, o[k]);
|
||||
});
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
unsafe_object_repeated: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
objects: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
var o = { a: { b: 1 }, a: 1 };
|
||||
console.log(
|
||||
o + 1,
|
||||
o.a + 1,
|
||||
o.b + 1,
|
||||
o.a.b + 1
|
||||
);
|
||||
}
|
||||
expect: {
|
||||
var o = { a: 1 };
|
||||
console.log(
|
||||
o + 1,
|
||||
2,
|
||||
o.b + 1,
|
||||
NaN
|
||||
);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
numeric_literal: {
|
||||
options = {
|
||||
objects: true,
|
||||
side_effects: true,
|
||||
}
|
||||
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: 3,',
|
||||
' 37: 4,',
|
||||
' o: 5,',
|
||||
' 1e42: 8,',
|
||||
' b: 7',
|
||||
'};',
|
||||
'',
|
||||
'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",
|
||||
]
|
||||
}
|
||||
181
test/compress/preserve_line.js
Normal file
181
test/compress/preserve_line.js
Normal file
@@ -0,0 +1,181 @@
|
||||
return_1: {
|
||||
beautify = {
|
||||
beautify: false,
|
||||
preserve_line: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function f() {
|
||||
return (
|
||||
f.toString() != 42
|
||||
);
|
||||
}());
|
||||
}
|
||||
expect_exact: [
|
||||
"console.log(function f(){",
|
||||
"",
|
||||
"return 42!=f.toString()}());",
|
||||
]
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
return_2: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
preserve_line: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function f() {
|
||||
return (
|
||||
f.toString() != 42
|
||||
);
|
||||
}());
|
||||
}
|
||||
expect_exact: [
|
||||
"console.log(function f() {",
|
||||
"",
|
||||
" return 42 != f.toString();",
|
||||
"}());",
|
||||
]
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
return_3: {
|
||||
options = {}
|
||||
beautify = {
|
||||
beautify: false,
|
||||
preserve_line: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function f() {
|
||||
return (
|
||||
f.toString() != 42
|
||||
);
|
||||
}());
|
||||
}
|
||||
expect_exact: [
|
||||
"console.log(function f(){",
|
||||
"",
|
||||
"return 42!=f.toString()}());",
|
||||
]
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
return_4: {
|
||||
options = {}
|
||||
beautify = {
|
||||
beautify: true,
|
||||
preserve_line: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function f() {
|
||||
return (
|
||||
f.toString() != 42
|
||||
);
|
||||
}());
|
||||
}
|
||||
expect_exact: [
|
||||
"console.log(function f() {",
|
||||
"",
|
||||
" return 42 != f.toString();",
|
||||
"}());",
|
||||
]
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
return_5: {
|
||||
beautify = {
|
||||
beautify: false,
|
||||
preserve_line: true,
|
||||
}
|
||||
input: {
|
||||
_is_selected = function(tags, slug) {
|
||||
var ref;
|
||||
return (ref = _.find(tags, {
|
||||
slug: slug
|
||||
})) != null ? ref.selected : void 0;
|
||||
};
|
||||
}
|
||||
expect_exact: [
|
||||
"_is_selected=function(tags,slug){",
|
||||
"var ref",
|
||||
"",
|
||||
"",
|
||||
";return null!=(ref=_.find(tags,{slug:slug}))?ref.selected:void 0};",
|
||||
]
|
||||
}
|
||||
|
||||
return_6: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
preserve_line: true,
|
||||
}
|
||||
input: {
|
||||
_is_selected = function(tags, slug) {
|
||||
var ref;
|
||||
return (ref = _.find(tags, {
|
||||
slug: slug
|
||||
})) != null ? ref.selected : void 0;
|
||||
};
|
||||
}
|
||||
expect_exact: [
|
||||
"_is_selected = function(tags, slug) {",
|
||||
" var ref;",
|
||||
"",
|
||||
"",
|
||||
" return null != (ref = _.find(tags, {",
|
||||
" slug: slug",
|
||||
" })) ? ref.selected : void 0;",
|
||||
"};",
|
||||
]
|
||||
}
|
||||
|
||||
return_7: {
|
||||
options = {}
|
||||
mangle = {}
|
||||
beautify = {
|
||||
beautify: false,
|
||||
preserve_line: true,
|
||||
}
|
||||
input: {
|
||||
_is_selected = function(tags, slug) {
|
||||
var ref;
|
||||
return (ref = _.find(tags, {
|
||||
slug: slug
|
||||
})) != null ? ref.selected : void 0;
|
||||
};
|
||||
}
|
||||
expect_exact: [
|
||||
"_is_selected=function(e,l){",
|
||||
"var n",
|
||||
"",
|
||||
"",
|
||||
";return null!=(n=_.find(e,{slug:l}))?n.selected:void 0};",
|
||||
]
|
||||
}
|
||||
|
||||
return_8: {
|
||||
options = {}
|
||||
mangle = {}
|
||||
beautify = {
|
||||
beautify: true,
|
||||
preserve_line: true,
|
||||
}
|
||||
input: {
|
||||
_is_selected = function(tags, slug) {
|
||||
var ref;
|
||||
return (ref = _.find(tags, {
|
||||
slug: slug
|
||||
})) != null ? ref.selected : void 0;
|
||||
};
|
||||
}
|
||||
expect_exact: [
|
||||
"_is_selected = function(e, l) {",
|
||||
" var n;",
|
||||
"",
|
||||
"",
|
||||
" return null != (n = _.find(e, {",
|
||||
" slug: l",
|
||||
" })) ? n.selected : void 0;",
|
||||
"};",
|
||||
]
|
||||
}
|
||||
@@ -567,16 +567,41 @@ native_prototype: {
|
||||
}
|
||||
input: {
|
||||
Array.prototype.splice.apply(a, [1, 2, b, c]);
|
||||
Function.prototype.call.apply(console.log, console, [ "foo" ]);
|
||||
Number.prototype.toFixed.call(Math.PI, 2);
|
||||
Object.prototype.hasOwnProperty.call(d, "foo");
|
||||
RegExp.prototype.test.call(/foo/, "bar");
|
||||
String.prototype.indexOf.call(e, "bar");
|
||||
}
|
||||
expect: {
|
||||
[].splice.apply(a, [1, 2, b, c]);
|
||||
(function() {}).call.apply(console.log, console, [ "foo" ]);
|
||||
0..toFixed.call(Math.PI, 2);
|
||||
({}).hasOwnProperty.call(d, "foo");
|
||||
/t/.test.call(/foo/, "bar");
|
||||
"".indexOf.call(e, "bar");
|
||||
}
|
||||
}
|
||||
|
||||
native_prototype_lhs: {
|
||||
options = {
|
||||
unsafe_proto: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
Function.prototype.bar = "PASS";
|
||||
return function() {};
|
||||
}().bar);
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
Function.prototype.bar = "PASS";
|
||||
return function() {};
|
||||
}().bar);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
accessor_boolean: {
|
||||
input: {
|
||||
var a = 1;
|
||||
@@ -1054,3 +1079,812 @@ issue_2513: {
|
||||
"undefined undefined",
|
||||
]
|
||||
}
|
||||
|
||||
const_prop_assign_strict: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function Simulator() {
|
||||
/abc/.index = 1;
|
||||
this._aircraft = [];
|
||||
}
|
||||
(function() {}).prototype.destroy = x();
|
||||
}
|
||||
expect: {
|
||||
function Simulator() {
|
||||
this._aircraft = [];
|
||||
}
|
||||
x();
|
||||
}
|
||||
}
|
||||
|
||||
const_prop_assign_pure: {
|
||||
options = {
|
||||
pure_getters: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function Simulator() {
|
||||
/abc/.index = 1;
|
||||
this._aircraft = [];
|
||||
}
|
||||
(function() {}).prototype.destroy = x();
|
||||
}
|
||||
expect: {
|
||||
function Simulator() {
|
||||
this._aircraft = [];
|
||||
}
|
||||
x();
|
||||
}
|
||||
}
|
||||
|
||||
join_object_assignments_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
var x = {
|
||||
a: 1,
|
||||
c: (console.log("c"), "C"),
|
||||
};
|
||||
x.b = 2;
|
||||
x[3] = function() {
|
||||
console.log(x);
|
||||
},
|
||||
x["a"] = /foo/,
|
||||
x.bar = x;
|
||||
return x;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
var x = {
|
||||
a: 1,
|
||||
c: (console.log("c"), "C"),
|
||||
b: 2,
|
||||
3: function() {
|
||||
console.log(x);
|
||||
},
|
||||
a: /foo/,
|
||||
};
|
||||
x.bar = x;
|
||||
return x;
|
||||
}());
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
join_object_assignments_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_props: true,
|
||||
join_vars: true,
|
||||
passes: 3,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
foo: 1,
|
||||
};
|
||||
o.bar = 2;
|
||||
o.baz = 3;
|
||||
console.log(o.foo, o.bar + o.bar, o.foo * o.bar * o.baz);
|
||||
}
|
||||
expect: {
|
||||
console.log(1, 4, 6);
|
||||
}
|
||||
expect_stdout: "1 4 6"
|
||||
}
|
||||
|
||||
join_object_assignments_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
var o = {
|
||||
a: "PASS",
|
||||
}, a = o.a;
|
||||
o.a = "FAIL";
|
||||
return a;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
var o = {
|
||||
a: "PASS",
|
||||
}, a = o.a;
|
||||
o.a = "FAIL";
|
||||
return a;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
join_object_assignments_4: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
var o;
|
||||
console.log(o);
|
||||
o = {};
|
||||
o.a = "foo";
|
||||
console.log(o.b);
|
||||
o.b = "bar";
|
||||
console.log(o.a);
|
||||
}
|
||||
expect: {
|
||||
var o;
|
||||
console.log(o),
|
||||
o = {
|
||||
a: "foo",
|
||||
},
|
||||
console.log(o.b),
|
||||
o.b = "bar",
|
||||
console.log(o.a);
|
||||
}
|
||||
expect_stdout: [
|
||||
"undefined",
|
||||
"undefined",
|
||||
"foo",
|
||||
]
|
||||
}
|
||||
|
||||
join_object_assignments_return_1: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
var o = {
|
||||
p: 3
|
||||
};
|
||||
return o.q = "foo";
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
var o = {
|
||||
p: 3,
|
||||
q: "foo"
|
||||
};
|
||||
return o.q;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "foo"
|
||||
}
|
||||
|
||||
join_object_assignments_return_2: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
var o = {
|
||||
p: 3
|
||||
};
|
||||
return o.q = /foo/,
|
||||
o.r = "bar";
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
var o = {
|
||||
p: 3,
|
||||
q: /foo/,
|
||||
r: "bar"
|
||||
};
|
||||
return o.r;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "bar"
|
||||
}
|
||||
|
||||
join_object_assignments_return_3: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
var o = {
|
||||
p: 3
|
||||
};
|
||||
return o.q = "foo",
|
||||
o.p += "",
|
||||
console.log(o.q),
|
||||
o.p;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
var o = {
|
||||
p: 3,
|
||||
q: "foo"
|
||||
};
|
||||
return o.p += "",
|
||||
console.log(o.q),
|
||||
o.p;
|
||||
}());
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"3",
|
||||
]
|
||||
}
|
||||
|
||||
join_object_assignments_for: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
var o = {
|
||||
p: 3
|
||||
};
|
||||
for (o.q = "foo"; console.log(o.q););
|
||||
return o.p;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
for (var o = {
|
||||
p: 3,
|
||||
q: "foo"
|
||||
}; console.log(o.q););
|
||||
return o.p;
|
||||
}());
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"3",
|
||||
]
|
||||
}
|
||||
|
||||
join_object_assignments_if: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
var o = {};
|
||||
if (o.a = "PASS") return o.a;
|
||||
}())
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
var o = { a: "PASS" };
|
||||
if (o.a) return o.a;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
join_object_assignments_forin: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
var o = {};
|
||||
for (var a in o.a = "PASS", o)
|
||||
return o[a];
|
||||
}())
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
var o = { a: "PASS" };
|
||||
for (var a in o)
|
||||
return o[a];
|
||||
}());
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
join_object_assignments_negative: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
join_vars: true,
|
||||
properties: true,
|
||||
}
|
||||
input: {
|
||||
var o = {};
|
||||
o[0] = 0;
|
||||
o[-0] = 1;
|
||||
o[-1] = 2;
|
||||
console.log(o[0], o[-0], o[-1]);
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
0: 0,
|
||||
0: 1,
|
||||
"-1": 2
|
||||
};
|
||||
console.log(o[0], o[-0], o[-1]);
|
||||
}
|
||||
expect_stdout: "1 1 2"
|
||||
}
|
||||
|
||||
join_object_assignments_NaN_1: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
var o = {};
|
||||
o[NaN] = 1;
|
||||
o[0/0] = 2;
|
||||
console.log(o[NaN], o[NaN]);
|
||||
}
|
||||
expect: {
|
||||
var o = {};
|
||||
o[NaN] = 1;
|
||||
o[0/0] = 2;
|
||||
console.log(o[NaN], o[NaN]);
|
||||
}
|
||||
expect_stdout: "2 2"
|
||||
}
|
||||
|
||||
join_object_assignments_NaN_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
join_vars: true,
|
||||
properties: true,
|
||||
}
|
||||
input: {
|
||||
var o = {};
|
||||
o[NaN] = 1;
|
||||
o[0/0] = 2;
|
||||
console.log(o[NaN], o[NaN]);
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
NaN: 1,
|
||||
NaN: 2
|
||||
};
|
||||
console.log(o.NaN, o.NaN);
|
||||
}
|
||||
expect_stdout: "2 2"
|
||||
}
|
||||
|
||||
join_object_assignments_null_0: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
var o = {};
|
||||
o[null] = 1;
|
||||
console.log(o[null]);
|
||||
}
|
||||
expect: {
|
||||
var o = {};
|
||||
o[null] = 1;
|
||||
console.log(o[null]);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
join_object_assignments_null_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
join_vars: true,
|
||||
properties: true,
|
||||
}
|
||||
input: {
|
||||
var o = {};
|
||||
o[null] = 1;
|
||||
console.log(o[null]);
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
null: 1
|
||||
};
|
||||
console.log(o.null);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
join_object_assignments_void_0: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
var o = {};
|
||||
o[void 0] = 1;
|
||||
console.log(o[void 0]);
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
undefined: 1
|
||||
};
|
||||
console.log(o[void 0]);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
join_object_assignments_undefined_1: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
var o = {};
|
||||
o[undefined] = 1;
|
||||
console.log(o[undefined]);
|
||||
}
|
||||
expect: {
|
||||
var o = {};
|
||||
o[void 0] = 1;
|
||||
console.log(o[void 0]);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
join_object_assignments_undefined_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
join_vars: true,
|
||||
properties: true,
|
||||
}
|
||||
input: {
|
||||
var o = {};
|
||||
o[undefined] = 1;
|
||||
console.log(o[undefined]);
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
undefined : 1
|
||||
};
|
||||
console.log(o[void 0]);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
join_object_assignments_Infinity: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
join_vars: true,
|
||||
properties: true,
|
||||
}
|
||||
input: {
|
||||
var o = {};
|
||||
o[Infinity] = 1;
|
||||
o[1/0] = 2;
|
||||
o[-Infinity] = 3;
|
||||
o[-1/0] = 4;
|
||||
console.log(o[Infinity], o[1/0], o[-Infinity], o[-1/0]);
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
Infinity: 1,
|
||||
Infinity: 2,
|
||||
"-Infinity": 3,
|
||||
"-Infinity": 4
|
||||
};
|
||||
console.log(o[1/0], o[1/0], o[-1/0], o[-1/0]);
|
||||
}
|
||||
expect_stdout: "2 2 4 4"
|
||||
}
|
||||
|
||||
join_object_assignments_regex: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
join_vars: true,
|
||||
properties: true,
|
||||
}
|
||||
input: {
|
||||
var o = {};
|
||||
o[/rx/] = 1;
|
||||
console.log(o[/rx/]);
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
"/rx/": 1
|
||||
};
|
||||
console.log(o[/rx/]);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_2816: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var o = {
|
||||
a: 1
|
||||
};
|
||||
o.b = 2;
|
||||
o.a = 3;
|
||||
o.c = 4;
|
||||
console.log(o.a, o.b, o.c);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var o = {
|
||||
a: 1,
|
||||
b: 2
|
||||
};
|
||||
o.a = 3;
|
||||
o.c = 4;
|
||||
console.log(o.a, o.b, o.c);
|
||||
}
|
||||
expect_stdout: "3 2 4"
|
||||
}
|
||||
|
||||
issue_2893_1: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
get a() {
|
||||
return "PASS";
|
||||
},
|
||||
};
|
||||
o.a = "FAIL";
|
||||
console.log(o.a);
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
get a() {
|
||||
return "PASS";
|
||||
},
|
||||
};
|
||||
o.a = "FAIL";
|
||||
console.log(o.a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_2893_2: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
set a(v) {
|
||||
this.b = v;
|
||||
},
|
||||
b: "FAIL",
|
||||
};
|
||||
o.a = "PASS";
|
||||
console.log(o.b);
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
set a(v) {
|
||||
this.b = v;
|
||||
},
|
||||
b: "FAIL",
|
||||
};
|
||||
o.a = "PASS";
|
||||
console.log(o.b);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_869_1: {
|
||||
mangle = {
|
||||
properties: {
|
||||
reserved: [ "get" ]
|
||||
},
|
||||
}
|
||||
input: {
|
||||
var o = { p: "FAIL" };
|
||||
Object.defineProperty(o, "p", {
|
||||
get: function() {
|
||||
return "PASS";
|
||||
}
|
||||
});
|
||||
console.log(o.p);
|
||||
}
|
||||
expect: {
|
||||
var o = { o: "FAIL" };
|
||||
Object.defineProperty(o, "o", {
|
||||
get: function() {
|
||||
return "PASS";
|
||||
}
|
||||
});
|
||||
console.log(o.o);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_869_2: {
|
||||
mangle = {
|
||||
properties: {
|
||||
reserved: [ "get" ]
|
||||
},
|
||||
}
|
||||
input: {
|
||||
var o = { p: "FAIL" };
|
||||
Object.defineProperties(o, {
|
||||
p: {
|
||||
get: function() {
|
||||
return "PASS";
|
||||
}
|
||||
}
|
||||
});
|
||||
console.log(o.p);
|
||||
}
|
||||
expect: {
|
||||
var o = { o: "FAIL" };
|
||||
Object.defineProperties(o, {
|
||||
o: {
|
||||
get: function() {
|
||||
return "PASS";
|
||||
}
|
||||
}
|
||||
});
|
||||
console.log(o.o);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3188_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
inline: true,
|
||||
properties: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
function f() {
|
||||
console.log(this.p);
|
||||
}
|
||||
(function() {
|
||||
var o = {
|
||||
p: "PASS",
|
||||
f: f
|
||||
};
|
||||
o.f();
|
||||
})();
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
function f() {
|
||||
console.log(this.p);
|
||||
}
|
||||
({
|
||||
p: "PASS",
|
||||
f: f
|
||||
}).f();
|
||||
var o;
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3188_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
inline: true,
|
||||
properties: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
var f = function() {
|
||||
console.log(this.p);
|
||||
};
|
||||
function g() {
|
||||
var o = {
|
||||
p: "PASS",
|
||||
f: f
|
||||
};
|
||||
o.f();
|
||||
}
|
||||
g();
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
({
|
||||
p: "PASS",
|
||||
f: function() {
|
||||
console.log(this.p);
|
||||
}
|
||||
}).f();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3188_3: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
inline: true,
|
||||
properties: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
function f() {
|
||||
console.log(this[0]);
|
||||
}
|
||||
(function() {
|
||||
var o = ["PASS", f];
|
||||
o[1]();
|
||||
})();
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
function f() {
|
||||
console.log(this[0]);
|
||||
}
|
||||
["PASS", f][1]();
|
||||
var o;
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
join_expr: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
var c = "FAIL";
|
||||
(function() {
|
||||
var a = 0;
|
||||
switch ((a = {}) && (a.b = 0)) {
|
||||
case 0:
|
||||
c = "PASS";
|
||||
}
|
||||
})();
|
||||
console.log(c);
|
||||
}
|
||||
expect: {
|
||||
var c = "FAIL";
|
||||
(function() {
|
||||
var a = 0;
|
||||
switch (a = { b: 0 }, a.b) {
|
||||
case 0:
|
||||
c = "PASS";
|
||||
}
|
||||
})();
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3389: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
properties: true,
|
||||
reduce_vars: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
var a = "PASS";
|
||||
if (delete b)
|
||||
b = a[null] = 42;
|
||||
console.log(a);
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
var a = "PASS";
|
||||
if (delete b)
|
||||
b = a.null = 42;
|
||||
console.log(a);
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -293,3 +293,390 @@ unary: {
|
||||
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());",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2705_1: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
beautify = {
|
||||
comments: "all",
|
||||
}
|
||||
input: {
|
||||
/*@__PURE__*/ new a();
|
||||
/*@__PURE__*/ (new b());
|
||||
new (/*@__PURE__*/ c)();
|
||||
(/*@__PURE__*/ new d());
|
||||
}
|
||||
expect_exact: [
|
||||
"new/* */c;",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2705_2: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
beautify = {
|
||||
comments: "all",
|
||||
}
|
||||
input: {
|
||||
/*@__PURE__*/ new a(1)(2)(3);
|
||||
/*@__PURE__*/ new (b(1))(2)(3);
|
||||
/*@__PURE__*/ new (c(1)(2))(3);
|
||||
/*@__PURE__*/ new (d(1)(2)(3));
|
||||
new (/*@__PURE__*/ e)(1)(2)(3);
|
||||
(/*@__PURE__*/ new f(1))(2)(3);
|
||||
(/*@__PURE__*/ new g(1)(2))(3);
|
||||
(/*@__PURE__*/ new h(1)(2)(3));
|
||||
}
|
||||
expect_exact: [
|
||||
"new/* */e(1)(2)(3);",
|
||||
"/* */new f(1)(2)(3);",
|
||||
"/* */new g(1)(2)(3);",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2705_3: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
beautify = {
|
||||
comments: "all",
|
||||
}
|
||||
input: {
|
||||
/*@__PURE__*/ new a.x(1).y(2).z(3);
|
||||
/*@__PURE__*/ new (b.x)(1).y(2).z(3);
|
||||
/*@__PURE__*/ new (c.x(1)).y(2).z(3);
|
||||
/*@__PURE__*/ new (d.x(1).y)(2).z(3);
|
||||
/*@__PURE__*/ new (e.x(1).y(2)).z(3);
|
||||
/*@__PURE__*/ new (f.x(1).y(2).z)(3);
|
||||
/*@__PURE__*/ new (g.x(1).y(2).z(3));
|
||||
new (/*@__PURE__*/ h).x(1).y(2).z(3);
|
||||
/* */ new (/*@__PURE__*/ i.x)(1).y(2).z(3);
|
||||
(/*@__PURE__*/ new j.x(1)).y(2).z(3);
|
||||
(/*@__PURE__*/ new k.x(1).y)(2).z(3);
|
||||
(/*@__PURE__*/ new l.x(1).y(2)).z(3);
|
||||
(/*@__PURE__*/ new m.x(1).y(2).z)(3);
|
||||
(/*@__PURE__*/ new n.x(1).y(2).z(3));
|
||||
}
|
||||
expect_exact: [
|
||||
"new/* */h.x(1).y(2).z(3);",
|
||||
"/* */new/* */i.x(1).y(2).z(3);",
|
||||
"/* */new j.x(1).y(2).z(3);",
|
||||
"/* */new k.x(1).y(2).z(3);",
|
||||
"/* */new l.x(1).y(2).z(3);",
|
||||
"/* */new m.x(1).y(2).z(3);",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2705_4: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(/*@__PURE__*/ new x(), y());
|
||||
(w(), /*@__PURE__*/ new x(), y());
|
||||
}
|
||||
expect: {
|
||||
y();
|
||||
w(), y();
|
||||
}
|
||||
}
|
||||
|
||||
issue_2705_5: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
[ /*@__PURE__*/ new x() ];
|
||||
[ /*@__PURE__*/ new x(), y() ];
|
||||
[ w(), /*@__PURE__*/ new x(), y() ];
|
||||
}
|
||||
expect: {
|
||||
y();
|
||||
w(), y();
|
||||
}
|
||||
}
|
||||
|
||||
issue_2705_6: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
beautify = {
|
||||
comments: "all",
|
||||
}
|
||||
input: {
|
||||
/*@__PURE__*/new (g() || h())(x(), y());
|
||||
/* */ new (/*@__PURE__*/ (a() || b()))(c(), d());
|
||||
}
|
||||
expect_exact: [
|
||||
"/* */x(),y();",
|
||||
"/* */new(/* */a()||b())(c(),d());",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3065_1: {
|
||||
options = {
|
||||
inline: true,
|
||||
pure_funcs: [ "pureFunc" ],
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function modifyWrapper(a, f, wrapper) {
|
||||
wrapper.a = a;
|
||||
wrapper.f = f;
|
||||
return wrapper;
|
||||
}
|
||||
function pureFunc(fun) {
|
||||
return modifyWrapper(1, fun, function(a) {
|
||||
return fun(a);
|
||||
});
|
||||
}
|
||||
var unused = pureFunc(function(x) {
|
||||
return x;
|
||||
});
|
||||
}
|
||||
expect: {}
|
||||
}
|
||||
|
||||
issue_3065_2: {
|
||||
rename = true
|
||||
options = {
|
||||
inline: true,
|
||||
pure_funcs: [ "pureFunc" ],
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
mangle = {
|
||||
reserved: [ "pureFunc" ],
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
function modifyWrapper(a, f, wrapper) {
|
||||
wrapper.a = a;
|
||||
wrapper.f = f;
|
||||
return wrapper;
|
||||
}
|
||||
function pureFunc(fun) {
|
||||
return modifyWrapper(1, fun, function(a) {
|
||||
return fun(a);
|
||||
});
|
||||
}
|
||||
var unused = pureFunc(function(x) {
|
||||
return x;
|
||||
});
|
||||
}
|
||||
expect: {}
|
||||
}
|
||||
|
||||
issue_3065_3: {
|
||||
options = {
|
||||
pure_funcs: [ "debug" ],
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function debug(msg) {
|
||||
console.log(msg);
|
||||
}
|
||||
debug(function() {
|
||||
console.log("PASS");
|
||||
return "FAIL";
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
console.log("PASS");
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
||||
issue_3065_4: {
|
||||
options = {
|
||||
pure_funcs: [ "debug" ],
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var debug = function(msg) {
|
||||
console.log(msg);
|
||||
};
|
||||
debug(function() {
|
||||
console.log("PASS");
|
||||
return "FAIL";
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
console.log("PASS");
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
||||
issue_3325_1: {
|
||||
options = {
|
||||
pure_funcs: "cb",
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function cb() {
|
||||
console.log("PASS");
|
||||
}
|
||||
cb();
|
||||
}
|
||||
expect: {
|
||||
function cb() {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_3325_2: {
|
||||
options = {
|
||||
pure_funcs: "xxxcbxxx",
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function cb() {
|
||||
console.log("PASS");
|
||||
}
|
||||
cb();
|
||||
}
|
||||
expect: {
|
||||
function cb() {
|
||||
console.log("PASS");
|
||||
}
|
||||
cb();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -185,12 +185,12 @@ impure_getter_2: {
|
||||
|
||||
issue_2110_1: {
|
||||
options = {
|
||||
cascade: true,
|
||||
collapse_vars: true,
|
||||
pure_getters: "strict",
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
@@ -274,7 +274,7 @@ set_immutable_1: {
|
||||
|
||||
set_immutable_2: {
|
||||
options = {
|
||||
cascade: true,
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
pure_getters: "strict",
|
||||
reduce_funcs: true,
|
||||
@@ -324,7 +324,7 @@ set_immutable_3: {
|
||||
|
||||
set_immutable_4: {
|
||||
options = {
|
||||
cascade: true,
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
pure_getters: "strict",
|
||||
reduce_funcs: true,
|
||||
@@ -348,6 +348,57 @@ set_immutable_4: {
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
set_immutable_5: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
pure_getters: "strict",
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
side_effects: 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 += "";
|
||||
1..foo ? console.log("FAIL") : console.log("PASS");
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
set_immutable_6: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
pure_getters: "strict",
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 1;
|
||||
a.foo += "";
|
||||
if (a.foo) console.log("FAIL");
|
||||
else console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
1..foo ? console.log("FAIL") : console.log("PASS");
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
set_mutable_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
@@ -375,7 +426,7 @@ set_mutable_1: {
|
||||
|
||||
set_mutable_2: {
|
||||
options = {
|
||||
cascade: true,
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
pure_getters: "strict",
|
||||
reduce_funcs: true,
|
||||
@@ -400,7 +451,7 @@ set_mutable_2: {
|
||||
|
||||
issue_2313_1: {
|
||||
options = {
|
||||
cascade: true,
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
pure_getters: "strict",
|
||||
sequences: true,
|
||||
@@ -446,7 +497,7 @@ issue_2313_1: {
|
||||
|
||||
issue_2313_2: {
|
||||
options = {
|
||||
cascade: true,
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
pure_getters: true,
|
||||
sequences: true,
|
||||
@@ -611,3 +662,550 @@ issue_2313_6: {
|
||||
x();
|
||||
}
|
||||
}
|
||||
|
||||
issue_2678: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var a = 1, c = "FAIL";
|
||||
(function f() {
|
||||
(a-- && f()).p;
|
||||
return {
|
||||
get p() {
|
||||
c = "PASS";
|
||||
}
|
||||
};
|
||||
})();
|
||||
console.log(c);
|
||||
}
|
||||
expect: {
|
||||
var a = 1, c = "FAIL";
|
||||
(function f() {
|
||||
(a-- && f()).p;
|
||||
return {
|
||||
get p() {
|
||||
c = "PASS";
|
||||
}
|
||||
};
|
||||
})();
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_2838: {
|
||||
options = {
|
||||
pure_getters: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b) {
|
||||
(a || b).c = "PASS";
|
||||
(function() {
|
||||
return f(a, b);
|
||||
}).prototype.foo = "bar";
|
||||
}
|
||||
var o = {};
|
||||
f(null, o);
|
||||
console.log(o.c);
|
||||
}
|
||||
expect: {
|
||||
function f(a, b) {
|
||||
(a || b).c = "PASS";
|
||||
}
|
||||
var o = {};
|
||||
f(null, o);
|
||||
console.log(o.c);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_2938_1: {
|
||||
options = {
|
||||
pure_getters: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
a.b = "PASS";
|
||||
}
|
||||
var o = {};
|
||||
f(o);
|
||||
console.log(o.b);
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
a.b = "PASS";
|
||||
}
|
||||
var o = {};
|
||||
f(o);
|
||||
console.log(o.b);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_2938_2: {
|
||||
options = {
|
||||
pure_getters: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var Parser = function Parser() {};
|
||||
var p = Parser.prototype;
|
||||
p.initialContext = function initialContext() {
|
||||
console.log("PASS");
|
||||
};
|
||||
p.braceIsBlock = function() {};
|
||||
(new Parser).initialContext();
|
||||
}
|
||||
expect: {
|
||||
var Parser = function() {};
|
||||
var p = Parser.prototype;
|
||||
p.initialContext = function() {
|
||||
console.log("PASS");
|
||||
};
|
||||
p.braceIsBlock = function() {};
|
||||
(new Parser).initialContext();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_2938_3: {
|
||||
options = {
|
||||
pure_getters: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
var unused = a.a;
|
||||
a.b = "PASS";
|
||||
a.c;
|
||||
}
|
||||
var o = {};
|
||||
o.d;
|
||||
f(o);
|
||||
console.log(o.b);
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
a.b = "PASS";
|
||||
}
|
||||
var o = {};
|
||||
f(o);
|
||||
console.log(o.b);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_2938_4: {
|
||||
options = {
|
||||
pure_getters: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var Parser = function Parser() {};
|
||||
var p = Parser.prototype;
|
||||
var unused = p.x;
|
||||
p.initialContext = function initialContext() {
|
||||
p.y;
|
||||
console.log("PASS");
|
||||
};
|
||||
p.braceIsBlock = function() {};
|
||||
(new Parser).initialContext();
|
||||
}
|
||||
expect: {
|
||||
var Parser = function() {};
|
||||
var p = Parser.prototype;
|
||||
p.initialContext = function() {
|
||||
console.log("PASS");
|
||||
};
|
||||
p.braceIsBlock = function() {};
|
||||
(new Parser).initialContext();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
collapse_vars_1_true: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b) {
|
||||
for (;;) {
|
||||
var c = a.g();
|
||||
var d = b.p;
|
||||
if (c || d) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(a, b) {
|
||||
for (;;) {
|
||||
if (a.g() || b.p) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
collapse_vars_1_false: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: false,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b) {
|
||||
for (;;) {
|
||||
var c = a.g();
|
||||
var d = b.p;
|
||||
if (c || d) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(a, b) {
|
||||
for (;;) {
|
||||
var c = a.g();
|
||||
var d = b.p;
|
||||
if (c || d) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
collapse_vars_1_strict: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: "strict",
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b) {
|
||||
for (;;) {
|
||||
var c = a.g();
|
||||
var d = b.p;
|
||||
if (c || d) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(a, b) {
|
||||
for (;;) {
|
||||
var c = a.g();
|
||||
var d = b.p;
|
||||
if (c || d) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
collapse_vars_2_true: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
function g() {}
|
||||
g.a = function() {};
|
||||
g.b = g.a;
|
||||
return g;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
function g() {}
|
||||
g.b = g.a = function() {};
|
||||
return g;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
collapse_vars_2_false: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: false,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
function g() {}
|
||||
g.a = function() {};
|
||||
g.b = g.a;
|
||||
return g;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
function g() {}
|
||||
g.a = function() {};
|
||||
g.b = g.a;
|
||||
return g;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
collapse_vars_2_strict: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
function g() {}
|
||||
g.a = function() {};
|
||||
g.b = g.a;
|
||||
return g;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
function g() {}
|
||||
g.b = g.a = function() {};
|
||||
return g;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
collapse_rhs_true: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: true,
|
||||
}
|
||||
input: {
|
||||
console.log((42..length = "PASS", "PASS"));
|
||||
console.log(("foo".length = "PASS", "PASS"));
|
||||
console.log((false.length = "PASS", "PASS"));
|
||||
console.log((function() {}.length = "PASS", "PASS"));
|
||||
console.log(({
|
||||
get length() {
|
||||
return "FAIL";
|
||||
}
|
||||
}.length = "PASS", "PASS"));
|
||||
}
|
||||
expect: {
|
||||
console.log(42..length = "PASS");
|
||||
console.log("foo".length = "PASS");
|
||||
console.log(false.length = "PASS");
|
||||
console.log(function() {}.length = "PASS");
|
||||
console.log({
|
||||
get length() {
|
||||
return "FAIL";
|
||||
}
|
||||
}.length = "PASS");
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
]
|
||||
}
|
||||
|
||||
collapse_rhs_false: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: false,
|
||||
}
|
||||
input: {
|
||||
console.log((42..length = "PASS", "PASS"));
|
||||
console.log(("foo".length = "PASS", "PASS"));
|
||||
console.log((false.length = "PASS", "PASS"));
|
||||
console.log((function() {}.length = "PASS", "PASS"));
|
||||
console.log(({
|
||||
get length() {
|
||||
return "FAIL";
|
||||
}
|
||||
}.length = "PASS", "PASS"));
|
||||
}
|
||||
expect: {
|
||||
console.log(42..length = "PASS");
|
||||
console.log("foo".length = "PASS");
|
||||
console.log(false.length = "PASS");
|
||||
console.log(function() {}.length = "PASS");
|
||||
console.log({
|
||||
get length() {
|
||||
return "FAIL";
|
||||
}
|
||||
}.length = "PASS");
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
]
|
||||
}
|
||||
|
||||
collapse_rhs_strict: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: "strict",
|
||||
}
|
||||
input: {
|
||||
console.log((42..length = "PASS", "PASS"));
|
||||
console.log(("foo".length = "PASS", "PASS"));
|
||||
console.log((false.length = "PASS", "PASS"));
|
||||
console.log((function() {}.length = "PASS", "PASS"));
|
||||
console.log(({
|
||||
get length() {
|
||||
return "FAIL";
|
||||
}
|
||||
}.length = "PASS", "PASS"));
|
||||
}
|
||||
expect: {
|
||||
console.log(42..length = "PASS");
|
||||
console.log("foo".length = "PASS");
|
||||
console.log(false.length = "PASS");
|
||||
console.log(function() {}.length = "PASS");
|
||||
console.log({
|
||||
get length() {
|
||||
return "FAIL";
|
||||
}
|
||||
}.length = "PASS");
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
]
|
||||
}
|
||||
|
||||
collapse_rhs_setter: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: "strict",
|
||||
}
|
||||
input: {
|
||||
try {
|
||||
console.log(({
|
||||
set length(v) {
|
||||
throw "PASS";
|
||||
}
|
||||
}.length = "FAIL", "FAIL"));
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
try {
|
||||
console.log({
|
||||
set length(v) {
|
||||
throw "PASS";
|
||||
}
|
||||
}.length = "FAIL");
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
collapse_rhs_call: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
passes: 2,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = {};
|
||||
function f() {
|
||||
console.log("PASS");
|
||||
}
|
||||
o.f = f;
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
({}.f = function() {
|
||||
console.log("PASS");
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
collapse_rhs_lhs: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b) {
|
||||
a.b = b, b += 2;
|
||||
console.log(a.b, b);
|
||||
}
|
||||
f({}, 1);
|
||||
}
|
||||
expect: {
|
||||
function f(a, b) {
|
||||
a.b = b, b += 2;
|
||||
console.log(a.b, b);
|
||||
}
|
||||
f({}, 1);
|
||||
}
|
||||
expect_stdout: "1 3"
|
||||
}
|
||||
|
||||
drop_arguments: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
arguments.slice = function() {
|
||||
console.log("PASS");
|
||||
};
|
||||
arguments[42];
|
||||
arguments.length;
|
||||
arguments.slice();
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
arguments.slice = function() {
|
||||
console.log("PASS");
|
||||
};
|
||||
arguments.slice();
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3427: {
|
||||
options = {
|
||||
assignments: true,
|
||||
collapse_vars: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
pure_getters: "strict",
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
(function(b) {
|
||||
b.p = 42;
|
||||
})(a || (a = {}));
|
||||
}
|
||||
expect: {}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user