Compare commits

...

738 Commits

Author SHA1 Message Date
Alex Lam S.L
787dfbed64 enhance inline (#5871) 2024-06-30 14:00:05 +03:00
Alex Lam S.L
6b23899ef3 fix corner case in collapse_vars (#5870)
fixes #5869
2024-06-28 21:19:58 +03:00
Alex Lam S.L
8c5a899986 enhance collapse_vars, unsafe & unused (#5868) 2024-06-26 22:38:27 +03:00
Alex Lam S.L
ed36c1ec5c fix corner case in unused (#5867)
fixes #5866
2024-06-26 16:13:29 +03:00
Alex Lam S.L
ce8ef52e2b enhance hoist_vars (#5865) 2024-06-25 23:56:39 +03:00
Alex Lam S.L
6669ea19ef fix corner case in hoist_vars (#5864)
fixes #5863
2024-06-25 19:19:47 +03:00
Alex Lam S.L
205a1d1f19 fix corner case in reduce_vars (#5862)
fixes #5860
fixes #5861
2024-06-21 01:29:11 +03:00
Alex Lam S.L
95d3ede664 fix corner cases in pure_getters & reduce_vars (#5859)
fixes #5856
fixes #5857
fixes #5858
2024-06-20 17:43:55 +03:00
Alex Lam S.L
8195a664fd fix corner case in collapse_vars (#5855)
fixes #5854
2024-06-19 05:15:03 +03:00
Alex Lam S.L
9c80456634 enhance dead_code & side_effects (#5840)
closes #5794
2024-06-19 01:36:04 +03:00
Alex Lam S.L
dc7aa32172 fix corner case in inline (#5853)
fixes #5851
2024-06-17 10:37:18 +03:00
Alex Lam S.L
23d74bedeb fix corner cases in join_vars (#5852)
fixes #5849
fixes #5850
2024-06-17 09:11:11 +03:00
Alex Lam S.L
f31311e439 fix corner case in inline (#5848)
fixes #5844
2024-06-17 06:38:16 +03:00
Alex Lam S.L
87c9edbbc7 fix corner case in unused (#5847)
fixes #5843
2024-06-17 04:36:02 +03:00
Alex Lam S.L
8dc99fa25f fix corner case in inline (#5846)
fixes #5842
2024-06-17 02:09:06 +03:00
Alex Lam S.L
dc51a23d31 fix corner case in inline (#5845)
fixes #5841
2024-06-17 02:08:53 +03:00
alexlamsl
0934c0e431 v3.18.0 2024-06-10 03:01:35 +03:00
Alex Lam S.L
ca4185a0fd improve ESTree compatibility (#5836)
closes #5834
closes #5835
2024-06-10 01:37:24 +03:00
Alex Lam S.L
e7b9b4aafb workaround function declaration quirks in ES6+ (#5833)
fixes #1666
2024-06-09 00:57:15 +03:00
Alex Lam S.L
3dfb379486 fix corner case in join_vars (#5832)
fixes #5831
2024-06-08 20:15:50 +03:00
Alex Lam S.L
2cb6454b1f fix corner case in merge_vars (#5830)
fixes #5829
2024-06-08 20:15:37 +03:00
Alex Lam S.L
09910771a1 fix corner case in awaits (#5828)
fixes #5791
2024-06-06 04:51:02 +03:00
Alex Lam S.L
c21a8eee7b include Node.js v20 in CI tests (#5827) 2024-06-05 23:49:20 +03:00
Alex Lam S.L
34b6143306 fix scope assignment to switch expressions (#5826)
fixes #5787
fixes #5792
2024-06-05 22:05:16 +03:00
Alex Lam S.L
ffe0fe7762 enhance join_vars (#5824)
closes #5790
2024-06-05 13:46:11 +03:00
forgotPassword
aa7c3389e6 domprops: enableHighAccuracy, maximumAge (#5822) 2024-06-05 04:17:30 +03:00
Alex Lam S.L
30fd331bf1 workaround node & npm issues (#5825)
- upgrade GitHub Actions dependencies
- workaround `sucrase` issues
2024-06-05 03:55:16 +03:00
Alex Lam S.L
f0ca9cfbe6 fix corner case in collapse_vars (#5780)
fixes #5779
2023-01-16 21:30:59 +08:00
Alex Lam S.L
a437a61518 fix corner case in reduce_vars (#5778)
fixes #5777
2023-01-16 21:30:45 +08:00
Alex Lam S.L
57dd3f6a2c fix corner case in evaluate (#5775)
fixes #5774
2023-01-07 20:38:04 +08:00
Alex Lam S.L
f07dc5cfba fix corner case in merge_vars (#5773)
fixes #5772
2023-01-07 18:27:18 +08:00
Alex Lam S.L
358faaacaa fix corner case in merge_vars (#5771)
fixes #5770
2023-01-04 13:17:04 +08:00
Alex Lam S.L
c9117041fa fix corner case in functions & inline (#5767)
fixes #5766
2022-12-27 08:59:16 +08:00
Alex Lam S.L
f2b6f1def0 improve --reduce-test (#5763) 2022-12-13 10:07:15 +08:00
Alex Lam S.L
797184f587 improve CLI interoperability (#5762) 2022-12-11 13:25:06 +08:00
Alex Lam S.L
78242ff21d minor lints (#5761) 2022-12-09 05:55:57 +08:00
Alex Lam S.L
dd88f3866b fix corner case in inline (#5760)
fixes #5759
2022-12-07 11:40:12 +08:00
Alex Lam S.L
17c3ae6cba improve usability (#5758) 2022-12-04 09:10:32 +08:00
Alex Lam S.L
0cbd5ea64a fix corner case in join_vars & loops (#5757)
fixes #5756
2022-12-03 11:44:37 +08:00
Alex Lam S.L
404794f5db fix corner case in if_return (#5755)
fixes #5754
2022-12-02 11:05:36 +08:00
Alex Lam S.L
650e63c8aa improve usability (#5753) 2022-12-02 10:14:07 +08:00
Alex Lam S.L
59e385591c improve interoperability of custom Errors (#5752)
closes #5751
2022-12-02 03:54:00 +08:00
Alex Lam S.L
574ca47666 fix corner case in yields (#5750)
fixes #5749
2022-12-01 05:18:04 +08:00
Alex Lam S.L
548f0938e8 fix corner case in collapse_vars (#5748)
fixes #5747
2022-12-01 03:59:22 +08:00
Alex Lam S.L
2352909c3d fix corner case in join_vars (#5746)
fixes #5745
2022-11-23 21:49:30 +08:00
Alex Lam S.L
4e7744af2d minor lints (#5744) 2022-11-23 07:26:35 +08:00
Alex Lam S.L
aef7065262 fix corner case in inline (#5742)
fixes #5741
2022-11-23 07:26:08 +08:00
Alex Lam S.L
24c3db11e6 minor lints (#5740) 2022-11-23 05:08:42 +08:00
Alex Lam S.L
e5cbd3e0f3 enhance join_vars (#5739) 2022-11-23 01:57:16 +08:00
Alex Lam S.L
68d62a8a31 enable --module by default (#5738)
- fix corner case in `mangle`
2022-11-22 02:25:34 +08:00
Alex Lam S.L
21aff996a5 enhance varify (#5737) 2022-11-21 11:30:02 +08:00
Alex Lam S.L
1d400f1a25 fix corner case in inline (#5736)
fixes #5735
2022-11-14 10:35:26 +08:00
Alex Lam S.L
7f424a55c5 suppress false positives in ufuzz (#5734) 2022-11-14 10:34:43 +08:00
Alex Lam S.L
e37a1489d4 fix corner case in reduce_vars (#5731)
fixes #5730
2022-11-03 13:05:07 +08:00
Alex Lam S.L
2b1c321ac8 fix corner case in evaluate (#5729)
fixes #5728
2022-11-03 12:25:48 +08:00
Alex Lam S.L
8d28052182 fix corner cases in evaluate & side_effects (#5726) 2022-11-01 09:38:33 +08:00
Alex Lam S.L
f40dbd6e33 fix corner case in inline & unused (#5725)
fixes #5724
2022-10-29 10:53:30 +08:00
Alex Lam S.L
7270671687 fix corner case in conditionals (#5723)
fixes #5722
2022-10-29 00:17:59 +08:00
Alex Lam S.L
30bf068768 fix corner case in collapse_vars (#5720)
fixes #5719
2022-10-24 22:16:06 +08:00
Alex Lam S.L
fb1bff2c0a v3.17.4 2022-10-24 01:46:19 +08:00
Alex Lam S.L
19c471c16a fix corner cases in reduce_vars (#5717)
fixes #5716
2022-10-19 23:22:19 +08:00
Alex Lam S.L
8319badea8 fix corner case in merge_vars (#5715)
fixes #5714
2022-10-17 11:19:43 +08:00
Alex Lam S.L
5a5200d657 fix corner case in conditionals (#5713)
fixes #5712
2022-10-14 23:55:08 +08:00
Alex Lam S.L
5411360829 fix corner case in if_return (#5711)
fixes #5710
2022-10-13 22:34:55 +01:00
Alex Lam S.L
7edd10e5e5 fix corner case in unused (#5708)
fixes #5707
2022-10-10 21:45:57 +08:00
Alex Lam S.L
bccb1c3bd9 fix corner case in unused (#5706)
fixes #5705
2022-10-10 08:02:23 +08:00
Alex Lam S.L
ed7051b9bb enhance side_effects & strings (#5704) 2022-10-10 08:01:40 +08:00
Alex Lam S.L
a391897388 enhance conditionals (#5703) 2022-10-08 09:59:33 +08:00
Alex Lam S.L
4a1da492dd v3.17.3 2022-10-06 02:14:42 +08:00
Alex Lam S.L
94a954c3d1 minor clean-ups (#5701) 2022-10-06 02:06:21 +08:00
Alex Lam S.L
be8ccc3ab5 fix corner case in varify (#5698)
fixes #5697
2022-10-04 16:03:24 +08:00
Alex Lam S.L
58d997a3d6 fix corner case in booleans & conditionals (#5696) 2022-10-04 12:58:55 +08:00
Alex Lam S.L
dabcc39b51 fix corner cases in booleans & conditionals (#5695)
fixes #5694
2022-10-03 22:47:15 +08:00
Alex Lam S.L
140e4e0da8 fix corner case in inline (#5693)
fixes #5692
2022-10-03 08:01:56 +08:00
Alex Lam S.L
80fc862547 enhance assignments, booleans & conditionals (#5691) 2022-10-03 08:01:23 +08:00
Alex Lam S.L
6cdc035b2f fix corner case in if_return (#5689)
fixes #5688
2022-09-30 06:49:51 +08:00
Alex Lam S.L
e1e3516397 fix corner case in reduce_vars (#5687) 2022-09-30 02:00:37 +08:00
Alex Lam S.L
bd5fc4cb1b implement mangle.properties.domprops (#5686)
- support destructuring syntax
- fix corner case with comma operator
2022-09-29 12:18:04 +08:00
Alex Lam S.L
a570c00251 fix corner case in conditionals & if_return (#5685)
fixes #5684
2022-09-28 00:04:32 +08:00
Alex Lam S.L
3fa2086681 improve usability of mangle.properties (#5683)
fixes #5682
2022-09-27 13:52:58 +08:00
Alex Lam S.L
8e65413b99 fix corner cases in conditionals & if_return (#5680)
fixes #5679
2022-09-27 01:28:03 +08:00
Alex Lam S.L
8ca40070a4 workaround GitHub Actions quirks (#5678) 2022-09-27 00:16:40 +08:00
Alex Lam S.L
f9b811ce83 v3.17.2 2022-09-26 00:12:51 +08:00
Alex Lam S.L
9ac3879b06 fix corner case in conditionals (#5676) 2022-09-23 11:09:55 +08:00
Alex Lam S.L
37d3e4feaa fix corner case in if_return (#5675) 2022-09-22 23:27:06 +08:00
Alex Lam S.L
43ec350cd2 fix corner case in conditionals (#5674)
fixes #5673
2022-09-22 10:58:44 +08:00
Alex Lam S.L
63b04a687a minor tweaks (#5672) 2022-09-21 23:11:46 +08:00
Alex Lam S.L
9efa02afb6 fix corner case in assignments (#5671)
fixes #5670
2022-09-21 07:56:16 +08:00
Alex Lam S.L
3a6e58109e v3.17.1 2022-09-20 04:13:28 +08:00
Alex Lam S.L
5ac6ec5496 improve usability of --mangle-props (#5669) 2022-09-18 09:37:06 +08:00
Alex Lam S.L
eb22f0101e fix corner case in unused (#5668)
fixes #5663
2022-09-17 13:32:41 +08:00
Alex Lam S.L
e4bff315eb fix corner case in conditionals (#5667)
fixes #5666
2022-09-17 10:42:32 +08:00
Alex Lam S.L
001f6f9719 fix corner case in inline (#5664)
fixes #5662
2022-09-17 08:54:54 +08:00
Alex Lam S.L
e0b302d651 fix corner case in merge_vars (#5661)
fixes #5660
2022-09-14 23:36:54 +08:00
Alex Lam S.L
fa2511f71c tweak ufuzz job scheduling (#5659) 2022-09-11 04:05:21 +08:00
Alex Lam S.L
edf1bf1106 enhance varify (#5658) 2022-09-11 03:28:54 +08:00
Alex Lam S.L
88dfc49683 fix corner case in merge_vars (#5657)
fixes #5656
2022-09-10 04:14:33 +08:00
Alex Lam S.L
9dec612cd5 enhance inline (#5655)
- improve fix for #5653
2022-09-09 04:07:47 +08:00
Alex Lam S.L
02d966d914 fix corner case in hoist_props (#5654)
fixes #5653
2022-09-08 10:55:59 +08:00
Alex Lam S.L
5b5f6e329c fix corner case in ie (#5652)
fixes #5651
2022-09-08 10:49:40 +08:00
Alex Lam S.L
4e4a2f8ed3 fix corner case in if_return (#5650)
fixes #5649
2022-09-08 10:49:05 +08:00
Alex Lam S.L
32bd65a87f support ExtendScript parser quirks (#5648)
closes #1144
2022-09-07 02:28:34 +08:00
Alex Lam S.L
318206d41d suppress false positives in ufuzz (#5647) 2022-09-06 01:33:22 +08:00
Alex Lam S.L
535212c69e allow glob-style input for --in-situ (#5646)
closes #5645
2022-09-05 22:54:35 +08:00
Alex Lam S.L
1d42e9ad55 fix corner case in collapse_vars (#5644)
fixes #5643
2022-09-04 10:10:31 +08:00
Alex Lam S.L
78f354beb8 fix corner case in dead_code (#5642)
fixes #5641
2022-09-04 06:18:25 +08:00
Alex Lam S.L
e012f046bc tweak test cases (#5640) 2022-08-31 12:16:42 +08:00
Alex Lam S.L
f63b7b079d fix corner case in collapse_vars (#5639)
fixes #5638
2022-08-31 08:44:04 +08:00
Alex Lam S.L
d530f9332c enhance awaits (#5637) 2022-08-31 02:51:42 +08:00
Alex Lam S.L
10bc86ba10 enhance reduce_vars (#5636) 2022-08-30 16:00:43 +08:00
Alex Lam S.L
15b608f74c fix corner case in inline (#5635)
fixes #5634
2022-08-30 00:45:35 +08:00
Alex Lam S.L
7c52af0dec workaround quirks from npm (#5633) 2022-08-26 20:08:04 +08:00
Alex Lam S.L
cd97237c59 workaround quirks from GitHub Actions (#5632) 2022-08-26 15:16:03 +08:00
Alex Lam S.L
965e9767e5 workaround quirks from Node.js (#5631) 2022-08-26 06:25:44 +08:00
Alex Lam S.L
41a7000745 workaround quirks from GitHub Actions (#5630) 2022-08-26 02:35:53 +08:00
Alex Lam S.L
9cdc1ef6c2 fix corner case in unused (#5629)
fixes #5628
2022-08-25 05:01:12 +08:00
Alex Lam S.L
4db81065ee fix corner case in hoist_vars (#5627)
fixes #5626
2022-08-24 00:19:47 +08:00
Alex Lam S.L
4653e8aec0 improve diagnostics on top_retain & mangle.properties (#5622)
closes #5618
2022-08-19 02:32:21 +08:00
Alex Lam S.L
ac002b6338 fix corner case in reduce_vars (#5624)
fixes #5623
2022-08-19 02:31:48 +08:00
Alex Lam S.L
9eea3a673a provide diagnostic details on --mangle-props (#5621)
closes #5618
2022-08-17 22:22:30 +08:00
Alex Lam S.L
d6d2f5ced2 enhance reduce_vars (#5616)
closes #5614
2022-08-17 09:25:59 +08:00
Alex Lam S.L
887e086890 fix corner case in if_return (#5620)
fixes #5619
2022-08-17 09:10:33 +08:00
Alex Lam S.L
8602d1ba17 v3.17.0 2022-08-17 03:45:32 +08:00
Alex Lam S.L
dd90135944 fix corner case in pure_getters (#5617) 2022-08-14 02:54:06 +08:00
Alex Lam S.L
612701a706 tweak ufuzz test case generation (#5615) 2022-08-12 03:55:54 +08:00
Alex Lam S.L
503532cf77 workaround sporadic I/O lags in GitHub Actions (#5613) 2022-08-10 07:36:14 +08:00
Alex Lam S.L
6c0e522922 workaround sporadic I/O lags in GitHub Actions (#5612) 2022-08-10 04:33:32 +08:00
Alex Lam S.L
9d37276986 tweak ufuzz test case generation (#5611) 2022-08-10 00:20:20 +08:00
Alex Lam S.L
5a4cd09938 enhance inline (#5610) 2022-08-09 22:54:29 +08:00
Alex Lam S.L
c32fe26b8d fix corner case in merge_vars (#5609) 2022-08-09 10:18:11 +08:00
Alex Lam S.L
2c3c4ec323 improve source mapping accuracy (#5608) 2022-08-09 02:02:43 +08:00
Alex Lam S.L
f451a7ad79 implement --expression (#5607) 2022-08-08 03:42:18 +08:00
Alex Lam S.L
07953b36b0 update dependencies (#5605) 2022-08-06 13:16:47 +08:00
Alex Lam S.L
387c69b194 minor clean-ups (#5604) 2022-08-06 10:45:44 +08:00
Alex Lam S.L
a9d9af53e9 fix corner case in if_return (#5603)
fixes #5602
2022-08-06 07:56:20 +08:00
Alex Lam S.L
8a07f1202c expand builtins exclusions (#5601)
closes #5600
2022-08-05 13:37:02 +08:00
Alex Lam S.L
41b65af6e2 fix corner cases with static modifier (#5599) 2022-08-05 02:48:21 +08:00
Alex Lam S.L
884842cd6c fix corner case in if_return (#5598)
fixes #5597
2022-08-04 06:50:51 +08:00
Alex Lam S.L
8076d66ae5 fix corner case in if_return (#5596)
fixes #5595
2022-08-03 20:07:55 +08:00
Alex Lam S.L
64e3ceec3b enhance if_return (#5594) 2022-08-03 07:37:31 +08:00
Alex Lam S.L
672cdfa57a enhance conditionals (#5593) 2022-08-02 19:01:57 +08:00
Alex Lam S.L
e39f33e41b fix corner cases in if_return (#5590)
fixes #5589
fixes #5591
fixes #5592
2022-07-31 02:45:52 +08:00
Alex Lam S.L
6667440aaf enhance if_return (#5588)
fixes #5587
2022-07-30 20:53:46 +08:00
Alex Lam S.L
ab5c7e6863 fix corner cases in if_return (#5585)
fixes #5583
fixes #5584
fixes #5586
2022-07-30 16:07:19 +08:00
Alex Lam S.L
08c386f363 enhance if_return (#5582) 2022-07-30 05:25:17 +08:00
Alex Lam S.L
937a672879 fix corner case in mangle (#5581)
fixes #5580
2022-07-29 03:04:10 +08:00
Alex Lam S.L
513995f57d fix corner case in inline & reduce_vars (#5579) 2022-07-28 23:53:11 +08:00
Alex Lam S.L
db6fd6db3e enhance side_effects (#5578) 2022-07-28 04:06:11 +08:00
Alex Lam S.L
da930affd2 fix corner case in inline (#5577)
fixes #5576
2022-07-26 10:46:54 +08:00
Alex Lam S.L
996836b67e enhance conditionals (#5575) 2022-07-26 01:49:45 +08:00
Alex Lam S.L
fc7678c115 v3.16.3 2022-07-25 06:08:04 +08:00
Alex Lam S.L
b371dc2d1e fix corner case in collapse_vars (#5574)
fixes #5573
2022-07-23 07:18:26 +08:00
Alex Lam S.L
56e9454f1f fix corner case with spread syntax (#5572) 2022-07-23 03:07:04 +08:00
Alex Lam S.L
d67daa8314 support string namespace in import & export (#5570) 2022-07-20 05:55:38 +08:00
Alex Lam S.L
f0120e90b6 fix corner case collapse_vars (#5569)
fixes #5568
2022-07-18 09:04:51 +08:00
Alex Lam S.L
ec4558be29 fix corner cases with parameter scope (#5567)
fixes #5566
2022-07-17 16:03:12 +08:00
Alex Lam S.L
685ab357cc document v8 quirks (#5565)
closes #5564
2022-07-17 00:22:16 +08:00
Alex Lam S.L
5792f30175 fix corner case in evaluate (#5559)
fixes #5558
2022-07-15 20:36:52 +08:00
Alex Lam S.L
24443b6764 enhance collapse_vars (#5556) 2022-07-12 23:49:43 +08:00
Alex Lam S.L
154edf0427 enhance collapse_vars (#5555) 2022-07-11 23:10:40 +08:00
Alex Lam S.L
4778cf88e2 upgrade AST<->ESTree translation (#5554) 2022-07-11 07:18:25 +08:00
Alex Lam S.L
38bd4f65d0 fix corner cases in collapse_vars (#5553)
fixes #5552
2022-07-09 20:50:54 +08:00
Alex Lam S.L
0b808f6428 parse import expressions correctly (#5551)
fixes #5550
2022-07-08 19:25:30 +08:00
Alex Lam S.L
b2bc2e1173 parse export & import statements correctly (#5550)
fixes #5548
2022-07-08 04:04:56 +08:00
Alex Lam S.L
80787ff7ef minor cleanups (#5549) 2022-07-08 03:14:54 +08:00
Alex Lam S.L
b92a89f325 fix corner case in conditionals (#5548) 2022-07-07 21:28:33 +08:00
Alex Lam S.L
902292f776 fix corner case in conditionals (#5547)
fixes #5546
2022-07-07 15:49:33 +08:00
Alex Lam S.L
3dcf098468 fix corner cases in conditionals & switches (#5545)
fixes #5543
fixes #5544
2022-07-07 14:59:06 +08:00
Alex Lam S.L
d89f0965aa enhance conditionals (#5542) 2022-07-07 12:17:23 +08:00
Alex Lam S.L
c8d98f4787 enhance if_return (#5541) 2022-07-07 04:28:00 +08:00
Alex Lam S.L
0207b46d70 enhance if_return & inline (#5538) 2022-07-06 11:40:07 +08:00
Alex Lam S.L
aa2a9fbedb v3.16.2 2022-07-04 08:50:56 +08:00
Alex Lam S.L
3596b4feda fix corner case in inline (#5537)
fixes #5536
2022-07-02 00:10:02 +08:00
Alex Lam S.L
51deeff72e enhance inline (#5535) 2022-07-01 11:24:16 +08:00
Alex Lam S.L
4c227cc6bd fix corner cases in inline & unused (#5534)
fixes #5533
2022-06-30 15:34:45 +08:00
Alex Lam S.L
2426657daa fix corner case in inline (#5532)
fixes #5531
2022-06-30 04:09:53 +08:00
Alex Lam S.L
e1b03d0235 fix corner case in inline (#5529)
fixes #5528
2022-06-29 07:37:58 +08:00
Alex Lam S.L
f1b3e9df1e fix corner case in inline (#5527)
fixes #5526
2022-06-26 20:48:14 +08:00
Alex Lam S.L
fcc87edb71 fix corner cases in dead_code & if_return (#5525)
fixes #5521
fixes #5522
fixes #5523
fixes #5524
2022-06-26 18:40:56 +08:00
Alex Lam S.L
8b464331ba enhance dead_code & if_return (#5520) 2022-06-26 12:32:25 +08:00
Alex Lam S.L
9f57920566 enhance if_return (#5518) 2022-06-24 00:52:22 +08:00
Alex Lam S.L
933ca9ddd8 fix corner case in reduce_vars (#5517)
fixes #5516
2022-06-19 03:27:00 +08:00
Alex Lam S.L
74e36e4456 v3.16.1 2022-06-17 07:53:29 +08:00
Alex Lam S.L
4382bfe848 fix corner case in collapse_vars (#5513)
fixes #5512
2022-06-13 07:55:15 +08:00
Alex Lam S.L
b6f250f5c9 enhance unused (#5511) 2022-06-12 21:24:42 +08:00
Alex Lam S.L
5d69545299 enhance unsafe_comps (#5510) 2022-06-12 12:15:43 +08:00
Alex Lam S.L
139fad0c05 fix corner cases with instanceof (#5509)
- enhance `evaluate`
2022-06-12 10:01:54 +08:00
Alex Lam S.L
99946a3993 fix corner case in dead_code (#5507)
fixes #5506
2022-06-12 05:26:51 +08:00
Alex Lam S.L
053cb27fe3 fix corner case in collapse_vars (#5505)
fixes #5504
2022-06-10 09:12:59 +08:00
Alex Lam S.L
25017978e7 fix corner case in collapse_vars (#5503)
fixes #5502
2022-06-10 02:07:07 +08:00
Alex Lam S.L
f749863cb2 document ECMAScript quirks (#5501)
closes #5500
2022-06-09 03:01:00 +08:00
Alex Lam S.L
123f9cf987 fix corner case in hoist_props (#5499)
fixes #5498
2022-06-07 23:29:42 +08:00
Alex Lam S.L
a758b40e3f suppress false positives in ufuzz (#5497) 2022-06-07 23:28:06 +08:00
Alex Lam S.L
44e5e99aae parse directives within arrow functions correctly (#5496)
fixes #5495
2022-06-07 10:33:17 +08:00
Alex Lam S.L
be53c4838b fix corner case in collapse_vars (#5494)
fixes #5493
2022-06-06 23:36:19 +08:00
Alex Lam S.L
0c7b016fa7 fix corner case in inline & module (#5492)
fixes #5491
2022-06-06 22:52:22 +08:00
Alex Lam S.L
00665766da fix corner case in side_effects (#5490)
fixes #5489
2022-06-06 20:32:32 +08:00
Alex Lam S.L
88b4283200 support class static initialization block (#5488) 2022-06-06 12:01:15 +08:00
Alex Lam S.L
d2bd0d1c1c support top-level await (#5487) 2022-06-06 11:52:01 +08:00
Alex Lam S.L
25441d44f6 v3.16.0 2022-06-06 11:29:26 +08:00
Alex Lam S.L
a025392a30 fix corner case in comparisons (#5486)
fixes #5485
2022-06-05 00:47:38 +08:00
Alex Lam S.L
ad5f5ef2a3 fix corner case in webkit (#5483)
fixes #5480
2022-06-02 02:45:02 +08:00
Chen Yangjian
40e669eacb docs: toplevel webkit option sets compress.webkit as well (#5480) 2022-06-02 02:44:06 +08:00
Alex Lam S.L
ad3a331ca3 fix corner case in collapse_vars (#5482)
fixes #5481
2022-06-02 02:42:39 +08:00
Alex Lam S.L
3c9e1693d5 fix corner case in side_effects (#5479)
fixes #5478
2022-05-31 00:27:40 +08:00
Alex Lam S.L
8bc03dc6c4 fix corner case in keep_fargs (#5477)
fixes #5476
2022-05-29 12:10:19 +08:00
Alex Lam S.L
2152f00de2 enhance inline & module (#5475) 2022-05-27 11:57:05 +08:00
Alex Lam S.L
94aae05d45 fix corner case in merge_vars (#5472)
fixes #5471
2022-05-27 03:13:24 +08:00
Alex Lam S.L
0dbf2b1d3c suppress false positives in ufuzz (#5473) 2022-05-26 23:17:47 +08:00
Alex Lam S.L
59b23b8c13 fix corner case in booleans (#5470)
fixes #5469
2022-05-26 05:33:50 +08:00
Alex Lam S.L
5979b195fe suppress false positives in ufuzz (#5468) 2022-05-25 23:50:47 +08:00
Alex Lam S.L
a1cff23377 suppress false positives in ufuzz (#5467) 2022-05-25 06:35:59 +08:00
Alex Lam S.L
c82fc1ef71 implement --module (#5462) 2022-05-24 05:45:47 +08:00
Alex Lam S.L
740f93f5a9 fix corner case in merge_vars (#5466)
fixes #5465
2022-05-24 05:45:07 +08:00
Alex Lam S.L
d4caa97b88 fix corner case in reduce_vars (#5464)
fixes #5463
2022-05-23 11:08:12 +08:00
Alex Lam S.L
c2ca7b7659 drop unused extends properly (#5461) 2022-05-23 03:53:32 +08:00
Alex Lam S.L
59edda6ca5 suppress false positives in ufuzz (#5460) 2022-05-22 01:36:45 +08:00
Alex Lam S.L
1668bc33c3 improve ufuzz coverage (#5459) 2022-05-21 02:57:13 +08:00
Alex Lam S.L
01f1e3fef8 avoid v8 quirks in ufuzz (#5458) 2022-05-20 00:00:24 +08:00
Alex Lam S.L
27aa85f84b fix corner cases in merge_vars (#5457)
fixes #5456
2022-05-19 06:39:20 +08:00
Alex Lam S.L
33c9c48318 fix corner case in hoist_props & unused (#5455)
fixes #5454
2022-05-19 04:45:38 +08:00
Alex Lam S.L
63f16e4616 fix corner case in merge_vars (#5452)
fixes #5451
2022-05-18 02:41:05 +08:00
Alex Lam S.L
cb6dd34b98 avoid broken versions of Node.js (#5453) 2022-05-18 02:40:31 +08:00
Alex Lam S.L
27727e6926 fix corner cases in unused (#5449)
fixes #5448
2022-05-17 17:03:06 +08:00
Alex Lam S.L
a968ddc78c avoid webpack bug in web-tooling-benchmark (#5450) 2022-05-17 14:08:11 +08:00
Alex Lam S.L
f70462aeb2 fix corner case in merge_vars (#5445)
fixes #5444
2022-05-16 16:30:14 +08:00
Alex Lam S.L
3aa92c76cc avoid extends error in ufuzz (#5447) 2022-05-16 11:11:10 +08:00
Alex Lam S.L
fc6a66836a fix corner case in unused (#5446)
fixes #5444
2022-05-16 09:13:30 +08:00
Alex Lam S.L
31167da1a9 avoid extends error in test cases (#5443) 2022-05-16 06:50:22 +08:00
Alex Lam S.L
7db2ada880 fix corner case in hoist_props (#5442)
fixes #5441
2022-05-16 06:49:09 +08:00
Alex Lam S.L
e31bbe329a improve compatibility with use strict (#5440) 2022-05-14 12:15:54 +08:00
Alex Lam S.L
8946c87011 suppress invalid test case generation (#5439)
- document v8 quirks

closes #5438
2022-05-12 04:38:11 +08:00
Alex Lam S.L
a9ef659bcb v3.15.5 2022-05-11 05:26:10 +08:00
Alex Lam S.L
35c2149dbd fix corner case in merge_vars (#5437)
fixes #5436
2022-05-08 04:16:28 +08:00
Alex Lam S.L
89a35f9fcd fix corner case in reduce_vars (#5435)
fixes #5434
2022-05-06 09:32:47 +08:00
Alex Lam S.L
1a4e99dc2d avoid v8 quirks in ufuzz (#5431)
closes #5428
closes #5429
2022-04-25 21:33:31 +08:00
Alex Lam S.L
cb870f6fd6 document v8 quirks (#5430)
closes #5428
closes #5429
2022-04-21 02:51:53 +08:00
Alex Lam S.L
a0c0c294c5 fix corner case in assignments (#5426)
fixes #5425
2022-04-19 13:19:30 +08:00
Alex Lam S.L
fbdb7eeda3 fix corner case in merge_vars (#5424)
fixes #5423
2022-04-19 09:04:06 +08:00
Alex Lam S.L
1bc0fccc8c improve ufuzz resilience (#5422) 2022-04-18 13:03:01 +08:00
Alex Lam S.L
20252c6483 fix corner case in merge_vars (#5421)
fixes #5420
2022-04-18 06:38:08 +08:00
Alex Lam S.L
e396912ea2 suppress false positives with export & import (#5418) 2022-04-16 04:27:50 +08:00
Alex Lam S.L
5ebfa78f56 fix corner case with arguments (#5417)
fixes #5416
2022-04-15 06:52:10 +08:00
Alex Lam S.L
950609f578 fix corner case in inline (#5415)
fixes #5414
2022-04-13 06:19:37 +08:00
Alex Lam S.L
4a44d95f09 v3.15.4 2022-04-10 01:16:11 +08:00
David Luhmer
36718948be rename reserved keyword await (#5413) 2022-04-08 00:31:29 +08:00
Alex Lam S.L
21bd4c4a9d fix corner cases in collapse_vars & hoist_vars (#5412)
fixes #5411
2022-04-07 04:12:03 +08:00
Alex Lam S.L
998c9792da fix corner case in inline (#5410)
fixes #5409
2022-04-06 12:23:47 +08:00
Alex Lam S.L
ccd77d70db fix corner case in reduce_vars (#5408)
fixes #5407
2022-04-05 10:09:25 +08:00
Alex Lam S.L
d75a946707 fix corner case in reduce_vars (#5406)
fixes #5405
2022-04-03 21:57:37 +08:00
Alex Lam S.L
696a20f10d patch export default within sandbox correctly (#5404)
fixes #5403
2022-04-03 19:56:19 +08:00
Alex Lam S.L
224c91b6c1 fix corner case in inline (#5402)
fixes #5401
2022-04-03 01:12:53 +08:00
Alex Lam S.L
8065e27a7d patch export default within sandbox correctly (#5400)
fixes #5399
2022-04-02 21:59:28 +08:00
Alex Lam S.L
584e253f33 enahnce collapse_vars (#5398) 2022-04-01 20:26:27 +08:00
Alex Lam S.L
fb5e08e4ec fix corner case in collapse_vars (#5397)
fixes #5396
2022-03-31 20:02:56 +08:00
Alex Lam S.L
e3d328f741 fix corner case in collapse_vars (#5395)
fixes #5394
2022-03-30 01:22:57 +08:00
Alex Lam S.L
8922f08fbf fix corner cases in keep_fnames (#5393) 2022-03-29 03:01:01 +08:00
Alex Lam S.L
15a4074d1a fix corner case in unused (#5392)
fixes #5391
2022-03-28 05:46:43 +08:00
Alex Lam S.L
c624b43739 fix corner case in collapse_vars (#5390)
fixes #5389
2022-03-22 13:05:57 +08:00
Alex Lam S.L
a8e040b133 fix corner case in properties (#5388)
fixes #5387
2022-03-21 00:01:42 +08:00
Alex Lam S.L
5e30f3a48b fix corner case in inline (#5386)
fixes #5385
2022-03-20 22:50:28 +08:00
Alex Lam S.L
46570a4eb6 fix corner case in side_effects (#5383)
fixes #5382
2022-03-12 14:14:30 +08:00
Alex Lam S.L
01b84074d7 fix corner case in evaluate (#5381)
fixes #5380
2022-03-12 13:08:29 +08:00
Alex Lam S.L
7aba2dc5f2 v3.15.3 2022-03-10 12:50:19 +08:00
Alex Lam S.L
12a6728c4e fix corner case in hoist_vars (#5379)
fixes #5378
2022-03-06 17:56:00 +08:00
Alex Lam S.L
042c228c7b fix corner case in inline (#5377)
fixes #5376
2022-03-06 03:29:56 +08:00
Alex Lam S.L
e2b00814a8 fix corner cases in inline (#5375) 2022-03-04 04:05:31 +08:00
Alex Lam S.L
104d385ba9 fix corner case in ie (#5372)
fixes #5370
2022-03-02 13:52:27 +08:00
Alex Lam S.L
fdbbef2991 enhance conditionals (#5371) 2022-03-02 11:00:37 +08:00
Alex Lam S.L
f8edf05c3c v3.15.2 2022-02-26 20:41:02 +08:00
Alex Lam S.L
a9d0ddea9d fix corner case in directives & expression (#5369)
fixes #5368
2022-02-24 05:04:04 +08:00
Alex Lam S.L
313e4974a4 fix corner case in inline (#5367)
fixes #5366
2022-02-21 11:31:29 +08:00
Alex Lam S.L
dd3b81dec6 enhance booleans (#5365) 2022-02-21 11:02:19 +08:00
Alex Lam S.L
d5afe16bc8 enhance booleans & evaluate (#5364) 2022-02-21 01:25:37 +08:00
Alex Lam S.L
212ce4608e fix corner case in evaluate (#5363)
fixes #5362
2022-02-20 21:38:04 +08:00
Alex Lam S.L
fbc5ecf75a fix corner case in unused (#5361)
fixes #5360
2022-02-20 02:26:51 +08:00
Alex Lam S.L
a7d06167a0 enhance mangle (#5359) 2022-02-19 14:02:40 +08:00
Alex Lam S.L
9686379884 enhance comparisons (#5358) 2022-02-19 04:27:17 +08:00
Alex Lam S.L
82e8ebd77d fix corner case in evaluate (#5357)
fixes #5356
2022-02-15 16:28:49 +00:00
Alex Lam S.L
0b50880b4f fix corner case in evaluate & unsafe (#5355)
fixes #5354
2022-02-15 14:47:22 +08:00
Alex Lam S.L
316245ee12 fix corner case in merge_vars (#5353)
fixes #5352
2022-02-13 08:22:34 +08:00
Alex Lam S.L
63b92ead4e fix corner case in properties (#5351)
fixes #5350
2022-02-13 06:09:33 +08:00
Alex Lam S.L
a14555a39e enhance conditionals, if_return & side_effects (#5348) 2022-02-12 23:18:07 +08:00
Alex Lam S.L
6d0bb58d68 enhance merge_vars (#5349) 2022-02-12 20:41:02 +08:00
Alex Lam S.L
33c163f648 patch export default within sandbox correctly (#5346)
fixes #5345
2022-02-10 16:07:40 +08:00
Alex Lam S.L
b6c72c84d4 reduce overlap of sequences & side_effects (#5344) 2022-02-08 00:29:04 +08:00
Alex Lam S.L
327e94a759 v3.15.1 2022-02-07 10:15:48 +08:00
Alex Lam S.L
6fb7de7787 fix corner case in inline (#5343)
fixes #5342
2022-02-05 13:19:42 +08:00
Alex Lam S.L
d338e45033 add test case for unused (#5341)
closes #5340
2022-02-04 10:36:54 +08:00
Alex Lam S.L
b106cd9476 fix corner case in unused (#5339)
fixes #5338
2022-02-04 07:13:23 +08:00
Alex Lam S.L
9a91a7a4dc fix corner case in default_values (#5337)
fixes #5336
2022-02-04 05:44:25 +08:00
Alex Lam S.L
fa30960b8b fix corner case in conditionals (#5335)
fixes #5334
2022-02-04 01:48:30 +08:00
Alex Lam S.L
8ceb4b0492 fix corner case in inline (#5333)
fixes #5332
2022-02-03 13:13:35 +08:00
Alex Lam S.L
aad5d6e122 enhance if_return (#5330) 2022-02-02 08:13:38 +08:00
Alex Lam S.L
77552d9e69 fix corner case in inline (#5329)
fixes #5328
2022-02-01 19:35:03 +08:00
Alex Lam S.L
93105f1a6d suppress false positives in ufuzz (#5327) 2022-02-01 12:17:47 +08:00
Alex Lam S.L
d7eb80b050 enhance if_return (#5326) 2022-01-31 06:32:25 +08:00
Alex Lam S.L
0a5a1f3687 fix corner case in reduce_vars (#5325)
fixes #5324
2022-01-29 21:39:30 +08:00
Alex Lam S.L
e7d6dd2ea2 fix corner case in unused (#5323)
fixes #5322
2022-01-29 19:28:19 +08:00
Alex Lam S.L
28943bcebb fix corner cases in collapse_vars (#5321)
fixes #5319
2022-01-29 15:57:53 +08:00
Alex Lam S.L
18f00457f6 fix corner case in merge_vars (#5320)
fixes #5319
2022-01-28 16:05:57 +08:00
Alex Lam S.L
e4a91a89e0 support custom indentation (#5318)
closes #50
2022-01-28 08:38:11 +08:00
Alex Lam S.L
3693bde2dd fix corner case in inline (#5317)
fixes #5316
2022-01-28 07:17:17 +08:00
Alex Lam S.L
67438f3ff9 fix corner case in side_effects (#5315)
fixes #5314
2022-01-27 08:13:19 +08:00
Alex Lam S.L
371d25944d fix corner case in max_line_len (#5313)
- speed up `max_line_len` & `preserve_line`
2022-01-26 23:47:21 +08:00
Alex Lam S.L
5c863b74d7 enhance collapse_vars (#5312) 2022-01-26 04:18:58 +08:00
Alex Lam S.L
6de708af37 v3.15.0 2022-01-26 01:33:13 +08:00
Alex Lam S.L
b9b2a4f7f8 fix corner case in inline (#5311)
fixes #5222
2022-01-26 00:47:24 +08:00
Alex Lam S.L
b46c7944c6 fix corner case in collapse_vars (#5310)
fixes #5309
2022-01-23 00:45:11 +08:00
Alex Lam S.L
866cd4a975 enhance merge_vars (#5308) 2022-01-21 09:40:33 +08:00
Alex Lam S.L
e24b255350 implement keep_fargs for mangle (#5307)
closes #4657
2022-01-21 05:13:26 +08:00
Alex Lam S.L
efed55f42d fix corner case in inline (#5306)
fixes #5305
2022-01-19 08:14:19 +08:00
Alex Lam S.L
8c2b76eff9 enhance side_effects (#5304) 2022-01-17 23:18:42 +08:00
Alex Lam S.L
b636e97e3b fix corner cases in awaits (#5303) 2022-01-17 16:22:26 +08:00
Alex Lam S.L
35d7f316ef fix corner cases in typeofs (#5301) 2022-01-17 14:03:41 +08:00
Alex Lam S.L
43807c26fb fix performance regression (#5302)
fixes #5297
2022-01-17 11:49:47 +08:00
Alex Lam S.L
774feeadb8 minor clean-ups (#5300) 2022-01-17 01:14:52 +08:00
Alex Lam S.L
d96c59f9e6 fix corner case in side_effects (#5299)
fixes #5298
2022-01-16 02:33:14 +08:00
Alex Lam S.L
dfd6418878 fix corner case in inline (#5297)
fixes #5296
2022-01-15 04:18:35 +08:00
Alex Lam S.L
87e8aca245 fix corner cases in reduce_vars, side_effects & unused (#5295)
fixes #5294
2022-01-15 01:44:36 +08:00
Alex Lam S.L
14e1311bdf fix corner cases in side_effects (#5293)
fixes #5292
2022-01-14 09:14:04 +08:00
Alex Lam S.L
ff3c2ed7a2 fix corner case in inline (#5291)
fixes #5290
2022-01-12 20:17:34 +08:00
Alex Lam S.L
f8602aca96 fix corner case in inline (#5289)
fixes #5288
2022-01-12 16:24:50 +08:00
Alex Lam S.L
9a58270b70 enhance imports (#5287) 2022-01-12 16:24:04 +08:00
Alex Lam S.L
f639a30bd2 fix corner cases in typeofs (#5286) 2022-01-11 13:13:46 +08:00
Alex Lam S.L
082013c20f report runtime process aborts correctly (#5285) 2022-01-11 09:12:01 +08:00
Alex Lam S.L
c7d2837184 fix corner case in inline (#5284)
fixes #5283
2022-01-10 15:43:26 +08:00
Alex Lam S.L
caaa753861 minor clean-ups (#5282) 2022-01-10 13:02:26 +08:00
Alex Lam S.L
4b949f6686 suppress false positives in ufuzz (#5281) 2022-01-10 05:05:35 +08:00
Alex Lam S.L
e9d9d5a9d2 improve class compatibility in side_effects (#5279) 2022-01-09 21:15:42 +08:00
Alex Lam S.L
f473b4db38 fix corner case in collapse_vars (#5278)
fixes #5277
2022-01-08 09:46:21 +08:00
Alex Lam S.L
b0df5d7b55 enhance collapse_vars & reduce_vars (#5275)
fixes #5276
2022-01-08 05:26:49 +08:00
Alex Lam S.L
be8c75bae1 fix corner case in collapse_vars (#5274)
fixes #5273
2022-01-07 15:00:23 +08:00
Alex Lam S.L
58bea676ac fix corner case in unused (#5272)
fixes #5271
2022-01-07 14:33:42 +08:00
Alex Lam S.L
9aab1f3661 fix corner case in inline (#5270)
fixes #5269
2022-01-07 13:22:16 +08:00
Alex Lam S.L
10a1523ee6 enhance collapse_vars (#5268) 2022-01-07 05:13:37 +08:00
Alex Lam S.L
d46eb69320 fix corner case in inline (#5267)
fixes #5266
2022-01-05 04:25:48 +08:00
Alex Lam S.L
3a3666a94e fix corner cases in inline (#5265)
fixes #5263
fixes #5264
2022-01-04 22:05:03 +08:00
Alex Lam S.L
2f568b9357 enhance mangle (#5262) 2022-01-04 10:06:00 +08:00
Alex Lam S.L
c94624f36c fix corner case in collapse_vars (#5261)
fixes #5260
2022-01-04 04:18:41 +08:00
Alex Lam S.L
dec359ce58 fix corner case in awaits & inline (#5259)
fixes #5258
2022-01-03 20:57:24 +08:00
Alex Lam S.L
1a054e869e fix corner case in inline (#5257)
fixes #5256
2022-01-03 10:13:29 +08:00
Alex Lam S.L
7889192cae fix corner cases in inline (#5255)
fixes #5254
2022-01-02 21:24:41 +08:00
Alex Lam S.L
f7841bc8b8 fix corner case in inline (#5253)
fixes #5251
2022-01-02 16:10:39 +08:00
Alex Lam S.L
aa6eb0d5be fix corner cases in inline (#5252)
fixes #5249
fixes #5250
2022-01-02 14:59:32 +08:00
Alex Lam S.L
87a7426598 enhance inline & unused (#5245) 2022-01-02 05:40:43 +08:00
Alex Lam S.L
8d0422b6f3 enhance reduce_vars (#5248) 2022-01-01 07:53:47 +08:00
Alex Lam S.L
e7ce1051fe fix corner cases in reduce_vars & unused (#5247)
fixes #5246
2021-12-31 04:47:13 +08:00
Alex Lam S.L
80d5f23fee fix corner case with lexical variables (#5244) 2021-12-30 05:15:53 +08:00
Alex Lam S.L
d51caaf358 enhance inline (#5243) 2021-12-28 00:53:12 +08:00
Alex Lam S.L
835d130ccf fix corner cases in inline (#5241)
fixes #5239
fixes #5240
2021-12-26 08:39:06 +08:00
Alex Lam S.L
e1013bd56d fix corner case in inline (#5238)
fixes #5237
2021-12-25 19:30:49 +08:00
Alex Lam S.L
13d41778b3 suppress false positives in test/reduce (#5235) 2021-12-25 03:13:37 +08:00
Alex Lam S.L
bab416465f fix corner case in conditionals (#5233)
fixes #5232
2021-12-23 22:25:02 +08:00
Alex Lam S.L
29a1e71705 fix corner case in inline (#5231)
fixes #5230
2021-12-23 14:26:07 +08:00
Alex Lam S.L
7b2eb4b5ff improve handling of non-trivial assignment values (#5227) 2021-12-23 07:55:06 +08:00
Alex Lam S.L
343bf6d7a5 fix corner case in booleans & inline (#5229)
fixes #5228
2021-12-21 23:46:20 +08:00
Alex Lam S.L
ba42cbad3f enhance inline (#5226) 2021-12-21 13:03:11 +08:00
Alex Lam S.L
86406e71ec fix corner case in unused (#5225)
fixes #5224
2021-12-20 02:25:38 +08:00
Alex Lam S.L
9e927ecc9a fix corner case in hoist_props (#5223)
fixes #5222
2021-12-16 02:57:34 +08:00
Alex Lam S.L
509896a410 improve compress efficiency (#5220) 2021-12-15 08:08:24 +08:00
Alex Lam S.L
7fe7c39a01 speed up compress (#5219) 2021-12-14 07:42:47 +08:00
Alex Lam S.L
2c5e23506b v3.14.5 2021-12-13 08:11:48 +08:00
Alex Lam S.L
07f35ea2c9 suppress false positives in ufuzz (#5216)
closes #5212
closes #5215
2021-12-12 06:19:06 +08:00
Alex Lam S.L
57a9519c3d fix corner case in objects (#5214)
fixes #5213
2021-12-10 06:02:22 +08:00
Alex Lam S.L
9e4c4c995c minor clean-up (#5210) 2021-12-10 04:48:06 +08:00
Alex Lam S.L
d11c82f8ca minor clean-up (#5209) 2021-12-09 05:14:57 +08:00
Alex Lam S.L
bc27966a19 workaround v8 performance quirks (#5207) 2021-12-08 13:40:47 +08:00
Alex Lam S.L
8f39491e96 workaround Unicode compatibility in testing (#5206) 2021-12-07 18:56:57 +08:00
Alex Lam S.L
065c50ebde improve sandbox resilience against process aborts (#5205) 2021-12-07 04:54:58 +08:00
Alex Lam S.L
d2e7c4af20 improve testing compatibility with Node.js (#5204) 2021-12-06 22:42:45 +08:00
Alex Lam S.L
033d8d9405 reduce memory pressure via bit fields (#5203) 2021-12-06 11:30:05 +08:00
Alex Lam S.L
b0799105c2 improve Dictionary performance (#5202)
- workaround `__proto__` quirks on v8
2021-12-05 14:58:52 +08:00
Alex Lam S.L
860aa9531b v3.14.4 2021-12-01 02:34:20 +08:00
Alex Lam S.L
2547542873 workaround sporadic slowdown in GitHub Actions (#5201) 2021-11-28 08:45:29 +08:00
Alex Lam S.L
3f8f0e246e fix corner case in collapse_vars (#5200)
fixes #5199
2021-11-28 01:43:43 +08:00
Alex Lam S.L
12227ebbb0 workaround toString() quirks on global context (#5198)
closes #5197
2021-11-27 23:17:51 +08:00
Alex Lam S.L
1b4bd7082b fix corner case in hoist_vars (#5196)
fixes #5195
2021-11-25 04:49:38 +08:00
Alex Lam S.L
0b6c185818 enhance merge_vars (#5194)
closes #5182
2021-11-24 19:08:40 +08:00
Alex Lam S.L
bfd0ac7f4b fix corner case in ie (#5193)
fixes #5192
2021-11-24 17:29:26 +08:00
Alex Lam S.L
1a8f2ecc65 enhance collapse_vars (#5186)
closes #5182
2021-11-24 17:28:36 +08:00
Alex Lam S.L
dc9e1ff0b1 fix corner case in unused (#5190)
fixes #5189
2021-11-23 20:10:05 +08:00
Alex Lam S.L
ea10498902 fix corner case in hoist_vars (#5188)
fixes #5187
2021-11-23 18:00:47 +08:00
Alex Lam S.L
69636dad69 improve sandbox async detection (#5185)
closes #5184
2021-11-23 02:29:54 +08:00
Alex Lam S.L
3ee1b0d00d enhance hoist_props & reduce_vars (#5183)
closes #5182
2021-11-23 00:31:10 +08:00
Alex Lam S.L
1e3ca4c6f7 enhance side_effects & unused (#5181) 2021-11-22 11:14:28 +08:00
Alex Lam S.L
839f4361f4 minor clean-up (#5180) 2021-11-19 16:34:11 +08:00
Alex Lam S.L
ae5c3ee8a1 fix corner cases in properties (#5178)
fixes #5177
2021-11-17 04:21:44 +08:00
Alex Lam S.L
77f7ae5ba2 fix corner case in join_vars (#5176)
fixes #5175
2021-11-15 21:35:54 +08:00
Alex Lam S.L
2d0f8bcff5 fix corner case in inline (#5174)
fixes #5173
2021-11-15 07:14:08 +08:00
Alex Lam S.L
f97e107c09 enhance reduce_vars (#5171) 2021-11-13 22:18:56 +08:00
Alex Lam S.L
e9932e1314 fix corner case in collapse_vars (#5169)
fixes #5168
2021-11-13 22:18:18 +08:00
Alex Lam S.L
eaa84d32df include Node.js v16 in CI tests (#5170)
- fix compatibility issues on v0.10 & v0.12
2021-11-13 18:34:18 +08:00
Alex Lam S.L
6e4aa0326f enhance reduce_vars (#5164)
- fix corner case in `join_vars`
2021-11-04 18:36:39 +08:00
Alex Lam S.L
f9a4b36dd1 fix corner cases in reduce_vars & rests (#5166)
fixes #5165
2021-11-03 21:29:01 +08:00
Alex Lam S.L
3acb5a329e enhance join_vars (#5162) 2021-11-02 11:33:24 +08:00
Alex Lam S.L
6d94242318 enhance reduce_vars (#5163) 2021-11-02 11:32:26 +08:00
Alex Lam S.L
bca83cb9df v3.14.3 2021-11-02 05:03:46 +08:00
Alex Lam S.L
a841d45bc3 fix corner case in awaits (#5160)
fixes #5159
2021-10-31 23:46:55 +08:00
Alex Lam S.L
eb93d92357 fix corner case in awaits (#5158)
fixes #5157
2021-10-29 23:33:10 +08:00
Alex Lam S.L
a0250ec923 fix corner case in dead_code (#5154)
fixes #5153
2021-10-25 06:18:16 +08:00
Alex Lam S.L
25801627be parse let as symbol names correctly (#5151)
fixes #5149
2021-10-21 02:14:29 +08:00
Alex Lam S.L
32ae994f88 fix issues in tests flagged by LGTM (#5150) 2021-10-21 02:07:23 +08:00
Alex Lam S.L
03aec89f60 fix corner cases in strings & templates (#5147)
fixes #5145
2021-10-16 18:02:23 +08:00
Alex Lam S.L
faf0190546 document ECMAScript quirks (#5148)
- exclude Node.js v0.8 from CI as npm registry no longer works

closes #5146
2021-10-16 13:28:13 +08:00
Alex Lam S.L
c8b0f685ee fix corner case in merge_vars (#5143)
fixes #5142
2021-10-05 00:42:46 +08:00
Alex Lam S.L
87b99162fb fix corner case in inline (#5141)
fixes #5140
2021-10-02 06:54:42 +08:00
Alex Lam S.L
940887f20f fix corner case in evaluate (#5139)
fixes #5138
2021-10-01 02:52:21 +08:00
Alex Lam S.L
0b2573c3fa fix corner case in templates (#5137)
fixes #5136
2021-09-30 21:43:34 +08:00
Alex Lam S.L
157521066f avoid potential RegExp denial-of-service (#5135)
closes #5133
closes #5134
2021-09-30 01:49:46 +08:00
Alex Lam S.L
f766babf5e enhance templates (#5131)
closes #5125
2021-09-23 18:26:26 +08:00
Alex Lam S.L
436a29367c enhance dead_code (#5130) 2021-09-22 03:11:45 +08:00
Alex Lam S.L
55418fd460 fix corner case in rests (#5129)
fixes #5128
2021-09-20 05:02:35 +08:00
Alex Lam S.L
85786889bd v3.14.2 2021-09-07 21:52:59 +08:00
Alex Lam S.L
4b88dfb8d9 tweak test & warnings (#5123)
closes #5116
closes #5117
closes #5122
2021-09-07 01:33:23 +08:00
Alex Lam S.L
c3aef23614 fix corner case in reduce_vars (#5121)
fixes #5120
2021-08-25 10:39:35 +08:00
Alex Lam S.L
db94d21980 fix corner case in side_effects (#5118) 2021-08-23 08:51:59 +08:00
Alex Lam S.L
9634a9d1fd fix corner cases in optional_chains (#5110) 2021-08-20 10:10:10 +08:00
Alex Lam S.L
befb99bd71 fix corner case in inline (#5115)
fixes #5114
2021-08-18 15:57:08 +08:00
Alex Lam S.L
02eb8baa1c fix corner case in collapse_vars (#5113)
fixes #5112
2021-08-18 10:54:24 +08:00
Alex Lam S.L
c09f63aefb fix corner case in rests (#5109)
fixes #5108
2021-08-09 08:59:33 +08:00
Alex Lam S.L
fdcc6d3a9c fix corner case in dead_code (#5107)
fixes #5106
2021-08-06 08:35:11 +08:00
Alex Lam S.L
4fe2cac35e enhance inline (#5105) 2021-07-27 21:47:01 +08:00
Alex Lam S.L
e219a9a78a v3.14.1 2021-07-27 16:53:57 +08:00
Alex Lam S.L
c80eabd61e fix ie8 option alias (#5103)
fixes #5102
2021-07-26 16:45:43 +08:00
Alex Lam S.L
9b82f9be91 fix corner case in unused (#5101)
fixes #5100
2021-07-26 16:44:34 +08:00
Alex Lam S.L
657d525c80 fix corner case in reduce_vars (#5099)
fixes #5098
2021-07-24 07:10:14 +08:00
Alex Lam S.L
6a3fe9d1df fix corner cases in reduce_vars (#5097)
fixes #5096
2021-07-23 17:17:20 +08:00
Alex Lam S.L
ec7fadcb5b v3.14.0 2021-07-22 21:13:43 +08:00
Alex Lam S.L
65adeba55d extend keep_quoted_props over numeric keys (#5094)
fixes #5093
2021-07-22 06:12:57 +08:00
Alex Lam S.L
7fac839c62 fix corner case in merge_vars (#5092)
fixes #5091
2021-07-21 02:47:53 +08:00
Alex Lam S.L
8926a2f327 fix corner case in unused (#5090)
fixes #5089
2021-07-21 01:10:58 +08:00
Alex Lam S.L
85968dee54 fix corner case in inline (#5088)
fixes #5087
2021-07-19 22:35:45 +08:00
Alex Lam S.L
a7e7865e6b fix corner case in unused (#5086)
fixes #5085
2021-07-18 19:38:09 +08:00
Alex Lam S.L
ef5f7fc25e workaround various IE quirks (#5084)
fixes #5081
2021-07-17 20:20:56 +08:00
Alex Lam S.L
902997b73d fix corner case in inline (#5083)
fixes #5082
2021-07-16 22:13:33 +08:00
Alex Lam S.L
f18804fa06 fix corner case in unused (#5080)
fixes #5079
2021-07-14 23:02:45 +08:00
Alex Lam S.L
8e2dff632e suppress false positives in ufuzz (#5078) 2021-07-13 04:10:59 +08:00
Alex Lam S.L
92c3fddd7a fix corner case in unused & yields (#5077)
fixes #5076
2021-07-12 23:16:12 +08:00
Alex Lam S.L
0d350b78bf fix corner cases in unused (#5075)
fixes #5074
2021-07-12 07:43:13 +08:00
Alex Lam S.L
1ad830facb fix corner cases in unused (#5073)
fixes #5071
2021-07-11 14:52:38 +08:00
Alex Lam S.L
64ebf6efe9 fix corner case in awaits & side_effects (#5072)
fixes #5070
2021-07-11 13:43:08 +08:00
Alex Lam S.L
08391b8e1c fix corner case in hoist_props (#5069) 2021-07-11 10:59:57 +08:00
Alex Lam S.L
d147d5d7f0 fix corner case in inline (#5068)
fixes #5067
2021-07-11 04:11:10 +08:00
Alex Lam S.L
aae1fcd12d fix corner case in unused (#5066)
fixes #5065
2021-07-11 00:43:01 +08:00
Alex Lam S.L
f67dd31cbb enhance unused (#5064) 2021-07-10 19:58:57 +08:00
Alex Lam S.L
450aabaaa0 fix corner cases in rests & unused (#5063) 2021-07-10 00:28:23 +08:00
Alex Lam S.L
ea7829daf5 fix corner case in reduce_vars (#5062)
fixes #5061
2021-07-08 16:31:04 +08:00
Alex Lam S.L
6577d641ac enhance evaluate & reduce_vars (#5060) 2021-07-08 00:29:23 +08:00
Alex Lam S.L
2340feff87 support destructured shorthand for default parameters (#5059)
closes #4990
2021-07-07 22:45:24 +08:00
Alex Lam S.L
0c48b84540 fix corner cases in inline & unused (#5058)
fixes #5057
2021-07-07 10:29:16 +08:00
Alex Lam S.L
1fefe3f1d1 fix corner case in reduce_vars (#5056)
fixes #5055
2021-07-07 02:23:09 +08:00
Alex Lam S.L
0668fad5e9 fix corner case with class (#5054)
fixes #5053
2021-07-06 16:04:11 +08:00
Alex Lam S.L
d0e3f6955d enhance functions (#5052) 2021-07-06 02:43:09 +08:00
Alex Lam S.L
6961c57d1e fix corner case in reduce_vars (#5051)
fixes #5050
2021-07-05 11:57:58 +08:00
Alex Lam S.L
f5dbb672b9 fix corner case in reduce_funcs (#5049)
fixes #5048
2021-07-04 15:09:05 +08:00
Alex Lam S.L
f4ae267920 fix corner case in reduce_vars (#5047)
fixes #5046
2021-07-04 13:45:09 +08:00
Alex Lam S.L
972b9f0bef enhance functions & reduce_vars (#5045) 2021-07-04 06:19:08 +08:00
Alex Lam S.L
668f96623c tweak beautify output (#5044) 2021-07-03 23:10:39 +08:00
Alex Lam S.L
1b745494ce enhance booleans (#5043) 2021-07-01 03:05:52 +08:00
Alex Lam S.L
611abff49f fix corner case in booleans (#5042)
fixes #5041
2021-07-01 00:52:54 +08:00
Alex Lam S.L
4ba8b66c5a fix corner case in ie8 (#5040)
fixes #5039
2021-06-30 02:14:07 +08:00
Alex Lam S.L
798121c9f3 enhance reduce_vars (#5038) 2021-06-29 03:51:44 +08:00
Alex Lam S.L
b23b333d9d v3.13.10 2021-06-27 22:59:34 +08:00
Alex Lam S.L
7621527a5f fix corner case in functions (#5037)
fixes #5036
2021-06-25 03:43:52 +08:00
Alex Lam S.L
1a064b6e74 fix corner case in functions (#5035)
fixes #5034
2021-06-24 19:43:46 +08:00
Alex Lam S.L
82772ccb12 workaround Safari quirks (#5033)
closes #5032
2021-06-24 17:09:19 +08:00
Alex Lam S.L
7cbcd11440 fix corner case in dead_code (#5031)
fixes #5030
2021-06-23 22:56:28 +08:00
Alex Lam S.L
980dbde171 fix corner cases in booleans (#5029)
fixes #5028
2021-06-23 07:42:57 +08:00
Alex Lam S.L
8b05677c15 fix corner case in collapse_vars (#5026)
fixes #5025
2021-06-23 05:03:11 +08:00
Alex Lam S.L
95090dbf24 fix corner case in side_effects (#5024)
fixes #5023
2021-06-23 00:36:07 +08:00
Alex Lam S.L
7c5b6f349e enhance booleans (#5022)
closes #5021
2021-06-23 00:35:50 +08:00
Alex Lam S.L
e9c902b044 fix corner cases in dead_code & inline (#5020)
fixes #5019
2021-06-21 22:28:54 +08:00
Alex Lam S.L
111366fca0 fix corner case in collapse_vars (#5018)
fixes #5017
2021-06-21 11:12:45 +08:00
Alex Lam S.L
e368d39715 fix corner cases in reduce_vars & side_effects (#5016)
fixes #5015
2021-06-21 03:13:05 +08:00
Alex Lam S.L
fd8dec61ad enhance dead_code (#5014) 2021-06-20 15:30:04 +08:00
Alex Lam S.L
7880568d15 fix corner case in switches (#5013)
fixes #5012
2021-06-15 23:51:53 +08:00
Alex Lam S.L
21fc8f4630 fix corner case in switches (#5011)
fixes #5010
2021-06-15 20:59:53 +08:00
Alex Lam S.L
bf76e35772 fix corner case in switches (#5009)
fixes #5008
2021-06-15 18:27:55 +08:00
Alex Lam S.L
ac1262dc97 fix corner case in arguments (#5007)
fixes #5006
2021-06-15 12:53:22 +08:00
Alex Lam S.L
498ac83541 enhance switches (#5005)
closes #5004
2021-06-15 10:32:39 +08:00
Alex Lam S.L
6fc7a2ab6a fix corner case in side_effects (#5002)
fixes #5001
2021-06-13 20:29:14 +08:00
Alex Lam S.L
f8b2215145 fix corner cases in parse & unused (#5000) 2021-06-13 00:10:01 +08:00
Alex Lam S.L
70ceda5398 minor clean-up (#4998) 2021-06-12 09:20:06 +08:00
Alex Lam S.L
ce75477670 fix corner case in reduce_vars (#4997)
fixes #4996
2021-06-10 08:03:17 +08:00
Alex Lam S.L
e70b84895c fix corner cases in loops & unused (#4995)
fixes #4994
2021-06-10 07:58:33 +08:00
Alex Lam S.L
8dbf0b042e v3.13.9 2021-06-05 05:21:10 +08:00
Alex Lam S.L
83f7887e5d fix corner case in unused (#4993)
fixes #4992
2021-06-03 20:23:14 +08:00
Alex Lam S.L
dff7b48921 workaround GitHub Actions issues (#4991) 2021-06-02 02:43:34 +08:00
Alex Lam S.L
f4f0d2a2dd workaround transient npm failures (#4989) 2021-05-30 17:19:29 +08:00
Alex Lam S.L
06e3dbc089 improve handling of declaration statements (#4980) 2021-05-30 16:32:48 +08:00
Alex Lam S.L
55a230daa8 fix corner case in awaits (#4988)
fixes #4987
2021-05-30 13:40:13 +08:00
Alex Lam S.L
23b9f36bd8 fix corner case in hoist_props (#4986)
fixes #4985
2021-05-30 12:00:32 +08:00
Alex Lam S.L
7e88d52fae fix corner case in dead_code (#4984) 2021-05-30 11:07:55 +08:00
Alex Lam S.L
b9d5bba5fb fix corner case in dead_code (#4983)
fixes #4982
2021-05-30 09:00:48 +08:00
Alex Lam S.L
8d23496e0f fix corner case in dead_code (#4981) 2021-05-30 03:16:18 +08:00
Alex Lam S.L
260431f4e0 improve handling of lexical scope (#4979) 2021-05-29 12:48:34 +08:00
Alex Lam S.L
7fa1dea9d0 fix corner cases in collapse_vars (#4978)
fixes #4977
2021-05-29 08:57:24 +08:00
Alex Lam S.L
d40631fd44 fix corner cases in awaits (#4976)
fixes #4974
fixes #4975
2021-05-29 01:47:54 +08:00
Alex Lam S.L
d320a6cde2 fix corner case in awaits (#4973)
fixes #4972
2021-05-28 10:53:10 +08:00
Alex Lam S.L
8cd95dd263 enhance awaits (#4971) 2021-05-28 08:47:37 +08:00
Alex Lam S.L
749a828fc5 fix corner case in collapse_vars (#4970) 2021-05-28 06:32:43 +08:00
Alex Lam S.L
ab42a90edb enhance awaits (#4969) 2021-05-28 00:57:14 +08:00
Alex Lam S.L
362abe0ffb enhance unused (#4968) 2021-05-26 22:25:07 +08:00
Alex Lam S.L
e3798d9a76 fix corner case in arguments (#4967) 2021-05-26 22:24:26 +08:00
Alex Lam S.L
c8d10b7cde v3.13.8 2021-05-26 19:17:50 +08:00
Alex Lam S.L
7caab39e26 fix corner case in mangle (#4966)
fixes #4965
2021-05-26 06:21:52 +08:00
Alex Lam S.L
eff45eac0e fix corner case in ie8 (#4963)
fixes #4962
2021-05-26 00:12:31 +08:00
Alex Lam S.L
1e787c556b fix corner case in mangle (#4961)
fixes #4960
2021-05-24 11:46:58 +08:00
Alex Lam S.L
df47632ecc fix corner case in ie8 (#4959)
fixes #4958
2021-05-24 11:24:02 +08:00
Alex Lam S.L
eb08fed120 fix corner case in merge_vars (#4957)
fixes #4956
2021-05-24 09:56:02 +08:00
Alex Lam S.L
8b0c836515 fix corner cases in rename & varify (#4955)
fixes #4954
2021-05-24 06:54:48 +08:00
Alex Lam S.L
5d4e6e3bdc enhance sourceMap (#4953) 2021-05-23 23:57:44 +08:00
Alex Lam S.L
d2a45ba441 fix corner case in parsing private field/method (#4952)
fixes #4951
2021-05-22 10:12:37 +08:00
Alex Lam S.L
de376c3d33 fix corner case in reduce_vars (#4950)
fixes #4949
2021-05-21 18:49:07 +08:00
Alex Lam S.L
4a19575e74 fix corner case in conditionals (#4948)
fixes #4947
2021-05-20 18:08:22 +08:00
Alex Lam S.L
e0695ef549 enhance pure_funcs (#4945) 2021-05-20 07:09:47 +08:00
Alex Lam S.L
d6152e6a76 fix corner case in collapse_vars (#4946) 2021-05-20 05:11:39 +08:00
Alex Lam S.L
d930c705f6 v3.13.7 2021-05-19 02:38:19 +08:00
Alex Lam S.L
254937754c fix corner case in reduce_vars (#4944)
fixes #4943
2021-05-18 05:52:24 +08:00
Alex Lam S.L
ae4dbcb5b9 document v8 quirks (#4942)
closes #4941
2021-05-16 02:13:30 +08:00
Alex Lam S.L
e13615549e fix corner case in pure_getters (#4940)
fixes #4939
2021-05-16 02:12:58 +08:00
Alex Lam S.L
a7698f8845 fix corner case in reduce_vars (#4938)
fixes #4937
2021-05-15 22:38:09 +08:00
Alex Lam S.L
bbed9b13b1 fix corner case in collapse_vars (#4936)
fixes #4935
2021-05-15 22:34:14 +08:00
Alex Lam S.L
2cff7c94e8 fix corner case in reduce_vars (#4934)
fixes #4933
2021-05-15 01:49:46 +08:00
Alex Lam S.L
7576048118 fix corner case in unsafe evaluate (#4932)
fixes #4931
2021-05-14 22:51:19 +08:00
Alex Lam S.L
3c1898fd65 suppress invalid test case generation (#4930) 2021-05-13 19:57:36 +08:00
Alex Lam S.L
e04429350f fix corner case in ie8 (#4929)
fixes #4928
2021-05-13 09:26:57 +08:00
Alex Lam S.L
60f3b55156 fix corner case with optional chain operator (#4927) 2021-05-12 10:12:19 +08:00
Alex Lam S.L
689f8f504d enhance mangle (#4926) 2021-05-11 23:41:32 +08:00
Alex Lam S.L
ae51f76ba7 fix corner case in unused (#4925)
fixes #4924
2021-05-11 20:50:58 +08:00
Alex Lam S.L
7eef86ed05 workaround GitHub Actions issue (#4923) 2021-05-11 18:21:21 +08:00
Alex Lam S.L
b1cfa71131 enhance unused (#4922) 2021-05-11 10:30:20 +08:00
Alex Lam S.L
7b8570f16c v3.13.6 2021-05-11 03:15:16 +08:00
Alex Lam S.L
bb225367cb fix corner case collapse_vars (#4921)
fixes #4920
2021-05-09 02:59:45 +08:00
Alex Lam S.L
bbca9de9cd fix corner case in collapse_vars (#4919)
fixes #4918
2021-05-08 03:58:29 +08:00
Alex Lam S.L
ee9ceb79ca fix corner case in collapse_vars (#4917)
fixes #4916
2021-05-08 02:34:27 +08:00
Alex Lam S.L
ac1f7d689b fix corner case in collapse_vars (#4915)
fixes #4914
2021-05-08 01:14:59 +08:00
Alex Lam S.L
19d232badb fix corner case in unused (#4913)
fixes #4912
2021-05-07 19:38:22 +08:00
Alex Lam S.L
d464be3f3f fix corner case in collapse_vars (#4911)
fixes #4910
2021-05-05 00:03:43 +08:00
Alex Lam S.L
3094eaaa89 fix corner case in collapse_vars (#4909)
fixes #4908
2021-05-04 16:33:52 +08:00
Alex Lam S.L
ce3c35fa8b fix corner case in unused (#4907)
fixes #4906
2021-05-04 06:19:25 +08:00
Alex Lam S.L
5d9224deb8 fix corner cases with template literals (#4903)
fixes #4902
2021-05-03 22:26:20 +08:00
Alex Lam S.L
45b6d23d36 suppress false positives in ufuzz (#4901) 2021-05-03 19:11:53 +08:00
Alex Lam S.L
f0de9a8b5d support optional chaining operator (#4899) 2021-05-03 10:08:29 +08:00
Alex Lam S.L
203f4b7ad9 fix corner case in hoist_vars (#4900)
fixes #4898
2021-05-03 04:05:52 +08:00
Alex Lam S.L
4114431eec fix corner case in collapse_vars (#4896)
fixes #4895
2021-05-02 18:23:18 +08:00
Alex Lam S.L
fb03561799 fix corner case in hoist_vars (#4894)
fixes #4893
2021-05-02 07:28:31 +08:00
Alex Lam S.L
6ab26eef6c fix corner case in collapse_vars (#4892)
fixes #4891
2021-05-02 03:57:17 +08:00
Alex Lam S.L
53b57ee57e enhance reduce_vars & unused (#4890) 2021-05-02 00:19:56 +08:00
Alex Lam S.L
16411dcb87 enhance collapse_vars (#4885) 2021-05-01 21:37:52 +08:00
Alex Lam S.L
8bbfaacdae fix corner case in properties (#4889)
fixes #4888
2021-05-01 07:52:53 +08:00
Alex Lam S.L
df980db4a8 fix corner case in unsafe evaluate (#4887)
fixes #4886
2021-05-01 07:24:39 +08:00
Alex Lam S.L
8e4a19ffec fix corner case in spreads (#4883)
fixes #4882
2021-04-30 22:21:15 +08:00
Alex Lam S.L
d833e66d23 enhance join_vars (#4881) 2021-04-30 11:40:47 +08:00
Alex Lam S.L
8aa650bcf9 v3.13.5 2021-04-30 00:44:50 +08:00
Alex Lam S.L
d576495e5a support #__PURE__ in ESTree (#4879) 2021-04-29 04:13:42 +08:00
Alex Lam S.L
a06e20304b fix corner case in pure_getters (#4877)
fixes #4876
2021-04-27 22:52:37 +08:00
Alex Lam S.L
4cccc01f3e fix corner case in collapse_vars (#4875)
fixes #4874
2021-04-27 08:54:02 +08:00
Alex Lam S.L
97bd56b7e8 improve AST tests & tools (#4873) 2021-04-27 08:53:45 +08:00
Alex Lam S.L
acf951a5bc fix corner case with for [await]...of (#4872) 2021-04-26 05:10:22 +08:00
Alex Lam S.L
324587f769 upgrade AST<->ESTree translation (#4870)
fixes #968
2021-04-26 04:23:52 +08:00
Alex Lam S.L
80efaa2f33 fix corner case with export (#4871) 2021-04-25 22:37:26 +08:00
Alex Lam S.L
a1a212f639 fix corner case in collapse_vars (#4869)
fixes #4868
2021-04-25 05:16:51 +08:00
Alex Lam S.L
a2b1b96752 fix corner case with yield (#4867) 2021-04-25 03:10:12 +08:00
Alex Lam S.L
c296a63fb3 fix corner case in collapse_vars (#4866)
fixes #4865
2021-04-24 20:04:31 +08:00
Alex Lam S.L
10dd9d4eaf enhance collapse_vars (#4864) 2021-04-24 12:45:18 +08:00
Alex Lam S.L
9b8deff64d enhance pure_getters, reduce_vars & unused (#4863) 2021-04-24 07:17:30 +08:00
Alex Lam S.L
f46209b7e5 enhance unsafe side_effects (#4862)
closes #4861
2021-04-23 06:58:14 +08:00
Alex Lam S.L
bddb5a0102 enhance unused (#4858) 2021-04-22 10:58:50 +08:00
Alex Lam S.L
3c161a6662 fix corner case in hoist_vars (#4860)
fixes #4859
2021-04-22 05:47:21 +08:00
Alex Lam S.L
c58e174647 document various ECMAScript bugs (#4857) 2021-04-21 08:33:54 +08:00
Alex Lam S.L
c53af3dfb1 fix corner case in collapse_vars (#4855)
fixes #4854
2021-04-14 01:22:08 +08:00
Alex Lam S.L
f1f4a4dd82 v3.13.4 2021-04-12 04:33:40 +08:00
Alex Lam S.L
ca49f6f41a fix corner case in collapse_vars (#4853)
fixes #4852
2021-04-08 17:50:40 +08:00
Alex Lam S.L
8a82822654 fix corner case in if_return (#4851)
fixes #4848
2021-04-08 08:57:59 +08:00
Alex Lam S.L
ebe4e1ad28 fix corner case in unused (#4850)
fixes #4849
2021-04-08 06:31:15 +08:00
Alex Lam S.L
a37ca558dd reject invalid for await syntax (#4847) 2021-04-07 22:37:15 +08:00
Alex Lam S.L
73a564343b preserve compatibility of quote_style (#4845) 2021-04-07 06:49:12 +08:00
Alex Lam S.L
4870747306 speed up OutputStream (#4844) 2021-04-07 02:57:23 +08:00
Alex Lam S.L
b179a2459f parse octal literals correctly (#4843) 2021-04-07 02:23:35 +08:00
Alex Lam S.L
231c3d7c84 clean up OutputStream (#4842) 2021-04-06 21:34:27 +08:00
Alex Lam S.L
aed758ed5c enhance comparisons & reduce_vars (#4841) 2021-04-03 22:06:05 +08:00
Alex Lam S.L
0df028187d fix corner case in hoist_vars (#4840)
fixes #4839
2021-04-03 10:07:18 +08:00
Alex Lam S.L
10fbf8e295 support mangle.properties on class (#4838) 2021-04-03 06:00:19 +08:00
Alex Lam S.L
cf38b52afa parse import.meta correctly (#4836) 2021-04-03 04:31:29 +08:00
Alex Lam S.L
e755d01a0b fix corner case in unused (#4835)
fixes #4834
2021-04-02 03:55:53 +08:00
Alex Lam S.L
4084948d3b suppress invalid AST transform in --reduce-test (#4833) 2021-04-01 18:52:29 +08:00
Alex Lam S.L
cea1fb5c58 fix corner case in properties (#4832)
fixes #4831
2021-04-01 14:39:51 +08:00
Alex Lam S.L
1947a21824 fix corner case in properties (#4830)
fixes #4829
2021-04-01 07:05:50 +08:00
Alex Lam S.L
6335b5fd8a v3.13.3 2021-03-29 06:58:06 +08:00
Alex Lam S.L
daa8319b8a fix corner cases with logical assignment operators (#4828)
fixes #4827
2021-03-28 03:44:45 +08:00
Alex Lam S.L
d5599604e8 enhance collapse_vars (#4826) 2021-03-27 22:14:37 +08:00
Alex Lam S.L
072933f1d5 diagnose GitHub Actions (#4825) 2021-03-25 18:44:39 +08:00
Alex Lam S.L
39df3a1680 fix corner case in functions (#4824)
fixes #4823
2021-03-25 08:49:01 +08:00
Alex Lam S.L
03c5ecb2e3 fix corner cases with class (#4822)
fixes #4821
2021-03-25 04:36:50 +08:00
Alex Lam S.L
40ef074cb3 fix corner case in comparisons (#4820)
fixes #4819
2021-03-24 10:10:02 +08:00
Alex Lam S.L
78e3936cd4 fix corner case in inline (#4818)
fixes #4817
2021-03-23 22:33:24 +08:00
Alex Lam S.L
e7be38b42a fix corner cases with logical assignment operators (#4816)
fixes #4815
2021-03-23 13:02:45 +08:00
Alex Lam S.L
44394e61c9 workaround toString() quirks on global context (#4814) 2021-03-23 11:15:41 +08:00
Alex Lam S.L
f9055df44d support logical assignment operators (#4813) 2021-03-23 04:59:43 +08:00
Alex Lam S.L
51bdb7281b improve global context enumeration under sandbox (#4812)
fixes #4811
2021-03-22 22:43:33 +08:00
Alex Lam S.L
9c01511f84 v3.13.2 2021-03-22 04:34:26 +08:00
Alex Lam S.L
9faee3b66a fix corner case in arguments (#4810)
fixes #4809
2021-03-21 10:40:32 +08:00
Alex Lam S.L
8ea1ced389 document various v8 bugs (#4808)
closes #4805
2021-03-21 06:33:45 +08:00
Alex Lam S.L
24619daf68 fix corner cases in collapse_vars & unused (#4807)
fixes #4806
2021-03-21 03:51:03 +08:00
Alex Lam S.L
b89cc84c3a fix corner case in pure_getters (#4804)
fixes #4803
2021-03-19 16:16:53 +08:00
Alex Lam S.L
3016a78d85 fix corner case in reduce_vars (#4802)
fixes #4801
2021-03-18 23:58:35 +08:00
Alex Lam S.L
2508481e33 fix corner case in evaluate (#4800)
fixes #4799
2021-03-18 11:31:20 +08:00
Alex Lam S.L
48c46fa9a7 fix corner case in sequences (#4798) 2021-03-18 08:31:55 +08:00
Alex Lam S.L
7da49b5709 fix corner case in collapse_vars (#4797) 2021-03-18 07:50:55 +08:00
Alex Lam S.L
d837a46ebd fix corner case in reduce_vars (#4796) 2021-03-18 05:14:14 +08:00
Alex Lam S.L
d4303b62cc build Bootstrap for verification testing (#4795) 2021-03-17 22:34:17 +08:00
Alex Lam S.L
7d595e2eac improve comment formatting logic (#4794) 2021-03-17 13:51:52 +08:00
Alex Lam S.L
9fc0ff5953 parse extended Unicode literal correctly (#4792) 2021-03-17 10:34:50 +08:00
Alex Lam S.L
997d09bb33 extend keep_fnames to classes (#4793) 2021-03-17 09:28:27 +08:00
Alex Lam S.L
b244b4ec21 enhance "functions" (#4791) 2021-03-17 05:38:33 +08:00
Alex Lam S.L
b872ffee01 fix corner case in hoist_funs (#4790) 2021-03-17 01:48:23 +08:00
Alex Lam S.L
9a9543013c fix corner case in functions (#4789)
fixes #4788
2021-03-16 20:58:51 +08:00
Alex Lam S.L
b98ce6c84f avoid flaky cases in verification testing (#4785) 2021-03-16 20:50:33 +08:00
Alex Lam S.L
7b43b6396f ensure valid generated cases in --reduce-test (#4787)
closes #4786
2021-03-16 18:14:24 +08:00
Alex Lam S.L
67f8fcb103 build web-tooling-benchmark for verification testing (#4776) 2021-03-16 17:34:10 +08:00
Alex Lam S.L
352a944868 fix corner cases with new.target (#4784) 2021-03-16 14:34:36 +08:00
Alex Lam S.L
77c9116c91 fix corner case in unsafe (#4783) 2021-03-16 09:42:28 +08:00
Alex Lam S.L
e821787095 fix corner case in reduce_vars (#4782) 2021-03-16 08:05:01 +08:00
Alex Lam S.L
aa6e33e208 parse out-of-range numerals correctly (#4781) 2021-03-16 06:52:21 +08:00
Alex Lam S.L
176581d732 fix corner cases with template literals (#4780) 2021-03-15 21:54:05 +08:00
Alex Lam S.L
01aa078e9c support **= (#4778) 2021-03-15 21:53:48 +08:00
Alex Lam S.L
149d75c092 fix corner case in unsafe (#4779) 2021-03-15 17:51:32 +08:00
Alex Lam S.L
2619bff3cf fix corner case in conditionals (#4777) 2021-03-15 12:44:41 +08:00
Alex Lam S.L
4fb54b066f improve Node.js setup on GitHub Actions (#4775) 2021-03-15 06:25:33 +08:00
Alex Lam S.L
e124ef57e3 parse parentheses-terminated statements correctly (#4774)
fixes #4772
2021-03-14 14:09:29 +08:00
Alex Lam S.L
73e6b2550b fix corner cases with yield (#4771)
fixes #4769
2021-03-14 04:39:30 +08:00
Alex Lam S.L
241113200e support shorthand key-symbol output (#4768) 2021-03-13 15:37:01 +08:00
Alex Lam S.L
6f3ab09319 fix corner case in unused (#4767)
fixes #4766
2021-03-13 15:09:07 +08:00
Alex Lam S.L
3b5d5014e0 implement annotations (#4763) 2021-03-13 03:40:49 +08:00
Alex Lam S.L
c36c3cb470 fix corner case in side_effects (#4765)
fixes #4764
2021-03-13 02:40:28 +08:00
Alex Lam S.L
24b73a95fa v3.13.1 2021-03-12 06:50:05 +08:00
Alex Lam S.L
862b1b77b5 fix corner cases in merge_vars & with exports (#4762)
fixes #4761
2021-03-11 09:16:16 +08:00
Alex Lam S.L
b4944a31a4 fix corner case in merge_vars (#4760)
fixes #4759
2021-03-10 23:44:49 +08:00
Alex Lam S.L
58362d5ec7 build Math.js for verification testing (#4758) 2021-03-10 03:34:30 +08:00
Alex Lam S.L
01fa430a3e fix corner case in unused (#4757)
fixes #4756
2021-03-09 07:59:52 +08:00
Alex Lam S.L
f4ee0f651c fix corner case in unsafe (#4755) 2021-03-09 04:40:21 +08:00
Alex Lam S.L
077512d151 fix corner case in inline (#4754)
fixes #4753
2021-03-08 12:38:53 +08:00
Alex Lam S.L
e4848a7f5a speed up ufuzz asynchronous testing (#4750) 2021-03-08 04:25:56 +08:00
Alex Lam S.L
f52b0e7c31 fix corner case in side_effects (#4752)
fixes #4751
2021-03-08 04:19:51 +08:00
Alex Lam S.L
31e7d25cad fix issues uncovered by lgtm (#4749) 2021-03-07 12:44:34 +08:00
Alex Lam S.L
12babdfe20 build external projects for verification testing (#4741) 2021-03-07 12:41:52 +08:00
Alex Lam S.L
397e48b97e fix corner case in collapse_vars & reduce_vars (#4748)
fixes #4747
2021-03-07 10:33:51 +08:00
Alex Lam S.L
c7520b4b97 support new.target (#4746)
fixes #4745
2021-03-07 07:11:36 +08:00
Alex Lam S.L
ad903e9240 fix corner cases with export (#4743)
fixes #4742
2021-03-06 22:49:39 +08:00
Alex Lam S.L
83c3838b07 fix corner case in awaits (#4740)
fixes #4738
2021-03-06 04:25:44 +08:00
Alex Lam S.L
fa09f87589 fix corner case in hoist_vars (#4739)
fixes #4736
2021-03-06 04:25:32 +08:00
Alex Lam S.L
2db1a141ab speed up compress tests (#4737) 2021-03-06 01:11:05 +08:00
Alex Lam S.L
dd30ed6a9b enhance collapse_vars (#4735) 2021-03-05 13:18:01 +08:00
Alex Lam S.L
cb50a2d192 fix corner case in collapse_vars (#4733)
fixes #4732
2021-03-04 17:13:54 +08:00
Alex Lam S.L
20be5209c0 fix corner cases in ie8 & side_effects (#4731)
fixes #4729
fixes #4730
2021-03-04 03:30:07 +08:00
Alex Lam S.L
2a49760032 enhance side_effects (#4727) 2021-03-03 18:47:17 +08:00
Alex Lam S.L
04ed818f0a improve ufuzz test generation (#4724) 2021-03-03 15:42:46 +08:00
Alex Lam S.L
10ca578ee5 fix corner case in inline (#4726)
fixes #4725
2021-03-03 09:18:02 +08:00
Alex Lam S.L
955411e065 fix corner cases with class (#4723)
fixes #4720
fixes #4721
fixes #4722
2021-03-03 03:32:58 +08:00
Alex Lam S.L
adcafce048 fix corner cases in varify (#4719) 2021-03-02 23:33:58 +08:00
Alex Lam S.L
b1e05fd48a fix corner case in inline & sequences (#4718)
fixes #4717
2021-03-02 17:39:34 +08:00
Alex Lam S.L
23b51287aa fix corner case in evaluate (#4716)
fixes #4715
2021-03-02 17:33:28 +08:00
Alex Lam S.L
74dee5c445 enhance reduce_vars & varify (#4714) 2021-03-02 15:27:55 +08:00
Alex Lam S.L
ee27d87a08 enhance reduce_vars & side_effects (#4712) 2021-03-02 13:43:10 +08:00
Alex Lam S.L
62887f2c66 fix corner case with class (#4713) 2021-03-02 12:08:08 +08:00
Alex Lam S.L
68b2dadc58 enhance side_effects & unused (#4711) 2021-03-02 04:55:09 +08:00
Alex Lam S.L
bd73720061 v3.13.0 2021-03-01 23:24:17 +08:00
Alex Lam S.L
ec0440f264 fix corner cases with import (#4709)
fixes #4708
2021-03-01 07:13:49 +08:00
Alex Lam S.L
81254f67e4 support limited ufuzz testing for import (#4707) 2021-03-01 02:27:41 +08:00
Alex Lam S.L
c549ee89b9 fix corner case reduce_vars (#4706)
fixes #4705
2021-02-28 04:41:21 +08:00
Alex Lam S.L
7924a3ae8b improve export compatibility mode (#4704) 2021-02-27 21:06:23 +08:00
Alex Lam S.L
13ad10a6b5 improve export compatibility mode (#4703) 2021-02-27 14:05:36 +08:00
Alex Lam S.L
e6ebf827ce fix corner cases with export (#4699)
fixes #4698
fixes #4700
fixes #4701
fixes #4702
2021-02-27 10:15:14 +08:00
Alex Lam S.L
0a42457df6 fix corner case with arguments (#4697)
fixes #4696
2021-02-27 09:26:15 +08:00
Alex Lam S.L
ba4a771bbc support limited ufuzz testing for export (#4693)
fixes #4692
2021-02-27 04:56:34 +08:00
Alex Lam S.L
ac26993b5a fix corner cases with block-scoped functions (#4695) 2021-02-27 04:16:14 +08:00
Alex Lam S.L
ea52339502 use strict-mode-safe placeholder (#4694) 2021-02-26 16:43:53 +08:00
Alex Lam S.L
992952d8f6 fix corner cases with exports (#4691) 2021-02-26 02:22:49 +08:00
Alex Lam S.L
6d7ab63a66 fix corner cases in sequences (#4690)
fixes #4689
2021-02-25 12:48:40 +08:00
Alex Lam S.L
822b1da5d2 fix corner cases with arrow functions (#4688)
fixes #4687
2021-02-25 09:01:45 +08:00
Alex Lam S.L
72805ea73a fix corner case in collapse_vars (#4686)
fixes #4685
2021-02-25 05:31:12 +08:00
Alex Lam S.L
a5e6946f74 fix corner case in loops (#4684)
fixes #4683
2021-02-25 04:41:21 +08:00
Alex Lam S.L
b8672b55b2 fix corner case in unused (#4682)
fixes #4681
2021-02-25 02:17:28 +08:00
Alex Lam S.L
a5a958beda fix corner case in comparisons (#4680)
fixes #4679
2021-02-24 13:38:44 +00:00
Alex Lam S.L
c885660347 support nullish coalescing operator (#4678) 2021-02-24 05:57:11 +08:00
Alex Lam S.L
d68d155f93 support class literals (#4658) 2021-02-23 22:55:08 +08:00
Alex Lam S.L
e535f19189 fix corner case in templates (#4677)
fixes #4676
2021-02-22 23:59:28 +08:00
Alex Lam S.L
f9a2a9d78e enhance side_effects (#4675) 2021-02-22 15:44:16 +08:00
Alex Lam S.L
960668ccdb improve CLI usability (#4670)
closes #3308
2021-02-22 15:27:03 +08:00
Alex Lam S.L
55b59407e4 fix corner cases in reduce_vars (#4674) 2021-02-22 08:21:21 +08:00
Alex Lam S.L
b726e364c1 fix corner cases with export default (#4673) 2021-02-21 13:01:56 +08:00
Alex Lam S.L
bfe3a8b516 fix corner case with import (#4672) 2021-02-21 10:00:34 +08:00
Alex Lam S.L
ae09773ba0 parse dynamic import correctly (#4671) 2021-02-21 06:54:15 +08:00
Alex Lam S.L
8d668c2963 fix corner case in conditionals & side_effects (#4669)
fixes #4668
2021-02-20 11:13:15 +08:00
Alex Lam S.L
5f60c1b830 fix corner cases in arrow functions & rests (#4667)
fixes #4666
2021-02-19 08:26:57 +08:00
Alex Lam S.L
10de27ca3d fix corner case in reduce_vars (#4665)
fixes #4664
2021-02-19 02:04:33 +08:00
Alex Lam S.L
7b4fd858ba fix corner case in reduce_vars (#4663)
fixes #4662
2021-02-18 23:24:55 +08:00
Alex Lam S.L
a7bcd4d613 fix corner case in inline (#4660)
fixes #4659
2021-02-18 16:15:44 +08:00
Alex Lam S.L
6a2bda52f3 workaround bug in ECMAScript specification (#4656)
closes #4655
2021-02-16 23:39:06 +08:00
Alex Lam S.L
fa8aa204a0 fix corner case in reduce_vars (#4654)
fixes #4653
2021-02-16 06:46:45 +08:00
Alex Lam S.L
76b27891c6 fix syntax error in tests (#4652) 2021-02-15 14:41:07 +08:00
Alex Lam S.L
203ca2586a introduce hoist_exports (#4651) 2021-02-15 09:01:18 +08:00
Alex Lam S.L
c21f096ab8 support export statements (#4650) 2021-02-15 04:13:54 +08:00
Alex Lam S.L
b7219ac489 support import statements (#4646) 2021-02-14 04:26:43 +08:00
Alex Lam S.L
a6bb66931b improve fix for #4325 (#4649) 2021-02-14 02:24:57 +08:00
Alex Lam S.L
766742e1d3 v3.12.8 2021-02-13 21:38:27 +08:00
Alex Lam S.L
94e8944f67 avoid false positive in --reduce-test (#4648) 2021-02-13 21:15:11 +08:00
Alex Lam S.L
83197ffdb3 fix corner case in evaluate (#4645)
fixes #4644
2021-02-12 03:26:12 +08:00
Alex Lam S.L
952765be66 enhance join_vars (#4643) 2021-02-11 04:59:25 +08:00
Alex Lam S.L
083679bcad fix corner cases with asynchronous generators (#4642)
fixes #4641
2021-02-10 23:41:00 +08:00
Alex Lam S.L
f5659f292b enhance collapse_vars (#4637) 2021-02-10 23:06:12 +08:00
Alex Lam S.L
c6e287331d fix corner cases in inline (#4640)
fixes #4639
2021-02-10 20:40:57 +08:00
Alex Lam S.L
a98ec7e4df enhance side_effects (#4638) 2021-02-10 18:09:54 +08:00
Alex Lam S.L
5ec82e5801 fix corner case in reduce_vars (#4636) 2021-02-10 10:37:00 +08:00
Alex Lam S.L
c76481341c fix corner case in merge_vars (#4635) 2021-02-10 09:13:38 +08:00
Alex Lam S.L
5e6307974f fix corner case in collapse_vars (#4634)
fixes #4633
2021-02-10 08:45:36 +08:00
Alex Lam S.L
228cdf8e7e reject invalid for...of syntax (#4632) 2021-02-10 05:42:27 +08:00
Alex Lam S.L
14fedbf123 fix corner case with template literals (#4631)
fixes #4630
2021-02-09 14:21:15 +08:00
Alex Lam S.L
fcee32527b fix corner case in merge_vars (#4629)
fixes #4628
2021-02-09 12:36:12 +08:00
Alex Lam S.L
e13d1e9969 support for [await]...of statements (#4627) 2021-02-09 04:28:23 +08:00
Alex Lam S.L
aedc1e7fc9 improve false positive detection in ufuzz (#4626) 2021-02-08 20:17:14 +08:00
Alex Lam S.L
353f654038 fix corner case in --reduce-test (#4625) 2021-02-08 19:16:21 +08:00
Alex Lam S.L
357d861246 fix corner case in conditionals (#4624)
fixes #4623
2021-02-08 18:31:08 +08:00
Alex Lam S.L
fd4caf7a9c support generator functions (#4620) 2021-02-08 06:44:20 +08:00
Alex Lam S.L
c44b6399c3 fix corner case in side_effects (#4622)
fixes #4621
2021-02-07 22:40:41 +08:00
Alex Lam S.L
522cceeccf fix corner case in functions (#4619)
fixes #4618
2021-02-07 13:52:09 +08:00
Alex Lam S.L
5c84dfa151 v3.12.7 2021-02-07 02:43:47 +08:00
Alex Lam S.L
5359900b78 enhance compress on arrow and async functions (#4616) 2021-02-06 12:39:46 +08:00
Alex Lam S.L
739fa266f8 fix corner case in pure_getters (#4615)
fixes #4614
2021-02-05 09:03:51 +08:00
Alex Lam S.L
da24dfb59e fix corner cases with function inlining (#4613)
fixes #4612
2021-02-05 04:49:37 +08:00
Alex Lam S.L
a2f27c7640 fix corner cases in templates (#4610) 2021-02-02 17:39:30 +00:00
Alex Lam S.L
3c556b8689 fix corner case in arguments (#4609)
fixes #4608
2021-02-02 23:07:31 +08:00
Alex Lam S.L
7110c6923b fix corner case in templates (#4607)
fixes #4606
2021-02-02 02:29:43 +08:00
Alex Lam S.L
b27b6807cb fix corner case in collapse_vars (#4605)
fixes #4604
2021-02-01 23:24:11 +08:00
Alex Lam S.L
ba6e29d6fd introduce templates (#4603) 2021-02-01 17:20:13 +08:00
Alex Lam S.L
d4685640a0 support template literals (#4601) 2021-02-01 10:36:45 +08:00
167 changed files with 54172 additions and 7609 deletions

58
.github/workflows/build.yml vendored Normal file
View File

@@ -0,0 +1,58 @@
name: Build testing
on:
pull_request:
push:
branches: [ master ]
jobs:
ufuzz:
strategy:
fail-fast: false
matrix:
options:
- '--ie -c'
- '-mb braces'
- '--toplevel -mc'
- '-p acorn -mco spidermonkey'
- '-mc passes=3,pure_getters,unsafe'
script:
- acorn.sh
- bootstrap.sh
- buble.sh
- butternut.sh
- mathjs.sh
- rollup-es.sh
- rollup-ts.sh
- sucrase.sh
- web-tooling-benchmark.sh
include:
- node: '14'
script: acorn.sh
- node: '14'
script: bootstrap.sh
- node: '14'
script: buble.sh
- node: '14'
script: butternut.sh
- node: '14'
script: mathjs.sh
- node: '8'
script: rollup-es.sh
- node: '14'
script: rollup-ts.sh
- node: '14'
script: sucrase.sh
- node: '14'
script: web-tooling-benchmark.sh
name: ${{ matrix.script }} ${{ matrix.options }}
runs-on: ubuntu-latest
env:
NODE: ${{ matrix.node }}
OPTIONS: ${{ matrix.options }}
SCRIPT: ${{ matrix.script }}
steps:
- uses: actions/checkout@v4
- name: Perform uglify, build & test
shell: bash
run: |
. ./test/release/install.sh
./test/release/$SCRIPT $OPTIONS

View File

@@ -7,42 +7,23 @@ jobs:
test:
strategy:
matrix:
node: [ '0.8', '0.10', '0.12', '4', '6', '8', '10', '12', latest ]
node: [ '0.10', '0.12', '4', '6', '8', '10', '12', '14', '16', '18', '20' ]
os: [ ubuntu-latest, windows-latest ]
script: [ compress, mocha, release/benchmark, release/jetstream ]
exclude:
- node: '0.8'
script: release/benchmark
- node: '0.8'
script: release/jetstream
name: ${{ matrix.node }} ${{ matrix.os }} ${{ matrix.script }}
runs-on: ${{ matrix.os }}
env:
NODE: ${{ matrix.node }}
TYPE: ${{ matrix.script }}
UGLIFY_GITHUB_LAG: 10000
steps:
- uses: actions/checkout@v2
- uses: actions/cache@v2
- uses: actions/checkout@v4
- uses: actions/cache@v4
with:
path: tmp
key: tmp ${{ matrix.script }}
- name: Perform tests
shell: bash
run: |
git clone --branch v1.6.0 --depth 1 https://github.com/jasongin/nvs.git ~/.nvs
while ! timeout 60 bash -c '. ~/.nvs/nvs.sh add $NODE && nvs use $NODE'; do
cd ~/.nvs
while !(git clean -xdf); do echo "'git clean' failed - retrying..."; done
cd -
done
. ~/.nvs/nvs.sh --version
nvs use $NODE
node --version
npm config set audit false
npm config set optional false
npm config set save false
npm config set strict-ssl false
npm config set update-notifier false
npm --version
while !(npm install); do echo "'npm install' failed - retrying..."; done
. ./test/release/install.sh
node test/$TYPE

18
.github/workflows/moz.yml vendored Normal file
View File

@@ -0,0 +1,18 @@
name: ESTree
on:
pull_request:
push:
branches: [ master ]
jobs:
test:
name: fuzzing
runs-on: ubuntu-latest
env:
NODE: latest
steps:
- uses: actions/checkout@v4
- name: Perform tests
shell: bash
run: |
. ./test/release/install.sh
node test/mozilla-ast.js 5000

View File

@@ -2,11 +2,14 @@ name: Fuzzing
on:
pull_request:
schedule:
- cron: '*/5 * * * *'
- cron: '*/15 * * * *'
workflow_dispatch:
workflow_run:
branches: [ master ]
types: [ completed ]
workflows: [ 'Build testing', CI ]
env:
BASE_URL: https://api.github.com/repos/${{ github.repository }}
CAUSE: ${{ github.event_name }}
RUN_NUM: ${{ github.run_number }}
TOKEN: ${{ github.token }}
jobs:
ufuzz:
@@ -14,13 +17,13 @@ jobs:
fail-fast: false
matrix:
include:
- node: latest
- node: '16'
os: macos-latest
- node: '8'
- node: '12'
os: ubuntu-latest
- node: '8'
os: ubuntu-latest
- node: '8'
- node: '12'
os: windows-latest
- node: '8'
os: windows-latest
@@ -29,35 +32,13 @@ jobs:
env:
NODE: ${{ matrix.node }}
steps:
- uses: actions/checkout@v2
- name: Install GNU Core Utilities
if: ${{ startsWith(matrix.os, 'macos') }}
env:
HOMEBREW_NO_INSTALL_CLEANUP: 1
shell: bash
run: |
brew install coreutils
- uses: actions/checkout@v4
- name: Perform fuzzing
shell: bash
run: |
git clone --branch v1.6.0 --depth 1 https://github.com/jasongin/nvs.git ~/.nvs
while ! timeout 60 bash -c '. ~/.nvs/nvs.sh add $NODE && nvs use $NODE'; do
cd ~/.nvs
while !(git clean -xdf); do echo "'git clean' failed - retrying..."; done
cd -
done
. ~/.nvs/nvs.sh --version
nvs use $NODE
node --version
npm config set audit false
npm config set optional false
npm config set save false
npm config set strict-ssl false
npm config set update-notifier false
npm --version
while !(npm install); do echo "'npm install' failed - retrying..."; done
if [[ $CAUSE == "schedule" ]]; then
node test/ufuzz/job $BASE_URL $TOKEN $RUN_NUM
else
. ./test/release/install.sh
if [[ $GITHUB_EVENT_NAME == "pull_request" ]]; then
node test/ufuzz/job 5000
else
node test/ufuzz/job $BASE_URL $TOKEN $GITHUB_RUN_NUMBER
fi

View File

@@ -3,7 +3,7 @@ Contributing
## Documentation
Every new feature and API change should be accompanied by a README additon.
Every new feature and API change should be accompanied by a README addition.
## Testing

View File

@@ -1,6 +1,6 @@
UglifyJS is released under the BSD license:
Copyright 2012-2019 (c) Mihai Bazon <mihai.bazon@gmail.com>
Copyright 2012-2024 (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

507
README.md
View File

@@ -4,12 +4,11 @@ UglifyJS 3
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/UglifyJS/tree/v2.x)**.
- **Documentation for UglifyJS `2.x` releases can be found [here](https://github.com/mishoo/UglifyJS/tree/v2.x)**.
- `uglify-js` supports ECMAScript 5 and some newer language features.
- To minify ECMAScript 2015 or above, you may need to transpile using tools like
[Babel](https://babeljs.io/).
- `uglify-js` supports JavaScript and most language features in ECMAScript.
- For more exotic parts of ECMAScript, process your source file with transpilers
like [Babel](https://babeljs.io/) before passing onto `uglify-js`.
- `uglify-js@3` has a simplified [API](#api-reference) and [CLI](#command-line-usage)
that is not backwards compatible with [`uglify-js@2`](https://github.com/mishoo/UglifyJS/tree/v2.x).
Install
-------
@@ -55,8 +54,6 @@ a double dash to prevent input files being used as option arguments:
modules and Userscripts that may
be anonymous function wrapped (IIFE)
by the .user.js engine `caller`.
`expression` Parse a single expression, rather than
a program (for parsing JSON).
`spidermonkey` Assume input files are SpiderMonkey
AST format (as JSON).
-c, --compress [options] Enable compressor/specify compressor options:
@@ -86,13 +83,16 @@ a double dash to prevent input files being used as option arguments:
1 - single
2 - double
3 - original
`wrap_iife` Wrap IIFEs in parenthesis. Note: you may
`wrap_iife` Wrap IIFEs in parentheses. Note: you may
want to disable `negate_iife` under
compressor options.
-O, --output-opts [options] Specify output options (`beautify` disabled by default).
-o, --output <file> Output file path (default STDOUT). Specify `ast` or
`spidermonkey` to write UglifyJS or SpiderMonkey AST
as JSON to STDOUT respectively.
--annotations Process and preserve comment annotations.
(`/*@__PURE__*/` or `/*#__PURE__*/`)
--no-annotations Ignore and discard comment annotations.
--comments [filter] Preserve copyright comments in the output. By
default this works like Google Closure, keeping
JSDoc-style comments that contain "@license" or
@@ -109,12 +109,18 @@ a double dash to prevent input files being used as option arguments:
-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()`
--expression Parse a single expression, rather than a program
(for parsing JSON).
--ie Support non-standard Internet Explorer.
Equivalent to setting `ie: true` in `minify()`
for `compress`, `mangle` and `output` options.
By default UglifyJS will not try to be IE-proof.
--keep-fargs Do not mangle/drop function arguments.
--keep-fnames Do not mangle/drop function names. Useful for
code relying on Function.prototype.name.
--module Process input as ES module (implies --toplevel)
--no-module Avoid optimizations which may alter runtime behavior
under prior versions of JavaScript.
--name-cache <file> File to hold mangled name mappings.
--self Build UglifyJS as a library (implies --wrap UglifyJS)
--source-map [options] Enable source map/specify source map options:
@@ -143,7 +149,7 @@ a double dash to prevent input files being used as option arguments:
--warn Print warning messages.
--webkit Support non-standard Safari/Webkit.
Equivalent to setting `webkit: true` in `minify()`
for `mangle` and `output` options.
for `compress`, `mangle` and `output` options.
By default UglifyJS will not try to be Safari-proof.
--wrap <name> Embed everything in a big function, making the
“exports” and “global” variables available. You
@@ -222,10 +228,10 @@ Example:
To enable the mangler you need to pass `--mangle` (`-m`). The following
(comma-separated) options are supported:
- `eval` (default `false`) -- mangle names visible in scopes where `eval` or
- `eval` (default: `false`) mangle names visible in scopes where `eval` or
`with` are used.
- `reserved` (default: `[]`) -- when mangling is enabled but you want to
- `reserved` (default: `[]`) when mangling is enabled but you want to
prevent certain names from being mangled, you can declare those names with
`--mangle reserved` — pass a comma-separated list of names. For example:
@@ -323,7 +329,7 @@ unquoted style (`o.foo`). Example:
// stuff.js
var o = {
"foo": 1,
bar: 3
bar: 3,
};
o.foo += o.bar;
console.log(o.foo);
@@ -335,6 +341,16 @@ $ uglifyjs stuff.js --mangle-props keep_quoted -c -m
var o={foo:1,o:3};o.foo+=o.o,console.log(o.foo);
```
If the minified output will be processed again by UglifyJS, consider specifying
`keep_quoted_props` so the same property names are preserved:
```bash
$ uglifyjs stuff.js --mangle-props keep_quoted -c -m -O keep_quoted_props
```
```javascript
var o={"foo":1,o:3};o.foo+=o.o,console.log(o.foo);
```
### Debugging property name mangling
You can also pass `--mangle-props debug` in order to mangle property names
@@ -492,46 +508,60 @@ if (result.error) throw result.error;
## Minify options
- `compress` (default `{}`) — pass `false` to skip compressing entirely.
- `annotations` — pass `false` to ignore all comment annotations and elide them
from output. Useful when, for instance, external tools incorrectly applied
`/*@__PURE__*/` or `/*#__PURE__*/`. Pass `true` to both compress and retain
comment annotations in output to allow for further processing downstream.
- `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.
- `expression` (default: `false`) — parse as a single expression, e.g. JSON.
- `keep_fnames` (default: `false`) -- pass `true` to prevent discarding or mangling
- `ie` (default: `false`) — enable workarounds for Internet Explorer bugs.
- `keep_fargs` (default: `false`) — pass `true` to prevent discarding or mangling
of function arguments.
- `keep_fnames` (default: `false`) — pass `true` to prevent discarding or mangling
of function names. Useful for code relying on `Function.prototype.name`.
- `mangle` (default `true`) — pass `false` to skip mangling names, or pass
- `mangle` (default: `true`) — pass `false` to skip mangling names, or pass
an object to specify [mangle options](#mangle-options) (see below).
- `mangle.properties` (default `false`) — a subcategory of the mangle option.
- `mangle.properties` (default: `false`) — a subcategory of the mangle option.
Pass an object to specify custom [mangle property options](#mangle-properties-options).
- `nameCache` (default `null`) -- pass an empty object `{}` or a previously
- `module` (default: `true`) — process input as ES module, i.e. implicit
`"use strict";` and support for top-level `await`. When explicitly specified,
also enables `toplevel`.
- `nameCache` (default: `null`) — pass an empty object `{}` or a previously
used `nameCache` object if you wish to cache mangled variable and
property names across multiple invocations of `minify()`. Note: this is
a read/write property. `minify()` will read the name cache state of this
object and update it during minification so that it may be
reused or externally persisted by the user.
- `output` (default `null`) — pass an object if you wish to specify
- `output` (default: `null`) — pass an object if you wish to specify
additional [output options](#output-options). The defaults are optimized
for best compression.
- `parse` (default `{}`) — pass an object if you wish to specify some
- `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
- `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
- `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.
- `v8` (default `false`) -- enable workarounds for Chrome & Node.js bugs.
- `v8` (default: `false`) enable workarounds for Chrome & Node.js bugs.
- `warnings` (default `false`) — pass `true` to return compressor warnings
- `warnings` (default: `false`) — pass `true` to return compressor warnings
in `result.warnings`. Use the value `"verbose"` for more detailed warnings.
- `webkit` (default `false`) -- enable workarounds for Safari/WebKit bugs.
- `webkit` (default: `false`) enable workarounds for Safari/WebKit bugs.
PhantomJS users should set this option to `true`.
## Minify options structure
@@ -559,7 +589,6 @@ if (result.error) throw result.error;
},
nameCache: null, // or specify a name cache object
toplevel: false,
ie8: false,
warnings: false,
}
```
@@ -616,111 +645,129 @@ to be `false` and all symbol names will be omitted.
## Parse options
- `bare_returns` (default `false`) -- support top level `return` statements
- `bare_returns` (default: `false`) support top level `return` statements
- `html5_comments` (default `true`)
- `html5_comments` (default: `true`) — process HTML comment as workaround for
browsers which do not recognize `<script>` tags
- `shebang` (default `true`) -- support `#!command` as the first line
- `module` (default: `false`) — set to `true` if you wish to process input as
ES module, i.e. implicit `"use strict";` and support for top-level `await`.
- `shebang` (default: `true`) — support `#!command` as the first line
## Compress options
- `arguments` (default: `true`) -- replace `arguments[index]` with function
- `annotations` (default: `true`) — Pass `false` to disable potentially dropping
functions marked as "pure". A function call is marked as "pure" if a comment
annotation `/*@__PURE__*/` or `/*#__PURE__*/` immediately precedes the call. For
example: `/*@__PURE__*/foo();`
- `arguments` (default: `true`) — replace `arguments[index]` with function
parameter name whenever possible.
- `arrows` (default: `true`) -- apply optimizations to arrow functions
- `arrows` (default: `true`) apply optimizations to arrow functions
- `assignments` (default: `true`) -- apply optimizations to assignment expressions
- `assignments` (default: `true`) apply optimizations to assignment expressions
- `awaits` (default: `true`) -- apply optimizations to `await` expressions
- `awaits` (default: `true`) apply optimizations to `await` expressions
- `booleans` (default: `true`) -- various optimizations for boolean context,
- `booleans` (default: `true`) various optimizations for boolean context,
for example `!!a ? b : c → a ? b : c`
- `collapse_vars` (default: `true`) -- Collapse single-use non-constant variables,
- `collapse_vars` (default: `true`) Collapse single-use non-constant variables,
side effects permitting.
- `comparisons` (default: `true`) -- apply certain optimizations to binary nodes,
- `comparisons` (default: `true`) apply certain optimizations to binary nodes,
e.g. `!(a <= b) → a > b`, attempts to negate binary nodes, e.g.
`a = !b && !c && !d && !e → a=!(b||c||d||e)` etc.
- `conditionals` (default: `true`) -- apply optimizations for `if`-s and conditional
- `conditionals` (default: `true`) apply optimizations for `if`-s and conditional
expressions
- `dead_code` (default: `true`) -- remove unreachable code
- `dead_code` (default: `true`) remove unreachable code
- `default_values` (default: `true`) -- drop overshadowed default values
- `default_values` (default: `true`) drop overshadowed default values
- `directives` (default: `true`) -- remove redundant or non-standard directives
- `directives` (default: `true`) remove redundant or non-standard directives
- `drop_console` (default: `false`) -- Pass `true` to discard calls to
- `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
after dropping the function call then use `pure_funcs` instead.
- `drop_debugger` (default: `true`) -- remove `debugger;` statements
- `drop_debugger` (default: `true`) remove `debugger;` statements
- `evaluate` (default: `true`) -- Evaluate expression for shorter constant
- `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
- `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`
- `functions` (default: `true`) convert declarations from `var` to `function`
whenever possible.
- `global_defs` (default: `{}`) -- see [conditional compilation](#conditional-compilation)
- `global_defs` (default: `{}`) see [conditional compilation](#conditional-compilation)
- `hoist_funs` (default: `false`) -- hoist function declarations
- `hoist_exports` (default: `true`) hoist `export` statements to facilitate
various `compress` and `mangle` optimizations.
- `hoist_props` (default: `true`) -- hoist properties from constant object and
- `hoist_funs` (default: `false`) hoist function declarations
- `hoist_props` (default: `true`) — hoist properties from constant object and
array literals into regular variables subject to a set of constraints. For example:
`var o={p:1, q:2}; f(o.p, o.q);` is converted to `f(1, 2);`. Note: `hoist_props`
works best with `toplevel` and `mangle` enabled, alongside with `compress` option
`passes` set to `2` or higher.
- `hoist_vars` (default: `false`) -- hoist `var` declarations (this is `false`
- `hoist_vars` (default: `false`) hoist `var` declarations (this is `false`
by default because it seems to increase the size of the output in general)
- `if_return` (default: `true`) -- optimizations for if/return and if/continue
- `if_return` (default: `true`) optimizations for if/return and if/continue
- `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`
- `imports` (default: `true`) — drop unreferenced import symbols when used with `unused`
- `join_vars` (default: `true`) -- join consecutive `var` statements
- `inline` (default: `true`) — inline calls to function with simple/`return` statement:
- `false` — same as `0`
- `0` — disabled inlining
- `1` — inline simple functions
- `2` — inline functions with arguments
- `3` — inline functions with arguments and variables
- `4` — inline functions with arguments, variables and statements
- `true` — same as `4`
- `keep_fargs` (default: `false`) -- discard unused function arguments except
- `join_vars` (default: `true`) — join consecutive `var` statements
- `keep_fargs` (default: `false`) — discard unused function arguments except
when unsafe to do so, e.g. code which relies on `Function.prototype.length`.
Pass `true` to always retain function arguments.
- `keep_infinity` (default: `false`) -- Pass `true` to prevent `Infinity` from
- `keep_infinity` (default: `false`) Pass `true` to prevent `Infinity` from
being compressed into `1/0`, which may cause performance issues on Chrome.
- `loops` (default: `true`) -- optimizations for `do`, `while` and `for` loops
- `loops` (default: `true`) optimizations for `do`, `while` and `for` loops
when we can statically determine the condition.
- `merge_vars` (default: `true`) -- combine and reuse variables.
- `merge_vars` (default: `true`) combine and reuse variables.
- `negate_iife` (default: `true`) -- negate "Immediately-Called Function Expressions"
where the return value is discarded, to avoid the parens that the
- `module` (default: `false`) — set to `true` if you wish to process input as
ES module, i.e. implicit `"use strict";`.
- `negate_iife` (default: `true`) — negate "Immediately-Called Function Expressions"
where the return value is discarded, to avoid the parentheses that the
code generator would insert.
- `objects` (default: `true`) -- compact duplicate keys in object literals.
- `objects` (default: `true`) compact duplicate keys in object literals.
- `passes` (default: `1`) -- The maximum number of times to run compress.
- `passes` (default: `1`) The maximum number of times to run compress.
In some cases more than one pass leads to further compressed code. Keep in
mind more passes will take more time.
- `properties` (default: `true`) -- rewrite property access using the dot notation, for
- `properties` (default: `true`) rewrite property access using the dot notation, for
example `foo["bar"] → foo.bar`
- `pure_funcs` (default: `null`) -- You can pass an array of names and
- `pure_funcs` (default: `null`) You can pass an array of names and
UglifyJS will assume that those functions do not produce side
effects. DANGER: will not check if the name is redefined in scope.
An example case here, for instance `var q = Math.floor(a/b)`. If
@@ -732,24 +779,24 @@ to be `false` and all symbol names will be omitted.
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
(e.g. `foo.bar` or `foo["bar"]`) doesn't have any side effects.
Specify `"strict"` to treat `foo.bar` as side-effect-free only when
`foo` is certain to not throw, i.e. not `null` or `undefined`.
- `pure_getters` (default: `"strict"`) — Pass `true` for UglifyJS to assume that
object property access (e.g. `foo.bar` or `a[42]`) does not throw exception or
alter program states via getter function. Pass `"strict"` to allow dropping or
reordering `foo.bar` only if `foo` is not `null` or `undefined` and is safe to
access as a variable. Pass `false` to retain all property accesses.
- `reduce_funcs` (default: `true`) -- Allows single-use functions to be
- `reduce_funcs` (default: `true`) Allows single-use functions to be
inlined as function expressions when permissible allowing further
optimization. Enabled by default. Option depends on `reduce_vars`
being enabled. Some code runs faster in the Chrome V8 engine if this
option is disabled. Does not negatively impact other major browsers.
- `reduce_vars` (default: `true`) -- Improve optimization on variables assigned with and
- `reduce_vars` (default: `true`) Improve optimization on variables assigned with and
used as constant values.
- `rests` (default: `true`) -- apply optimizations to rest parameters
- `rests` (default: `true`) apply optimizations to rest parameters
- `sequences` (default: `true`) -- join consecutive simple statements using the
- `sequences` (default: `true`) join consecutive simple statements using the
comma operator. May be set to a positive integer to specify the maximum number
of consecutive comma sequences that will be generated. If this option is set to
`true` then the default `sequences` limit is `200`. Set option to `false` or `0`
@@ -758,65 +805,68 @@ to be `false` and all symbol names will be omitted.
occasions the default sequences limit leads to very slow compress times in which
case a value of `20` or less is recommended.
- `side_effects` (default: `true`) -- Pass `false` to disable potentially dropping
functions marked as "pure". A function call is marked as "pure" if a comment
annotation `/*@__PURE__*/` or `/*#__PURE__*/` immediately precedes the call. For
example: `/*@__PURE__*/foo();`
- `side_effects` (default: `true`) — drop extraneous code which does not affect
outcome of runtime execution.
- `spreads` (default: `true`) -- flatten spread expressions.
- `spreads` (default: `true`) flatten spread expressions.
- `strings` (default: `true`) -- compact string concatenations.
- `strings` (default: `true`) compact string concatenations.
- `switches` (default: `true`) -- de-duplicate and remove unreachable `switch` branches
- `switches` (default: `true`) de-duplicate and remove unreachable `switch` branches
- `top_retain` (default: `null`) -- prevent specific toplevel functions and
- `templates` (default: `true`) — compact template literals by embedding expressions
and/or converting to string literals, e.g. `` `foo ${42}` → "foo 42"``
- `top_retain` (default: `null`) — prevent specific toplevel functions and
variables from `unused` removal (can be array, comma-separated, RegExp or
function. Implies `toplevel`)
- `toplevel` (default: `false`) -- drop unreferenced functions (`"funcs"`) and/or
- `toplevel` (default: `false`) — drop unreferenced functions (`"funcs"`) and/or
variables (`"vars"`) in the top level scope (`false` by default, `true` to drop
both unreferenced functions and variables)
- `typeofs` (default: `true`) -- Transforms `typeof foo == "undefined"` into
`foo === void 0`. Note: recommend to set this value to `false` for IE10 and
earlier versions due to known issues.
- `typeofs` (default: `true`) — compress `typeof` expressions, e.g.
`typeof foo == "undefined" → void 0 === foo`
- `unsafe` (default: `false`) -- apply "unsafe" transformations (discussion below)
- `unsafe` (default: `false`) — apply "unsafe" transformations (discussion below)
- `unsafe_comps` (default: `false`) -- compress expressions like `a <= b` assuming
none of the operands can be (coerced to) `NaN`.
- `unsafe_comps` (default: `false`) — assume operands cannot be (coerced to) `NaN`
in numeric comparisons, e.g. `a <= b`. In addition, expressions involving `in`
or `instanceof` would never throw.
- `unsafe_Function` (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
- `unsafe_math` (default: `false`) — optimize numerical expressions like
`2 * x * 3` into `6 * x`, which may give imprecise floating point results.
- `unsafe_proto` (default: `false`) -- optimize expressions like
- `unsafe_proto` (default: `false`) — optimize expressions like
`Array.prototype.slice.call(a)` into `[].slice.call(a)`
- `unsafe_regexp` (default: `false`) -- enable substitutions of variables with
- `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
- `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
- `unused` (default: `true`) — drop unreferenced functions and variables (simple
direct variable assignments do not count as references unless set to `"keep_assign"`)
- `varify` (default: `true`) -- convert block-scoped declaractions into `var`
- `varify` (default: `true`) — convert block-scoped declarations into `var`
whenever safe to do so
- `yields` (default: `true`) — apply optimizations to `yield` expressions
## Mangle options
- `eval` (default `false`) -- Pass `true` to mangle names visible in scopes
- `eval` (default: `false`) — Pass `true` to mangle names visible in scopes
where `eval` or `with` are used.
- `reserved` (default `[]`) -- Pass an array of identifiers that should be
- `reserved` (default: `[]`) — Pass an array of identifiers that should be
excluded from mangling. Example: `["foo", "bar"]`.
- `toplevel` (default `false`) -- Pass `true` to mangle names declared in the
- `toplevel` (default: `false`) — Pass `true` to mangle names declared in the
top level scope.
Examples:
@@ -843,18 +893,24 @@ UglifyJS.minify(code, { mangle: { toplevel: true } }).code;
### Mangle properties options
- `builtins` (default: `false`) -- Use `true` to allow the mangling of builtin
DOM properties. Not recommended to override this setting.
- `builtins` (default: `false`) — Use `true` to allow the mangling of built-in
properties of JavaScript API. Not recommended to override this setting.
- `debug` (default: `false`) -— Mangle names with the original name still present.
- `debug` (default: `false`) — Mangle names with the original name still present.
Pass an empty string `""` to enable, or a non-empty string to set the debug suffix.
- `keep_quoted` (default: `false`) -Only mangle unquoted property names.
- `domprops` (default: `false`) — Use `true` to allow the mangling of properties
commonly found in Document Object Model. Not recommended to override this setting.
- `regex` (default: `null`) -Pass a RegExp literal to only mangle property
- `keep_fargs` (default: `false`) — Use `true` to prevent mangling of function
arguments.
- `keep_quoted` (default: `false`) — Only mangle unquoted property names.
- `regex` (default: `null`) — Pass a RegExp literal to only mangle property
names matching the regular expression.
- `reserved` (default: `[]`) -- Do not mangle property names listed in the
- `reserved` (default: `[]`) — Do not mangle property names listed in the
`reserved` array.
## Output options
@@ -863,19 +919,22 @@ The code generator tries to output shortest code possible by default. In
case you want beautified output, pass `--beautify` (`-b`). Optionally you
can pass additional arguments that control the code output:
- `ascii_only` (default `false`) -- escape Unicode characters in strings and
- `annotations` (default: `false`) — pass `true` to retain comment annotations
`/*@__PURE__*/` or `/*#__PURE__*/`, otherwise they will be discarded even if
`comments` is set.
- `ascii_only` (default: `false`) — escape Unicode characters in strings and
regexps (affects directives with non-ascii characters becoming invalid)
- `beautify` (default `true`) -- whether to actually beautify the output.
Passing `-b` will set this to true, but you might need to pass `-b` even
when you want to generate minified code, in order to specify additional
arguments, so you can use `-b beautify=false` to override it.
- `beautify` (default: `true`) — whether to actually beautify the output.
Passing `-b` will set this to true. Use `-O` if you want to generate minified
code and specify additional arguments.
- `braces` (default `false`) -- always insert braces 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.
- `comments` (default `false`) -- pass `true` or `"all"` to preserve all
- `comments` (default: `false`) — pass `true` or `"all"` to preserve all
comments, `"some"` to preserve multi-line comments that contain `@cc_on`,
`@license`, or `@preserve` (case-insensitive), a regular expression string
(e.g. `/^!/`), or a function which returns `boolean`, e.g.
@@ -885,53 +944,58 @@ can pass additional arguments that control the code output:
}
```
- `galio` (default `false`) -- enable workarounds for ANT Galio bugs
- `extendscript` (default: `false`) enable workarounds for Adobe ExtendScript
bugs
- `indent_level` (default `4`)
- `galio` (default: `false`) — enable workarounds for ANT Galio bugs
- `indent_start` (default `0`) -- prefix all lines by that many spaces
- `indent_level` (default: `4`) — indent by specified number of spaces or the
exact whitespace sequence supplied, e.g. `"\t"`.
- `inline_script` (default `true`) -- escape HTML comments and the slash in
- `indent_start` (default: `0`) — prefix all lines by whitespace sequence
specified in the same format as `indent_level`.
- `inline_script` (default: `true`) — escape HTML comments and the slash in
occurrences of `</script>` in strings
- `keep_quoted_props` (default `false`) -- when turned on, prevents stripping
- `keep_quoted_props` (default: `false`) when turned on, prevents stripping
quotes from property names in object literals.
- `max_line_len` (default `false`) -- maximum line length (for uglified code)
- `max_line_len` (default: `false`) maximum line length (for uglified code)
- `preamble` (default `null`) -- when passed it must be a string and
- `preamble` (default: `null`) when passed it must be a string and
it will be prepended to the output literally. The source map will
adjust for this text. Can be used to insert a comment containing
licensing information, for example.
- `preserve_line` (default `false`) -- pass `true` to retain line numbering on
- `preserve_line` (default: `false`) pass `true` to retain line numbering on
a best effort basis.
- `quote_keys` (default `false`) -- pass `true` to quote all keys in literal
- `quote_keys` (default: `false`) pass `true` to quote all keys in literal
objects
- `quote_style` (default `0`) -- preferred quote style for strings (affects
- `quote_style` (default: `0`) preferred quote style for strings (affects
quoted property names and directives as well):
- `0` -- prefers double quotes, switches to single quotes when there are
- `0` prefers double quotes, switches to single quotes when there are
more double quotes in the string itself. `0` is best for gzip size.
- `1` -- always use single quotes
- `2` -- always use double quotes
- `3` -- always use the original quotes
- `1` always use single quotes
- `2` always use double quotes
- `3` always use the original quotes
- `semicolons` (default `true`) -- separate statements with semicolons. If
- `semicolons` (default: `true`) separate statements with semicolons. If
you pass `false` then whenever possible we will use a newline instead of a
semicolon, leading to more readable output of uglified code (size before
gzip could be smaller; size after gzip insignificantly larger).
- `shebang` (default `true`) -- preserve shebang `#!` in preamble (bash scripts)
- `shebang` (default: `true`) preserve shebang `#!` in preamble (bash scripts)
- `width` (default `80`) -- only takes effect when beautification is on, this
- `width` (default: `80`) only takes effect when beautification is on, this
specifies an (orientative) line width that the beautifier will try to
obey. It refers to the width of the line text (excluding indentation).
It doesn't work very well currently, but it does make the code generated
by UglifyJS more readable.
- `wrap_iife` (default `false`) -- pass `true` to wrap immediately invoked
- `wrap_iife` (default: `false`) pass `true` to wrap immediately invoked
function expressions. See
[#640](https://github.com/mishoo/UglifyJS/issues/640) for more details.
@@ -1132,18 +1196,14 @@ in total it's a bit more than just using UglifyJS's own parser.
It's not well known, but whitespace removal and symbol mangling accounts
for 95% of the size reduction in minified code for most JavaScript - not
elaborate code transforms. One can simply disable `compress` to speed up
Uglify builds by 3 to 4 times. In this fast `mangle`-only mode Uglify has
comparable minify speeds and gzip sizes to
[`butternut`](https://www.npmjs.com/package/butternut):
Uglify builds by 3 to 5 times.
| d3.js | minify size | gzip size | minify time (seconds) |
| --- | ---: | ---: | ---: |
| original | 451,131 | 108,733 | - |
| uglify-js@3.0.24 mangle=false, compress=false | 316,600 | 85,245 | 0.70 |
| uglify-js@3.0.24 mangle=true, compress=false | 220,216 | 72,730 | 1.13 |
| butternut@0.4.6 | 217,568 | 72,738 | 1.41 |
| uglify-js@3.0.24 mangle=true, compress=true | 212,511 | 71,560 | 3.36 |
| babili@0.1.4 | 210,713 | 72,140 | 12.64 |
| original | 511,371 | 119,932 | - |
| uglify-js@3.13.0 mangle=false, compress=false | 363,988 | 95,695 | 0.56 |
| uglify-js@3.13.0 mangle=true, compress=false | 253,305 | 81,281 | 0.99 |
| uglify-js@3.13.0 mangle=true, compress=true | 244,436 | 79,854 | 5.30 |
To enable fast minify mode from the CLI use:
```
@@ -1181,6 +1241,17 @@ To allow for better optimizations, the compiler makes various assumptions:
- Object properties can be added, removed and modified (not prevented with
`Object.defineProperty()`, `Object.defineProperties()`, `Object.freeze()`,
`Object.preventExtensions()` or `Object.seal()`).
- If array destructuring is present, index-like properties in `Array.prototype`
have not been overridden:
```javascript
Object.prototype[0] = 42;
var [ a ] = [];
var { 0: b } = {};
// 42 undefined
console.log([][0], a);
// 42 42
console.log({}[0], b);
```
- Earlier versions of JavaScript will throw `SyntaxError` with the following:
```javascript
({
@@ -1260,3 +1331,149 @@ To allow for better optimizations, the compiler makes various assumptions:
// TypeError: can't convert BigInt to number
```
UglifyJS may modify the input which in turn may suppress those errors.
- Some versions of JavaScript will throw `SyntaxError` with the
following:
```javascript
console.log(String.raw`\uFo`);
// SyntaxError: Invalid Unicode escape sequence
```
UglifyJS may modify the input which in turn may suppress those errors.
- Some versions of JavaScript will throw `SyntaxError` with the
following:
```javascript
try {} catch (e) {
for (var e of []);
}
// SyntaxError: Identifier 'e' has already been declared
```
UglifyJS may modify the input which in turn may suppress those errors.
- Some versions of Chrome and Node.js will give incorrect results with the
following:
```javascript
console.log({
...{
set 42(v) {},
42: "PASS",
},
});
// Expected: { '42': 'PASS' }
// Actual: { '42': undefined }
```
UglifyJS may modify the input which in turn may suppress those errors.
- Later versions of JavaScript will throw `SyntaxError` with the following:
```javascript
var await;
class A {
static p = await;
}
// SyntaxError: Unexpected reserved word
```
UglifyJS may modify the input which in turn may suppress those errors.
- Later versions of JavaScript will throw `SyntaxError` with the following:
```javascript
var async;
for (async of []);
// SyntaxError: The left-hand side of a for-of loop may not be 'async'.
```
UglifyJS may modify the input which in turn may suppress those errors.
- Some versions of Chrome and Node.js will give incorrect results with the
following:
```javascript
console.log({
...console,
get 42() {
return "FAIL";
},
[42]: "PASS",
}[42], {
...console,
get 42() {
return "FAIL";
},
42: "PASS",
}[42]);
// Expected: "PASS PASS"
// Actual: "PASS FAIL"
```
UglifyJS may modify the input which in turn may suppress those errors.
- Earlier versions of JavaScript will throw `TypeError` with the following:
```javascript
(function() {
{
const a = "foo";
}
{
const a = "bar";
}
})();
// TypeError: const 'a' has already been declared
```
UglifyJS may modify the input which in turn may suppress those errors.
- Later versions of Chrome and Node.js will give incorrect results with the
following:
```javascript
try {
class A {
static 42;
static get 42() {}
}
console.log("PASS");
} catch (e) {
console.log("FAIL");
}
// Expected: "PASS"
// Actual: "FAIL"
```
UglifyJS may modify the input which in turn may suppress those errors.
- Some versions of Chrome and Node.js will give incorrect results with the
following:
```javascript
(async function(a) {
(function() {
var b = await => console.log("PASS");
b();
})();
})().catch(console.error);
// Expected: "PASS"
// Actual: SyntaxError: Unexpected reserved word
```
UglifyJS may modify the input which in turn may suppress those errors.
- Later versions of Chrome and Node.js will give incorrect results with the
following:
```javascript
try {
f();
function f() {
throw 42;
}
} catch (e) {
console.log(typeof f, e);
}
// Expected: "function 42"
// Actual: "undefined 42"
```
UglifyJS may modify the input which in turn may suppress those errors.
- Later versions of JavaScript will throw `SyntaxError` with the following:
```javascript
"use strict";
console.log(function f() {
return f = "PASS";
}());
// Expected: "PASS"
// Actual: TypeError: invalid assignment to const 'f'
```
UglifyJS may modify the input which in turn may suppress those errors.
- Adobe ExtendScript will give incorrect results with the following:
```javascript
alert(true ? "PASS" : false ? "FAIL" : null);
// Expected: "PASS"
// Actual: "FAIL"
```
UglifyJS may modify the input which in turn may suppress those errors.
- Adobe ExtendScript will give incorrect results with the following:
```javascript
alert(42 ? null ? "FAIL" : "PASS" : "FAIL");
// Expected: "PASS"
// Actual: SyntaxError: Expected: :
```
UglifyJS may modify the input which in turn may suppress those errors.

View File

@@ -10,7 +10,9 @@ var info = require("../package.json");
var path = require("path");
var UglifyJS = require("../tools/node");
var skip_keys = [ "cname", "inlined", "parent_scope", "scope", "uses_eval", "uses_with" ];
var skip_keys = [ "cname", "fixed", "in_arg", "inlined", "length_read", "parent_scope", "redef", "scope", "unused" ];
var truthy_keys = [ "optional", "pure", "terminal", "uses_arguments", "uses_eval", "uses_with" ];
var files = {};
var options = {};
var short_forms = {
@@ -70,6 +72,7 @@ function process_option(name, no_value) {
} else {
if (padding.length < name.length) padding = Array(name.length + 1).join(" ");
toplevels.push([ {
keep_fargs: "keep-fargs",
keep_fnames: "keep-fnames",
nameCache: "name-cache",
}[name] || name, option ]);
@@ -95,12 +98,18 @@ function process_option(name, no_value) {
" -b, --beautify [options] Beautify output/specify output options.",
" -O, --output-opts <options> Output options (beautify disabled).",
" -o, --output <file> Output file (default STDOUT).",
" --annotations Process and preserve comment annotations.",
" --no-annotations Ignore and discard comment annotations.",
" --comments [filter] Preserve copyright comments in the output.",
" --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.",
" --expression Parse a single expression, rather than a program.",
" --ie Support non-standard Internet Explorer.",
" --keep-fargs Do not mangle/drop function arguments.",
" --keep-fnames Do not mangle/drop function names. Useful for code relying on Function.prototype.name.",
" --module Process input as ES module (implies --toplevel).",
" --no-module Process input with improved JavaScript compatibility.",
" --name-cache <file> File to hold mangled name mappings.",
" --rename Force symbol expansion.",
" --no-rename Disable symbol expansion.",
@@ -108,11 +117,15 @@ function process_option(name, no_value) {
" --source-map [options] Enable source map/specify source map options.",
" --timings Display operations run time on STDERR.",
" --toplevel Compress and/or mangle variables in toplevel scope.",
" --v8 Support non-standard Chrome & Node.js.",
" --validate Perform validation during AST manipulations.",
" --verbose Print diagnostic messages.",
" --warn Print warning messages.",
" --webkit Support non-standard Safari/Webkit.",
" --wrap <name> Embed everything as a function with “exports” corresponding to “name” globally.",
"",
"(internal debug use only)",
" --in-situ Warning: replaces original source files with minified output.",
" --reduce-test Reduce a standalone test case (assumes cloned repository).",
].join("\n"));
}
@@ -139,13 +152,23 @@ function process_option(name, no_value) {
case "enclose":
options[name] = read_value();
break;
case "annotations":
case "expression":
case "ie":
case "ie8":
case "timings":
case "toplevel":
case "v8":
case "validate":
case "webkit":
options[name] = true;
break;
case "no-annotations":
options.annotations = false;
break;
case "keep-fargs":
options.keep_fargs = true;
break;
case "keep-fnames":
options.keep_fnames = true;
break;
@@ -178,6 +201,12 @@ function process_option(name, no_value) {
if (typeof options.mangle != "object") options.mangle = {};
options.mangle.properties = parse_js(read_value(), options.mangle.properties);
break;
case "module":
options.module = true;
break;
case "no-module":
options.module = false;
break;
case "name-cache":
nameCache = read_value(true);
options.nameCache = JSON.parse(read_file(nameCache, "{}"));
@@ -194,6 +223,7 @@ function process_option(name, no_value) {
case "no-rename":
options.rename = false;
break;
case "in-situ":
case "reduce-test":
case "self":
break;
@@ -214,21 +244,11 @@ if (specified["beautify"] && specified["output-opts"]) fatal("--beautify cannot
[ "compress", "mangle" ].forEach(function(name) {
if (!(name in options)) options[name] = false;
});
if (options.mangle && options.mangle.properties) {
if (options.mangle.properties.domprops) {
delete options.mangle.properties.domprops;
} else {
if (typeof options.mangle.properties != "object") options.mangle.properties = {};
if (!Array.isArray(options.mangle.properties.reserved)) options.mangle.properties.reserved = [];
require("../tools/domprops").forEach(function(name) {
UglifyJS.push_uniq(options.mangle.properties.reserved, name);
});
}
if (/^ast|spidermonkey$/.test(output)) {
if (typeof options.output != "object") options.output = {};
options.output.ast = true;
options.output.code = false;
}
if (output == "ast") options.output = {
ast: true,
code: false,
};
if (options.parse && (options.parse.acorn || options.parse.spidermonkey)
&& options.sourceMap && options.sourceMap.content == "inline") {
fatal("inline source map only works with built-in parser");
@@ -253,18 +273,47 @@ if (specified["self"]) {
if (paths.length) UglifyJS.AST_Node.warn("Ignoring input files since --self was passed");
if (!options.wrap) options.wrap = "UglifyJS";
paths = UglifyJS.FILES;
} else if (paths.length) {
paths = simple_glob(paths);
}
if (paths.length) {
simple_glob(paths).forEach(function(name) {
if (specified["in-situ"]) {
if (output && output != "spidermonkey" || specified["reduce-test"] || specified["self"]) {
fatal("incompatible options specified");
}
paths.forEach(function(name) {
print(name);
if (/^ast|spidermonkey$/.test(name)) fatal("invalid file name specified");
files = {};
files[convert_path(name)] = read_file(name);
output = name;
run();
});
} else if (paths.length) {
paths.forEach(function(name) {
files[convert_path(name)] = read_file(name);
});
run();
} else {
var timerId = process.stdin.isTTY && process.argv.length < 3 && setTimeout(function() {
print_error("Waiting for input... (use `--help` to print usage information)");
}, 1500);
var chunks = [];
process.stdin.setEncoding("utf8");
process.stdin.on("data", function(chunk) {
process.stdin.once("data", function() {
clearTimeout(timerId);
}).on("data", process.stdin.isTTY ? function(chunk) {
// emulate console input termination via Ctrl+D / Ctrl+Z
var match = /[\x04\x1a]\r?\n?$/.exec(chunk);
if (match) {
chunks.push(chunk.slice(0, -match[0].length));
process.stdin.pause();
process.stdin.emit("end");
} else {
chunks.push(chunk);
}
} : function(chunk) {
chunks.push(chunk);
}).on("end", function() {
}).once("end", function() {
files = { STDIN: chunks.join("") };
run();
});
@@ -286,13 +335,43 @@ function run() {
try {
if (options.parse) {
if (options.parse.acorn) {
var annotations = Object.create(null);
files = convert_ast(function(toplevel, name) {
return require("acorn").parse(files[name], {
var content = files[name];
var list = annotations[name] = [];
var prev = -1;
return require("acorn").parse(content, {
allowHashBang: true,
ecmaVersion: "latest",
locations: true,
onComment: function(block, text, start, end) {
var match = /[@#]__PURE__/.exec(text);
if (!match) {
if (start != prev) return;
match = [ list[prev] ];
}
while (/\s/.test(content[end])) end++;
list[end] = match[0];
prev = end;
},
preserveParens: true,
program: toplevel,
sourceFile: name
sourceFile: name,
sourceType: "module",
});
});
files.walk(new UglifyJS.TreeWalker(function(node) {
if (!(node instanceof UglifyJS.AST_Call)) return;
var list = annotations[node.start.file];
var pure = list[node.start.pos];
if (!pure) {
var tokens = node.start.parens;
if (tokens) for (var i = 0; !pure && i < tokens.length; i++) {
pure = list[tokens[i].pos];
}
}
if (pure) node.pure = pure;
}));
} else if (options.parse.spidermonkey) {
files = convert_ast(function(toplevel, name) {
var obj = JSON.parse(files[name]);
@@ -360,16 +439,16 @@ function run() {
}
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":
case "variables":
return value.size() ? value.map(symdef) : undefined;
case "thedef":
return symdef(value);
}
if (skip_key(key)) return;
if (skip_property(key, value)) return;
if (value instanceof UglifyJS.AST_Token) return;
if (value instanceof UglifyJS.Dictionary) return;
if (value instanceof UglifyJS.AST_Node) {
@@ -384,16 +463,19 @@ function run() {
return value;
}, 2));
} else if (output == "spidermonkey") {
print(JSON.stringify(UglifyJS.minify(result.code, {
compress: false,
mangle: false,
output: {
ast: true,
code: false
},
}).ast.to_mozilla_ast(), null, 2));
print(JSON.stringify(result.ast.to_mozilla_ast(), null, 2));
} else if (output) {
fs.writeFileSync(output, result.code);
var code;
if (result.ast) {
var opts = {};
for (var name in options.output) {
if (!/^ast|code$/.test(name)) opts[name] = options.output[name];
}
code = UglifyJS.AST_Node.from_mozilla_ast(result.ast.to_mozilla_ast()).print_to_string(opts);
} else {
code = result.code;
}
fs.writeFileSync(output, code);
if (result.map) fs.writeFileSync(output + ".map", result.map);
} else {
print(result.code);
@@ -416,33 +498,42 @@ function fatal(message) {
// A file glob function that only supports "*" and "?" wildcards in the basename.
// Example: "foo/bar/*baz??.*.js"
// Argument `glob` may be a string or an array of strings.
// Argument `paths` must be an array of strings.
// Returns an array of strings. Garbage in, garbage out.
function simple_glob(glob) {
if (Array.isArray(glob)) {
return [].concat.apply([], glob.map(simple_glob));
}
if (glob.match(/\*|\?/)) {
var dir = path.dirname(glob);
try {
var entries = fs.readdirSync(dir);
} catch (ex) {}
if (entries) {
var pattern = "^" + path.basename(glob)
.replace(/[.+^$[\]\\(){}]/g, "\\$&")
.replace(/\*/g, "[^/\\\\]*")
.replace(/\?/g, "[^/\\\\]") + "$";
var mod = process.platform === "win32" ? "i" : "";
var rx = new RegExp(pattern, mod);
var results = entries.sort().filter(function(name) {
return rx.test(name);
}).map(function(name) {
return path.join(dir, name);
});
if (results.length) return results;
function simple_glob(paths) {
return paths.reduce(function(paths, glob) {
if (/\*|\?/.test(glob)) {
var dir = path.dirname(glob);
try {
var entries = fs.readdirSync(dir).filter(function(name) {
try {
return fs.statSync(path.join(dir, name)).isFile();
} catch (ex) {
return false;
}
});
} catch (ex) {}
if (entries) {
var pattern = "^" + path.basename(glob)
.replace(/[.+^$[\]\\(){}]/g, "\\$&")
.replace(/\*/g, "[^/\\\\]*")
.replace(/\?/g, "[^/\\\\]") + "$";
var mod = process.platform === "win32" ? "i" : "";
var rx = new RegExp(pattern, mod);
var results = entries.filter(function(name) {
return rx.test(name);
}).sort().map(function(name) {
return path.join(dir, name);
});
if (results.length) {
[].push.apply(paths, results);
return paths;
}
}
}
}
return [ glob ];
paths.push(glob);
return paths;
}, []);
}
function read_file(path, default_value) {
@@ -455,7 +546,7 @@ function read_file(path, default_value) {
}
function parse_js(value, options, flag) {
if (!options || typeof options != "object") options = {};
if (!options || typeof options != "object") options = Object.create(null);
if (typeof value == "string") try {
UglifyJS.parse(value, {
expression: true
@@ -495,8 +586,10 @@ function parse_js(value, options, flag) {
return options;
}
function skip_key(key) {
return skip_keys.indexOf(key) >= 0;
function skip_property(key, value) {
return skip_keys.indexOf(key) >= 0
// only skip truthy_keys if their value is falsy
|| truthy_keys.indexOf(key) >= 0 && !value;
}
function symdef(def) {

1071
lib/ast.js

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -28,7 +28,7 @@ function read_source_map(name, toplevel) {
var match = /^# ([^\s=]+)=(\S+)\s*$/.exec(comment.value);
if (!match) break;
if (match[1] == "sourceMappingURL") {
match = /^data:application\/json(;.*?)?;base64,(\S+)$/.exec(match[2]);
match = /^data:application\/json(;.*?)?;base64,([^,]+)$/.exec(match[2]);
if (!match) break;
return to_ascii(match[2]);
}
@@ -47,14 +47,12 @@ function parse_source_map(content) {
}
function set_shorthand(name, options, keys) {
if (options[name]) {
keys.forEach(function(key) {
if (options[key]) {
if (typeof options[key] != "object") options[key] = {};
if (!(name in options[key])) options[key][name] = options[name];
}
});
}
keys.forEach(function(key) {
if (options[key]) {
if (typeof options[key] != "object") options[key] = {};
if (!(name in options[key])) options[key][name] = options[name];
}
});
}
function init_cache(cache) {
@@ -75,18 +73,23 @@ function to_json(cache) {
function minify(files, options) {
try {
options = defaults(options, {
annotations: undefined,
compress: {},
enclose: false,
expression: false,
ie: false,
ie8: false,
keep_fargs: false,
keep_fnames: false,
mangle: {},
module: undefined,
nameCache: null,
output: {},
parse: {},
rename: undefined,
sourceMap: false,
timings: false,
toplevel: false,
toplevel: options && !options["expression"] && options["module"] ? true : undefined,
v8: false,
validate: false,
warnings: false,
@@ -94,23 +97,25 @@ function minify(files, options) {
wrap: false,
}, true);
if (options.validate) AST_Node.enable_validation();
var timings = options.timings && {
start: Date.now()
};
if (options.rename === undefined) {
options.rename = options.compress && options.mangle;
}
set_shorthand("ie8", options, [ "compress", "mangle", "output" ]);
set_shorthand("keep_fnames", options, [ "compress", "mangle" ]);
set_shorthand("toplevel", options, [ "compress", "mangle" ]);
set_shorthand("v8", options, [ "mangle", "output" ]);
set_shorthand("webkit", options, [ "mangle", "output" ]);
var timings = options.timings && { start: Date.now() };
if (options.annotations !== undefined) set_shorthand("annotations", options, [ "compress", "output" ]);
if (options.expression) set_shorthand("expression", options, [ "compress", "parse" ]);
if (options.ie8) options.ie = options.ie || options.ie8;
if (options.ie) set_shorthand("ie", options, [ "compress", "mangle", "output", "rename" ]);
if (options.keep_fargs) set_shorthand("keep_fargs", options, [ "compress", "mangle", "rename" ]);
if (options.keep_fnames) set_shorthand("keep_fnames", options, [ "compress", "mangle", "rename" ]);
if (options.module === undefined && !options.ie) options.module = true;
if (options.module) set_shorthand("module", options, [ "compress", "parse" ]);
if (options.toplevel !== undefined) set_shorthand("toplevel", options, [ "compress", "mangle", "rename" ]);
if (options.v8) set_shorthand("v8", options, [ "mangle", "output", "rename" ]);
if (options.webkit) set_shorthand("webkit", options, [ "compress", "mangle", "output", "rename" ]);
var quoted_props;
if (options.mangle) {
options.mangle = defaults(options.mangle, {
cache: options.nameCache && (options.nameCache.vars || {}),
eval: false,
ie8: false,
ie: false,
keep_fargs: false,
keep_fnames: false,
properties: false,
reserved: [],
@@ -134,6 +139,7 @@ function minify(files, options) {
init_cache(options.mangle.cache);
init_cache(options.mangle.properties.cache);
}
if (options.rename === undefined) options.rename = options.compress && options.mangle;
if (options.sourceMap) {
options.sourceMap = defaults(options.sourceMap, {
content: null,
@@ -150,13 +156,11 @@ function minify(files, options) {
}, options.warnings == "verbose");
if (timings) timings.parse = Date.now();
var toplevel;
if (files instanceof AST_Toplevel) {
options.parse = options.parse || {};
if (files instanceof AST_Node) {
toplevel = files;
} else {
if (typeof files == "string") {
files = [ files ];
}
options.parse = options.parse || {};
if (typeof files == "string") files = [ files ];
options.parse.toplevel = null;
var source_map_content = options.sourceMap && options.sourceMap.content;
if (typeof source_map_content == "string" && source_map_content != "inline") {
@@ -168,17 +172,14 @@ function minify(files, options) {
options.parse.toplevel = toplevel = parse(files[name], options.parse);
if (source_map_content == "inline") {
var inlined_content = read_source_map(name, toplevel);
if (inlined_content) {
options.sourceMap.orig[name] = parse_source_map(inlined_content);
}
if (inlined_content) options.sourceMap.orig[name] = parse_source_map(inlined_content);
} else if (source_map_content) {
options.sourceMap.orig[name] = source_map_content;
}
}
}
if (quoted_props) {
reserve_quoted_keys(toplevel, quoted_props);
}
if (options.parse.expression) toplevel = toplevel.wrap_expression();
if (quoted_props) reserve_quoted_keys(toplevel, quoted_props);
[ "enclose", "wrap" ].forEach(function(action) {
var option = options[action];
if (!option) return;
@@ -189,8 +190,8 @@ function minify(files, options) {
if (options.validate) toplevel.validate_ast();
if (timings) timings.rename = Date.now();
if (options.rename) {
toplevel.figure_out_scope(options.mangle);
toplevel.expand_names(options.mangle);
toplevel.figure_out_scope(options.rename);
toplevel.expand_names(options.rename);
}
if (timings) timings.compress = Date.now();
if (options.compress) {
@@ -205,30 +206,34 @@ function minify(files, options) {
toplevel.mangle_names(options.mangle);
}
if (timings) timings.properties = Date.now();
if (quoted_props) reserve_quoted_keys(toplevel, quoted_props);
if (options.mangle && options.mangle.properties) mangle_properties(toplevel, options.mangle.properties);
if (options.parse.expression) toplevel = toplevel.unwrap_expression();
if (timings) timings.output = Date.now();
var result = {};
if (options.output.ast) {
result.ast = toplevel;
}
if (!HOP(options.output, "code") || options.output.code) {
var output = defaults(options.output, {
ast: false,
code: true,
});
if (output.ast) result.ast = toplevel;
if (output.code) {
if (options.sourceMap) {
options.output.source_map = SourceMap(options.sourceMap);
output.source_map = SourceMap(options.sourceMap);
if (options.sourceMap.includeSources) {
if (files instanceof AST_Toplevel) {
throw new Error("original source content unavailable");
} else for (var name in files) if (HOP(files, name)) {
options.output.source_map.setSourceContent(name, files[name]);
output.source_map.setSourceContent(name, files[name]);
}
}
}
delete options.output.ast;
delete options.output.code;
var stream = OutputStream(options.output);
delete output.ast;
delete output.code;
var stream = OutputStream(output);
toplevel.print(stream);
result.code = stream.get();
if (options.sourceMap) {
result.map = options.output.source_map.toString();
result.map = output.source_map.toString();
var url = options.sourceMap.url;
if (url) {
result.code = result.code.replace(/\n\/\/# sourceMappingURL=\S+\s*$/, "");

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

View File

@@ -43,10 +43,11 @@
"use strict";
var builtins = function() {
var names = [];
// NaN will be included due to Number.NaN
function get_builtins() {
var names = new Dictionary();
// constants
[
"NaN",
"null",
"true",
"false",
@@ -54,35 +55,85 @@ var builtins = function() {
"-Infinity",
"undefined",
].forEach(add);
// global functions
[
Array,
Boolean,
Date,
Error,
Function,
Math,
Number,
Object,
RegExp,
String,
].forEach(function(ctor) {
"encodeURI",
"encodeURIComponent",
"escape",
"eval",
"decodeURI",
"decodeURIComponent",
"isFinite",
"isNaN",
"parseFloat",
"parseInt",
"unescape",
].forEach(add);
// global constructors & objects
var global = Function("return this")();
[
"Array",
"ArrayBuffer",
"Atomics",
"BigInt",
"Boolean",
"console",
"DataView",
"Date",
"Error",
"Function",
"Int8Array",
"Intl",
"JSON",
"Map",
"Math",
"Number",
"Object",
"Promise",
"Proxy",
"Reflect",
"RegExp",
"Set",
"String",
"Symbol",
"WebAssembly",
].forEach(function(name) {
add(name);
var ctor = global[name];
if (!ctor) return;
Object.getOwnPropertyNames(ctor).map(add);
if (ctor.prototype) {
if (typeof ctor != "function") return;
if (ctor.__proto__) Object.getOwnPropertyNames(ctor.__proto__).map(add);
if (ctor.prototype) Object.getOwnPropertyNames(ctor.prototype).map(add);
try {
Object.getOwnPropertyNames(new ctor()).map(add);
Object.getOwnPropertyNames(ctor.prototype).map(add);
} catch (e) {
try {
Object.getOwnPropertyNames(ctor()).map(add);
} catch (e) {}
}
});
return makePredicate(names);
return (get_builtins = function() {
return names.clone();
})();
function add(name) {
names.push(name);
names.set(name, true);
}
}();
}
function reserve_quoted_keys(ast, reserved) {
ast.walk(new TreeWalker(function(node) {
if (node instanceof AST_ObjectProperty) {
if (node.start && node.start.quote) add(node.key);
if (node instanceof AST_ClassProperty
|| node instanceof AST_DestructuredKeyVal
|| node instanceof AST_ObjectProperty) {
if (node.key instanceof AST_Node) {
addStrings(node.key, add);
} else if (node.start && node.start.quote) {
add(node.key);
}
} else if (node instanceof AST_Dot) {
if (node.quoted) add(node.property);
} else if (node instanceof AST_Sub) {
addStrings(node.property, add);
}
@@ -109,14 +160,18 @@ function mangle_properties(ast, options) {
builtins: false,
cache: null,
debug: false,
domprops: false,
keep_quoted: false,
regex: null,
reserved: null,
}, true);
var reserved = Object.create(options.builtins ? null : builtins);
var reserved = options.builtins ? new Dictionary() : get_builtins();
if (!options.domprops && typeof domprops !== "undefined") domprops.forEach(function(name) {
reserved.set(name, true);
});
if (Array.isArray(options.reserved)) options.reserved.forEach(function(name) {
reserved[name] = true;
reserved.set(name, true);
});
var cname = -1;
@@ -124,7 +179,7 @@ function mangle_properties(ast, options) {
if (options.cache) {
cache = options.cache.props;
cache.each(function(name) {
reserved[name] = true;
reserved.set(name, true);
});
} else {
cache = new Dictionary();
@@ -133,20 +188,18 @@ function mangle_properties(ast, options) {
var regex = options.regex;
// note debug is either false (disabled), or a string of the debug suffix to use (enabled).
// note debug may be enabled as an empty string, which is falsey. Also treat passing 'true'
// note debug may be enabled as an empty string, which is falsy. Also treat passing 'true'
// the same as passing an empty string.
var debug = options.debug !== false;
var debug_suffix;
if (debug) debug_suffix = options.debug === true ? "" : options.debug;
var names_to_mangle = Object.create(null);
var unmangleable = Object.create(reserved);
var names_to_mangle = new Dictionary();
var unmangleable = reserved.clone();
// step 1: find candidates to mangle
ast.walk(new TreeWalker(function(node) {
if (node instanceof AST_Binary) {
if (node.operator == "in") addStrings(node.left, add);
} else if (node.TYPE == "Call") {
if (node.TYPE == "Call") {
var exp = node.expression;
if (exp instanceof AST_Dot) switch (exp.property) {
case "defineProperty":
@@ -163,12 +216,18 @@ function mangle_properties(ast, options) {
addStrings(node.args[0], add);
break;
}
} else if (node instanceof AST_ClassProperty
|| node instanceof AST_DestructuredKeyVal
|| node instanceof AST_ObjectProperty) {
if (node.key instanceof AST_Node) {
addStrings(node.key, add);
} else {
add(node.key);
}
} else if (node instanceof AST_Dot) {
add(node.property);
} else if (node instanceof AST_ObjectProperty) {
if (typeof node.key == "string") add(node.key);
if (is_lhs(node, this.parent())) add(node.property);
} else if (node instanceof AST_Sub) {
addStrings(node.property, add);
if (is_lhs(node, this.parent())) addStrings(node.property, add);
}
}));
@@ -193,10 +252,16 @@ function mangle_properties(ast, options) {
mangleStrings(node.args[0]);
break;
}
} else if (node instanceof AST_ClassProperty
|| node instanceof AST_DestructuredKeyVal
|| node instanceof AST_ObjectProperty) {
if (node.key instanceof AST_Node) {
mangleStrings(node.key);
} else {
node.key = mangle(node.key);
}
} else if (node instanceof AST_Dot) {
node.property = mangle(node.property);
} else if (node instanceof AST_ObjectProperty) {
if (typeof node.key == "string") node.key = mangle(node.key);
} else if (node instanceof AST_Sub) {
if (!options.keep_quoted) mangleStrings(node.property);
}
@@ -205,26 +270,30 @@ function mangle_properties(ast, options) {
// only function declarations after this line
function can_mangle(name) {
if (unmangleable[name]) return false;
if (unmangleable.has(name)) return false;
if (/^-?[0-9]+(\.[0-9]+)?(e[+-][0-9]+)?$/.test(name)) return false;
return true;
}
function should_mangle(name) {
if (reserved[name]) return false;
if (regex && !regex.test(name)) return false;
return cache.has(name) || names_to_mangle[name];
if (reserved.has(name)) {
AST_Node.info("Preserving reserved property {this}", name);
return false;
}
if (regex && !regex.test(name)) {
AST_Node.info("Preserving excluded property {this}", name);
return false;
}
return cache.has(name) || names_to_mangle.has(name);
}
function add(name) {
if (can_mangle(name)) names_to_mangle[name] = true;
if (!should_mangle(name)) unmangleable[name] = true;
if (can_mangle(name)) names_to_mangle.set(name, true);
if (!should_mangle(name)) unmangleable.set(name, true);
}
function mangle(name) {
if (!should_mangle(name)) {
return name;
}
if (!should_mangle(name)) return name;
var mangled = cache.get(name);
if (!mangled) {
if (debug) {
@@ -236,14 +305,19 @@ function mangle_properties(ast, options) {
if (!mangled) do {
mangled = base54(++cname);
} while (!can_mangle(mangled));
if (/^#/.test(name)) mangled = "#" + mangled;
cache.set(name, mangled);
}
AST_Node.info("Mapping property {name} to {mangled}", {
mangled: mangled,
name: name,
});
return mangled;
}
function mangleStrings(node) {
if (node instanceof AST_Sequence) {
mangleStrings(node.expressions.tail_node());
mangleStrings(node.tail_node());
} else if (node instanceof AST_String) {
node.value = mangle(node.value);
} else if (node instanceof AST_Conditional) {

View File

@@ -44,8 +44,9 @@
"use strict";
function SymbolDef(id, scope, orig, init) {
this._bits = 0;
this.defun = undefined;
this.eliminated = 0;
this.global = false;
this.id = id;
this.init = init;
this.mangled_name = null;
@@ -53,8 +54,8 @@ function SymbolDef(id, scope, orig, init) {
this.orig = [ orig ];
this.references = [];
this.replaced = 0;
this.safe_ids = undefined;
this.scope = scope;
this.undeclared = false;
}
SymbolDef.prototype = {
@@ -63,58 +64,111 @@ SymbolDef.prototype = {
this.references.forEach(fn);
},
mangle: function(options) {
var cache = options.cache && options.cache.props;
if (this.global && cache && cache.has(this.name)) {
if (this.mangled_name) return;
var cache = this.global && options.cache && options.cache.props;
if (cache && cache.has(this.name)) {
this.mangled_name = cache.get(this.name);
} else if (!this.mangled_name && !this.unmangleable(options)) {
} else if (!this.unmangleable(options)) {
var def = this.redefined();
if (def) {
this.mangled_name = def.mangled_name || def.name;
} else {
this.mangled_name = next_mangled_name(this, options);
}
if (this.global && cache) {
cache.set(this.name, this.mangled_name);
}
if (cache) cache.set(this.name, this.mangled_name);
}
},
redefined: function() {
var scope = this.defun;
var self = this;
var scope = self.defun;
if (!scope) return;
var name = this.name;
var name = self.name;
var def = scope.variables.get(name)
|| scope instanceof AST_Toplevel && scope.globals.get(name)
|| this.orig[0] instanceof AST_SymbolConst && find_if(function(def) {
|| self.orig[0] instanceof AST_SymbolConst && find_if(function(def) {
return def.name == name;
}, scope.enclosed);
if (def && def !== this) return def.redefined() || def;
if (def && def !== self) return def.redefined() || def;
},
unmangleable: function(options) {
return this.global && !options.toplevel
|| this.undeclared
|| !options.eval && this.scope.pinned()
|| options.keep_fnames
&& (this.orig[0] instanceof AST_SymbolLambda
|| this.orig[0] instanceof AST_SymbolDefun);
if (this.exported) return true;
if (this.undeclared) return true;
if (!options.eval && this.scope.pinned()) return true;
if (options.keep_fargs && is_funarg(this)) return true;
if (options.keep_fnames) {
var sym = this.orig[0];
if (sym instanceof AST_SymbolClass) return true;
if (sym instanceof AST_SymbolDefClass) return true;
if (sym instanceof AST_SymbolDefun) return true;
if (sym instanceof AST_SymbolLambda) return true;
}
if (!options.toplevel && this.global) return true;
return false;
},
};
DEF_BITPROPS(SymbolDef, [
"const_redefs",
"cross_loop",
"direct_access",
"exported",
"global",
"undeclared",
]);
function is_funarg(def) {
return def.orig[0] instanceof AST_SymbolFunarg || def.orig[1] instanceof AST_SymbolFunarg;
}
var unary_side_effects = makePredicate("delete ++ --");
function is_lhs(node, parent) {
if (parent instanceof AST_Assign) return parent.left === node && node;
if (parent instanceof AST_DefaultValue) return parent.name === node && node;
if (parent instanceof AST_Destructured) return node;
if (parent instanceof AST_DestructuredKeyVal) return node;
if (parent instanceof AST_ForEnumeration) return parent.init === node && node;
if (parent instanceof AST_Unary) return unary_side_effects[parent.operator] && parent.expression;
}
AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
options = defaults(options, {
cache: null,
ie8: false,
ie: false,
});
// pass 1: setup scope chaining and handle definitions
var self = this;
var defun = null;
var exported = false;
var next_def_id = 0;
var scope = self.parent_scope = null;
var tw = new TreeWalker(function(node, descend) {
if (is_defun(node)) {
if (node instanceof AST_DefClass) {
var save_exported = exported;
exported = tw.parent() instanceof AST_ExportDeclaration;
node.name.walk(tw);
exported = save_exported;
walk_scope(function() {
if (node.extends) node.extends.walk(tw);
node.properties.forEach(function(prop) {
prop.walk(tw);
});
});
return true;
}
if (node instanceof AST_Definitions) {
var save_exported = exported;
exported = tw.parent() instanceof AST_ExportDeclaration;
descend();
exported = save_exported;
return true;
}
if (node instanceof AST_LambdaDefinition) {
var save_exported = exported;
exported = tw.parent() instanceof AST_ExportDeclaration;
node.name.walk(tw);
exported = save_exported;
walk_scope(function() {
node.argnames.forEach(function(argname) {
argname.walk(tw);
@@ -124,6 +178,13 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
});
return true;
}
if (node instanceof AST_Switch) {
node.expression.walk(tw);
walk_scope(function() {
walk_body(node, tw);
});
return true;
}
if (node instanceof AST_SwitchBranch) {
node.init_vars(scope);
descend();
@@ -161,21 +222,23 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
if (node instanceof AST_SymbolCatch) {
scope.def_variable(node).defun = defun;
} else if (node instanceof AST_SymbolConst) {
scope.def_variable(node).defun = defun;
var def = scope.def_variable(node);
def.defun = defun;
if (exported) def.exported = true;
} else if (node instanceof AST_SymbolDefun) {
defun.def_function(node, tw.parent());
entangle(defun, scope);
var def = defun.def_function(node, tw.parent());
if (exported) def.exported = true;
} else if (node instanceof AST_SymbolFunarg) {
defun.def_variable(node);
entangle(defun, scope);
} else if (node instanceof AST_SymbolLambda) {
var def = defun.def_function(node, node.name == "arguments" ? undefined : defun);
if (options.ie8) def.defun = defun.parent_scope.resolve();
if (options.ie && node.name != "arguments") def.defun = defun.parent_scope.resolve();
} else if (node instanceof AST_SymbolLet) {
scope.def_variable(node);
var def = scope.def_variable(node);
if (exported) def.exported = true;
} else if (node instanceof AST_SymbolVar) {
defun.def_variable(node, null);
entangle(defun, scope);
var def = defun.def_variable(node, node instanceof AST_SymbolImport ? undefined : null);
if (exported) def.exported = true;
}
function walk_scope(descend) {
@@ -188,16 +251,6 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
scope = save_scope;
defun = save_defun;
}
function entangle(defun, scope) {
if (defun === scope) return;
node.mark_enclosed(options);
var def = scope.find_variable(node.name);
if (node.thedef === def) return;
node.thedef = def;
def.orig.push(node);
node.mark_enclosed(options);
}
});
self.make_def = function(orig, init) {
return new SymbolDef(++next_def_id, this, orig, init);
@@ -218,6 +271,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
}
if (node instanceof AST_Lambda) {
in_arg.push(node);
if (node.name) node.name.walk(tw);
node.argnames.forEach(function(argname) {
argname.walk(tw);
});
@@ -231,17 +285,29 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
return true;
}
if (node instanceof AST_SymbolDeclaration) {
var def = node.definition();
def.preinit = def.references.length;
if (node instanceof AST_SymbolCatch) {
// ensure mangling works if `catch` reuses a scope variable
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;
var redef = def.redefined();
if (redef) for (var s = node.scope; s; s = s.parent_scope) {
if (!push_uniq(s.enclosed, redef)) break;
if (s === redef.scope) break;
}
} else if (node instanceof AST_SymbolConst) {
// ensure compression works if `const` reuses a scope variable
var redef = node.definition().redefined();
var redef = def.redefined();
if (redef) redef.const_redefs = true;
} else if (def.scope !== node.scope && (node instanceof AST_SymbolDefun
|| node instanceof AST_SymbolFunarg
|| node instanceof AST_SymbolVar)) {
node.mark_enclosed(options);
var redef = node.scope.find_variable(node.name);
if (node.thedef !== redef) {
node.thedef = redef;
redef.orig.push(node);
node.mark_enclosed(options);
}
}
if (node.name != "arguments") return true;
var parent = node instanceof AST_SymbolVar && tw.parent();
@@ -269,8 +335,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
sym = self.def_global(node);
} else if (name == "arguments" && is_arguments(sym)) {
var parent = tw.parent();
if (parent instanceof AST_Assign && parent.left === node
|| parent instanceof AST_Unary && unary_side_effects[parent.operator]) {
if (is_lhs(node, parent)) {
sym.scope.uses_arguments = 3;
} else if (sym.scope.uses_arguments < 2
&& !(parent instanceof AST_PropAccess && parent.expression === node)) {
@@ -292,6 +357,13 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
self.uses_eval = true;
}
}
if (sym.init instanceof AST_LambdaDefinition && sym.scope !== sym.init.name.scope) {
var scope = node.scope;
do {
if (scope === sym.init.name.scope) break;
} while (scope = scope.parent_scope);
if (!scope) sym.init = undefined;
}
node.thedef = sym;
node.reference(options);
return true;
@@ -300,10 +372,11 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
self.walk(tw);
// pass 3: fix up any scoping issue with IE8
if (options.ie8) self.walk(new TreeWalker(function(node) {
if (options.ie) 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) {
var def = node.thedef;
var scope = def.defun;
if (def.name != "arguments" && scope.name instanceof AST_SymbolLambda && scope.name.name == def.name) {
scope = scope.parent_scope.resolve();
}
redefine(node, scope);
@@ -312,7 +385,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
if (node instanceof AST_SymbolLambda) {
var def = node.thedef;
if (!redefine(node, node.scope.parent_scope.resolve())) {
delete def.defun;
def.defun = undefined;
} else if (typeof node.thedef.init !== "undefined") {
node.thedef.init = false;
} else if (def.init) {
@@ -346,13 +419,14 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
} else {
new_def = scope.def_variable(node);
}
if (new_def.undeclared) self.variables.set(name, new_def);
if (name == "arguments" && is_arguments(old_def) && node instanceof AST_SymbolLambda) return true;
old_def.defun = new_def.scope;
old_def.forEach(function(node) {
node.redef = old_def;
node.thedef = new_def;
node.reference(options);
});
if (new_def.undeclared) self.variables.set(name, new_def);
return true;
}
});
@@ -370,37 +444,47 @@ AST_Toplevel.DEFMETHOD("def_global", function(node) {
}
});
function init_block_vars(scope, parent) {
scope.enclosed = []; // variables from this or outer scope(s) that are referenced from this or inner scopes
scope.parent_scope = parent; // the parent scope (null if this is the top level)
scope.functions = new Dictionary(); // map name to AST_SymbolDefun (functions defined in this scope)
scope.variables = new Dictionary(); // map name to AST_SymbolVar (variables defined in this scope; includes functions)
if (parent) scope.make_def = parent.make_def; // top-level tracking of SymbolDef instances
function init_block_vars(scope, parent, orig) {
// variables from this or outer scope(s) that are referenced from this or inner scopes
scope.enclosed = orig ? orig.enclosed.slice() : [];
// map name to AST_SymbolDefun (functions defined in this scope)
scope.functions = orig ? orig.functions.clone() : new Dictionary();
// map name to AST_SymbolVar (variables defined in this scope; includes functions)
scope.variables = orig ? orig.variables.clone() : new Dictionary();
if (!parent) return;
// top-level tracking of SymbolDef instances
scope.make_def = parent.make_def;
// the parent scope (null if this is the top level)
scope.parent_scope = parent;
}
function init_scope_vars(scope, parent) {
init_block_vars(scope, parent);
scope.uses_eval = false; // will be set to true if this or nested scope uses the global `eval`
scope.uses_with = false; // will be set to true if this or some nested scope uses the `with` statement
function init_scope_vars(scope, parent, orig) {
init_block_vars(scope, parent, orig);
// will be set to true if this or nested scope uses the global `eval`
scope.uses_eval = false;
// will be set to true if this or some nested scope uses the `with` statement
scope.uses_with = false;
}
AST_BlockScope.DEFMETHOD("init_vars", function(parent_scope) {
init_block_vars(this, parent_scope);
AST_BlockScope.DEFMETHOD("init_vars", function(parent, orig) {
init_block_vars(this, parent, orig);
});
AST_Scope.DEFMETHOD("init_vars", function(parent_scope) {
init_scope_vars(this, parent_scope);
AST_Scope.DEFMETHOD("init_vars", function(parent, orig) {
init_scope_vars(this, parent, orig);
});
AST_Arrow.DEFMETHOD("init_vars", function(parent_scope) {
init_scope_vars(this, parent_scope);
AST_Arrow.DEFMETHOD("init_vars", function(parent, orig) {
init_scope_vars(this, parent, orig);
return this;
});
AST_AsyncArrow.DEFMETHOD("init_vars", function(parent_scope) {
init_scope_vars(this, parent_scope);
AST_AsyncArrow.DEFMETHOD("init_vars", function(parent, orig) {
init_scope_vars(this, parent, orig);
});
AST_Lambda.DEFMETHOD("init_vars", function(parent_scope) {
init_scope_vars(this, parent_scope);
AST_Lambda.DEFMETHOD("init_vars", function(parent, orig) {
init_scope_vars(this, parent, orig);
this.uses_arguments = false;
this.def_variable(new AST_SymbolFunarg({
name: "arguments",
scope: this,
start: this.start,
end: this.end,
}));
@@ -410,9 +494,14 @@ AST_Lambda.DEFMETHOD("init_vars", function(parent_scope) {
AST_Symbol.DEFMETHOD("mark_enclosed", function(options) {
var def = this.definition();
for (var s = this.scope; s; s = s.parent_scope) {
push_uniq(s.enclosed, def);
if (options.keep_fnames) {
s.functions.each(function(d) {
if (!push_uniq(s.enclosed, def)) break;
if (!options) {
s._var_names = undefined;
} else {
if (options.keep_fargs && s instanceof AST_Lambda) s.each_argname(function(arg) {
push_uniq(def.scope.enclosed, arg.definition());
});
if (options.keep_fnames) s.functions.each(function(d) {
push_uniq(def.scope.enclosed, d);
});
}
@@ -432,7 +521,7 @@ AST_BlockScope.DEFMETHOD("find_variable", function(name) {
AST_BlockScope.DEFMETHOD("def_function", function(symbol, init) {
var def = this.def_variable(symbol, init);
if (!def.init || is_defun(def.init)) def.init = init;
if (!def.init || def.init instanceof AST_LambdaDefinition) def.init = init;
this.functions.set(symbol.name, def);
return def;
});
@@ -441,7 +530,7 @@ AST_BlockScope.DEFMETHOD("def_variable", function(symbol, init) {
var def = this.variables.get(symbol.name);
if (def) {
def.orig.push(symbol);
if (is_function(def.init)) def.init = init;
if (def.init instanceof AST_LambdaExpression) def.init = init;
} else {
def = this.make_def(symbol, init);
this.variables.set(symbol.name, def);
@@ -455,12 +544,12 @@ function names_in_use(scope, options) {
if (!names) {
scope.cname = -1;
scope.cname_holes = [];
scope.names_in_use = names = Object.create(null);
scope.names_in_use = names = new Dictionary();
var cache = options.cache && options.cache.props;
scope.enclosed.forEach(function(def) {
if (def.unmangleable(options)) names[def.name] = true;
if (def.unmangleable(options)) names.set(def.name, true);
if (def.global && cache && cache.has(def.name)) {
names[cache.get(def.name)] = true;
names.set(cache.get(def.name), true);
}
});
}
@@ -471,34 +560,33 @@ function next_mangled_name(def, options) {
var scope = def.scope;
var in_use = names_in_use(scope, options);
var holes = scope.cname_holes;
var names = Object.create(null);
var names = new Dictionary();
var scopes = [ scope ];
def.forEach(function(sym) {
var scope = sym.scope;
do {
if (scopes.indexOf(scope) < 0) {
for (var name in names_in_use(scope, options)) {
names[name] = true;
}
scopes.push(scope);
} else break;
if (member(scope, scopes)) break;
names_in_use(scope, options).each(function(marker, name) {
names.set(name, marker);
});
scopes.push(scope);
} while (scope = scope.parent_scope);
});
var name;
for (var i = 0; i < holes.length; i++) {
name = base54(holes[i]);
if (names[name]) continue;
if (names.has(name)) continue;
holes.splice(i, 1);
in_use[name] = true;
in_use.set(name, true);
return name;
}
while (true) {
name = base54(++scope.cname);
if (in_use[name] || RESERVED_WORDS[name] || options.reserved.has[name]) continue;
if (!names[name]) break;
if (in_use.has(name) || RESERVED_WORDS[name] || options.reserved.has[name]) continue;
if (!names.has(name)) break;
holes.push(scope.cname);
}
in_use[name] = true;
in_use.set(name, true);
return name;
}
@@ -517,7 +605,8 @@ AST_Symbol.DEFMETHOD("definition", function() {
function _default_mangler_options(options) {
options = defaults(options, {
eval : false,
ie8 : false,
ie : false,
keep_fargs : false,
keep_fnames : false,
reserved : [],
toplevel : false,
@@ -525,38 +614,32 @@ function _default_mangler_options(options) {
webkit : false,
});
if (!Array.isArray(options.reserved)) options.reserved = [];
// Never mangle arguments
// Never mangle `arguments`
push_uniq(options.reserved, "arguments");
options.reserved.has = makePredicate(options.reserved);
return options;
}
// We only need to mangle declaration nodes. Special logic wired into the code
// generator will display the mangled name if it is present (and for
// `AST_SymbolRef`s it will use the mangled name of the `AST_SymbolDeclaration`
// that it points to).
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;
if (options.cache && options.cache.props) {
var mangled_names = names_in_use(this, options);
options.cache.props.each(function(mangled_name) {
mangled_names[mangled_name] = true;
mangled_names.set(mangled_name, true);
});
}
var cutoff = 36;
var lname = -1;
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();
if (!options.v8 || !in_label(tw)) lname = save_nesting;
return true;
}
var save_nesting;
if (node instanceof AST_BlockScope) {
// `lname` is incremented when we get to the `AST_Label`
if (node instanceof AST_LabeledStatement) save_nesting = lname;
if (options.webkit && node instanceof AST_IterationStatement && node.init instanceof AST_Let) {
node.init.definitions.forEach(function(defn) {
defn.name.match_symbol(function(sym) {
@@ -572,9 +655,13 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
});
}, true);
}
node.to_mangle = [];
node.variables.each(function(def) {
if (!defer_redef(def)) node.to_mangle.push(def);
var to_mangle = node.to_mangle = [];
node.variables.each(function(def, name) {
if (def.unmangleable(options)) {
names_in_use(node, options).set(name, true);
} else if (!defer_redef(def)) {
to_mangle.push(def);
}
});
descend();
if (options.cache && node instanceof AST_Toplevel) {
@@ -585,7 +672,24 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
sym.scope = node;
sym.reference(options);
}
node.to_mangle.forEach(mangle);
if (to_mangle.length > cutoff) {
var indices = to_mangle.map(function(def, index) {
return index;
}).sort(function(i, j) {
return to_mangle[j].references.length - to_mangle[i].references.length || i - j;
});
to_mangle = indices.slice(0, cutoff).sort(function(i, j) {
return i - j;
}).map(function(index) {
return to_mangle[index];
}).concat(indices.slice(cutoff).sort(function(i, j) {
return i - j;
}).map(function(index) {
return to_mangle[index];
}));
}
to_mangle.forEach(mangle);
if (node instanceof AST_LabeledStatement && !(options.v8 && in_label(tw))) lname = save_nesting;
return true;
}
if (node instanceof AST_Label) {
@@ -618,7 +722,12 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
}
redefined.push(def);
def.references.forEach(reference);
if (sym instanceof AST_SymbolCatch || sym instanceof AST_SymbolConst) reference(sym);
if (sym instanceof AST_SymbolCatch || sym instanceof AST_SymbolConst) {
reference(sym);
def.redefined = function() {
return redef;
};
}
return true;
function reference(sym) {
@@ -747,6 +856,7 @@ var base54 = (function() {
var leading = init("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_");
var chars, frequency;
function reset() {
chars = null;
frequency = Object.create(freq);
}
base54.consider = function(str, delta) {
@@ -758,19 +868,15 @@ var base54 = (function() {
return frequency[b] - frequency[a];
}
base54.sort = function() {
chars = leading.sort(compare).concat(digits.sort(compare));
chars = leading.sort(compare).concat(digits).sort(compare);
};
base54.reset = reset;
reset();
function base54(num) {
var ret = "", base = 54;
num++;
do {
num--;
ret += chars[num % base];
num = Math.floor(num / base);
base = 64;
} while (num > 0);
var ret = leading[num % 54];
for (num = Math.floor(num / 54); --num >= 0; num >>= 6) {
ret += chars[num & 0x3F];
}
return ret;
}
return base54;

View File

@@ -77,21 +77,23 @@ function vlq_encode(num) {
}
function create_array_map() {
var map = Object.create(null);
var map = new Dictionary();
var array = [];
array.index = function(name) {
if (!HOP(map, name)) {
map[name] = array.length;
var index = map.get(name);
if (!(index >= 0)) {
index = array.length;
array.push(name);
map.set(name, index);
}
return map[name];
return index;
};
return array;
}
function SourceMap(options) {
var sources = create_array_map();
var sources_content = options.includeSources && Object.create(null);
var sources_content = options.includeSources && new Dictionary();
var names = create_array_map();
var mappings = "";
if (options.orig) Object.keys(options.orig).forEach(function(name) {
@@ -110,7 +112,7 @@ function SourceMap(options) {
if (!sources_content || !map.sourcesContent) return;
for (var i = 0; i < map.sources.length; i++) {
var content = map.sourcesContent[i];
if (content) sources_content[map.sources[i]] = content;
if (content) sources_content.set(map.sources[i], content);
}
});
var prev_source;
@@ -144,8 +146,8 @@ function SourceMap(options) {
add(source, gen_line, gen_col, orig_line, orig_col, name);
} : add,
setSourceContent: sources_content ? function(source, content) {
if (!(source in sources_content)) {
sources_content[source] = content;
if (!sources_content.has(source)) {
sources_content.set(source, content);
}
} : noop,
toString: function() {
@@ -155,7 +157,7 @@ function SourceMap(options) {
sourceRoot: options.root || undefined,
sources: sources,
sourcesContent: sources_content ? sources.map(function(source) {
return sources_content[source] || null;
return sources_content.get(source) || null;
}) : undefined,
names: names,
mappings: mappings,

View File

@@ -82,7 +82,7 @@ TreeTransformer.prototype = new TreeWalker;
if (self.step) self.step = self.step.transform(tw);
self.body = self.body.transform(tw);
});
DEF(AST_ForIn, function(self, tw) {
DEF(AST_ForEnumeration, function(self, tw) {
self.init = self.init.transform(tw);
self.object = self.object.transform(tw);
self.body = self.body.transform(tw);
@@ -147,6 +147,15 @@ TreeTransformer.prototype = new TreeWalker;
}
DEF(AST_Arrow, transform_arrow);
DEF(AST_AsyncArrow, transform_arrow);
DEF(AST_Class, function(self, tw) {
if (self.name) self.name = self.name.transform(tw);
if (self.extends) self.extends = self.extends.transform(tw);
self.properties = do_list(self.properties, tw);
});
DEF(AST_ClassProperty, function(self, tw) {
if (self.key instanceof AST_Node) self.key = self.key.transform(tw);
if (self.value) self.value = self.value.transform(tw);
});
DEF(AST_Call, function(self, tw) {
self.expression = self.expression.transform(tw);
self.args = do_list(self.args, tw);
@@ -157,6 +166,9 @@ TreeTransformer.prototype = new TreeWalker;
DEF(AST_Await, function(self, tw) {
self.expression = self.expression.transform(tw);
});
DEF(AST_Yield, function(self, tw) {
if (self.expression) self.expression = self.expression.transform(tw);
});
DEF(AST_Dot, function(self, tw) {
self.expression = self.expression.transform(tw);
});
@@ -201,6 +213,24 @@ TreeTransformer.prototype = new TreeWalker;
if (self.key instanceof AST_Node) self.key = self.key.transform(tw);
self.value = self.value.transform(tw);
});
DEF(AST_ExportDeclaration, function(self, tw) {
self.body = self.body.transform(tw);
});
DEF(AST_ExportDefault, function(self, tw) {
self.body = self.body.transform(tw);
});
DEF(AST_ExportReferences, function(self, tw) {
self.properties = do_list(self.properties, tw);
});
DEF(AST_Import, function(self, tw) {
if (self.all) self.all = self.all.transform(tw);
if (self.default) self.default = self.default.transform(tw);
if (self.properties) self.properties = do_list(self.properties, tw);
});
DEF(AST_Template, function(self, tw) {
if (self.tag) self.tag = self.tag.transform(tw);
self.expressions = do_list(self.expressions, tw);
});
})(function(node, descend) {
node.DEFMETHOD("transform", function(tw, in_list) {
var x, y;

View File

@@ -55,36 +55,41 @@ function find_if(func, array) {
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;
return i & 1 ? d + str : d;
}
function configure_error_stack(fn) {
Object.defineProperty(fn.prototype, "stack", {
function configure_error_stack(ex, cause) {
var stack = ex.name + ": " + ex.message;
Object.defineProperty(ex, "stack", {
get: function() {
var err = new Error(this.message);
err.name = this.name;
try {
throw err;
} catch (e) {
return e.stack;
if (cause) {
cause.name = "" + ex.name;
stack = "" + cause.stack;
var msg = "" + cause.message;
cause = null;
var index = stack.indexOf(msg);
if (index < 0) {
index = 0;
} else {
index += msg.length;
index = stack.indexOf("\n", index) + 1;
}
stack = stack.slice(0, index) + stack.slice(stack.indexOf("\n", index) + 1);
}
}
return stack;
},
});
}
function DefaultsError(msg, defs) {
this.message = msg;
this.defs = defs;
try {
throw new Error(msg);
} catch (cause) {
configure_error_stack(this, cause);
}
}
DefaultsError.prototype = Object.create(Error.prototype);
DefaultsError.prototype.constructor = DefaultsError;
DefaultsError.prototype.name = "DefaultsError";
configure_error_stack(DefaultsError);
function defaults(args, defs, croak) {
if (croak) for (var i in args) {
@@ -96,15 +101,6 @@ function defaults(args, defs, croak) {
return defs;
}
function merge(obj, ext) {
var count = 0;
for (var i in ext) if (HOP(ext, i)) {
obj[i] = ext[i];
count++;
}
return count;
}
function noop() {}
function return_false() { return false; }
function return_true() { return true; }
@@ -143,9 +139,11 @@ function push_uniq(array, el) {
}
function string_template(text, props) {
return text.replace(/\{([^}]+)\}/g, function(str, p) {
var value = props[p];
return value instanceof AST_Node ? value.print_to_string() : value;
return text.replace(/\{([^{}]+)\}/g, function(str, p) {
var value = p == "this" ? props : props[p];
if (value instanceof AST_Node) return value.print_to_string();
if (value instanceof AST_Token) return value.file + ":" + value.line + "," + value.col;
return value;
});
}
@@ -171,63 +169,80 @@ function all(array, predicate) {
}
function Dictionary() {
this._values = Object.create(null);
this._size = 0;
this.values = Object.create(null);
}
Dictionary.prototype = {
set: function(key, val) {
if (!this.has(key)) ++this._size;
this._values["$" + key] = val;
if (key == "__proto__") {
this.proto_value = val;
} else {
this.values[key] = val;
}
return this;
},
add: function(key, val) {
if (this.has(key)) {
this.get(key).push(val);
var list = this.get(key);
if (list) {
list.push(val);
} else {
this.set(key, [ val ]);
}
return this;
},
get: function(key) { return this._values["$" + key] },
get: function(key) {
return key == "__proto__" ? this.proto_value : this.values[key];
},
del: function(key) {
if (this.has(key)) {
--this._size;
delete this._values["$" + key];
if (key == "__proto__") {
delete this.proto_value;
} else {
delete this.values[key];
}
return this;
},
has: function(key) { return ("$" + key) in this._values },
has: function(key) {
return key == "__proto__" ? "proto_value" in this : key in this.values;
},
all: function(predicate) {
for (var i in this._values)
if (!predicate(this._values[i], i.substr(1)))
return false;
for (var i in this.values)
if (!predicate(this.values[i], i)) return false;
if ("proto_value" in this && !predicate(this.proto_value, "__proto__")) return false;
return true;
},
each: function(f) {
for (var i in this._values)
f(this._values[i], i.substr(1));
for (var i in this.values)
f(this.values[i], i);
if ("proto_value" in this) f(this.proto_value, "__proto__");
},
size: function() {
return this._size;
return Object.keys(this.values).length + ("proto_value" in this);
},
map: function(f) {
var ret = [];
for (var i in this._values)
ret.push(f(this._values[i], i.substr(1)));
for (var i in this.values)
ret.push(f(this.values[i], i));
if ("proto_value" in this) ret.push(f(this.proto_value, "__proto__"));
return ret;
},
clone: function() {
var ret = new Dictionary();
for (var i in this._values)
ret._values[i] = this._values[i];
ret._size = this._size;
this.each(function(value, i) {
ret.set(i, value);
});
return ret;
},
toObject: function() { return this._values }
toObject: function() {
var obj = {};
this.each(function(value, i) {
obj["$" + i] = value;
});
return obj;
},
};
Dictionary.fromObject = function(obj) {
var dict = new Dictionary();
dict._size = merge(dict._values, obj);
for (var i in obj)
if (HOP(obj, i)) dict.set(i.slice(1), obj[i]);
return dict;
};
@@ -238,7 +253,7 @@ function HOP(obj, prop) {
// return true if the node at the top of the stack (that means the
// innermost node in the current output) is lexically the first in
// a statement.
function first_in_statement(stack, arrow) {
function first_in_statement(stack, arrow, export_default) {
var node = stack.parent(-1);
for (var i = 0, p; p = stack.parent(i++); node = p) {
if (is_arrow(p)) {
@@ -249,15 +264,37 @@ function first_in_statement(stack, arrow) {
if (p.expression === node) continue;
} else if (p instanceof AST_Conditional) {
if (p.condition === node) continue;
} else if (p instanceof AST_ExportDefault) {
return export_default;
} 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_SimpleStatement) {
return true;
} else if (p instanceof AST_Template) {
if (p.tag === node) continue;
} else if (p instanceof AST_UnaryPostfix) {
if (p.expression === node) continue;
}
return false;
}
}
function DEF_BITPROPS(ctor, props) {
if (props.length > 31) throw new Error("Too many properties: " + props.length + "\n" + props.join(", "));
props.forEach(function(name, pos) {
var mask = 1 << pos;
Object.defineProperty(ctor.prototype, name, {
get: function() {
return !!(this._bits & mask);
},
set: function(val) {
if (val)
this._bits |= mask;
else
this._bits &= ~mask;
},
});
});
}

View File

@@ -3,7 +3,7 @@
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
"license": "BSD-2-Clause",
"version": "3.12.6",
"version": "3.18.0",
"engines": {
"node": ">=0.8.0"
},
@@ -23,7 +23,7 @@
"LICENSE"
],
"devDependencies": {
"acorn": "~7.1.0",
"acorn": "~8.7.1",
"semver": "~6.3.0"
},
"scripts": {

View File

@@ -3,6 +3,7 @@
"use strict";
require("../tools/tty");
var createHash = require("crypto").createHash;
var fetch = require("./fetch");
var spawn = require("child_process").spawn;
@@ -16,7 +17,8 @@ var urls = [
"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",
"https://cdnjs.cloudflare.com/ajax/libs/d3/5.12.0/d3.js",
"https://cdnjs.cloudflare.com/ajax/libs/d3/6.7.0/d3.js",
"https://cdnjs.cloudflare.com/ajax/libs/antd/4.18.7/antd.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",

View File

@@ -10,33 +10,38 @@ var sandbox = require("./sandbox");
var semver = require("semver");
var U = require("./node");
var file = process.argv[2];
var batch = 50;
var dir = path.resolve(path.dirname(module.filename), "compress");
if (file) {
if (process.argv.length > 3) {
var file = process.argv[2];
var start = process.argv[3] | 0;
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) {
process.exit(Object.keys(tests).slice(start, start + batch).filter(function(name) {
return !test_case(tests[name]);
}).length);
} else {
var files = fs.readdirSync(dir).filter(function(name) {
var files = process.argv.length == 3 ? [ process.argv[2] ] : 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 ], {
(function next(file, start, length) {
if (start < length) {
child_process.spawn(process.argv[0], [ process.argv[1], file, start, batch ], {
stdio: [ "ignore", 1, 2 ]
}).on("exit", function(code) {
if (code) {
failures += code;
failed_files[file] = code;
failed_files[file] = true;
}
next();
next(file, start + batch, length);
});
} else if (file = files.shift()) {
log("--- {file}", { file: file });
start = 0;
length = Object.keys(parse_test(path.resolve(dir, file))).length;
next(file, start, length);
} else if (failures) {
console.error();
console.error("!!! Failed " + failures + " test case(s).");
@@ -55,8 +60,9 @@ function log() {
console.log("%s", tmpl.apply(null, arguments));
}
function make_code(ast, options) {
function make_code(ast, options, expression) {
var stream = U.OutputStream(options);
if (expression) ast = ast.clone(true).unwrap_expression();
ast.print(stream);
return stream.get();
}
@@ -64,9 +70,7 @@ function make_code(ast, options) {
function parse_test(file) {
var script = fs.readFileSync(file, "utf8");
try {
var ast = U.parse(script, {
filename: file
});
var ast = U.parse(script, { filename: file, module: "" });
} catch (e) {
console.error("Caught error while parsing tests in " + file);
console.error(e);
@@ -93,14 +97,14 @@ function parse_test(file) {
file: file,
line: node.start.line,
col: node.start.col,
code: make_code(node, { beautify: false })
code: make_code(node, { beautify: false }),
}));
}
function read_string(stat) {
if (stat.TYPE == "SimpleStatement") {
var body = stat.body;
switch(body.TYPE) {
switch (body.TYPE) {
case "String":
return body.value;
case "Array":
@@ -122,6 +126,17 @@ function parse_test(file) {
croak(node);
}
var name = node.left.name;
assert.ok([
"beautify",
"expression",
"mangle",
"options",
"rename",
].indexOf(name) >= 0, tmpl("Unsupported setting {name} [{line},{col}]", {
name: name,
line: node.start.line,
col: node.start.col,
}));
test[name] = evaluate(node.right);
return true;
}
@@ -137,7 +152,7 @@ function parse_test(file) {
].indexOf(label.name) >= 0, tmpl("Unsupported label {name} [{line},{col}]", {
name: label.name,
line: label.start.line,
col: label.start.col
col: label.start.col,
}));
var stat = node.body;
if (label.name == "expect_exact" || label.name == "node_version") {
@@ -150,12 +165,12 @@ function parse_test(file) {
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
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
col: label.start.col,
}));
return node.value;
}));
@@ -175,16 +190,23 @@ function parse_test(file) {
// Try to reminify original input with standard options
// to see if it matches expect_stdout.
function reminify(orig_options, input_code, input_formatted, stdout) {
function reminify(expression, 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) [
if (expression) {
if (!options.parse || typeof options.parse != "object") options.parse = {};
options.parse.expression = true;
if (options.compress == null) options.compress = {};
if (options.compress) {
if (typeof options.compress != "object") options.compress = {};
options.compress.expression = true;
}
}
[
"keep_fargs",
"keep_fnames",
].forEach(function(name) {
if (name in orig_options) {
options.compress[name] = orig_options[name];
}
if (name in orig_options) options[name] = orig_options[name];
});
var options_formatted = JSON.stringify(options, null, 4);
options.validate = true;
@@ -209,7 +231,7 @@ function reminify(orig_options, input_code, input_formatted, stdout) {
} else {
var toplevel = sandbox.has_toplevel(options);
var expected = stdout[toplevel ? 1 : 0];
var actual = sandbox.run_code(result.code, toplevel);
var actual = run_code(expression, result.code, toplevel);
if (typeof expected != "string" && typeof actual != "string" && expected.name == actual.name) {
actual = expected;
}
@@ -244,19 +266,27 @@ function reminify(orig_options, input_code, input_formatted, stdout) {
return true;
}
function run_code(expression, code, toplevel) {
return sandbox.run_code(expression ? "console.log(" + code + ");" : code, toplevel);
}
function test_case(test) {
log(" Running test [{name}]", { name: test.name });
U.AST_Node.enable_validation();
var output_options = test.beautify || {};
var expect;
if (test.expect) {
expect = make_code(to_toplevel(test.expect, test.mangle), output_options);
expect = to_toplevel(test.expect, test.mangle, test.expression);
expect = make_code(expect, output_options, test.expression);
} else {
expect = test.expect_exact;
}
var input = to_toplevel(test.input, test.mangle);
var input_code = make_code(input);
var input = to_toplevel(test.input, test.mangle, test.expression);
var input_code = make_code(input, {
keep_quoted_props: true,
}, test.expression);
var input_formatted = make_code(test.input, {
annotations: true,
beautify: true,
comments: "all",
keep_quoted_props: true,
@@ -264,7 +294,7 @@ function test_case(test) {
});
try {
input.validate_ast();
U.parse(input_code);
U.parse(input_code, { expression: test.expression });
} catch (ex) {
log([
"!!! Cannot parse input",
@@ -290,8 +320,9 @@ function test_case(test) {
warnings_emitted.push(text);
}, /"INFO: /.test(expected_warnings));
}
var quoted_props;
if (test.mangle && test.mangle.properties && test.mangle.properties.keep_quoted) {
var quoted_props = test.mangle.properties.reserved;
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);
@@ -306,9 +337,10 @@ function test_case(test) {
if (test.mangle) {
output.compute_char_frequency(test.mangle);
output.mangle_names(test.mangle);
if (quoted_props) U.reserve_quoted_keys(input, quoted_props);
if (test.mangle.properties) U.mangle_properties(output, test.mangle.properties);
}
var output_code = make_code(output, output_options);
var output_code = make_code(output, output_options, test.expression);
U.AST_Node.log_function();
if (expect != output_code) {
log([
@@ -331,7 +363,7 @@ function test_case(test) {
// expect == output
try {
output.validate_ast();
U.parse(output_code);
U.parse(output_code, { expression: test.expression });
} catch (ex) {
log([
"!!! Test matched expected result but cannot parse output",
@@ -375,7 +407,7 @@ function test_case(test) {
}
}
if (test.expect_stdout && (!test.node_version || semver.satisfies(process.version, test.node_version))) {
var stdout = [ sandbox.run_code(input_code), sandbox.run_code(input_code, true) ];
var stdout = [ run_code(test.expression, input_code), run_code(test.expression, input_code, true) ];
var toplevel = sandbox.has_toplevel({
compress: test.options,
mangle: test.mangle
@@ -404,7 +436,7 @@ function test_case(test) {
});
return false;
}
actual = sandbox.run_code(output_code, toplevel);
actual = run_code(test.expression, output_code, toplevel);
if (!sandbox.same_stdout(test.expect_stdout, actual)) {
log([
"!!! failed",
@@ -425,7 +457,7 @@ function test_case(test) {
});
return false;
}
if (!reminify(test.options, input_code, input_formatted, stdout)) {
if (!reminify(test.expression, test.options, input_code, input_formatted, stdout)) {
return false;
}
}
@@ -436,20 +468,30 @@ function tmpl() {
return U.string_template.apply(null, arguments);
}
function to_toplevel(input, mangle_options) {
function to_toplevel(input, mangle_options, expression) {
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) {
input.walk(new U.TreeWalker(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 {
if (U.push_uniq(tokens, node.end)) node.end.line -= offset;
}));
var toplevel;
if (!expression) {
var directive = true;
toplevel = new U.AST_Toplevel(input.transform(new U.TreeTransformer(function(node) {
if (!directive) return node;
if (node === input) return;
if (node instanceof U.AST_SimpleStatement && node.body instanceof U.AST_String) {
return new U.AST_Directive(node.body);
}
directive = false;
}
})));
})));
} else if (input.body.length == 1) {
toplevel = input.body[0].wrap_expression();
} else {
throw new Error("Invalid expression");
}
toplevel.figure_out_scope(mangle_options);
return toplevel;
}

View File

@@ -0,0 +1,474 @@
issue_2629_1: {
options = {
annotations: true,
side_effects: true,
}
beautify = {
comments: "all",
}
input: {
/*@__PURE__*/ a();
/*@__PURE__*/ (b());
(/*@__PURE__*/ c)();
(/*@__PURE__*/ d());
}
expect_exact: "c();"
}
issue_2629_2: {
options = {
annotations: true,
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 = {
annotations: true,
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 = {
annotations: true,
side_effects: true,
}
input: {
(/*@__PURE__*/ x(), y());
(w(), /*@__PURE__*/ x(), y());
}
expect: {
y();
w(), y();
}
}
issue_2629_5: {
options = {
annotations: true,
side_effects: true,
}
input: {
[ /*@__PURE__*/ x() ];
[ /*@__PURE__*/ x(), y() ];
[ w(), /*@__PURE__*/ x(), y() ];
}
expect: {
y();
w(), y();
}
}
issue_2638: {
options = {
annotations: true,
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 = {
annotations: true,
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 = {
annotations: true,
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 = {
annotations: true,
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 = {
annotations: true,
side_effects: true,
}
input: {
(/*@__PURE__*/ new x(), y());
(w(), /*@__PURE__*/ new x(), y());
}
expect: {
y();
w(), y();
}
}
issue_2705_5: {
options = {
annotations: true,
side_effects: true,
}
input: {
[ /*@__PURE__*/ new x() ];
[ /*@__PURE__*/ new x(), y() ];
[ w(), /*@__PURE__*/ new x(), y() ];
}
expect: {
y();
w(), y();
}
}
issue_2705_6: {
options = {
annotations: true,
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_3858: {
options = {
annotations: true,
collapse_vars: true,
inline: true,
keep_fargs: false,
unsafe: true,
unused: true,
}
input: {
var f = function(a) {
return /*@__PURE__*/ function(b) {
console.log(b);
}(a);
};
f("PASS");
}
expect: {
var f = function(a) {
return function() {
console.log(a);
}();
};
f("PASS");
}
expect_stdout: "PASS"
}
inline_pure_call_1: {
options = {
annotations: true,
collapse_vars: true,
inline: true,
keep_fargs: false,
reduce_vars: true,
sequences: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var f = function(a) {
return /*@__PURE__*/ function(b) {
console.log(b);
}(a);
};
f("PASS");
}
expect: {}
}
inline_pure_call_2: {
options = {
annotations: true,
collapse_vars: true,
inline: true,
keep_fargs: false,
reduce_vars: true,
sequences: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var f = function(a) {
return /*@__PURE__*/ function(b) {
console.log(b);
}(a);
};
var a = f("PASS");
}
expect: {}
}
inline_pure_call_3: {
options = {
annotations: true,
collapse_vars: true,
evaluate: true,
inline: true,
keep_fargs: false,
passes: 2,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var f = function(a) {
return /*@__PURE__*/ function(b) {
console.log(b);
}(a);
};
var a = f("PASS");
console.log(a);
}
expect: {
var a = function() {
console.log("PASS");
}();
console.log(a);
}
expect_stdout: [
"PASS",
"undefined",
]
}
inline_pure_call_4: {
options = {
annotations: true,
evaluate: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = /*@__PURE__*/ function() {
return console.log("PASS"), 42;
}();
console.log(a);
}
expect: {
var a = function() {
return console.log("PASS"), 42;
}();
console.log(a);
}
expect_stdout: [
"PASS",
"42",
]
}
compress_and_output_annotations_enabled: {
options = {
annotations: true,
side_effects: true,
}
beautify = {
annotations: true,
beautify: true,
comments: false,
}
input: {
var top = /*@__PURE__*/ foo();
/*@__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));
/*@__PURE__*/ l(1).p(2);
(/*@__PURE__*/ m(1)).p(2);
(/*@__PURE__*/ n(1).p)(2);
(/*@__PURE__*/ o(1).p(2));
}
expect_exact: [
"var top = /*@__PURE__*/foo();",
"",
"e(1)(2)(3);",
"",
"f(1)(2)(3);",
"",
"g(1)(2)(3);",
"",
"m(1).p(2);",
"",
"n(1).p(2);",
]
}
compress_annotations_disabled_output_annotations_enabled: {
options = {
annotations: false,
evaluate: true,
sequences: true,
side_effects: true,
}
beautify = {
annotations: true,
comments: true,
}
input: {
/*@__PURE__*/ a(1+2);
/*#__PURE__*/ (b(2+3));
(/*@__PURE__*/ c)(side_effect);
(/*#__PURE__*/ d(effect()));
}
expect_exact: [
"/*@__PURE__*/a(3),",
"/*@__PURE__*/b(5),",
"c(side_effect),",
"/*@__PURE__*/d(effect());",
]
}
compress_and_output_annotations_disabled: {
options = {
annotations: false,
evaluate: true,
sequences: true,
side_effects: true,
}
beautify = {
annotations: false,
comments: true,
}
input: {
/*@__PURE__*/ a(1+2);
/*@__PURE__*/ (b(2+3));
(/*@__PURE__*/ c)(side_effect);
(/*@__PURE__*/ d(effect()));
}
expect_exact: [
"a(3),",
"b(5),",
"c(side_effect),",
"d(effect());",
]
}

View File

@@ -84,6 +84,7 @@ replace_index_drop_fargs_1: {
evaluate: true,
keep_fargs: false,
properties: true,
reduce_vars: true,
}
input: {
var arguments = [];
@@ -119,7 +120,7 @@ replace_index_drop_fargs_1: {
console.log(b, b, arguments.foo);
})("bar", 42);
(function(arguments) {
console.log(arguments[1], arguments[1], arguments.foo);
console.log("bar"[1], "bar"[1], "bar".foo);
})("bar", 42);
(function(argument_0, argument_1) {
var arguments;
@@ -253,6 +254,25 @@ duplicate_argname: {
expect_stdout: "bar 42 foo 42 bar"
}
fraction: {
options = {
arguments: true,
keep_fargs: false,
reduce_vars: true,
}
input: {
console.log(function() {
return arguments[0.3];
}("FAIL") || "PASS");
}
expect: {
console.log(function() {
return arguments[0.3];
}("FAIL") || "PASS");
}
expect_stdout: "PASS"
}
issue_3273: {
options = {
arguments: true,
@@ -649,6 +669,7 @@ issue_3420_1: {
options = {
arguments: true,
keep_fargs: false,
reduce_vars: true,
}
input: {
console.log(function() {
@@ -671,6 +692,7 @@ issue_3420_2: {
options = {
arguments: true,
keep_fargs: false,
reduce_vars: true,
}
input: {
var foo = function() {
@@ -691,6 +713,7 @@ issue_3420_3: {
options = {
arguments: true,
keep_fargs: false,
reduce_vars: true,
}
input: {
"use strict";
@@ -713,6 +736,7 @@ issue_3420_4: {
options = {
arguments: true,
keep_fargs: false,
reduce_vars: true,
}
input: {
!function() {
@@ -738,6 +762,7 @@ issue_3420_5: {
options = {
arguments: true,
keep_fargs: false,
reduce_vars: true,
}
input: {
"use strict";
@@ -765,6 +790,7 @@ issue_3420_6: {
options = {
arguments: true,
keep_fargs: false,
reduce_vars: true,
}
input: {
console.log(function() {
@@ -783,6 +809,7 @@ issue_3420_7: {
options = {
arguments: true,
keep_fargs: false,
reduce_vars: true,
}
input: {
"use strict";
@@ -827,6 +854,7 @@ issue_4291_1: {
options = {
arguments: true,
keep_fargs: false,
reduce_vars: true,
}
input: {
console.log(function() {
@@ -847,6 +875,7 @@ issue_4291_2: {
options = {
arguments: true,
keep_fargs: false,
reduce_vars: true,
}
input: {
var a = function() {
@@ -857,8 +886,8 @@ issue_4291_2: {
console.log(a[1], a[0], a.length);
}
expect: {
var a = function(argument_0) {
if (argument_0)
var a = function() {
if (arguments[0])
arguments[1] = "PASS";
return arguments;
}(42);
@@ -871,6 +900,7 @@ issue_4397: {
options = {
arguments: true,
keep_fargs: false,
reduce_vars: true,
}
input: {
console.log(typeof function() {
@@ -977,3 +1007,48 @@ issue_4432: {
}
expect_stdout: "PASS"
}
issue_4696: {
options = {
arguments: true,
keep_fargs: false,
}
input: {
console.log(function() {
for (arguments in [ 42 ]);
for (var a in arguments[0])
return "PASS";
}());
}
expect: {
console.log(function() {
for (arguments in [ 42 ]);
for (var a in arguments[0])
return "PASS";
}());
}
expect_stdout: "PASS"
}
issue_4809: {
options = {
arguments: true,
keep_fargs: false,
reduce_vars: true,
}
input: {
A = 0;
(function() {
arguments[A] = "PASS";
console.log(arguments[0]);
})();
}
expect: {
A = 0;
(function() {
arguments[A] = "PASS";
console.log(arguments[0]);
})();
}
expect_stdout: "PASS"
}

View File

@@ -355,3 +355,72 @@ constructor_good: {
expect_stdout: true
expect_warnings: []
}
unsafe_evaluate_modified_binary: {
options = {
evaluate: true,
reduce_vars: true,
unsafe: true,
}
input: {
(function(a) {
(console && a).push(1);
if (a.length)
console.log("PASS");
})([]);
}
expect: {
(function(a) {
(console && a).push(1);
if (a.length)
console.log("PASS");
})([]);
}
expect_stdout: "PASS"
}
unsafe_evaluate_modified_conditional: {
options = {
evaluate: true,
reduce_vars: true,
unsafe: true,
}
input: {
(function(a) {
(console ? a : []).push(1);
if (a.length)
console.log("PASS");
})([]);
}
expect: {
(function(a) {
(console ? a : []).push(1);
if (a.length)
console.log("PASS");
})([]);
}
expect_stdout: "PASS"
}
unsafe_evaluate_modified_sequence: {
options = {
evaluate: true,
reduce_vars: true,
unsafe: true,
}
input: {
(function(a) {
(0, a).push(1);
if (a.length)
console.log("PASS");
})([]);
}
expect: {
(function(a) {
(0, a).push(1);
if (a.length)
console.log("PASS");
})([]);
}
expect_stdout: "PASS"
}

View File

@@ -34,7 +34,7 @@ destructured_funarg: {
node_version: ">=6"
}
await_parenthesis: {
await_parentheses: {
input: {
async function f() {
await (a => a);
@@ -43,7 +43,7 @@ await_parenthesis: {
expect_exact: "async function f(){await(a=>a)}"
}
for_parenthesis_init: {
for_parentheses_init: {
input: {
for (a => (a in a); console.log(42););
}
@@ -52,7 +52,7 @@ for_parenthesis_init: {
node_version: ">=4"
}
for_parenthesis_condition: {
for_parentheses_condition: {
input: {
for (console.log(42); a => (a in a);)
break;
@@ -62,7 +62,7 @@ for_parenthesis_condition: {
node_version: ">=4"
}
for_parenthesis_step: {
for_parentheses_step: {
input: {
for (; console.log(42); a => (a in a));
}
@@ -71,7 +71,7 @@ for_parenthesis_step: {
node_version: ">=4"
}
for_assign_parenthesis_init: {
for_assign_parentheses_init: {
input: {
for (f = a => (a in a); console.log(42););
}
@@ -80,7 +80,7 @@ for_assign_parenthesis_init: {
node_version: ">=4"
}
for_assign_parenthesis_condition: {
for_assign_parentheses_condition: {
input: {
for (console.log(42); f = a => (a in a);)
break;
@@ -90,7 +90,7 @@ for_assign_parenthesis_condition: {
node_version: ">=4"
}
for_assign_parenthesis_step: {
for_assign_parentheses_step: {
input: {
for (; console.log(42); f = a => (a in a));
}
@@ -99,7 +99,7 @@ for_assign_parenthesis_step: {
node_version: ">=4"
}
for_declaration_parenthesis_init: {
for_declaration_parentheses_init: {
input: {
for (var f = a => (a in a); console.log(42););
}
@@ -108,7 +108,7 @@ for_declaration_parenthesis_init: {
node_version: ">=4"
}
for_statement_parenthesis_init: {
for_statement_parentheses_init: {
input: {
for (a => {
a in a;
@@ -276,6 +276,7 @@ drop_arguments: {
options = {
arguments: true,
keep_fargs: false,
reduce_vars: true,
}
input: {
console.log(function() {
@@ -362,6 +363,28 @@ negate: {
}
inline_this: {
options = {
inline: true,
}
input: {
var p = "PASS";
console.log({
p: "FAIL",
q: (() => this.p)(),
}.q);
}
expect: {
var p = "PASS";
console.log({
p: "FAIL",
q: this.p,
}.q);
}
expect_stdout: "PASS"
node_version: ">=4"
}
dont_inline_this: {
options = {
inline: true,
}
@@ -420,6 +443,7 @@ collapse_value: {
arrows: true,
collapse_vars: true,
keep_fargs: false,
unsafe: true,
unused: true,
}
input: {
@@ -434,6 +458,62 @@ collapse_value: {
node_version: ">=4"
}
collapse_property_lambda: {
options = {
collapse_vars: true,
pure_getters: "strict",
}
input: {
console.log(function f() {
f.g = () => 42;
return f.g();
}());
}
expect: {
console.log(function f() {
return (f.g = () => 42)();
}());
}
expect_stdout: "42"
node_version: ">=4"
}
drop_return: {
options = {
arrows: true,
side_effects: true,
}
input: {
(a => {
while (!console);
return console.log(a);
})(42);
}
expect: {
(a => {
while (!console);
console.log(a);
})(42);
}
expect_stdout: "42"
node_version: ">=4"
}
drop_value: {
options = {
arrows: true,
side_effects: true,
}
input: {
((a, b) => a + b)(console.log(42));
}
expect: {
void console.log(42);
}
expect_stdout: "42"
node_version: ">=4"
}
reduce_iife_1: {
options = {
evaluate: true,
@@ -498,6 +578,75 @@ reduce_iife_3: {
node_version: ">=4"
}
reduce_lambda_1: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var f = () => {
console.log(a, b);
};
var a = "foo", b = 42;
f();
b = "bar";
f();
}
expect: {
var f = () => {
console.log("foo", b);
};
var b = 42;
f();
b = "bar";
f();
}
expect_stdout: [
"foo 42",
"foo bar",
]
node_version: ">=4"
}
reduce_lambda_2: {
options = {
evaluate: true,
passes: 2,
reduce_vars: true,
side_effects: true,
unused: true,
}
input: {
(function(f, a, b) {
f = () => {
console.log(a, b);
};
a = "foo", b = 42;
f();
b = "bar";
f();
})();
}
expect: {
(function(f, a, b) {
f = () => {
console.log("foo", b);
};
b = 42;
f();
b = "bar";
f();
})();
}
expect_stdout: [
"foo 42",
"foo bar",
]
node_version: ">=4"
}
single_use_recursive: {
options = {
reduce_vars: true,
@@ -519,6 +668,87 @@ single_use_recursive: {
node_version: ">=4"
}
inline_iife_within_arrow: {
options = {
arrows: true,
inline: true,
}
input: {
var f = () => console.log(function(a) {
return Math.ceil(a);
}(Math.random()));
f();
}
expect: {
var f = () => {
return console.log((a = Math.random(), Math.ceil(a)));
var a;
};
f();
}
expect_stdout: "1"
node_version: ">=4"
}
instanceof_lambda_1: {
options = {
evaluate: true,
side_effects: true,
}
input: {
console.log(42 instanceof (() => {}));
}
expect: {
console.log(false);
}
expect_stdout: "false"
node_version: ">=4"
}
instanceof_lambda_2: {
options = {
evaluate: true,
side_effects: false,
}
input: {
console.log(null instanceof (() => {}));
}
expect: {
console.log((null, () => {}, false));
}
expect_stdout: "false"
node_version: ">=4"
}
instanceof_lambda_3: {
options = {
evaluate: true,
side_effects: true,
}
input: {
console.log({} instanceof (() => {}));
}
expect: {
console.log({} instanceof (() => {}));
}
expect_stdout: TypeError("Function has non-object prototype 'undefined' in instanceof check")
node_version: ">=4"
}
instanceof_lambda_4: {
options = {
side_effects: true,
}
input: {
({ p: "foo" }) instanceof (() => {});
}
expect: {
[] instanceof (() => {});
}
expect_stdout: TypeError("Function has non-object prototype 'undefined' in instanceof check")
node_version: ">=4"
}
issue_4388: {
options = {
inline: true,
@@ -638,3 +868,453 @@ issue_4476: {
expect_stdout: "foo bar"
node_version: ">=4"
}
issue_4666: {
input: {
console.log((a => /[0-9]/.test(a))(42));
}
expect_exact: "console.log((a=>/[0-9]/.test(a))(42));"
expect_stdout: "true"
node_version: ">=4"
}
issue_4685_1: {
options = {
collapse_vars: true,
unused: true,
}
input: {
new function(f) {
if (f() !== this)
console.log("PASS");
}(() => this);
}
expect: {
new function(f) {
if (f() !== this)
console.log("PASS");
}(() => this);
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_4685_2: {
options = {
reduce_vars: true,
unused: true,
}
input: {
new function(f) {
if (f() !== this)
console.log("PASS");
}(() => {
if (console)
return this;
});
}
expect: {
new function(f) {
if (f() !== this)
console.log("PASS");
}(() => {
if (console)
return this;
});
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_4687_1: {
options = {
collapse_vars: true,
unused: true,
}
input: {
new function() {
console.log(function(f) {
return f() === this;
}(() => this) || "PASS");
}
}
expect: {
new function() {
console.log(function(f) {
return f() === this;
}(() => this) || "PASS");
}
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_4687_2: {
options = {
reduce_vars: true,
unused: true,
}
input: {
new function() {
console.log(function(f) {
return f() === this;
}(() => {
if (console)
return this;
}) || "PASS");
}
}
expect: {
new function() {
console.log(function(f) {
return f() === this;
}(() => {
if (console)
return this;
}) || "PASS");
}
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_4772: {
input: {
var f = a => (a)
/**/ console.log(f("PASS"));
}
expect_exact: 'var f=a=>a;console.log(f("PASS"));'
expect_stdout: "PASS"
node_version: ">=4"
}
issue_5251: {
options = {
inline: true,
toplevel: true,
}
input: {
(() => {
while (console.log(arguments))
var arguments = "FAIL";
})();
}
expect: {
(() => {
while (console.log(arguments))
var arguments = "FAIL";
})();
}
expect_stdout: true
node_version: ">=4"
}
issue_5342_1: {
options = {
dead_code: true,
inline: true,
toplevel: true,
unused: true,
}
input: {
for (var a in 0) {
(() => {
while (1);
})(new function(NaN) {
a.p;
}());
}
console.log(function() {
return b;
try {
b;
} catch (e) {
var b;
}
}());
}
expect: {
for (var a in 0) {
(function(NaN) {
a.p;
})();
while (1);
}
console.log(b);
var b;
}
expect_stdout: "undefined"
node_version: ">=4"
}
issue_5342_2: {
rename = true
options = {
dead_code: true,
inline: true,
toplevel: true,
unused: true,
}
input: {
for (var a in 0) {
(() => {
while (1);
})(new function(NaN) {
a.p;
}());
}
console.log(function() {
return b;
try {
b;
} catch (e) {
var b;
}
}());
}
expect: {
for (var a in 0) {
a.p;
while (1);
}
console.log(c);
var c;
}
expect_stdout: "undefined"
node_version: ">=4"
}
issue_5356: {
options = {
evaluate: true,
reduce_vars: true,
unused: true,
}
input: {
console.log((a => a++)(console));
}
expect: {
console.log((a => +a)(console));
}
expect_stdout: "NaN"
node_version: ">=4"
}
issue_5414_1: {
options = {
arrows: true,
if_return: true,
inline: true,
toplevel: true,
}
input: {
(() => {
(() => {
if (!console)
var arguments = 42;
while (console.log(arguments));
})();
})();
}
expect: {
(() => {
if (!console)
var arguments = 42;
while (console.log(arguments));
})();
}
expect_stdout: true
node_version: ">=4"
}
issue_5414_2: {
options = {
arrows: true,
inline: true,
side_effects: true,
toplevel: true,
}
input: {
(() => {
(() => {
if (!console)
var arguments = 42;
while (console.log(arguments));
})();
})();
}
expect: {
(() => {
if (!console)
var arguments = 42;
while (console.log(arguments));
})();
}
expect_stdout: true
node_version: ">=4"
}
issue_5416_1: {
options = {
dead_code: true,
evaluate: true,
inline: true,
loops: true,
unused: true,
}
input: {
var f = () => {
while ((() => {
console;
var a = function g(arguments) {
console.log(arguments);
}();
})());
};
f();
}
expect: {
var f = () => {
{
console;
arguments = void 0,
console.log(arguments);
var arguments;
return;
}
};
f();
}
expect_stdout: "undefined"
node_version: ">=4"
}
issue_5416_2: {
options = {
dead_code: true,
evaluate: true,
inline: true,
loops: true,
unused: true,
}
input: {
var f = () => {
while ((() => {
console;
var a = function g(arguments) {
while (console.log(arguments));
}();
})());
};
f();
}
expect: {
var f = () => {
{
console;
var arguments = void 0;
for (; console.log(arguments););
return;
}
};
f();
}
expect_stdout: "undefined"
node_version: ">=4"
}
issue_5416_3: {
options = {
inline: true,
side_effects: true,
unused: true,
}
input: {
var f = () => {
(() => {
var a = function g(arguments) {
console.log(arguments);
}();
})();
};
f();
}
expect: {
var f = () => {
arguments = void 0,
console.log(arguments);
var arguments;
};
f();
}
expect_stdout: "undefined"
node_version: ">=4"
}
issue_5416_4: {
options = {
arrows: true,
inline: true,
side_effects: true,
unused: true,
}
input: {
var f = () => {
(() => {
var a = function g(arguments) {
while (console.log(arguments));
}();
})();
};
f();
}
expect: {
var f = () => {
var arguments = void 0;
while (console.log(arguments));
return;
};
f();
}
expect_stdout: "undefined"
node_version: ">=4"
}
issue_5495: {
input: {
console.log((() => {
"use strict";
return function() {
return this;
}();
})());
}
expect_exact: 'console.log((()=>{"use strict";return function(){return this}()})());'
expect_stdout: "undefined"
node_version: ">=4"
}
issue_5653: {
options = {
arrows: true,
hoist_props: true,
passes: 2,
reduce_vars: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
console.log((a => {
a = { p: console };
return a++;
})());
}
expect: {
console.log((a => {
return +{};
})());
}
expect_stdout: "NaN"
node_version: ">=4"
}

View File

@@ -290,6 +290,45 @@ increment_decrement_2: {
expect_stdout: "42"
}
lazily_chained_assignments: {
options = {
assignments: true,
collapse_vars: true,
conditionals: true,
unused: true,
}
input: {
function f(a) {
if (a = console.log("foo"))
a = console.log("bar");
return a;
}
function g(b) {
if (b = console.log("baz"))
;
else
b = console.log("moo");
return b;
}
console.log(f(), g());
}
expect: {
function f(a) {
return console.log("foo") && console.log("bar");
}
function g(b) {
return console.log("baz") || console.log("moo");
}
console.log(f(), g());
}
expect_stdout: [
"foo",
"baz",
"moo",
"undefined undefined",
]
}
issue_3375_1: {
options = {
assignments: true,
@@ -475,3 +514,351 @@ issue_4521: {
}
expect_stdout: "42"
}
logical_assignments: {
input: {
var a = 42, b = null, c;
a &&= "foo";
b ||= "bar";
c ??= "baz";
console.log(a, b, c);
}
expect_exact: 'var a=42,b=null,c;a&&="foo";b||="bar";c??="baz";console.log(a,b,c);'
expect_stdout: "foo bar baz"
node_version: ">=15"
}
logical_collapse_vars_1: {
options = {
collapse_vars: true,
}
input: {
var a = "FAIL", b = false;
a = "PASS";
b ??= a;
console.log(a);
}
expect: {
var a = "FAIL", b = false;
a = "PASS";
b ??= a;
console.log(a);
}
expect_stdout: "PASS"
node_version: ">=15"
}
logical_collapse_vars_2: {
options = {
collapse_vars: true,
}
input: {
var a = "PASS";
(function(b) {
b ||= (a = "FAIL", {});
return b;
})(console).log(a);
}
expect: {
var a = "PASS";
(function(b) {
return b ||= (a = "FAIL", {});
})(console).log(a);
}
expect_stdout: "PASS"
node_version: ">=15"
}
logical_collapse_vars_3: {
options = {
collapse_vars: true,
}
input: {
var a = 6;
a *= 7;
a ??= "FAIL";
console.log(a);
}
expect: {
var a = 6;
a = a * 7 ?? "FAIL";
console.log(a);
}
expect_stdout: "42"
node_version: ">=15"
}
logical_reduce_vars: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = "PASS", b = 42;
b ??= a = "FAIL";
console.log(a);
}
expect: {
var a = "PASS", b = 42;
b ??= a = "FAIL";
console.log(a);
}
expect_stdout: "PASS"
node_version: ">=15"
}
logical_side_effects: {
options = {
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var a = "PASS", b = 42;
b ??= a = "FAIL";
console.log(a);
}
expect: {
var a = "PASS", b = 42;
b ??= a = "FAIL";
console.log(a);
}
expect_stdout: "PASS"
node_version: ">=15"
}
evaluate_lazy_assignment: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = 42;
console.log(a &&= "PASS");
}
expect: {
console.log("PASS");
}
expect_stdout: "PASS"
node_version: ">=15"
}
issue_4815_1: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = "PASS";
42..p &&= a = "FAIL";
console.log(a);
}
expect: {
var a = "PASS";
42..p &&= a = "FAIL";
console.log(a);
}
expect_stdout: "PASS"
node_version: ">=15"
}
issue_4815_2: {
options = {
pure_getters: "strict",
side_effects: true,
}
input: {
var a = "PASS";
42..p &&= a = "FAIL";
console.log(a);
}
expect: {
var a = "PASS";
42..p &&= a = "FAIL";
console.log(a);
}
expect_stdout: "PASS"
node_version: ">=15"
}
issue_4819: {
options = {
comparisons: true,
}
input: {
console.log(void 0 === ([].p &&= 42));
}
expect: {
console.log(void 0 === ([].p &&= 42));
}
expect_stdout: "true"
node_version: ">=15"
}
issue_4827_1: {
options = {
collapse_vars: true,
toplevel: true,
}
input: {
A = "FAIL";
var a = A, b = "PASS", c;
c &&= b = a, console.log(b);
}
expect: {
var a = A = "FAIL", b = "PASS", c;
c &&= b = a, console.log(b);
}
expect_stdout: "PASS"
node_version: ">=15"
}
issue_4827_2: {
options = {
collapse_vars: true,
inline: true,
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var a = 0, b = "PASS";
function f(c) {
a++,
c &&= b = a;
}
f();
console.log(b);
}
expect: {
var a = 0, b = "PASS";
a++,
c &&= b = a;
var c;
console.log(b);
}
expect_stdout: "PASS"
node_version: ">=15"
}
issue_4827_3: {
options = {
merge_vars: true,
toplevel: true,
}
input: {
var a = 0, b, c;
a++;
c &&= b = a;
console.log(b);
}
expect: {
var a = 0, b, c;
a++;
c &&= b = a;
console.log(b);
}
expect_stdout: "undefined"
node_version: ">=15"
}
issue_4876: {
options = {
pure_getters: "strict",
reduce_vars: true,
side_effects: true,
toplevel: true,
}
input: {
try {
var a = null;
var b = a &&= 42;
b.p;
} catch (e) {
console.log("PASS");
}
}
expect: {
try {
var a = null;
var b = a &&= 42;
b.p;
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "PASS"
node_version: ">=15"
}
issue_4924_1: {
options = {
collapse_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var a, b;
console.log("PASS");
a = function() {};
b = function() {}(b ||= a);
}
expect: {
var b;
console.log("PASS");
b = void (b ||= function() {});
}
expect_stdout: "PASS"
node_version: ">=15"
}
issue_4924_2: {
options = {
collapse_vars: true,
dead_code: true,
passes: 2,
sequences: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var a, b;
console.log("PASS");
a = function() {};
b = function() {}(b ||= a);
}
expect: {
console.log("PASS");
}
expect_stdout: "PASS"
node_version: ">=15"
}
issue_5670: {
options = {
assignments: true,
evaluate: true,
reduce_vars: true,
}
input: {
(function(a, b) {
a && a && (a = b += "") || console.log("PASS");
})();
}
expect: {
(function(a, b) {
a = a,
console.log("PASS");
})();
}
expect_stdout: "PASS"
}

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,7 @@ arithmetic: {
}
expect_exact: "console.log((1n+0x2n)*(0o3n- -4n)>>5n-6n);"
expect_stdout: "42n"
node_version: ">=10"
node_version: ">=10.4.0"
}
minus_dot: {
@@ -13,7 +13,7 @@ minus_dot: {
}
expect_exact: "console.log(typeof-42n.toString(),typeof(-42n).toString());"
expect_stdout: "number string"
node_version: ">=10"
node_version: ">=10.4.0"
}
evaluate: {
@@ -28,7 +28,7 @@ evaluate: {
console.log(0xdeadbeefn.toString(16));
}
expect_stdout: "deadbeef"
node_version: ">=10"
node_version: ">=10.4.0"
}
Number: {
@@ -42,7 +42,7 @@ Number: {
console.log(+("" + -0xfeed_dead_beef_badn));
}
expect_stdout: "-1148098955808013200"
node_version: ">=10"
node_version: ">=10.4.0"
}
issue_4590: {
@@ -58,5 +58,49 @@ issue_4590: {
0n || console.log("PASS");
}
expect_stdout: "PASS"
node_version: ">=10"
node_version: ">=10.4.0"
}
issue_4801: {
options = {
booleans: true,
collapse_vars: true,
reduce_vars: true,
unused: true,
}
input: {
try {
(function(a) {
A = 42;
a || A;
})(!(0 == 42 >> 0o644n));
} catch (e) {
console.log("PASS");
}
}
expect: {
try {
(function(a) {
0 != (A = 42) >> 0o644n || A;
})();
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "PASS"
node_version: ">=10.4.0"
}
issue_5728: {
options = {
evaluate: true,
}
input: {
console.log("" + 4n + 2);
}
expect: {
console.log("42");
}
expect_stdout: "42"
node_version: ">=10.4.0"
}

View File

@@ -47,3 +47,45 @@ keep_some_blocks: {
} else stuff();
}
}
issue_1666: {
input: {
var a = 42;
{
function a() {}
a();
}
console.log("PASS");
}
expect: {
var a = 42;
{
function a() {}
a();
}
console.log("PASS");
}
expect_stdout: true
}
issue_1666_strict: {
input: {
"use strict";
var a = 42;
{
function a() {}
a();
}
console.log("PASS");
}
expect: {
"use strict";
var a = 42;
{
function a() {}
a();
}
console.log("PASS");
}
expect_stdout: true
}

View File

@@ -29,6 +29,486 @@ iife_boolean_context: {
]
}
de_morgan_1a: {
options = {
booleans: true,
}
input: {
function f(a) {
return a || a;
}
console.log(f(null), f(42));
}
expect: {
function f(a) {
return a;
}
console.log(f(null), f(42));
}
expect_stdout: "null 42"
}
de_morgan_1b: {
options = {
booleans: true,
}
input: {
function f(a) {
return a && a;
}
console.log(f(null), f(42));
}
expect: {
function f(a) {
return a;
}
console.log(f(null), f(42));
}
expect_stdout: "null 42"
}
de_morgan_1c: {
options = {
booleans: true,
}
input: {
console.log(delete (NaN && NaN));
}
expect: {
console.log(delete (0, NaN));
}
expect_stdout: "true"
}
de_morgan_1d: {
options = {
booleans: true,
}
input: {
function f(a) {
return (a = false) || a;
}
console.log(f(null), f(42));
}
expect: {
function f(a) {
return a = !1;
}
console.log(f(null), f(42));
}
expect_stdout: "false false"
}
de_morgan_2a: {
options = {
booleans: true,
conditionals: true,
}
input: {
function f(a, b) {
return a || (a || b);
}
console.log(f(null), f(null, {}));
console.log(f(42), f(42, {}));
}
expect: {
function f(a, b) {
return a || b;
}
console.log(f(null), f(null, {}));
console.log(f(42), f(42, {}));
}
expect_stdout: [
"undefined {}",
"42 42",
]
}
de_morgan_2b: {
options = {
booleans: true,
evaluate: true,
}
input: {
function f(a, b) {
return a || (a && b);
}
console.log(f(null), f(null, {}));
console.log(f(42), f(42, {}));
}
expect: {
function f(a, b) {
return a;
}
console.log(f(null), f(null, {}));
console.log(f(42), f(42, {}));
}
expect_stdout: [
"null null",
"42 42",
]
}
de_morgan_2c: {
options = {
booleans: true,
evaluate: true,
}
input: {
function f(a, b) {
return a && (a || b);
}
console.log(f(null), f(null, {}));
console.log(f(42), f(42, {}));
}
expect: {
function f(a, b) {
return a;
}
console.log(f(null), f(null, {}));
console.log(f(42), f(42, {}));
}
expect_stdout: [
"null null",
"42 42",
]
}
de_morgan_2d: {
options = {
booleans: true,
evaluate: true,
side_effects: true,
}
input: {
function f(a, b) {
return a && (a && b);
}
console.log(f(null), f(null, {}));
console.log(f(42), f(42, {}));
}
expect: {
function f(a, b) {
return a && b;
}
console.log(f(null), f(null, {}));
console.log(f(42), f(42, {}));
}
expect_stdout: [
"null null",
"undefined {}",
]
}
de_morgan_2e: {
options = {
booleans: true,
conditionals: true,
}
input: {
function f(a, b) {
return (a && b) && b;
}
console.log(f(null), f(null, {}));
console.log(f(42), f(42, {}));
}
expect: {
function f(a, b) {
return a && b;
}
console.log(f(null), f(null, {}));
console.log(f(42), f(42, {}));
}
expect_stdout: [
"null null",
"undefined {}",
]
}
de_morgan_3a: {
options = {
booleans: true,
conditionals: true,
}
input: {
function f(a, b, c) {
return a || ((a || b) || c);
}
console.log(f(null, false), f(null, false, {}), f(null, true), f(null, true, {}));
console.log(f(42, false), f(42, false, {}), f(42, true), f(42, true, {}));
}
expect: {
function f(a, b, c) {
return a || b || c;
}
console.log(f(null, !1), f(null, !1, {}), f(null, !0), f(null, !0, {}));
console.log(f(42, !1), f(42, !1, {}), f(42, !0), f(42, !0, {}));
}
expect_stdout: [
"undefined {} true true",
"42 42 42 42",
]
}
de_morgan_3b: {
options = {
booleans: true,
evaluate: true,
side_effects: true,
}
input: {
function f(a, b, c) {
return a || ((a || b) && c);
}
console.log(f(null, false), f(null, false, {}), f(null, true), f(null, true, {}));
console.log(f(42, false), f(42, false, {}), f(42, true), f(42, true, {}));
}
expect: {
function f(a, b, c) {
return a || b && c;
}
console.log(f(null, !1), f(null, !1, {}), f(null, !0), f(null, !0, {}));
console.log(f(42, !1), f(42, !1, {}), f(42, !0), f(42, !0, {}));
}
expect_stdout: [
"false false undefined {}",
"42 42 42 42",
]
}
de_morgan_3c: {
options = {
booleans: true,
evaluate: true,
side_effects: true,
}
input: {
function f(a, b, c) {
return a || ((a && b) || c);
}
console.log(f(null, false), f(null, false, {}), f(null, true), f(null, true, {}));
console.log(f(42, false), f(42, false, {}), f(42, true), f(42, true, {}));
}
expect: {
function f(a, b, c) {
return a || c;
}
console.log(f(null, !1), f(null, !1, {}), f(null, !0), f(null, !0, {}));
console.log(f(42, !1), f(42, !1, {}), f(42, !0), f(42, !0, {}));
}
expect_stdout: [
"undefined {} undefined {}",
"42 42 42 42",
]
}
de_morgan_3d: {
options = {
booleans: true,
evaluate: true,
}
input: {
function f(a, b, c) {
return a || ((a && b) && c);
}
console.log(f(null, false), f(null, false, {}), f(null, true), f(null, true, {}));
console.log(f(42, false), f(42, false, {}), f(42, true), f(42, true, {}));
}
expect: {
function f(a, b, c) {
return a;
}
console.log(f(null, !1), f(null, !1, {}), f(null, !0), f(null, !0, {}));
console.log(f(42, !1), f(42, !1, {}), f(42, !0), f(42, !0, {}));
}
expect_stdout: [
"null null null null",
"42 42 42 42",
]
}
de_morgan_3e: {
options = {
booleans: true,
evaluate: true,
}
input: {
function f(a, b, c) {
return a && ((a || b) || c);
}
console.log(f(null, false), f(null, false, {}), f(null, true), f(null, true, {}));
console.log(f(42, false), f(42, false, {}), f(42, true), f(42, true, {}));
}
expect: {
function f(a, b, c) {
return a;
}
console.log(f(null, !1), f(null, !1, {}), f(null, !0), f(null, !0, {}));
console.log(f(42, !1), f(42, !1, {}), f(42, !0), f(42, !0, {}));
}
expect_stdout: [
"null null null null",
"42 42 42 42",
]
}
de_morgan_3f: {
options = {
booleans: true,
evaluate: true,
side_effects: true,
}
input: {
function f(a, b, c) {
return a && ((a || b) && c);
}
console.log(f(null, false), f(null, false, {}), f(null, true), f(null, true, {}));
console.log(f(42, false), f(42, false, {}), f(42, true), f(42, true, {}));
}
expect: {
function f(a, b, c) {
return a && c;
}
console.log(f(null, !1), f(null, !1, {}), f(null, !0), f(null, !0, {}));
console.log(f(42, !1), f(42, !1, {}), f(42, !0), f(42, !0, {}));
}
expect_stdout: [
"null null null null",
"undefined {} undefined {}",
]
}
de_morgan_3g: {
options = {
booleans: true,
evaluate: true,
side_effects: true,
}
input: {
function f(a, b, c) {
return a && ((a && b) || c);
}
console.log(f(null, false), f(null, false, {}), f(null, true), f(null, true, {}));
console.log(f(42, false), f(42, false, {}), f(42, true), f(42, true, {}));
}
expect: {
function f(a, b, c) {
return a && (b || c);
}
console.log(f(null, !1), f(null, !1, {}), f(null, !0), f(null, !0, {}));
console.log(f(42, !1), f(42, !1, {}), f(42, !0), f(42, !0, {}));
}
expect_stdout: [
"null null null null",
"undefined {} true true",
]
}
de_morgan_3h: {
options = {
booleans: true,
conditionals: true,
}
input: {
function f(a, b, c) {
return a && ((a && b) && c);
}
console.log(f(null, false), f(null, false, {}), f(null, true), f(null, true, {}));
console.log(f(42, false), f(42, false, {}), f(42, true), f(42, true, {}));
}
expect: {
function f(a, b, c) {
return a && b && c;
}
console.log(f(null, !1), f(null, !1, {}), f(null, !0), f(null, !0, {}));
console.log(f(42, !1), f(42, !1, {}), f(42, !0), f(42, !0, {}));
}
expect_stdout: [
"null null null null",
"false false undefined {}",
]
}
conditional_chain: {
options = {
booleans: true,
conditionals: true,
evaluate: true,
}
input: {
function f(a, b) {
return a ? a : b ? b : 42;
}
console.log(f("PASS", "FAIL"));
}
expect: {
function f(a, b) {
return a || b || 42;
}
console.log(f("PASS", "FAIL"));
}
expect_stdout: "PASS"
}
negated_if: {
options = {
booleans: true,
conditionals: true,
side_effects: true,
}
input: {
console.log(function(a) {
if (!a)
return a ? "FAIL" : "PASS";
}(!console));
}
expect: {
console.log(function(a) {
if (!a)
return "PASS";
}(!console));
}
expect_stdout: "PASS"
}
concat_truthy: {
options = {
booleans: true,
evaluate: true,
}
input: {
console.log("foo") + (console.log("bar"), "baz") || console.log("moo");
}
expect: {
console.log("foo") + (console.log("bar"), "baz");
}
expect_stdout: [
"foo",
"bar",
]
expect_warnings: [
"WARN: + in boolean context always true [test/compress/booleans.js:1,8]",
"WARN: Condition left of || always true [test/compress/booleans.js:1,8]",
]
}
process_returns: {
options = {
booleans: true,
}
input: {
(function() {
return 42;
})() && console.log("PASS");
}
expect: {
(function() {
return 42;
})() && console.log("PASS");
}
expect_stdout: "PASS"
}
issue_3465_1: {
options = {
booleans: true,
@@ -181,3 +661,206 @@ issue_4374: {
}
expect_stdout: "0"
}
issue_5028_1: {
options = {
booleans: true,
conditionals: true,
}
input: {
var a = 1;
console.log(function() {
return a-- ? a-- ? "FAIL 1" : "PASS" : "FAIL 2";
}());
}
expect: {
var a = 1;
console.log(function() {
return a-- ? a-- ? "FAIL 1" : "PASS" : "FAIL 2";
}());
}
expect_stdout: "PASS"
}
issue_5028_2: {
options = {
booleans: true,
conditionals: true,
dead_code: true,
if_return: true,
}
input: {
var a = 1;
(function() {
if (a--)
if (a--)
a = "FAIL";
else
return;
})();
console.log(a);
}
expect: {
var a = 1;
(function() {
a-- && a-- && (a = "FAIL");
})();
console.log(a);
}
expect_stdout: "-1"
}
issue_5028_3: {
options = {
booleans: true,
conditionals: true,
evaluate: true,
if_return: true,
}
input: {
var a = 1;
(function() {
if (a--)
if (a--)
a = "FAIL";
else
return;
})();
console.log(a);
}
expect: {
var a = 1;
(function() {
a-- && a-- && (a = "FAIL");
})();
console.log(a);
}
expect_stdout: "-1"
}
issue_5041_1: {
options = {
booleans: true,
conditionals: true,
}
input: {
var a = 42;
if (a)
if ([ a = null ])
if (a)
console.log("FAIL");
else
console.log("PASS");
}
expect: {
var a = 42;
a && [ a = null ] && (a ? console.log("FAIL") : console.log("PASS"));
}
expect_stdout: "PASS"
}
issue_5041_2: {
options = {
booleans: true,
conditionals: true,
}
input: {
var a;
if (!a)
if (a = 42)
if (a)
console.log("PASS");
else
console.log("FAIL");
}
expect: {
var a;
a || (a = 42) && (a ? console.log("PASS") : console.log("FAIL"));
}
expect_stdout: "PASS"
}
issue_5228: {
options = {
booleans: true,
evaluate: true,
inline: true,
passes: 2,
}
input: {
console.log(function() {
return !function() {
do {
return null;
} while (console);
}();
}());
}
expect: {
console.log(function() {
do {
return !0;
} while (console);
return !0;
}());
}
expect_stdout: "true"
}
issue_5469: {
options = {
assignments: true,
booleans: true,
conditionals: true,
dead_code: true,
evaluate: true,
pure_getters: "strict",
side_effects: true,
}
input: {
console.log(function f(a) {
a && 42[a = A && null];
}());
}
expect: {
console.log(function f(a) {
a && A,
0;
}());
}
expect_stdout: "undefined"
}
issue_5694_1: {
options = {
booleans: true,
conditionals: true,
}
input: {
var Infinity;
// Node.js v0.12~6 (vm): 42
console.log((Infinity = 42) && Infinity);
}
expect: {
var Infinity;
console.log((Infinity = 42) && Infinity);
}
expect_stdout: true
}
issue_5694_2: {
options = {
booleans: true,
conditionals: true,
}
input: {
var undefined;
// Node.js v0.12~6 (vm): NaN
console.log(("foo", ++undefined) || undefined);
}
expect: {
var undefined;
console.log(("foo", ++undefined) || undefined);
}
expect_stdout: true
}

4032
test/compress/classes.js Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -40,6 +40,22 @@ unsafe_comps: {
}
}
unsafe_in_instanceof: {
options = {
side_effects: true,
unsafe_comps: true,
}
input: {
var a;
42 in a;
f() instanceof "foo";
}
expect: {
var a;
f();
}
}
dont_change_in_or_instanceof_expressions: {
input: {
1 in 1;
@@ -259,6 +275,7 @@ issue_2857_3: {
issue_2857_4: {
options = {
comparisons: true,
conditionals: true,
}
input: {
function f(a, p) {
@@ -289,6 +306,7 @@ issue_2857_4: {
issue_2857_5: {
options = {
comparisons: true,
conditionals: true,
}
input: {
function f(a, p) {
@@ -489,7 +507,37 @@ issue_3413: {
}
expect: {
var b;
void 0 !== ("" < b || void 0) || console.log("PASS");
void 0 === ("" < b || void 0) && console.log("PASS");
}
expect_stdout: "PASS"
}
nullish_assign: {
options = {
comparisons: true,
}
input: {
var a;
void 0 !== (a = "PASS".split("")) && null !== a && console.log(a.join("-"));
}
expect: {
var a;
null != (a = "PASS".split("")) && console.log(a.join("-"));
}
expect_stdout: "P-A-S-S"
}
nullish_chain: {
options = {
comparisons: true,
conditionals: true,
}
input: {
var a;
A || B || void 0 === a || null === a || C;
}
expect: {
var a;
A || B || null == a || C;
}
}

View File

@@ -12,7 +12,7 @@ concat_1: {
var e = 1 + x() + 2 + "X" + 3 + "boo";
// be careful with concatentation with "\0" with octal-looking strings.
// be careful with concatenation with "\0" with octal-looking strings.
var f = "\0" + 360 + "\0" + 8 + "\0";
}
expect: {
@@ -273,6 +273,23 @@ concat_9: {
expect_stdout: true
}
concat_sequence: {
options = {
collapse_vars: true,
strings: true,
toplevel: true,
unused: true,
}
input: {
var a;
console.log(12 + (a = null, "34" + a));
}
expect: {
console.log(12 + "34" + null);
}
expect_stdout: "1234null"
}
issue_3689: {
options = {
strings: true,
@@ -289,3 +306,18 @@ issue_3689: {
}
expect_stdout: "00"
}
issue_5145: {
options = {
strings: true,
}
input: {
var a = [];
console.log("" + a + ((a[0] = 4) + "2"));
}
expect: {
var a = [];
console.log("" + a + (a[0] = 4) + "2");
}
expect_stdout: "42"
}

File diff suppressed because it is too large Load Diff

View File

@@ -142,6 +142,80 @@ if_dead_branch: {
expect_stdout: "undefined"
}
retain_tail_1: {
options = {
conditionals: true,
}
input: {
function f(a) {
var b = "foo";
if (a) {
const b = "bar";
while (console.log("baz"));
console.log(b);
} else {
while (console.log("moo"));
console.log(b);
}
}
f();
f(42);
}
expect: {
function f(a) {
var b = "foo";
if (a) {
const b = "bar";
while (console.log("baz"));
console.log(b);
} else {
while (console.log("moo"));
console.log(b);
}
}
f();
f(42);
}
expect_stdout: true
}
retain_tail_2: {
options = {
conditionals: true,
}
input: {
function f(a) {
var b = "foo";
if (a) {
while (console.log("bar"));
console.log(b);
} else {
const b = "baz";
while (console.log("moo"));
console.log(b);
}
}
f();
f(42);
}
expect: {
function f(a) {
var b = "foo";
if (a) {
while (console.log("bar"));
console.log(b);
} else {
const b = "baz";
while (console.log("moo"));
console.log(b);
}
}
f();
f(42);
}
expect_stdout: true
}
merge_vars_1: {
options = {
merge_vars: true,
@@ -220,6 +294,32 @@ merge_vars_3: {
expect_stdout: true
}
merge_vars_4: {
options = {
merge_vars: true,
toplevel: true,
}
input: {
var a = 1;
console.log(typeof a);
{
var b = console;
console.log(typeof b);
const a = 0;
}
}
expect: {
var a = 1;
console.log(typeof a);
{
var b = console;
console.log(typeof b);
const a = 0;
}
}
expect_stdout: true
}
use_before_init_1: {
options = {
reduce_vars: true,
@@ -486,7 +586,7 @@ do_continue: {
catch_ie8_1: {
options = {
ie8: true,
ie: true,
unused: true,
}
input: {
@@ -506,7 +606,7 @@ catch_ie8_1: {
catch_ie8_2: {
options = {
dead_code: true,
ie8: true,
ie: true,
passes: 2,
toplevel: true,
unused: true,
@@ -553,6 +653,37 @@ dead_block_after_return: {
expect_stdout: true
}
if_return_3: {
options = {
if_return: true,
}
input: {
var a = "PASS";
function f(b) {
if (console) {
const b = a;
return b;
} else
while (console.log("FAIL 1"));
return b;
}
console.log(f("FAIL 2"));
}
expect: {
var a = "PASS";
function f(b) {
if (console) {
const b = a;
return b;
} else
while (console.log("FAIL 1"));
return b;
}
console.log(f("FAIL 2"));
}
expect_stdout: true
}
do_if_continue_1: {
options = {
if_return: true,
@@ -571,8 +702,7 @@ do_if_continue_1: {
}
expect: {
do {
if (!console);
else {
if (console) {
console.log("PASS");
{
const a = 0;
@@ -602,8 +732,7 @@ do_if_continue_2: {
}
expect: {
do {
if (!console);
else {
if (console) {
console.log("PASS");
{
const a = 0;
@@ -727,7 +856,7 @@ issue_4193: {
issue_4195: {
mangle = {
ie8: true,
ie: true,
}
input: {
console.log(function f(a) {
@@ -838,12 +967,10 @@ issue_4202: {
expect: {
{
const o = {};
(function() {
function f() {
o.p = 42;
}
f(f);
})();
function f() {
o.p = 42;
}
f(f);
console.log(o.p++);
}
}
@@ -1131,7 +1258,7 @@ issue_4225: {
issue_4229: {
options = {
ie8: true,
ie: true,
side_effects: true,
}
input: {
@@ -1151,7 +1278,7 @@ issue_4229: {
issue_4231: {
options = {
ie8: true,
ie: true,
side_effects: true,
}
input: {
@@ -1219,9 +1346,9 @@ issue_4248: {
expect_stdout: "PASS"
}
issue_4261: {
issue_4261_1: {
options = {
inline: true,
inline: 3,
reduce_funcs: true,
reduce_vars: true,
toplevel: true,
@@ -1259,6 +1386,43 @@ issue_4261: {
expect_stdout: "42"
}
issue_4261_2: {
options = {
if_return: true,
inline: true,
reduce_funcs: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
{
const a = 42;
(function() {
function f() {
console.log(a);
}
function g() {
while (f());
}
(function() {
while (g());
})();
})();
}
}
expect: {
{
const a = 42;
function g() {
while (void console.log(a));
}
while (g());
}
}
expect_stdout: "42"
}
issue_4274_1: {
options = {
loops: true,
@@ -1434,3 +1598,636 @@ issue_4527: {
}
expect_stdout: "aaaa"
}
issue_4689: {
options = {
sequences: true,
}
input: {
"use strict";
var a = "PASS";
console.log(a);
for (const a in 42);
}
expect: {
"use strict";
var a = "PASS";
console.log(a);
for (const a in 42);
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_4691: {
options = {
conditionals: true,
if_return: true,
toplevel: true,
}
input: {
function A() {}
A.prototype.f = function() {
if (!this)
return;
const a = "PA";
function g(b) {
h(a + b);
}
[ "SS" ].forEach(function(c) {
g(c);
});
};
function h(d) {
console.log(d);
}
new A().f();
}
expect: {
function A() {}
A.prototype.f = function() {
if (this) {
const a = "PA";
[ "SS" ].forEach(function(c) {
g(c);
});
function g(b) {
h(a + b);
}
}
};
function h(d) {
console.log(d);
}
new A().f();
}
expect_stdout: "PASS"
}
issue_4848: {
options = {
if_return: true,
}
input: {
function f(a) {
a(function() {
console.log(b);
});
if (!console)
return;
const b = "PASS";
}
var g;
f(function(h) {
g = h;
});
g();
}
expect: {
function f(a) {
a(function() {
console.log(b);
});
if (!console)
return;
const b = "PASS";
}
var g;
f(function(h) {
g = h;
});
g();
}
expect_stdout: "PASS"
}
issue_4954_1: {
rename = true
input: {
"use strict";
(function() {
{
const a = "foo";
console.log(a);
}
{
const a = "bar";
console.log(a);
}
})();
}
expect: {
"use strict";
(function() {
{
const a = "foo";
console.log(a);
}
{
const b = "bar";
console.log(b);
}
})();
}
expect_stdout: [
"foo",
"bar",
]
node_version: ">=4"
}
issue_4954_2: {
mangle = {}
input: {
"use strict";
const a = null;
(function(b) {
for (const a in null);
for (const a in b)
console.log("PASS");
})([ null ]);
}
expect: {
"use strict";
const a = null;
(function(o) {
for (const n in null);
for (const n in o)
console.log("PASS");
})([ null ]);
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_4960: {
mangle = {}
input: {
"use strict";
var a;
(function() {
{
const a = console.log("PASS");
}
try {} catch (e) {
const a = console.log("FAIL");
}
})();
}
expect: {
"use strict";
var a;
(function() {
{
const o = console.log("PASS");
}
try {} catch (o) {
const c = console.log("FAIL");
}
})();
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_4965_1: {
mangle = {}
input: {
"use strict";
try {
c;
} catch (a) {
{
const a = 1;
}
{
const a = console.log(typeof c);
}
}
}
expect: {
"use strict";
try {
c;
} catch (t) {
{
const c = 1;
}
{
const t = console.log(typeof c);
}
}
}
expect_stdout: "undefined"
node_version: ">=4"
}
issue_4965_2: {
mangle = {}
input: {
"use strict";
try {
throw 1;
} catch (e) {
try {
{
const e = 2;
}
} finally {
const e = 3;
console.log(typeof t);
}
}
}
expect: {
"use strict";
try {
throw 1;
} catch (o) {
try {
{
const t = 2;
}
} finally {
const o = 3;
console.log(typeof t);
}
}
}
expect_stdout: "undefined"
node_version: ">=4"
}
issue_5254: {
options = {
inline: true,
toplevel: true,
}
input: {
do {
(function() {
const a = console.log;
a && a("foo");
})();
} while (console.log("bar"));
}
expect: {
do {
const a = console.log;
a && a("foo");
} while (console.log("bar"));
}
expect_stdout: [
"foo",
"bar",
]
}
issue_5260: {
options = {
collapse_vars: true,
}
input: {
"use strict";
var a = "foo", o;
while (console.log("bar"));
o = {
baz: function(b) {
console.log(a, b);
},
};
for (const a in o)
o[a](a);
}
expect: {
"use strict";
var a = "foo", o;
while (console.log("bar"));
o = {
baz: function(b) {
console.log(a, b);
},
};
for (const a in o)
o[a](a);
}
expect_stdout: [
"bar",
"foo baz",
]
node_version: ">=4"
}
issue_5319: {
options = {
collapse_vars: true,
merge_vars: true,
}
input: {
(function(a, c) {
var b = a, c = b;
{
const a = c;
console.log(c());
}
})(function() {
return "PASS";
});
}
expect: {
(function(a, c) {
var b = a, c;
{
const a = c = b;
console.log(c());
}
})(function() {
return "PASS";
});
}
expect_stdout: true
}
issue_5338: {
options = {
unused: true,
}
input: {
const a = a;
}
expect: {
const a = a;
}
expect_stdout: true
}
issue_5476: {
mangle = {
keep_fargs: true,
}
input: {
console.log(function(n) {
const a = 42;
}());
}
expect: {
console.log(function(n) {
const o = 42;
}());
}
expect_stdout: "undefined"
}
issue_5516: {
options = {
inline: true,
reduce_funcs: true,
reduce_vars: true,
unused: true,
}
input: {
console.log(typeof function() {
try {} catch (a) {
(function f() {
a;
})();
}
{
const a = function() {};
return a;
}
}());
}
expect: {
console.log(typeof function() {
try {} catch (a) {
void a;
}
{
const a = function() {};
return a;
}
}());
}
expect_stdout: "function"
}
issue_5580_1: {
mangle = {}
input: {
"use strict";
console.log(function(a, b, c) {
try {
FAIL;
} catch (e) {
return function() {
var d = e, i, j;
{
const e = j;
}
return a;
}();
} finally {
const e = 42;
}
}("PASS"));
}
expect: {
"use strict";
console.log(function(r, n, t) {
try {
FAIL;
} catch (o) {
return function() {
var n = o, t, c;
{
const o = c;
}
return r;
}();
} finally {
const c = 42;
}
}("PASS"));
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_5580_2: {
options = {
inline: true,
reduce_vars: true,
varify: true,
}
input: {
"use strict";
(function() {
try {
throw "PASS";
} catch (e) {
return function() {
console.log(e);
{
const e = "FAIL 1";
}
}();
} finally {
const e = "FAIL 2";
}
})();
}
expect: {
"use strict";
(function() {
try {
throw "PASS";
} catch (e) {
console.log(e);
{
const e = "FAIL 1";
}
return;
} finally {
var e = "FAIL 2";
}
})();
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_5591: {
options = {
dead_code: true,
if_return: true,
}
input: {
"use strict";
function f(a) {
switch (console.log("foo")) {
case console.log("bar"):
if (console.log("baz"))
return;
else {
const a = 42;
return;
}
break;
case null:
FAIL;
}
}
f();
}
expect: {
"use strict";
function f(a) {
switch (console.log("foo")) {
case console.log("bar"):
if (console.log("baz"))
return;
else {
const a = 42;
return;
}
case null:
FAIL;
}
}
f();
}
expect_stdout: [
"foo",
"bar",
"baz",
]
node_version: ">=4"
}
issue_5656: {
options = {
collapse_vars: true,
merge_vars: true,
}
input: {
console.log(function(a) {
var b = a;
b++;
{
const a = b;
}
}());
}
expect: {
console.log(function(a) {
var b = a;
{
const a = ++b;
}
}());
}
expect_stdout: true
}
issue_5660: {
options = {
merge_vars: true,
side_effects: true,
}
input: {
function f() {
try {
a;
var b;
return b;
} catch (e) {
var a = "FAIL";
const b = null;
return a;
}
}
console.log(f());
}
expect: {
function f() {
try {
var b;
return b;
} catch (e) {
var a = "FAIL";
const b = null;
return a;
}
}
console.log(f());
}
expect_stdout: true
}
issue_5787: {
options = {
unused: true,
}
input: {
console.log(function() {
const a = 42;
switch (a) {
case 42:
const a = "PASS";
return a;
}
}());
}
expect: {
console.log(function() {
const a = 42;
switch (a) {
case 42:
const a = "PASS";
return a;
}
}());
}
expect_stdout: true
}

View File

@@ -53,8 +53,10 @@ dead_code_2_should_warn: {
g();
x = 10;
throw new Error("foo");
var x;
function g(){};
{
var x;
function g(){};
}
}
f();
}
@@ -62,7 +64,6 @@ dead_code_2_should_warn: {
expect_warnings: [
"WARN: Dropping unreachable code [test/compress/dead-code.js:8,12]",
]
node_version: "<=4"
}
dead_code_constant_boolean_should_warn_more: {
@@ -88,8 +89,10 @@ dead_code_constant_boolean_should_warn_more: {
bar();
}
expect: {
var foo;
function bar() {}
{
var foo;
function bar() {}
}
// nothing for the while
// as for the for, it should keep:
var x = 10, y;
@@ -936,6 +939,185 @@ catch_return_assign: {
expect_stdout: "PASS"
}
catch_return_assign_may_throw: {
options = {
dead_code: true,
}
input: {
function f() {
try {
throw "FAIL";
} catch (e) {
return e = console.log("PASS");
}
}
f();
}
expect: {
function f() {
try {
throw "FAIL";
} catch (e) {
return console.log("PASS");
}
}
f();
}
expect_stdout: "PASS"
}
finally_return_assign: {
options = {
dead_code: true,
}
input: {
console.log(function(a) {
try {
throw "FAIL";
} finally {
return a = "PASS";
}
}());
}
expect: {
console.log(function(a) {
try {
throw "FAIL";
} finally {
return "PASS";
}
}());
}
expect_stdout: "PASS"
}
last_assign_statement: {
options = {
dead_code: true,
}
input: {
function f(a) {
a = a("PASS");
}
f(console.log);
}
expect: {
function f(a) {
a("PASS");
}
f(console.log);
}
expect_stdout: "PASS"
}
last_assign_if_else: {
options = {
dead_code: true,
}
input: {
function f(a) {
if (a)
a = console.log("foo");
else {
console.log("bar");
a = console.log("baz");
}
}
f(42);
f(null);
}
expect: {
function f(a) {
if (a)
console.log("foo");
else {
console.log("bar");
console.log("baz");
}
}
f(42);
f(null);
}
expect_stdout: [
"foo",
"bar",
"baz",
]
}
last_assign_catch: {
options = {
dead_code: true,
}
input: {
function f() {
try {
throw "FAIL";
} catch (e) {
e = console.log("PASS");
}
}
f();
}
expect: {
function f() {
try {
throw "FAIL";
} catch (e) {
console.log("PASS");
}
}
f();
}
expect_stdout: "PASS"
}
last_assign_finally: {
options = {
dead_code: true,
}
input: {
function f(a) {
try {
throw a.log;
} catch (e) {
a = e;
} finally {
a = a("PASS");
}
}
f(console);
}
expect: {
function f(a) {
try {
throw a.log;
} catch (e) {
a = e;
} finally {
a("PASS");
}
}
f(console);
}
expect_stdout: "PASS"
}
consecutive_assignments: {
options = {
dead_code: true,
}
input: {
while (a = void 0, a = "PASS", console.log(a));
var a;
}
expect: {
while (void 0, a = "PASS", console.log(a));
var a;
}
expect_stdout: "PASS"
}
issue_3578: {
options = {
dead_code: true,
@@ -1303,8 +1485,6 @@ self_assignments_5: {
}
expect: {
var i = 0, l = [ "FAIL", "PASS" ];
l[0];
l[0];
l[0] = l[1];
console.log(l[0], 2);
}
@@ -1417,3 +1597,136 @@ issue_4570: {
}
expect_stdout: "NaN"
}
issue_5030: {
options = {
dead_code: true,
}
input: {
(function(a, b) {
a = function f() {
if (a)
if (b--)
setImmediate(f);
else
console.log("FAIL");
else
console.log("PASS");
}();
})(42, 1);
}
expect: {
(function(a, b) {
a = function f() {
if (a)
if (b--)
setImmediate(f);
else
console.log("FAIL");
else
console.log("PASS");
}();
})(42, 1);
}
expect_stdout: "PASS"
node_version: ">=0.12"
}
issue_5106_1: {
options = {
dead_code: true,
}
input: {
console.log(typeof function(a) {
return a = arguments;
}("FAIL")[0]);
}
expect: {
console.log(typeof function(a) {
return a = arguments;
}("FAIL")[0]);
}
expect_stdout: "object"
}
issue_5106_2: {
options = {
dead_code: true,
}
input: {
"use strict";
console.log(function(a) {
return a = arguments;
}("PASS")[0]);
}
expect: {
"use strict";
console.log(function(a) {
return arguments;
}("PASS")[0]);
}
expect_stdout: "PASS"
}
issue_5506: {
options = {
dead_code: true,
}
input: {
try {
(function(a) {
var b = 1;
(function f() {
try {
b-- && f();
} catch (c) {}
console.log(a);
a = 42 in (a = "bar");
})();
})("foo");
} catch (e) {}
}
expect: {
try {
(function(a) {
var b = 1;
(function f() {
try {
b-- && f();
} catch (c) {}
console.log(a);
a = 42 in (a = "bar");
})();
})("foo");
} catch (e) {}
}
expect_stdout: [
"foo",
"bar",
]
}
issue_5641: {
options = {
collapse_vars: true,
conditionals: true,
dead_code: true,
}
input: {
function f(a) {
if (a || b) {
var b = "PASS", c = b && console.log(b);
} else
var d = a || b;
}
f(42);
}
expect: {
function f(a) {
var b, c, d;
(a || b) && (b = "PASS") && console.log(b);
}
f(42);
}
expect_stdout: "PASS"
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -129,3 +129,47 @@ valid_after_invalid_2: {
}
expect_stdout: "undefined"
}
issue_5368_1: {
expression = true
options = {
directives: true,
expression: true,
}
input: {
"foo"
}
expect_exact: '"foo"'
expect_stdout: "foo"
}
issue_5368_2: {
expression = true
options = {
directives: true,
expression: true,
}
input: {
(function() {
"foo";
})()
}
expect_exact: "function(){}()"
expect_stdout: "undefined"
}
issue_5368_3: {
options = {
directives: true,
expression: true,
}
input: {
"foo";
(function() {
"bar";
})();
}
expect: {
(function() {})();
}
}

View File

@@ -409,6 +409,15 @@ drop_toplevel_retain: {
a = 2;
console.log(3);
}
expect_stdout: "3"
expect_warnings: [
"INFO: Retaining variable a",
"INFO: Retaining variable f",
"INFO: Dropping unused variable b [test/compress/drop-unused.js:1,15]",
"INFO: Dropping unused variable c [test/compress/drop-unused.js:1,22]",
"INFO: Dropping unused function g [test/compress/drop-unused.js:8,17]",
"WARN: Dropping unused function h [test/compress/drop-unused.js:9,17]",
]
}
drop_toplevel_retain_array: {
@@ -442,6 +451,15 @@ drop_toplevel_retain_array: {
a = 2;
console.log(3);
}
expect_stdout: "3"
expect_warnings: [
"INFO: Retaining variable a",
"INFO: Retaining variable f",
"INFO: Dropping unused variable b [test/compress/drop-unused.js:1,15]",
"INFO: Dropping unused variable c [test/compress/drop-unused.js:1,22]",
"INFO: Dropping unused function g [test/compress/drop-unused.js:8,17]",
"WARN: Dropping unused function h [test/compress/drop-unused.js:9,17]",
]
}
drop_toplevel_retain_regex: {
@@ -471,6 +489,15 @@ drop_toplevel_retain_regex: {
a = 2;
console.log(3);
}
expect_stdout: "3"
expect_warnings: [
"INFO: Retaining variable a",
"INFO: Retaining variable f",
"INFO: Dropping unused variable b [test/compress/drop-unused.js:1,15]",
"INFO: Dropping unused variable c [test/compress/drop-unused.js:1,22]",
"INFO: Dropping unused function g [test/compress/drop-unused.js:8,17]",
"WARN: Dropping unused function h [test/compress/drop-unused.js:9,17]",
]
}
drop_toplevel_all_retain: {
@@ -501,6 +528,15 @@ drop_toplevel_all_retain: {
a = 2;
console.log(3);
}
expect_stdout: "3"
expect_warnings: [
"INFO: Retaining variable a",
"INFO: Retaining variable f",
"INFO: Dropping unused variable b [test/compress/drop-unused.js:1,15]",
"INFO: Dropping unused variable c [test/compress/drop-unused.js:1,22]",
"INFO: Dropping unused function g [test/compress/drop-unused.js:8,17]",
"WARN: Dropping unused function h [test/compress/drop-unused.js:9,17]",
]
}
drop_toplevel_funcs_retain: {
@@ -532,6 +568,12 @@ drop_toplevel_funcs_retain: {
function g() {}
console.log(b = 3);
}
expect_stdout: "3"
expect_warnings: [
"INFO: Retaining variable a",
"INFO: Retaining variable f",
"WARN: Dropping unused function h [test/compress/drop-unused.js:9,17]",
]
}
drop_toplevel_vars_retain: {
@@ -564,6 +606,13 @@ drop_toplevel_vars_retain: {
function h() {}
console.log(3);
}
expect_stdout: "3"
expect_warnings: [
"INFO: Retaining variable a",
"INFO: Retaining variable f",
"INFO: Dropping unused variable b [test/compress/drop-unused.js:1,15]",
"INFO: Dropping unused variable c [test/compress/drop-unused.js:1,22]",
]
}
drop_toplevel_keep_assign: {
@@ -671,6 +720,76 @@ iife: {
}
}
drop_instanceof: {
options = {
booleans: true,
toplevel: true,
unused: true,
}
input: {
function f() {}
console.log({} instanceof f, Math instanceof f);
}
expect: {
console.log(!1, (Math, !1));
}
expect_stdout: "false false"
}
keep_instanceof_1: {
options = {
toplevel: true,
unused: true,
}
input: {
function f() {}
var f;
console.log({} instanceof f, Math instanceof f);
}
expect: {
function f() {}
var f;
console.log({} instanceof f, Math instanceof f);
}
expect_stdout: "false false"
}
keep_instanceof_2: {
options = {
toplevel: true,
unused: true,
}
input: {
function f() {}
var f = Object;
console.log({} instanceof f, Math instanceof f);
}
expect: {
function f() {}
var f = Object;
console.log({} instanceof f, Math instanceof f);
}
expect_stdout: "true true"
}
keep_instanceof_3: {
options = {
toplevel: true,
unused: true,
}
input: {
f = Object;
function f() {}
console.log({} instanceof f, Math instanceof f);
}
expect: {
f = Object;
function f() {}
console.log({} instanceof f, Math instanceof f);
}
expect_stdout: "true true"
}
issue_1539: {
options = {
collapse_vars: true,
@@ -795,9 +914,9 @@ issue_1656: {
beautify: true,
}
input: {
for(var a=0;;);
for (var a=0;;);
}
expect_exact: "for (;;) ;"
expect_exact: "for (;;);"
}
issue_1709: {
@@ -1110,7 +1229,7 @@ issue_1838: {
}
expect_exact: [
"function f() {",
" for (a; c; ) ;",
" for (a; c; );",
"}",
]
}
@@ -1233,8 +1352,11 @@ issue_2105_2: {
issue_2105_3: {
options = {
inline: true,
passes: 2,
join_vars: true,
passes: 3,
reduce_vars: true,
side_effects: true,
sequences: true,
unused: true,
}
input: {
@@ -1258,12 +1380,12 @@ issue_2105_3: {
});
}
expect: {
!void void {
({
prop: function() {
console.log;
void console.log("PASS");
}
}.prop();
console.log,
console.log("PASS");
},
}).prop();
}
expect_stdout: "PASS"
}
@@ -1557,9 +1679,9 @@ issue_2665: {
}
expect: {
var a = 1;
!function g() {
(function g() {
a-- && g();
}();
})();
console.log(a);
}
expect_stdout: "-1"
@@ -1728,7 +1850,8 @@ issue_2768: {
}
expect: {
var a = "FAIL";
var c = (d = a, void (d && (a = "PASS")));
d = a;
var c = void (d && (a = "PASS"));
var d;
console.log(a, typeof c);
}
@@ -1755,7 +1878,7 @@ issue_2846: {
var c = function(a, b) {
a = 0;
b && b(a);
return a++;
return +a;
}();
console.log(c);
}
@@ -1765,7 +1888,7 @@ issue_2846: {
issue_805_1: {
options = {
inline: true,
passes: 2,
passes: 3,
pure_getters: "strict",
reduce_vars: true,
sequences: true,
@@ -1798,7 +1921,7 @@ issue_805_1: {
issue_805_2: {
options = {
inline: true,
passes: 2,
passes: 3,
pure_getters: "strict",
reduce_vars: true,
sequences: true,
@@ -2345,7 +2468,7 @@ function_argument_reference: {
function_parameter_ie8: {
options = {
ie8: true,
ie: true,
reduce_vars: true,
unused: true,
}
@@ -2371,6 +2494,7 @@ function_parameter_ie8: {
issue_3664: {
options = {
pure_getters: "strict",
side_effects: true,
unused: true,
}
input: {
@@ -2381,7 +2505,8 @@ issue_3664: {
}
expect: {
console.log(function() {
var b = ([ b && console.log("FAIL") ].p = 0, 0);
a = (a = [ b && console.log("FAIL") ]).p = 0;
var a, b = 0;
return "PASS";
}());
}
@@ -2391,6 +2516,7 @@ issue_3664: {
issue_3673: {
options = {
pure_getters: "strict",
sequences: true,
side_effects: true,
toplevel: true,
unused: true,
@@ -2401,8 +2527,6 @@ issue_3673: {
console.log("PASS");
}
expect: {
var a;
(a = [ a ]).p = 42;
console.log("PASS");
}
expect_stdout: "PASS"
@@ -2551,10 +2675,9 @@ issue_3899: {
console.log(typeof a);
}
expect: {
function a() {
console.log(typeof function() {
return 2;
}
console.log(typeof a);
});
}
expect_stdout: "function"
}
@@ -2652,7 +2775,7 @@ issue_3956: {
collapse_vars: true,
evaluate: true,
inline: true,
passes: 2,
passes: 3,
reduce_vars: true,
sequences: true,
side_effects: true,
@@ -2783,7 +2906,7 @@ issue_3986: {
expect_stdout: "0"
}
issue_4017: {
issue_4017_1: {
options = {
pure_getters: "strict",
reduce_vars: true,
@@ -2801,7 +2924,31 @@ issue_4017: {
var a = 0;
console.log(function() {
c &= 0;
var c;
var c = a++ + (A = a);
}());
}
expect_stdout: "undefined"
}
issue_4017_2: {
options = {
passes: 2,
pure_getters: "strict",
reduce_vars: true,
unused: true,
}
input: {
var a = 0;
console.log(function f() {
var b = c &= 0;
var c = a++ + (A = a);
var d = c && c[f];
}());
}
expect: {
var a = 0;
console.log(function() {
0;
a++,
A = a;
}());
@@ -2829,14 +2976,12 @@ issue_4025: {
console.log(a, b, d);
}
expect: {
var c = 0;
try {
console.log(c);
console.log(0);
} finally {
var d = c + 1;
c = 0;
0;
}
console.log(1, 1, d);
console.log(1, 1, 1);
}
expect_stdout: [
"0",
@@ -2916,7 +3061,7 @@ issue_4133: {
console.log(a);
}
expect: {
var b = 1;
var a = 1;
console.log(0);
}
expect_stdout: "0"
@@ -3062,7 +3207,7 @@ issue_4184: {
expect_stdout: "42"
}
issue_4235: {
issue_4235_1: {
options = {
inline: true,
reduce_vars: true,
@@ -3080,12 +3225,35 @@ issue_4235: {
})();
}
expect: {
void function() {
var f = console.log(f);
}();
}
expect_stdout: "undefined"
}
issue_4235_2: {
options = {
inline: true,
passes: 2,
reduce_vars: true,
side_effects: true,
unused: true,
varify: true,
}
input: {
(function() {
f = console.log(f),
void 0;
var f;
{
const f = 0;
}
(function f() {
var f = console.log(f);
})();
})();
}
expect: {
console.log(void 0);
}
expect_stdout: "undefined"
}
@@ -3221,7 +3389,7 @@ issue_4558_1: {
expect: {
var a = 0;
var b = c >>>= a;
var c;
var c = 0;
b && a++,
console.log(a);
}
@@ -3231,7 +3399,7 @@ issue_4558_1: {
issue_4558_2: {
options = {
evaluate: true,
ie8: true,
ie: true,
reduce_vars: true,
unused: true,
}
@@ -3251,3 +3419,398 @@ issue_4558_2: {
}
expect_stdout: "PASS"
}
issue_4662: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = 0;
function f(b, c) {
console.log(b, c);
}
f(++a, a = a, a);
}
expect: {
var a = 0;
(function(b, c) {
console.log(b, c);
})(++a, a = 1);
}
expect_stdout: "1 1"
}
issue_4806_1: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
O = {
f: function() {
console.log(this === O ? "FAIL" : "PASS");
},
};
var a;
(a = 42, O.f)();
a;
}
expect: {
O = {
f: function() {
console.log(this === O ? "FAIL" : "PASS");
},
};
(0, O.f)();
42;
}
expect_stdout: "PASS"
}
issue_4806_2: {
options = {
sequences: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
O = {
f: function() {
console.log(this === O ? "FAIL" : "PASS");
},
};
var a;
(a = 42, O.f)();
a;
}
expect: {
O = {
f: function() {
console.log(this === O ? "FAIL" : "PASS");
},
},
(0, O.f)();
}
expect_stdout: "PASS"
}
issue_4806_3: {
options = {
side_effects: true,
toplevel: true,
unused: true,
}
input: {
O = {
f: function() {
console.log(this === O ? "FAIL" : "PASS");
},
};
var a;
(a = 42, O.f)();
a;
}
expect: {
O = {
f: function() {
console.log(this === O ? "FAIL" : "PASS");
},
};
(0, O.f)();
}
expect_stdout: "PASS"
}
issue_4834: {
options = {
inline: true,
keep_fargs: false,
pure_getters: "strict",
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
try {
new function(a, b) {
b;
b.p;
}(42);
} catch (e) {
console.log("PASS");
}
}
expect: {
try {
b.p;
} catch (e) {
console.log("PASS");
}
var b;
}
expect_stdout: "PASS"
}
issue_4912_1: {
options = {
pure_getters: "strict",
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = A = function() {};
A;
a.prototype = {
f: function() {
console.log("PASS");
},
};
new A().f();
}
expect: {
var a = A = function() {};
A;
a.prototype = {
f: function() {
console.log("PASS");
},
};
new A().f();
}
expect_stdout: "PASS"
}
issue_4912_2: {
options = {
pure_getters: "strict",
unused: true,
}
input: {
console.log(function() {
var g, f = function() {};
f.p = {};
(g = f.p.q = function() {}).r = "PASS";
return f;
}().p.q.r);
}
expect: {
console.log(function() {
var g, f = function() {};
f.p = {};
(f.p.q = function() {}).r = "PASS";
return f;
}().p.q.r);
}
expect_stdout: "PASS"
}
issue_4912_3: {
options = {
pure_getters: "strict",
reduce_vars: true,
side_effects: true,
unused: true,
}
input: {
console.log(function(f, g) {
f = function() {};
f.p = {};
g = f.p.q = function() {};
g.r = "PASS";
return f;
}().p.q.r);
}
expect: {
console.log(function(f, g) {
f = function() {};
f.p = {};
g = f.p.q = function() {};
g.r = "PASS";
return f;
}().p.q.r);
}
expect_stdout: "PASS"
}
issue_5079: {
options = {
collapse_vars: true,
pure_getters: "strict",
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a;
do {
(a = 123456).p = a;
a.q = null;
} while (console.log("PASS"));
}
expect: {
do {
0, 0, null;
} while (console.log("PASS"));
}
expect_stdout: "PASS"
}
issue_5224: {
options = {
evaluate: true,
keep_fargs: false,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
function f() {
try {
var b = function() {
var a = "FAIL 1";
null && a;
a = console.log(a);
}(new function(c, d) {
console.log(d);
a;
}("FAIL 2", Infinity));
} finally {
return f;
}
}
f();
}
expect: {
(function f() {
try {
(function() {
var a = "FAIL 1";
null;
console.log(a);
})(function() {
console.log(1 / 0);
a;
}());
} finally {
return f;
}
})();
}
expect_stdout: "Infinity"
}
issue_5271: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
function f() {
do {
var a = b = 0 ^ f, b = b;
} while (console.log(42 - b));
}
f();
}
expect: {
(function f() {
do {
var b;
b = 0 ^ f;
} while (console.log(42 - b));
})();
}
expect_stdout: "42"
}
issue_5533_keep_fargs: {
options = {
evaluate: true,
inline: true,
join_vars: true,
keep_fargs: true,
loops: true,
side_effects: true,
unused: true,
}
input: {
"use strict";
try {
(function() {
var a;
for (; 1;)
a = function() {
(function f(b) {
b;
throw "PASS";
})();
}();
})();
} catch (e) {
console.log(e);
}
}
expect: {
"use strict";
try {
(function() {
for (;;)
throw "PASS";
})();
} catch (e) {
console.log(e);
}
}
expect_stdout: "PASS"
}
issue_5533_drop_fargs: {
options = {
evaluate: true,
inline: true,
join_vars: true,
keep_fargs: false,
loops: true,
side_effects: true,
unused: true,
}
input: {
"use strict";
try {
(function() {
var a;
for (; 1;)
a = function() {
(function f(b) {
b;
throw "PASS";
})();
}();
})();
} catch (e) {
console.log(e);
}
}
expect: {
"use strict";
try {
(function() {
for (;;)
throw "PASS";
})();
} catch (e) {
console.log(e);
}
}
expect_stdout: "PASS"
}

View File

@@ -399,18 +399,18 @@ unsafe_object_accessor: {
function f() {
var a = {
get b() {},
set b() {}
set b(v) {},
};
return {a:a};
return { a: a };
}
}
expect: {
function f() {
var a = {
get b() {},
set b() {}
set b(v) {},
};
return {a:a};
return { a: a };
}
}
}
@@ -684,25 +684,47 @@ prototype_function: {
side_effects: true,
}
input: {
var a = ({valueOf: 0}) < 1;
var b = ({toString: 0}) < 1;
var c = ({valueOf: 0}) + "";
var d = ({toString: 0}) + "";
var e = (({valueOf: 0}) + "")[2];
var f = (({toString: 0}) + "")[2];
var g = ({valueOf: 0}).valueOf();
var h = ({toString: 0}).toString();
function v() {
return this.valueOf === v ? "PASS" : "FAIL";
}
console.log(({ valueOf: v }) < 1);
console.log(({ valueOf: v }) + "");
console.log((( {valueOf: v }) + "")[2]);
console.log(({ valueOf: v }).valueOf());
function t() {
return this.toString === t ? "PASS" : "FAIL";
}
console.log(({ toString: t }) < 1);
console.log(({ toString: t }) + "");
console.log((( {toString: t }) + "")[2]);
console.log(({ toString: t }).toString());
}
expect: {
var a = ({valueOf: 0}) < 1;
var b = ({toString: 0}) < 1;
var c = ({valueOf: 0}) + "";
var d = ({toString: 0}) + "";
var e = (({valueOf: 0}) + "")[2];
var f = (({toString: 0}) + "")[2];
var g = 0();
var h = 0();
function v() {
return this.valueOf === v ? "PASS" : "FAIL";
}
console.log(({ valueOf: v }) < 1);
console.log(({ valueOf: v }) + "");
console.log((( {valueOf: v }) + "")[2]);
console.log(({ valueOf: v }).valueOf());
function t() {
return this.toString === t ? "PASS" : "FAIL";
}
console.log(({ toString: t }) < 1);
console.log(({ toString: t }) + "");
console.log((( {toString: t }) + "")[2]);
console.log(({ toString: t }).toString());
}
expect_stdout: [
"false",
"PASS",
"S",
"PASS",
"false",
"PASS",
"S",
"PASS",
]
}
call_args: {
@@ -723,7 +745,7 @@ call_args: {
expect: {
var a = 1;
console.log(1);
+(1, 1);
1, 1;
}
expect_stdout: true
}
@@ -747,7 +769,7 @@ call_args_drop_param: {
}
expect: {
console.log(1);
+(b, 1);
b, 1;
}
expect_stdout: true
}
@@ -846,6 +868,8 @@ unsafe_charAt_noop: {
unsafe: true,
}
input: {
s = "foo";
x = 42;
console.log(
s.charAt(0),
"string".charAt(x),
@@ -853,12 +877,48 @@ unsafe_charAt_noop: {
);
}
expect: {
s = "foo";
x = 42;
console.log(
s[0],
"string"[0 | x],
(typeof x)[0]
s[0] || "",
"string"[0 | x] || "",
(typeof x)[0] || ""
);
}
expect_stdout: "f n"
}
chained_side_effects: {
options = {
evaluate: true,
}
input: {
console.log("foo") || (console.log("bar"), "baz") || console.log("moo");
}
expect: {
console.log("foo") || (console.log("bar"), "baz");
}
expect_stdout: [
"foo",
"bar",
]
expect_warnings: [
"WARN: Condition left of || always true [test/compress/evaluate.js:1,8]",
]
}
instanceof_lambda: {
options = {
evaluate: true,
side_effects: true,
}
input: {
console.log(42 instanceof function() {});
}
expect: {
console.log(false);
}
expect_stdout: "false"
}
issue_1649: {
@@ -2725,8 +2785,7 @@ issue_3944: {
}
expect: {
void function f() {
while (a = 0 == (a = void 0), console.log(a), void 0);
var a;
while (0 == void 0, console.log(false), void 0);
f;
}();
}
@@ -2800,7 +2859,7 @@ operator_in: {
console.log("PASS" in { });
console.log("FAIL" in { });
console.log("toString" in { });
console.log(true);
console.log("toString" in { toString: 3 });
}
expect_stdout: [
"true",
@@ -3175,3 +3234,185 @@ issue_4552: {
}
expect_stdout: "NaN"
}
issue_4886_1: {
options = {
evaluate: true,
unsafe: true,
}
input: {
console.log("length" in {
__proto__: function() {},
length: void 0,
});
}
expect: {
console.log("length" in {
__proto__: function() {},
length: void 0,
});
}
expect_stdout: "true"
}
issue_4886_2: {
options = {
evaluate: true,
unsafe: true,
}
input: {
console.log("foo" in {
"foo": null,
__proto__: 42,
});
}
expect: {
console.log("foo" in {
"foo": null,
__proto__: 42,
});
}
expect_stdout: "true"
}
issue_5354: {
options = {
evaluate: true,
unsafe: true,
}
input: {
function f(a) {
return +a.toExponential(1);
}
function g(b) {
return 0 + b.toFixed(2);
}
function h(c) {
return 1 * c.toPrecision(3);
}
console.log(typeof f(45), typeof g(67), typeof h(89));
}
expect: {
function f(a) {
return +a.toExponential(1);
}
function g(b) {
return 0 + b.toFixed(2);
}
function h(c) {
return +c.toPrecision(3);
}
console.log(typeof f(45), typeof g(67), typeof h(89));
}
expect_stdout: "number string number"
}
issue_5356: {
options = {
evaluate: true,
inline: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
console.log(function() {
return a++;
var a = a;
}());
}
expect: {
console.log(+a);
var a;
}
expect_stdout: "NaN"
}
issue_5362_1: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
}
input: {
var a = -console;
console.log(delete +a);
}
expect: {
var a = -console;
console.log((+a, true));
}
expect_stdout: "true"
}
issue_5362_2: {
options = {
evaluate: true,
reduce_vars: true,
side_effects: true,
toplevel: true,
unsafe: true,
unused: true,
}
input: {
var a = -console;
console.log(delete +a);
}
expect: {
console.log(true);
}
expect_stdout: "true"
}
issue_5380: {
options = {
evaluate: true,
keep_fnames: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = function f(b) {
return function g() {
for (b in { PASS: 42 });
}(), b;
}("FAIL");
console.log(a);
}
expect: {
var a = function f(b) {
return function g() {
for (b in { PASS: 42 });
}(), b;
}("FAIL");
console.log(a);
}
expect_stdout: "PASS"
}
issue_5558: {
options = {
collapse_vars: true,
evaluate: true,
reduce_vars: true,
sequences: true,
toplevel: true,
}
input: {
var a = 99, b = 0;
a++;
b++;
b += a;
b *= a;
b += a;
console.log(a);
}
expect: {
var a = 99, b = 0;
b++,
b = (b += ++a) * a + a,
console.log(a);
}
expect_stdout: "100"
}

View File

@@ -43,6 +43,28 @@ await: {
node_version: ">=8"
}
assignment_1: {
input: {
var a = 2;
a **= 5;
console.log(a);
}
expect_exact: "var a=2;a**=5;console.log(a);"
expect_stdout: "32"
node_version: ">=8"
}
assignment_2: {
input: {
var a = 8n;
a **= a;
console.log(a);
}
expect_exact: "var a=8n;a**=a;console.log(a);"
expect_stdout: "16777216n"
node_version: ">=10.4.0"
}
evaluate: {
options = {
evaluate: true,
@@ -56,3 +78,70 @@ evaluate: {
expect_stdout: "5"
node_version: ">=8"
}
issue_4664: {
options = {
collapse_vars: true,
evaluate: true,
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
function f() {
new function(a) {
console.log(typeof f, a, typeof this);
}((A = 0, (NaN ^ 1) * 2 ** 30), 0);
}
f();
}
expect: {
(function f() {
new function(a) {
console.log(typeof f, 2 ** 30, typeof this);
}(A = 0);
})();
}
expect_stdout: "function 1073741824 object"
node_version: ">=8"
}
issue_4715: {
options = {
evaluate: true,
}
input: {
A = 1;
console.log((-0) ** A + 0);
console.log((-0) ** A - 0);
console.log((-0) ** A * 1);
console.log((-0) ** A / 1);
console.log(Math.pow(-0, A) + 0);
console.log(Math.pow(-0, A) - 0);
console.log(Math.pow(-0, A) * 1);
console.log(Math.pow(-0, A) / 1);
}
expect: {
A = 1;
console.log((-0) ** A + 0);
console.log((-0) ** A);
console.log((-0) ** A * 1);
console.log((-0) ** A);
console.log(Math.pow(-0, A) + 0);
console.log(+Math.pow(-0, A));
console.log(+Math.pow(-0, A));
console.log(+Math.pow(-0, A));
}
expect_stdout: [
"0",
"-0",
"-0",
"-0",
"0",
"-0",
"-0",
"-0",
]
node_version: ">=8"
}

582
test/compress/exports.js Normal file
View File

@@ -0,0 +1,582 @@
refs: {
input: {
export {};
export { a, b as B, c as case, d as default };
}
expect_exact: "export{};export{a,b as B,c as case,d as default};"
}
var_defs: {
input: {
export const a = 1;
export let b = 2, c = 3;
export var { d, e: [] } = f;
}
expect_exact: "export const a=1;export let b=2,c=3;export var{d,e:[]}=f;"
}
defuns: {
input: {
export class A {}
export function e() {}
export function* f(a) {}
export async function g(b, c) {}
export async function* h({}, ...[]) {}
}
expect_exact: "export class A{}export function e(){}export function*f(a){}export async function g(b,c){}export async function*h({},...[]){}"
}
defaults: {
input: {
export default 42;
export default async;
export default (x, y) => x * x;
export default class {};
export default function*(a, b) {};
export default async function f({ c }, ...[ d ]) {};
}
expect_exact: "export default 42;export default async;export default(x,y)=>x*x;export default class{}export default function*(a,b){}export default async function f({c},...[d]){}"
}
defaults_parentheses_1: {
input: {
export default function() {
console.log("FAIL");
}(console.log("PASS"));
}
expect_exact: 'export default function(){console.log("FAIL")}console.log("PASS");'
}
defaults_parentheses_2: {
input: {
export default (async function() {
console.log("PASS");
})();
}
expect_exact: 'export default(async function(){console.log("PASS")})();'
}
defaults_parentheses_3: {
input: {
export default (42, "PASS");
}
expect_exact: 'export default(42,"PASS");'
}
defaults_parentheses_4: {
input: {
export default (function f() {});
}
expect_exact: "export default(function f(){});"
}
defaults_parentheses_5: {
input: {
export default (function(a) {
console.log(a[0]);
}`PASS`);
}
expect_exact: "export default(function(a){console.log(a[0])})`PASS`;"
}
defaults_parentheses_6: {
options = {
conditionals: true,
}
input: {
export default !function() {
while (!console);
}() ? "PASS" : "FAIL";
}
expect_exact: 'export default(function(){while(!console);})()?"FAIL":"PASS";'
}
defaults_regexp: {
input: {
export default /foo/;
}
expect_exact: "export default/foo/;"
}
foreign: {
input: {
export * from "foo";
export {} from "bar";
export * as a from "baz";
export { default } from "moo";
export { b, c as case, default as delete, d } from "moz";
}
expect_exact: 'export*from"foo";export{}from"bar";export*as a from"baz";export{default}from"moo";export{b,c as case,default as delete,d}from"moz";'
}
non_identifiers: {
beautify = {
quote_style: 3,
}
input: {
export * as "42" from 'foo';
export { '42', "delete" as 'foo' } from "bar";
}
expect_exact: "export*as\"42\"from'foo';export{'42',delete as foo}from\"bar\";"
}
same_quotes: {
beautify = {
beautify: true,
quote_style: 3,
}
input: {
export * from 'foo';
export {} from "bar";
}
expect_exact: [
"export * from 'foo';",
"",
'export {} from "bar";',
]
}
drop_unused: {
options = {
toplevel: true,
unused: true,
}
input: {
export default 42;
export default (x, y) => x * x;
export default class A extends B { get p() { h() } }
export default function*(a, b) {}
export default async function f({ c }, ...[ d ]) {}
export var e;
export function g(x, [ y ], ...z) {}
function h() {}
}
expect: {
export default 42;
export default (x, y) => x * x;
export default class extends B { get p() { h() } }
export default function*(a, b) {}
export default async function({}) {}
export var e;
export function g(x, []) {}
function h() {}
}
}
mangle: {
rename = false
mangle = {
toplevel: true,
}
input: {
const a = 42;
export let b, { foo: c } = a;
export function f(d, { [b]: e }) {
d(e, f);
}
export default a;
export default async function g(x, ...{ [c]: y }) {
(await x)(g, y);
}
}
expect: {
const t = 42;
export let b, { foo: c } = t;
export function f(t, { [b]: o }) {
t(o, f);
}
export default t;
export default async function e(t, ...{ [c]: o}) {
(await t)(e, o);
}
}
}
mangle_rename: {
rename = true
mangle = {
toplevel: true,
}
input: {
const a = 42;
export let b, { foo: c } = a;
export function f(d, { [b]: e }) {
d(e, f);
}
export default a;
export default async function g(x, ...{ [c]: y }) {
(await x)(g, y);
}
}
expect: {
const t = 42;
export let b, { foo: c } = t;
export function f(t, { [b]: o }) {
t(o, f);
}
export default t;
export default async function e(t, ...{ [c]: o}) {
(await t)(e, o);
}
}
}
hoist_exports_1: {
options = {
hoist_exports: true,
}
input: {
export { a };
export var b;
export function f() {}
}
expect: {
var b;
function f() {}
export { a, b, f };
}
}
hoist_exports_2: {
options = {
evaluate: true,
hoist_exports: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
mangle = {
toplevel: true,
}
input: {
const a = 42;
export let bbb, { foo: ccc } = a;
export function fff(d, { [bbb]: e }) {
d(e, fff);
}
export default a;
export default async function g(x, ...{ [ccc]: y }) {
(await x)(g, y);
}
}
expect: {
let e, a = 42..foo;
function f(t, { [e]: o }) {
t(o, f);
}
export default 42;
export default async function n(t, ...{ [a]: o }) {
(await t)(n, o);
};
export { e as bbb, a as ccc, f as fff };
}
}
hoist_vars: {
options = {
hoist_vars: true,
}
input: {
var a;
export var b = 42;
}
expect: {
var a;
export var b = 42;
}
}
keep_return_values: {
options = {
booleans: true,
evaluate: true,
reduce_vars: true,
toplevel: true,
}
input: {
export default function() {
return [];
}
export default function f() {
return null;
}
}
expect: {
export default function() {
return [];
}
export default function f() {
return null;
}
}
}
in_use: {
options = {
pure_getters: "strict",
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
export function f() {}
f.prototype.p = 42;
}
expect: {
export function f() {}
f.prototype.p = 42;
}
}
in_use_default: {
options = {
pure_getters: "strict",
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
export default function f() {}
f.prototype.p = 42;
}
expect: {
export default function f() {}
f.prototype.p = 42;
}
}
single_use: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
export function f() {
console.log("PASS");
}
f();
}
expect: {
export function f() {
console.log("PASS");
}
f();
}
}
single_use_default: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
export default function f() {
console.log("PASS");
}
f();
}
expect: {
export default function f() {
console.log("PASS");
}
f();
}
}
single_use_class: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
export class A {}
A.prototype.p = "PASS";
}
expect: {
export class A {}
A.prototype.p = "PASS";
}
}
single_use_class_default: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
export default class A {}
A.prototype.p = "PASS";
}
expect: {
export default class A {}
A.prototype.p = "PASS";
}
}
hoist_funs: {
options = {
hoist_funs: true,
}
input: {
export function f() {}
export default async function* g() {}
}
expect_exact: "export function f(){}export default async function*g(){}"
}
instanceof_default_class: {
options = {
toplevel: true,
unused: true,
}
input: {
export default class A {
f(a) {
return a instanceof A;
}
}
}
expect: {
export default class A {
f(a) {
return a instanceof A;
}
}
}
}
instanceof_default_function: {
options = {
toplevel: true,
unused: true,
}
input: {
export default function f() {
if (!(this instanceof f))
throw new Error("must instantiate");
}
}
expect: {
export default function f() {
if (!(this instanceof f))
throw new Error("must instantiate");
}
}
}
issue_4742_join_vars_1: {
options = {
join_vars: true,
}
input: {
var a = 42;
export var a;
}
expect: {
var a = 42;
export var a;
}
}
issue_4742_join_vars_2: {
options = {
join_vars: true,
}
input: {
export var a = "foo";
var b;
b = "bar";
}
expect: {
export var a = "foo";
var b, b = "bar";
}
}
issue_4742_unused_1: {
options = {
unused: true,
}
input: {
var a = 42;
export var a;
}
expect: {
var a = 42;
export var a;
}
}
issue_4742_unused_2: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
export var a = "foo";
var a = "bar";
}
expect: {
export var a = "foo";
a = "bar";
}
}
issue_4761: {
input: {
export default "function" == 42;
}
expect_exact: 'export default"function"==42;'
}
issue_4766: {
options = {
unused: true,
}
input: {
var a = "foo";
export var a = "bar";
}
expect: {
var a = "foo";
export var a = "bar";
}
}
issue_5444: {
options = {
unused: true,
}
input: {
export var a = (console, console);
}
expect: {
console;
export var a = console;
}
}
issue_5628: {
options = {
unused: true,
}
input: {
var a;
export default function f() {
for (a in 42);
}
console.log(a);
}
expect: {
var a;
export default function f() {
for (a in 42);
}
console.log(a);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -217,7 +217,8 @@ name_collision_1: {
var obj_foo = 1;
var obj_bar = 2;
function f() {
var obj_foo$0 = 3,
var obj,
obj_foo$0 = 3,
obj_bar = 4,
obj_b_r = 5,
obj_b_r$0 = 6,
@@ -249,7 +250,8 @@ name_collision_2: {
console.log(o.p === o.p, o["+"](4), o["-"](5), o__$0, o__$1);
}
expect: {
var o_p = 1,
var o,
o_p = 1,
o__ = function(x) {
return x;
},
@@ -283,7 +285,8 @@ name_collision_3: {
console.log(o.p === o.p, o["+"](4), o["-"](5));
}
expect: {
var o_p = 1,
var o,
o_p = 1,
o__ = function(x) {
return x;
},
@@ -315,7 +318,7 @@ name_collision_4: {
}
expect: {
console.log(function() {
var o_p$0 = 0, o_q = "PASS";
var o, o_p$0 = 0, o_q = "PASS";
return function(o_p) {
if (!o_p$0) return o_p;
}(o_q);
@@ -459,6 +462,11 @@ issue_2473_1: {
var x = {};
var y = [];
}
expect_warnings: [
"INFO: Retaining variable x",
"INFO: Retaining variable y",
"WARN: Dropping unused variable z [test/compress/hoist_props.js:3,12]",
]
}
issue_2473_2: {
@@ -481,6 +489,11 @@ issue_2473_2: {
var x = {};
var y = [];
}
expect_warnings: [
"INFO: Retaining variable x",
"INFO: Retaining variable y",
"WARN: Dropping unused variable z [test/compress/hoist_props.js:3,12]",
]
}
issue_2473_3: {
@@ -506,6 +519,9 @@ issue_2473_3: {
console.log(o.a, o.b);
}
expect_stdout: "1 2"
expect_warnings: [
"INFO: Retaining variable o",
]
}
issue_2473_4: {
@@ -532,6 +548,9 @@ issue_2473_4: {
})();
}
expect_stdout: "1 2"
expect_warnings: [
"INFO: Dropping unused variable o [test/compress/hoist_props.js:2,16]",
]
}
issue_2508_1: {
@@ -768,7 +787,7 @@ issue_3046: {
expect: {
console.log(function(a) {
do {
var b_c = a++;
var b, b_c = a++;
} while (b_c && a);
return a;
}(0));
@@ -777,6 +796,32 @@ issue_3046: {
}
issue_3071_1: {
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() {
var obj = {};
obj.one = 1;
obj.two = 2;
console.log(obj.one, obj.two);
})();
}
expect: {
console.log(1, 2);
}
expect_stdout: "1 2"
}
issue_3071_1_toplevel: {
options = {
evaluate: true,
hoist_props: true,
@@ -905,7 +950,7 @@ issue_3411: {
expect: {
var c = 1;
!function f() {
var o_p = --c && f();
var o, o_p = --c && f();
+{} || console.log("PASS");
}();
}
@@ -1016,9 +1061,7 @@ issue_3945_1: {
expect: {
function f() {
o.p;
var o = {
q: 0,
};
var o, o_q = 0;
}
}
}
@@ -1037,9 +1080,7 @@ issue_3945_2: {
}
expect: {
console.log(typeof o);
var o = {
p: 0,
};
var o, o_p = 0;
}
expect_stdout: "undefined"
}
@@ -1068,3 +1109,134 @@ issue_4023: {
}
expect_stdout: "true"
}
object_super: {
options = {
hoist_props: true,
reduce_vars: true,
toplevel: true,
}
input: {
var o = {
f(a) {
return a ? console.log("PASS") : super.log("PASS");
},
};
o.f(42);
}
expect: {
var o = {
f(a) {
return a ? console.log("PASS") : super.log("PASS");
},
};
o.f(42);
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_4985: {
options = {
hoist_props: true,
reduce_vars: true,
toplevel: true,
}
input: {
var a = { p: 42 };
console.log(function() {
a;
}());
}
expect: {
var a, a_p = 42;
console.log(function() {
({});
}());
}
expect_stdout: "undefined"
}
issue_5182: {
options = {
hoist_props: true,
merge_vars: true,
passes: 2,
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var o = console;
log = o.log;
o = {
p: function(a) {
console.log(a ? "PASS" : "FAIL");
return a;
},
};
log(o.p(42));
}
expect: {
var o = console;
log = o.log;
o = function(a) {
console.log(a ? "PASS" : "FAIL");
return a;
};
log(o(42));
}
expect_stdout: [
"PASS",
"42",
]
}
issue_5441: {
options = {
hoist_props: true,
passes: 2,
reduce_vars: true,
side_effects: true,
}
input: {
console.log(function(a) {
(function() {
a = { p: this };
})();
return typeof a;
}());
}
expect: {
console.log(function(a) {
(function() {
a_p = this;
})();
var a_p;
return typeof {};
}());
}
expect_stdout: "object"
}
issue_5498: {
options = {
hoist_props: true,
reduce_vars: true,
toplevel: true,
}
input: {
var o = {
__proto__: 42,
};
while (console.log(typeof o.__proto__));
}
expect: {
var o = {
__proto__: 42,
};
while (console.log(typeof o.__proto__));
}
expect_stdout: "object"
}

View File

@@ -2,6 +2,8 @@ statements: {
options = {
hoist_funs: false,
hoist_vars: true,
join_vars: true,
unused: true,
}
input: {
function f() {
@@ -25,6 +27,8 @@ statements_funs: {
options = {
hoist_funs: true,
hoist_vars: true,
join_vars: true,
unused: true,
}
input: {
function f() {
@@ -48,6 +52,8 @@ sequences: {
options = {
hoist_funs: false,
hoist_vars: true,
join_vars: true,
unused: true,
}
input: {
function f() {
@@ -71,6 +77,8 @@ sequences_funs: {
options = {
hoist_funs: true,
hoist_vars: true,
join_vars: true,
unused: true,
}
input: {
function f() {
@@ -108,7 +116,8 @@ catch_var: {
console.log(a);
}
expect: {
var a = "PASS";
a = "PASS";
var a;
console.log(a);
}
expect_stdout: "PASS"
@@ -118,6 +127,8 @@ issue_2295: {
options = {
collapse_vars: true,
hoist_vars: true,
join_vars: true,
unused: true,
}
input: {
function foo(o) {
@@ -135,10 +146,11 @@ issue_2295: {
}
}
issue_4487: {
issue_4487_1: {
options = {
functions: true,
hoist_vars: true,
join_vars: true,
keep_fnames: true,
reduce_vars: true,
toplevel: true,
@@ -150,21 +162,73 @@ issue_4487: {
};
var b = a();
}
expect: {
var a = function f() {
var f = console.log(typeof f);
};
a();
}
expect_stdout: "undefined"
}
issue_4487_2: {
options = {
functions: true,
hoist_vars: true,
join_vars: true,
keep_fnames: true,
passes: 2,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = function f() {
var f = console.log(typeof f);
};
var b = a();
}
expect: {
function a() {
var a = console.log(typeof a);
var f = console.log(typeof f);
}
a();
}
expect_stdout: "undefined"
}
issue_4487_3: {
options = {
functions: true,
hoist_vars: true,
join_vars: true,
keep_fnames: true,
passes: 3,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = function f() {
var f = console.log(typeof f);
};
var b = a();
}
expect: {
(function a() {
console.log(typeof void 0);
})();
}
expect_stdout: "undefined"
}
issue_4489: {
options = {
collapse_vars: true,
evaluate: true,
hoist_vars: true,
reduce_vars: true,
sequences: true,
toplevel: true,
unused: true,
}
@@ -175,8 +239,7 @@ issue_4489: {
console.log(k);
}
expect: {
!(A = 0);
for (var k in true);
for (var k in !(A = 0));
console.log(k);
}
expect_stdout: "undefined"
@@ -200,10 +263,541 @@ issue_4517: {
}
expect: {
console.log(function() {
var a = 2;
A = a;
return A + typeof !1;
return (A = 2) + typeof !1;
}());
}
expect_stdout: "2boolean"
}
issue_4736: {
options = {
collapse_vars: true,
evaluate: true,
hoist_vars: true,
join_vars: true,
merge_vars: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a;
function f() {
(function g() {
var b = (a = 0, 1 << 30);
var c = (a = 0, console.log(b));
var d = c;
})(f);
}
f();
}
expect: {
(function() {
(function() {
0;
console.log(1 << 30);
})();
})();
}
expect_stdout: "1073741824"
}
issue_4839: {
options = {
evaluate: true,
hoist_vars: true,
join_vars: true,
keep_fargs: false,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var log = console.log, o = function(a, b) {
return b && b;
}("foo");
for (var k in o)
throw "FAIL";
log("PASS");
}
expect: {
var k, log = console.log;
for (k in void 0)
throw "FAIL";
log("PASS");
}
expect_stdout: "PASS"
}
issue_4859: {
options = {
evaluate: true,
hoist_vars: true,
join_vars: true,
keep_infinity: true,
merge_vars: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
function f(a) {
var b = (a = 2, 1 / 0), c = 3;
var d = a + b;
console.log(d);
return f;
}
f();
}
expect: {
(function f(a) {
console.log(2 + 1 / 0);
return f;
})();
}
expect_stdout: "Infinity"
}
issue_4893_1: {
options = {
collapse_vars: true,
evaluate: true,
hoist_vars: true,
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
function f() {
function g() {}
var a = null;
var b = null;
var c = null;
b.p += a = 42;
f;
}
try {
f();
} catch (e) {
console.log("PASS");
}
}
expect: {
try{
(function() {
null.p += 42;
})();
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "PASS"
}
issue_4893_2: {
options = {
collapse_vars: true,
hoist_vars: true,
pure_getters: "strict",
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
function f() {
function g() {}
var a = null;
var b = null;
var c = null;
b.p += a = 42;
f;
}
try {
f();
} catch (e) {
console.log("PASS");
}
}
expect: {
try{
(function() {
null.p += 42;
})();
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "PASS"
}
issue_4898: {
options = {
collapse_vars: true,
evaluate: true,
hoist_vars: true,
loops: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
do {
var b = [ console.log("PASS") ];
var c = b;
} while (c.p = 0);
}
expect: {
var b;
b = [ console.log("PASS") ];
b.p = 0;
}
expect_stdout: "PASS"
}
issue_5187_1: {
options = {
hoist_props: true,
hoist_vars: true,
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
function f() {
var a = 42;
do {
var b = { 0: a++ };
} while (console.log(b[b ^= 0]));
}
f();
}
expect: {
(function() {
var a, b;
a = 42;
do {
b = { 0: a++ };
} while (console.log(b[b ^= 0]));
})();
}
expect_stdout: "42"
}
issue_5187_2: {
options = {
hoist_props: true,
hoist_vars: true,
join_vars: true,
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
function f() {
var a = 42;
do {
var b = { 0: a++ };
} while (console.log(b[b ^= 0]));
}
f();
}
expect: {
(function() {
var b, a = 42;
do {
b = { 0: a++ };
} while (console.log(b[b ^= 0]));
})();
}
expect_stdout: "42"
}
issue_5195: {
options = {
hoist_props: true,
hoist_vars: true,
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
function f() {
var a;
do {
var b = { p: a };
} while (console.log(b += ""));
}
f();
}
expect: {
(function() {
var a, b;
do {
b = { p: a };
} while (console.log(b += ""));
})();
}
expect_stdout: "[object Object]"
}
issue_5378: {
options = {
hoist_vars: true,
inline: true,
toplevel: true,
}
input: {
var a = 2;
while (a--)
(function() {
var b;
var c;
while (console.log(b));
--b;
})();
}
expect: {
var a = 2;
while (a--) {
b = void 0;
var b, c;
while (console.log(b));
--b;
}
}
expect_stdout: [
"undefined",
"undefined",
]
}
issue_5411_1: {
options = {
collapse_vars: true,
dead_code: true,
hoist_vars: true,
reduce_vars: true,
side_effects: true,
toplevel: true,
}
input: {
var a = "PASS";
b++;
b = a;
var b = b, c = c && c[b];
console.log(b);
}
expect: {
var a, b, c;
b++;
b = a = "PASS";
c = c && c[b];
console.log(b);
}
expect_stdout: "PASS"
}
issue_5411_2: {
options = {
collapse_vars: true,
dead_code: true,
evaluate: true,
hoist_vars: true,
reduce_vars: true,
sequences: true,
toplevel: true,
unused: true,
}
input: {
var a = "PASS";
b++;
b = a;
var b = b, c = c && c[b];
console.log(b);
}
expect: {
var b, c;
b++,
b = "PASS",
c,
console.log(b);
}
expect_stdout: "PASS"
}
issue_5411_3: {
options = {
collapse_vars: true,
hoist_vars: true,
reduce_vars: true,
toplevel: true,
}
input: {
var a = console;
a++;
var a = A = a;
console.log(A);
}
expect: {
var a;
a = console;
a = A = ++a;
console.log(A);
}
expect_stdout: "NaN"
}
issue_5411_4: {
options = {
collapse_vars: true,
hoist_vars: true,
join_vars: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = console;
a++;
var a = A = a;
console.log(A);
}
expect: {
var a = console;
a = A = ++a;
console.log(A);
}
expect_stdout: "NaN"
}
issue_5626: {
options = {
conditionals: true,
evaluate: true,
hoist_vars: true,
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var a = function() {
return console.log(arguments[0]), 42;
}("PASS") ? null : "foo";
for (var b in a)
FAIL;
}
expect: {
(function() {
console.log(arguments[0]);
}("PASS"));
for (var b in null)
FAIL;
}
expect_stdout: "PASS"
}
issue_5638_1: {
options = {
collapse_vars: true,
hoist_vars: true,
reduce_vars: true,
toplevel: true,
}
input: {
var a = "FAIL";
var a = [ 42 ];
console || FAIL(a);
console.log(a++);
}
expect: {
var a;
a = "FAIL";
a = [ 42 ];
console || FAIL(a);
console.log(a++);
}
expect_stdout: "42"
}
issue_5638_2: {
options = {
collapse_vars: true,
hoist_vars: true,
reduce_vars: true,
toplevel: true,
}
input: {
var a = "FAIL";
var a = [ 6 ];
console || FAIL(a);
console.log(a *= 7);
}
expect: {
var a;
a = "FAIL";
a = [ 6 ];
console || FAIL(a);
console.log(a *= 7);
}
expect_stdout: "42"
}
issue_5638_3: {
options = {
collapse_vars: true,
hoist_vars: true,
pure_getters: "strict",
reduce_vars: true,
toplevel: true,
}
input: {
var log = console.log;
var o = { foo: 42 };
for (var k in o) {
var v = o[k];
log(k || v, v++);
}
}
expect: {
var log, o, k, v;
log = console.log;
for (k in o = { foo: 42 }) {
v = o[k];
log(k || v, v++);
}
}
expect_stdout: "foo 42"
}
issue_5638_4: {
options = {
collapse_vars: true,
hoist_vars: true,
pure_getters: "strict",
reduce_vars: true,
toplevel: true,
}
input: {
var log = console.log;
var o = { foo: 6 };
for (var k in o) {
var v = o[k];
log(k || v, v *= 7);
}
}
expect: {
var log, o, k, v;
log = console.log;
for (k in o = { foo: 6 }) {
v = o[k];
log(k || v, v *= 7);
}
}
expect_stdout: "foo 42"
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

298
test/compress/imports.js Normal file
View File

@@ -0,0 +1,298 @@
nought: {
input: {
import "foo";
}
expect_exact: 'import"foo";'
}
default_only: {
input: {
import foo from "bar";
}
expect_exact: 'import foo from"bar";'
}
all_only: {
input: {
import * as foo from "bar";
}
expect_exact: 'import*as foo from"bar";'
}
keys_only: {
input: {
import { as as foo, bar, delete as baz } from "moo";
}
expect_exact: 'import{as as foo,bar,delete as baz}from"moo";'
}
default_all: {
input: {
import foo, * as bar from "baz";
}
expect_exact: 'import foo,*as bar from"baz";'
}
default_keys: {
input: {
import foo, { bar } from "baz";
}
expect_exact: 'import foo,{bar}from"baz";'
}
non_identifiers: {
beautify = {
quote_style: 3,
}
input: {
import { '42' as foo } from "bar";
import { "foo" as bar } from 'baz';
}
expect_exact: "import{'42'as foo}from\"bar\";import{foo as bar}from'baz';"
}
dynamic: {
input: {
(async a => await import(a))("foo").then(bar);
}
expect_exact: '(async a=>await import(a))("foo").then(bar);'
}
dynamic_nought: {
input: {
import(foo);
}
expect_exact: "import(foo);"
}
import_meta_1: {
input: {
console.log(import.meta, import.meta.url);
}
expect_exact: "console.log(import.meta,import.meta.url);"
}
import_meta_2: {
input: {
import.meta.url.split("/").forEach(function(part, index) {
console.log(index, part);
});
}
expect_exact: 'import.meta.url.split("/").forEach(function(part,index){console.log(index,part)});'
}
same_quotes: {
beautify = {
beautify: true,
quote_style: 3,
}
input: {
import 'foo';
import "bar";
}
expect_exact: [
"import 'foo';",
"",
'import "bar";',
]
}
drop_unused: {
options = {
imports: true,
toplevel: true,
unused: true,
}
input: {
import a, * as b from "foo";
import { c } from "bar";
import { d, _ as e } from "baz";
console.log(d);
}
expect: {
import "foo";
import "bar";
import { d as d } from "baz";
console.log(d);
}
}
drop_side_effect_free: {
options = {
imports: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
import foo from "bar";
var a = foo;
}
expect: {
import "bar";
}
}
mangle: {
rename = false
mangle = {
toplevel: true,
}
input: {
import foo, { bar } from "baz";
console.log(moo);
import * as moo from "moz";
}
expect: {
import o, { bar as m } from "baz";
console.log(r);
import * as r from "moz";
}
}
rename_mangle: {
rename = true
mangle = {
toplevel: true,
}
input: {
import foo, { bar } from "baz";
console.log(moo);
import * as moo from "moz";
}
expect: {
import o, { bar as m } from "baz";
console.log(r);
import * as r from "moz";
}
}
mangle_export_import: {
mangle = {
toplevel: true,
}
input: {
export let o = A;
import { p as A } from "foo";
}
expect: {
export let o = p;
import { p } from "foo";
}
}
mangle_import_export: {
mangle = {
toplevel: true,
}
input: {
import { p as A } from "foo";
export let o = A;
}
expect: {
import { p } from "foo";
export let o = p;
}
}
keep_ref: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
import foo from "bar";
foo();
}
expect: {
import foo from "bar";
foo();
}
}
forbid_merge: {
options = {
merge_vars: true,
toplevel: true,
}
input: {
import A from "foo";
export default class extends A {}
var f = () => () => {};
f();
f();
}
expect: {
import A from "foo";
export default class extends A {}
var f = () => () => {};
f();
f();
}
}
issue_4708_1: {
options = {
imports: true,
toplevel: true,
unused: true,
}
input: {
var a;
import a from "foo";
}
expect: {
var a;
import a from "foo";
}
}
issue_4708_2: {
options = {
imports: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a;
console.log(a);
import a from "foo";
}
expect: {
var a;
console.log(a);
import a from "foo";
}
}
pr_5550_1: {
input: {
if (console)
import("foo");
else
import.meta.url.replace(/bar/g, console.log);
}
expect: {
if (console)
import("foo");
else
import.meta.url.replace(/bar/g, console.log);
}
}
pr_5550_2: {
input: {
L: {
import("foo");
import.meta.url.replace(/bar/g, console.log);
}
}
expect: {
L: {
import("foo");
import.meta.url.replace(/bar/g, console.log);
}
}
}

View File

@@ -0,0 +1,100 @@
numeric: {
beautify = {
beautify: true,
indent_start: 1,
indent_level: 3,
}
input: {
switch (42) {
case null:
console.log("FAIL");
}
console.log("PASS");
}
expect_exact: [
" switch (42) {",
" case null:",
' console.log("FAIL");',
" }",
"",
' console.log("PASS");',
]
expect_stdout: "PASS"
}
spaces: {
beautify = {
beautify: true,
indent_start: " ",
indent_level: " ",
}
input: {
switch (42) {
case null:
console.log("FAIL");
}
console.log("PASS");
}
expect_exact: [
" switch (42) {",
" case null:",
' console.log("FAIL");',
" }",
"",
' console.log("PASS");',
]
expect_stdout: "PASS"
}
tabs: {
beautify = {
beautify: true,
indent_start: "\t",
indent_level: "\t",
}
input: {
switch (42) {
case null:
console.log("FAIL");
}
console.log("PASS");
}
expect_exact: [
"\tswitch (42) {",
"\tcase null:",
'\t\tconsole.log("FAIL");',
"\t}",
"",
'\tconsole.log("PASS");',
]
expect_stdout: "PASS"
}
mixed: {
beautify = {
beautify: true,
indent_start: "\n",
indent_level: " \t",
}
input: {
switch (42) {
case null:
console.log("FAIL");
}
console.log("PASS");
}
expect_exact: [
"",
"switch (42) {",
"",
" case null:",
"",
' \tconsole.log("FAIL");',
"",
"}",
"",
"",
'console.log("PASS");',
]
expect_stdout: "PASS"
}

View File

@@ -4,22 +4,21 @@ multiple_functions: {
if_return: true,
}
input: {
( function() {
if ( !window ) {
(function() {
if (!window)
return;
}
function f() {}
function g() {}
} )();
})();
}
expect: {
( function() {
(function() {
// NOTE: other compression steps will reduce this
// down to just `window`.
if ( !window );
if (!window);
function f() {}
function g() {}
} )();
})();
}
}
@@ -29,18 +28,17 @@ single_function: {
if_return: true,
}
input: {
( function() {
if ( !window ) {
(function() {
if (!window)
return;
}
function f() {}
} )();
})();
}
expect: {
( function() {
if ( !window );
(function() {
if (!window);
function f() {}
} )();
})();
}
}
@@ -50,28 +48,26 @@ deeply_nested: {
if_return: true,
}
input: {
( function() {
if ( !window ) {
(function() {
if (!window)
return;
}
function f() {}
function g() {}
if ( !document ) {
if (!document)
return;
}
function h() {}
} )();
})();
}
expect: {
( function() {
(function() {
// NOTE: other compression steps will reduce this
// down to just `window`.
if ( window )
if ( !document );
if (!window);
else if (!document);
function f() {}
function g() {}
function h() {}
} )();
})();
}
}
@@ -81,18 +77,18 @@ not_hoisted_when_already_nested: {
if_return: true,
}
input: {
( function() {
if ( !window ) {
(function() {
if (!window)
return;
}
if ( foo ) function f() {}
} )();
if (foo) function f() {}
})();
}
expect: {
( function() {
if ( window )
if ( foo ) function f() {}
} )();
(function() {
if (!window);
else if (foo)
function f() {}
})();
}
}
@@ -104,15 +100,19 @@ defun_if_return: {
input: {
function e() {
function f() {}
if (!window) return;
else function g() {}
if (!window)
return;
else
function g() {}
function h() {}
}
}
expect: {
function e() {
function f() {}
if (window) function g() {}
if (!window);
else
function g() {}
function h() {}
}
}
@@ -126,8 +126,10 @@ defun_hoist_funs: {
input: {
function e() {
function f() {}
if (!window) return;
else function g() {}
if (!window)
return;
else
function g() {}
function h() {}
}
}
@@ -136,7 +138,7 @@ defun_hoist_funs: {
function f() {}
function g() {}
function h() {}
if (window);
if (!window);
}
}
}
@@ -149,15 +151,18 @@ defun_else_if_return: {
input: {
function e() {
function f() {}
if (window) function g() {}
else return;
if (window)
function g() {}
else
return;
function h() {}
}
}
expect: {
function e() {
function f() {}
if (window) function g() {}
if (window)
function g() {}
function h() {}
}
}

View File

@@ -2,61 +2,77 @@ keep_name_of_getter: {
options = {
unused: true,
}
input: { a = { get foo () {} } }
expect: { a = { get foo () {} } }
input: {
a = {
get foo() {},
};
}
expect: {
a = {
get foo() {},
};
}
}
keep_name_of_setter: {
options = {
unused: true,
}
input: { a = { set foo () {} } }
expect: { a = { set foo () {} } }
input: {
a = {
set foo(v) {},
};
}
expect: {
a = {
set foo(v) {},
};
}
}
setter_with_operator_keys: {
input: {
var tokenCodes = {
get instanceof(){
var tokenCodes = {
get instanceof() {
return test0;
},
set instanceof(value){
set instanceof(value) {
test0 = value;
},
set typeof(value){
set typeof(value) {
test1 = value;
},
get typeof(){
get typeof() {
return test1;
},
set else(value){
set else(value) {
test2 = value;
},
get else(){
get else() {
return test2;
}
},
};
}
expect: {
var tokenCodes = {
get instanceof(){
var tokenCodes = {
get instanceof() {
return test0;
},
set instanceof(value){
set instanceof(value) {
test0 = value;
},
set typeof(value){
set typeof(value) {
test1 = value;
},
get typeof(){
get typeof() {
return test1;
},
set else(value){
set else(value) {
test2 = value;
},
get else(){
get else() {
return test2;
}
},
};
}
}
}

View File

@@ -4,7 +4,7 @@ mangle_keep_fnames_false: {
keep_fnames: true,
}
mangle = {
keep_fnames : false,
keep_fnames: false,
}
input: {
"use strict";
@@ -30,7 +30,7 @@ mangle_keep_fnames_true: {
keep_fnames: true,
}
mangle = {
keep_fnames : true,
keep_fnames: true,
}
input: {
"use strict";

View File

@@ -1,5 +1,6 @@
pure_function_calls: {
options = {
annotations: true,
booleans: true,
comparisons: true,
conditionals: true,
@@ -60,6 +61,7 @@ pure_function_calls: {
pure_function_calls_toplevel: {
options = {
annotations: true,
booleans: true,
comparisons: true,
conditionals: true,
@@ -126,6 +128,7 @@ pure_function_calls_toplevel: {
should_warn: {
options = {
annotations: true,
booleans: true,
conditionals: true,
evaluate: true,

View File

@@ -1,6 +1,7 @@
issue_1321_no_debug: {
mangle = {
properties: {
domprops: true,
keep_quoted: true,
},
}
@@ -23,6 +24,7 @@ issue_1321_debug: {
mangle = {
properties: {
debug: "",
domprops: true,
keep_quoted: true,
},
}
@@ -44,6 +46,7 @@ issue_1321_debug: {
issue_1321_with_quoted: {
mangle = {
properties: {
domprops: true,
keep_quoted: false,
},
}

View File

@@ -1,5 +1,5 @@
/**
* There was an incorrect sort behaviour documented in issue #143:
* There was an incorrect sort behavior documented in issue #143:
* (x = f(…)) <= x → x >= (x = f(…))
*
* For example, let the equation be:
@@ -12,37 +12,54 @@
* a >= (a = parseInt('100')) → 99 >= 100 → false
*/
tranformation_sort_order_equal: {
transformation_sort_order_equal: {
options = {
comparisons: true,
}
input: { (a = parseInt('100')) == a }
expect: { (a = parseInt('100')) == a }
input: {
console.log((a = parseInt("100")) == a);
}
expect: {
console.log((a = parseInt("100")) == a);
}
expect_stdout: "true"
}
tranformation_sort_order_unequal: {
transformation_sort_order_unequal: {
options = {
comparisons: true,
}
input: { (a = parseInt('100')) != a }
expect: { (a = parseInt('100')) != a }
input: {
console.log((a = parseInt("100")) != a);
}
expect: {
console.log((a = parseInt("100")) != a);
}
expect_stdout: "false"
}
tranformation_sort_order_lesser_or_equal: {
transformation_sort_order_lesser_or_equal: {
options = {
comparisons: true,
}
input: { (a = parseInt('100')) <= a }
expect: { (a = parseInt('100')) <= a }
input: {
console.log((a = parseInt("100")) <= a);
}
expect: {
console.log((a = parseInt("100")) <= a);
}
expect_stdout: "true"
}
tranformation_sort_order_greater_or_equal: {
transformation_sort_order_greater_or_equal: {
options = {
comparisons: true,
}
input: { (a = parseInt('100')) >= a }
expect: { (a = parseInt('100')) >= a }
}
input: {
console.log((a = parseInt("100")) >= a);
}
expect: {
console.log((a = parseInt("100")) >= a);
}
expect_stdout: "true"
}

View File

@@ -24,7 +24,7 @@ typeof_eq_undefined: {
typeof_eq_undefined_ie8: {
options = {
comparisons: true,
ie8: true,
ie: true,
typeofs: true,
}
input: {

View File

@@ -40,6 +40,9 @@ conditional_false_stray_else_in_loop: {
console.log(i);
}
}
expect_exact: "for(var i=1;i<=4;++i)if(!(i<=2))console.log(i);"
expect_stdout: true
expect_exact: "for(var i=1;i<=4;++i)if(i<=2);else console.log(i);"
expect_stdout: [
"3",
"4",
]
}

View File

@@ -1,9 +1,9 @@
screw_ie8: {
options = {
ie8: false,
ie: false,
}
mangle = {
ie8: false,
ie: false,
}
input: {
try { throw "foo"; } catch (x) { console.log(x); }
@@ -16,10 +16,10 @@ screw_ie8: {
support_ie8: {
options = {
ie8: true,
ie: true,
}
mangle = {
ie8: true,
ie: true,
}
input: {
try { throw "foo"; } catch (x) { console.log(x); }

View File

@@ -1,10 +1,10 @@
mangle_catch: {
options = {
ie8: false,
ie: false,
toplevel: false,
}
mangle = {
ie8: false,
ie: false,
toplevel: false,
}
input: {
@@ -22,11 +22,11 @@ mangle_catch: {
mangle_catch_ie8: {
options = {
ie8: true,
ie: true,
toplevel: false,
}
mangle = {
ie8: true,
ie: true,
toplevel: false,
}
input: {
@@ -44,11 +44,11 @@ mangle_catch_ie8: {
mangle_catch_var: {
options = {
ie8: false,
ie: false,
toplevel: false,
}
mangle = {
ie8: false,
ie: false,
toplevel: false,
}
input: {
@@ -66,11 +66,11 @@ mangle_catch_var: {
mangle_catch_var_ie8: {
options = {
ie8: true,
ie: true,
toplevel: false,
}
mangle = {
ie8: true,
ie: true,
toplevel: false,
}
input: {
@@ -88,11 +88,11 @@ mangle_catch_var_ie8: {
mangle_catch_toplevel: {
options = {
ie8: false,
ie: false,
toplevel: true,
}
mangle = {
ie8: false,
ie: false,
toplevel: true,
}
input: {
@@ -110,11 +110,11 @@ mangle_catch_toplevel: {
mangle_catch_ie8_toplevel: {
options = {
ie8: true,
ie: true,
toplevel: true,
}
mangle = {
ie8: true,
ie: true,
toplevel: true,
}
input: {
@@ -132,11 +132,11 @@ mangle_catch_ie8_toplevel: {
mangle_catch_var_toplevel: {
options = {
ie8: false,
ie: false,
toplevel: true,
}
mangle = {
ie8: false,
ie: false,
toplevel: true,
}
input: {
@@ -154,11 +154,11 @@ mangle_catch_var_toplevel: {
mangle_catch_var_ie8_toplevel: {
options = {
ie8: true,
ie: true,
toplevel: true,
}
mangle = {
ie8: true,
ie: true,
toplevel: true,
}
input: {
@@ -176,11 +176,11 @@ mangle_catch_var_ie8_toplevel: {
mangle_catch_redef_1: {
options = {
ie8: false,
ie: false,
toplevel: false,
}
mangle = {
ie8: false,
ie: false,
toplevel: false,
}
input: {
@@ -198,11 +198,11 @@ mangle_catch_redef_1: {
mangle_catch_redef_1_ie8: {
options = {
ie8: true,
ie: true,
toplevel: false,
}
mangle = {
ie8: true,
ie: true,
toplevel: false,
}
input: {
@@ -220,11 +220,11 @@ mangle_catch_redef_1_ie8: {
mangle_catch_redef_1_toplevel: {
options = {
ie8: false,
ie: false,
toplevel: true,
}
mangle = {
ie8: false,
ie: false,
toplevel: true,
}
input: {
@@ -242,11 +242,11 @@ mangle_catch_redef_1_toplevel: {
mangle_catch_redef_1_ie8_toplevel: {
options = {
ie8: true,
ie: true,
toplevel: true,
}
mangle = {
ie8: true,
ie: true,
toplevel: true,
}
input: {
@@ -264,11 +264,11 @@ mangle_catch_redef_1_ie8_toplevel: {
mangle_catch_redef_2: {
options = {
ie8: false,
ie: false,
toplevel: false,
}
mangle = {
ie8: false,
ie: false,
toplevel: false,
}
input: {
@@ -285,11 +285,11 @@ mangle_catch_redef_2: {
mangle_catch_redef_2_ie8: {
options = {
ie8: true,
ie: true,
toplevel: false,
}
mangle = {
ie8: true,
ie: true,
toplevel: false,
}
input: {
@@ -306,11 +306,11 @@ mangle_catch_redef_2_ie8: {
mangle_catch_redef_2_toplevel: {
options = {
ie8: false,
ie: false,
toplevel: true,
}
mangle = {
ie8: false,
ie: false,
toplevel: true,
}
input: {
@@ -327,11 +327,11 @@ mangle_catch_redef_2_toplevel: {
mangle_catch_redef_2_ie8_toplevel: {
options = {
ie8: true,
ie: true,
toplevel: true,
}
mangle = {
ie8: true,
ie: true,
toplevel: true,
}
input: {
@@ -348,7 +348,7 @@ mangle_catch_redef_2_ie8_toplevel: {
mangle_catch_redef_3: {
mangle = {
ie8: false,
ie: false,
toplevel: false,
}
input: {
@@ -356,6 +356,7 @@ mangle_catch_redef_3: {
try {
throw 0;
} catch (o) {
// prints "FAIL" if inlined on Node.js v4-
(function() {
function f() {
o = "FAIL";
@@ -366,12 +367,13 @@ mangle_catch_redef_3: {
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
expect_stdout: "PASS"
node_version: ">=6"
}
mangle_catch_redef_3_toplevel: {
mangle = {
ie8: false,
ie: false,
toplevel: true,
}
input: {
@@ -379,6 +381,7 @@ mangle_catch_redef_3_toplevel: {
try {
throw 0;
} catch (o) {
// prints "FAIL" if inlined on Node.js v4-
(function() {
function f() {
o = "FAIL";
@@ -389,12 +392,13 @@ mangle_catch_redef_3_toplevel: {
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
expect_stdout: "PASS"
node_version: ">=6"
}
mangle_catch_redef_3_ie8: {
mangle = {
ie8: true,
ie: true,
toplevel: false,
}
input: {
@@ -402,6 +406,7 @@ mangle_catch_redef_3_ie8: {
try {
throw 0;
} catch (o) {
// prints "FAIL" if inlined on Node.js v4-
(function() {
function f() {
o = "FAIL";
@@ -412,12 +417,13 @@ mangle_catch_redef_3_ie8: {
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
expect_stdout: "PASS"
node_version: ">=6"
}
mangle_catch_redef_3_ie8_toplevel: {
mangle = {
ie8: true,
ie: true,
toplevel: true,
}
input: {
@@ -425,6 +431,7 @@ mangle_catch_redef_3_ie8_toplevel: {
try {
throw 0;
} catch (o) {
// prints "FAIL" if inlined on Node.js v4-
(function() {
function f() {
o = "FAIL";
@@ -435,5 +442,6 @@ mangle_catch_redef_3_ie8_toplevel: {
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
expect_stdout: "PASS"
node_version: ">=6"
}

View File

@@ -1,6 +1,6 @@
function_iife_catch: {
mangle = {
ie8: false,
ie: false,
}
input: {
function f(n) {
@@ -21,7 +21,7 @@ function_iife_catch: {
function_iife_catch_ie8: {
mangle = {
ie8: true,
ie: true,
}
input: {
function f(n) {
@@ -42,7 +42,7 @@ function_iife_catch_ie8: {
function_catch_catch: {
mangle = {
ie8: false,
ie: false,
}
input: {
var o = 0;
@@ -70,7 +70,7 @@ function_catch_catch: {
function_catch_catch_ie8: {
mangle = {
ie8: true,
ie: true,
}
input: {
var o = 0;

View File

@@ -53,11 +53,21 @@ mangle_props: {
);
}
expect_stdout: "1 1 1 2 2 2 3 3 3 4 4 4 5 5"
expect_warnings: [
"INFO: Preserving reserved property undefined",
"INFO: Preserving reserved property NaN",
"INFO: Preserving reserved property Infinity",
"INFO: Preserving reserved property -Infinity",
"INFO: Preserving reserved property null",
"INFO: Preserving reserved property log",
]
}
numeric_literal: {
mangle = {
properties: true,
properties: {
domprops: true,
},
}
beautify = {
beautify: true,
@@ -106,11 +116,19 @@ numeric_literal: {
"4 5 4 4",
"8 7 8",
]
expect_warnings: [
"INFO: Mapping property 0x25 to o",
"INFO: Mapping property 1E42 to b",
"INFO: Preserving reserved property log",
]
}
identifier: {
mangle = {
properties: true,
properties: {
builtins: true,
domprops: true,
},
}
input: {
var obj = {
@@ -209,37 +227,37 @@ identifier: {
B: 28,
C: 29,
D: 30,
F: 31,
G: 32,
false: 33,
null: 34,
true: 35,
H: 36,
I: 37,
J: 38,
K: 39,
L: 40,
M: 41,
N: 42,
O: 43,
P: 44,
Q: 45,
R: 46,
S: 47,
T: 48,
U: 49,
V: 50,
W: 51,
X: 52,
Y: 53,
Z: 54,
$: 55,
_: 56,
ee: 57,
te: 58,
ne: 59,
ae: 60,
ie: 61,
E: 31,
F: 32,
G: 33,
H: 34,
I: 35,
J: 36,
K: 37,
L: 38,
M: 39,
N: 40,
O: 41,
P: 42,
Q: 43,
R: 44,
S: 45,
T: 46,
U: 47,
V: 48,
W: 49,
X: 50,
Y: 51,
Z: 52,
$: 53,
_: 54,
ee: 55,
te: 56,
ne: 57,
ae: 58,
ie: 59,
oe: 60,
re: 61,
};
}
}

View File

@@ -108,6 +108,7 @@ safe_undefined: {
}
negate_iife_3: {
expression = true
options = {
conditionals: true,
expression: true,
@@ -123,6 +124,7 @@ negate_iife_3: {
}
negate_iife_3_off: {
expression = true
options = {
conditionals: true,
expression: true,
@@ -203,6 +205,7 @@ negate_iife_5_off: {
}
issue_1254_negate_iife_true: {
expression = true
options = {
expression: true,
inline: true,
@@ -215,11 +218,12 @@ issue_1254_negate_iife_true: {
};
})()();
}
expect_exact: 'void console.log("test");'
expect_exact: 'void console.log("test")'
expect_stdout: true
}
issue_1254_negate_iife_nested: {
expression = true
options = {
expression: true,
inline: true,
@@ -232,7 +236,7 @@ issue_1254_negate_iife_nested: {
};
})()()()()();
}
expect_exact: '(void console.log("test"))()()();'
expect_exact: '(void console.log("test"))()()()'
}
negate_iife_issue_1073: {
@@ -426,6 +430,7 @@ wrap_iife_in_return_call: {
pure_annotation_1: {
options = {
annotations: true,
inline: true,
side_effects: true,
}
@@ -439,6 +444,7 @@ pure_annotation_1: {
pure_annotation_2: {
options = {
annotations: true,
collapse_vars: true,
inline: true,
side_effects: true,
@@ -463,15 +469,19 @@ drop_fargs: {
var a = 1;
!function(a_1) {
a++;
}(a++ + (a && a.var));
}(a++ + (a && console.log(a)));
console.log(a);
}
expect: {
var a = 1;
++a && a.var, a++;
++a && console.log(a),
a++;
console.log(a);
}
expect_stdout: "3"
expect_stdout: [
"2",
"3",
]
}
keep_fargs: {
@@ -486,13 +496,17 @@ keep_fargs: {
var a = 1;
!function(a_1) {
a++;
}(a++ + (a && a.var));
}(a++ + (a && console.log(a)));
console.log(a);
}
expect: {
var a = 1;
++a && a.var, a++;
++a && console.log(a),
a++;
console.log(a);
}
expect_stdout: "3"
expect_stdout: [
"2",
"3",
]
}

View File

@@ -15,7 +15,7 @@ collapse: {
var a;
b = c();
a = typeof b === 'function' ? b() : b;
return 'stirng' == typeof a && d();
return 'string' == typeof a && d();
}
function f3(c) {
var a;
@@ -41,7 +41,7 @@ collapse: {
return void 0 !== ('function' === typeof b ? b() : b) && c();
}
function f2(b) {
return 'stirng' == typeof ('function' === typeof (b = c()) ? b() : b) && d();
return 'string' == typeof ('function' === typeof (b = c()) ? b() : b) && d();
}
function f3(c) {
var a;

195
test/compress/issue-5614.js Normal file
View File

@@ -0,0 +1,195 @@
record_update: {
options = {
loops: true,
passes: 3,
pure_getters: "strict",
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var value = { a: 42, b: "PASS" };
var unused = _Utils_update(value, { b: "FAIL" });
function _Utils_update(oldRecord, updatedFields) {
var newRecord = {};
for (var key in oldRecord)
newRecord[key] = oldRecord[key];
for (var key in updatedFields)
newRecord[key] = updatedFields[key];
return newRecord;
}
}
expect: {}
}
currying: {
options = {
inline: true,
passes: 3,
pure_getters: "strict",
reduce_funcs: true,
reduce_vars: true,
sequences: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
function F(arity, fun, wrapper) {
wrapper.a = arity;
wrapper.f = fun;
return wrapper;
}
function F2(fun) {
return F(2, fun, function(a) {
return function(b) {
return fun(a, b);
};
});
}
function _Utils_eq(x, y) {
var pair, stack = [], isEqual = _Utils_eqHelp(x, y, 0, stack);
while (isEqual && (pair = stack.pop()))
isEqual = _Utils_eqHelp(pair.a, pair.b, 0, stack);
return isEqual;
}
var _Utils_equal = F2(_Utils_eq);
}
expect: {}
}
conditional_property_write: {
options = {
pure_getters: "strict",
reduce_vars: true,
unused: true,
}
input: {
function f(a) {
var o = {};
if (a)
o.p = console.log("foo");
else
o.q = console.log("bar");
o.r = console.log("baz");
}
f(42);
f(null);
}
expect: {
function f(a) {
if (a)
console.log("foo");
else
console.log("bar");
console.log("baz");
}
f(42);
f(null);
}
expect_stdout: [
"foo",
"baz",
"bar",
"baz",
]
}
reassign_1: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = "PASS", b = "FAIL";
(b = a).toString();
console.log(b);
}
expect: {
var b = "FAIL";
(b = "PASS").toString();
console.log(b);
}
expect_stdout: "PASS"
}
reassign_2: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
}
input: {
var a = "PASS";
if (false) {
a = null + 0;
a();
}
console.log(a);
}
expect: {
var a = "PASS";
if (false) {
a = 0;
a();
}
console.log(a);
}
expect_stdout: "PASS"
}
reassign_3: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
}
input: {
var a = 0;
(a = a || "PASS").toString();
console.log(a);
}
expect: {
var a = 0;
(a = (0, "PASS")).toString();
console.log(a);
}
expect_stdout: "PASS"
}
retain_instance_write: {
options = {
pure_getters: true,
reduce_vars: true,
unused: true,
}
input: {
function f(a) {
return a;
}
function g() {
var o = {};
var b = new f(o);
if (console)
b.p = "PASS";
return o;
}
console.log(g().p);
}
expect: {
function f(a) {
return a;
}
function g() {
var o = {};
var b = new f(o);
if (console)
b.p = "PASS";
return o;
}
console.log(g().p);
}
expect_stdout: "PASS"
}

View File

@@ -68,6 +68,7 @@ drop_console_2: {
}
drop_value: {
expression = true
options = {
expression: true,
side_effects: true,
@@ -106,6 +107,7 @@ wrongly_optimized: {
}
negate_iife_1: {
expression = true
options = {
expression: true,
negate_iife: true,
@@ -119,6 +121,7 @@ negate_iife_1: {
}
negate_iife_3: {
expression = true
options = {
conditionals: true,
expression: true,
@@ -133,6 +136,7 @@ negate_iife_3: {
}
negate_iife_3_off: {
expression = true
options = {
conditionals: true,
expression: true,
@@ -215,6 +219,7 @@ negate_iife_5_off: {
}
issue_1254_negate_iife_true: {
expression = true
options = {
expression: true,
negate_iife: true,
@@ -226,11 +231,12 @@ issue_1254_negate_iife_true: {
};
})()();
}
expect_exact: '(function(){return function(){console.log("test")}})()();'
expect_exact: 'function(){return function(){console.log("test")}}()()'
expect_stdout: true
}
issue_1254_negate_iife_nested: {
expression = true
options = {
expression: true,
negate_iife: true,
@@ -242,7 +248,7 @@ issue_1254_negate_iife_nested: {
};
})()()()()();
}
expect_exact: '(function(){return function(){console.log("test")}})()()()()();'
expect_exact: 'function(){return function(){console.log("test")}}()()()()()'
expect_stdout: true
}
@@ -317,7 +323,35 @@ iife: {
typeof function g() {}();
}
expect: {
x = 42, function a() {}(), function b() {}(), function c() {}(),
function d() {}(), function e() {}(), function f() {}(), typeof function g() {}();
x = 42,
function a() {}(),
!function b() {}(),
~function c() {}(),
+function d() {}(),
-function e() {}(),
void function f() {}(),
typeof function g() {}();
}
}
iife_drop_side_effect_free: {
options = {
expression: true,
sequences: true,
side_effects: true,
}
input: {
x = 42;
(function a() {})();
!function b() {}();
~function c() {}();
+function d() {}();
-function e() {}();
void function f() {}();
typeof function g() {}();
}
expect: {
x = 42,
typeof void 0;
}
}

View File

@@ -1,6 +1,7 @@
dont_reuse_prop: {
mangle = {
properties: {
domprops: true,
regex: /asd/,
},
}
@@ -19,11 +20,17 @@ dont_reuse_prop: {
console.log(obj.a);
}
expect_stdout: "123"
expect_warnings: [
"INFO: Preserving excluded property a",
"INFO: Mapping property asd to b",
"INFO: Preserving reserved property log",
]
}
unmangleable_props_should_always_be_reserved: {
mangle = {
properties: {
domprops: true,
regex: /asd/,
},
}
@@ -42,4 +49,9 @@ unmangleable_props_should_always_be_reserved: {
console.log(obj.a);
}
expect_stdout: "123"
expect_warnings: [
"INFO: Preserving excluded property a",
"INFO: Mapping property asd to b",
"INFO: Preserving reserved property log",
]
}

View File

@@ -1,6 +1,4 @@
dont_mangle_arguments: {
mangle = {
};
options = {
booleans: true,
comparisons: true,
@@ -21,12 +19,13 @@ dont_mangle_arguments: {
side_effects: true,
unused: true,
}
mangle = {}
input: {
(function(){
var arguments = arguments, not_arguments = 9;
console.log(not_arguments, arguments);
})(5,6,7);
})(5, 6, 7);
}
expect_exact: "(function(){var arguments=arguments,o=9;console.log(o,arguments)})(5,6,7);"
expect_exact: "(function(){var arguments,o=9;console.log(o,arguments)})(5,6,7);"
expect_stdout: true
}

View File

@@ -1,17 +1,18 @@
keep_var_for_in: {
options = {
hoist_vars: true,
join_vars: true,
unused: true,
}
input: {
(function(obj){
(function(obj) {
var foo = 5;
for (var i in obj)
return foo;
})();
}
expect: {
(function(obj){
(function(obj) {
var i, foo = 5;
for (i in obj)
return foo;

View File

@@ -1,4 +1,4 @@
issue979_reported: {
reported: {
options = {
booleans: true,
comparisons: true,
@@ -17,29 +17,26 @@ issue979_reported: {
}
input: {
function f1() {
if (a == 1 || b == 2) {
if (a == 1 || b == 2)
foo();
}
}
function f2() {
if (!(a == 1 || b == 2)) {
}
else {
if (!(a == 1 || b == 2));
else
foo();
}
}
}
expect: {
function f1() {
1!=a&&2!=b||foo();
1 != a && 2 != b || foo();
}
function f2() {
1!=a&&2!=b||foo();
1 != a && 2 != b || foo();
}
}
}
issue979_test_negated_is_best: {
test_negated_is_best: {
options = {
booleans: true,
comparisons: true,
@@ -58,53 +55,47 @@ issue979_test_negated_is_best: {
}
input: {
function f3() {
if (a == 1 | b == 2) {
if (a == 1 | b == 2)
foo();
}
}
function f4() {
if (!(a == 1 | b == 2)) {
}
else {
if (!(a == 1 | b == 2));
else
foo();
}
}
function f5() {
if (a == 1 && b == 2) {
if (a == 1 && b == 2)
foo();
}
}
function f6() {
if (!(a == 1 && b == 2)) {
}
else {
if (!(a == 1 && b == 2));
else
foo();
}
}
function f7() {
if (a == 1 || b == 2) {
if (a == 1 || b == 2)
foo();
}
else {
else
return bar();
}
}
}
expect: {
function f3() {
1==a|2==b&&foo();
1 == a | 2 == b && foo();
}
function f4() {
1==a|2==b&&foo();
1 == a | 2 == b && foo();
}
function f5() {
1==a&&2==b&&foo();
1 == a && 2 == b && foo();
}
function f6() {
1!=a||2!=b||foo();
1 == a && 2 == b && foo();
}
function f7() {
if(1!=a&&2!=b)return bar();foo()
if (1 != a && 2 != b)
return bar();
foo();
}
}
}

View File

@@ -16,6 +16,105 @@ join_vars_assign: {
expect_stdout: "PASS"
}
join_array_assignments_1: {
options = {
evaluate: true,
join_vars: true,
}
input: {
console.log(function () {
var a = [ "foo", , "bar" ];
a[1] = "baz";
a[7] = "moo";
a[0] = "moz";
return a;
}().join());
}
expect: {
console.log(function () {
var a = [ "moz", "baz", "bar", , , , , "moo" ];
return a;
}().join());
}
expect_stdout: "moz,baz,bar,,,,,moo"
}
join_array_assignments_2: {
options = {
evaluate: true,
join_vars: true,
}
input: {
console.log(function () {
var a = [ "foo" ];
a[1] = "bar";
a[7] = "baz";
a[2] = "moo";
return a;
}().join());
}
expect: {
console.log(function () {
var a = [ "foo", "bar" ];
a[7] = "baz";
a[2] = "moo";
return a;
}().join());
}
expect_stdout: "foo,bar,moo,,,,,baz"
}
join_array_assignments_3: {
options = {
evaluate: true,
join_vars: true,
}
input: {
console.log(function () {
var a = [ "foo" ];
a[1] = "bar";
a.b = "baz";
a[2] = "moo";
return a;
}().join());
}
expect: {
console.log(function () {
var a = [ "foo", "bar" ];
a.b = "baz";
a[2] = "moo";
return a;
}().join());
}
expect_stdout: true
}
join_array_assignments_4: {
options = {
evaluate: true,
join_vars: true,
side_effects: true,
}
input: {
console.log(function () {
var a = [ "foo" ];
a[0] = "bar";
a[1] = a;
a[2] = "baz";
return a;
}().join());
}
expect: {
console.log(function () {
var a = [ "bar" ];
a[1] = a;
a[2] = "baz";
return a;
}().join());
}
expect_stdout: true
}
join_object_assignments_1: {
options = {
evaluate: true,
@@ -489,6 +588,160 @@ join_object_assignments_regex: {
expect_stdout: "1"
}
chained_assignments: {
options = {
join_vars: true,
}
input: {
var a, b = a = {};
b.p = "PASS";
console.log(a.p);
}
expect: {
var a, b = a = {
p: "PASS",
};
console.log(a.p);
}
expect_stdout: "PASS"
}
folded_assignments_1: {
options = {
evaluate: true,
join_vars: true,
}
input: {
var a = {};
a[a.PASS = 42] = "PASS";
console.log(a[42], a.PASS);
}
expect: {
var a = {
PASS: 42,
42: "PASS",
};
console.log(a[42], a.PASS);
}
expect_stdout: "PASS 42"
}
folded_assignments_2: {
options = {
evaluate: true,
join_vars: true,
}
input: {
"use strict";
var a = {};
a[42] = "FAIL";
a[a.PASS = 42] = "PASS";
console.log(a[42], a.PASS);
}
expect: {
"use strict";
var a = {
42: "FAIL",
PASS: 42,
};
a[42] = "PASS";
console.log(a[42], a.PASS);
}
expect_stdout: "PASS 42"
}
inlined_assignments: {
options = {
join_vars: true,
unused: true,
}
input: {
var a;
(a = {}).p = "PASS";
console.log(a.p);
}
expect: {
var a = {
p: "PASS",
};
console.log(a.p);
}
expect_stdout: "PASS"
}
inline_for: {
options = {
inline: true,
join_vars: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = function() {
for (; console.log("PASS"););
};
a();
}
expect: {
for (; console.log("PASS"););
}
expect_stdout: "PASS"
}
inline_var: {
options = {
inline: true,
join_vars: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
A = "PASS";
var a = function() {
var b = A;
for (b in console.log(b));
};
a();
}
expect: {
A = "PASS";
var b = A;
for (b in console.log(b));
}
expect_stdout: "PASS"
}
typescript_enum: {
rename = true
options = {
assignments: true,
collapse_vars: true,
evaluate: true,
hoist_props: true,
inline: true,
join_vars: true,
passes: 4,
reduce_vars: true,
sequences: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var Enum;
(function (Enum) {
Enum[Enum.PASS = 42] = "PASS";
})(Enum || (Enum = {}));
console.log(Enum[42], Enum.PASS);
}
expect: {
console.log("PASS", 42);
}
expect_stdout: "PASS 42"
}
issue_2816: {
options = {
join_vars: true,
@@ -990,7 +1243,7 @@ conditional_assignments_3: {
expect_stdout: "PASS"
}
issue_3856: {
issue_3856_1: {
options = {
booleans: true,
conditionals: true,
@@ -1015,16 +1268,53 @@ issue_3856: {
console.log(function() {
(function() {
var a, b;
if (a) return !!a;
for (a = 0; !console;);
return 0;
if (a) a;
else {
a = 0;
for (; !console;);
}
})();
}());
}
expect_stdout: "undefined"
}
issue_3916: {
issue_3856_2: {
options = {
booleans: true,
conditionals: true,
if_return: true,
join_vars: true,
passes: 2,
sequences: true,
side_effects: true,
}
input: {
console.log(function() {
(function() {
var a;
if (!a) {
a = 0;
for (var b; !console;);
return 0;
}
if (a) return 1;
})();
}());
}
expect: {
console.log(function() {
(function() {
var a, b;
if (!a)
for (a = 0; !console;);
})();
}());
}
expect_stdout: "undefined"
}
issue_3916_1: {
options = {
join_vars: true,
}
@@ -1044,8 +1334,8 @@ issue_3916: {
var o = {
p: "PASS",
__proto__: 42,
q: "FAIL",
};
o.q = "FAIL";
o.__proto__ = {
p: "FAIL",
q: "PASS",
@@ -1055,3 +1345,185 @@ issue_3916: {
}
expect_stdout: "object PASS true PASS"
}
issue_3916_2: {
options = {
join_vars: true,
}
input: {
var log = console.log, o = {};
o.p = "FAIL 1";
o.__proto__ = {
get p() {
return "FAIL 2";
},
set p(u) {
log("FAIL 3");
},
set q(v) {
log("PASS 1");
},
get q() {
return "PASS 3";
},
};
o.p = "PASS 2";
o.q = "FAIL 4";
log(o.p);
log(o.q);
}
expect: {
var log = console.log, o = {
p: "FAIL 1",
__proto__: {
get p() {
return "FAIL 2";
},
set p(u) {
log("FAIL 3");
},
set q(v) {
log("PASS 1");
},
get q() {
return "PASS 3";
},
},
};
o.p = "PASS 2";
o.q = "FAIL 4";
log(o.p);
log(o.q);
}
expect_stdout: [
"PASS 1",
"PASS 2",
"PASS 3",
]
}
assign_var: {
options = {
join_vars: true,
}
input: {
b = "foo";
var a = [ , "bar" ];
console.log(b);
for (var b in a)
console.log(b, a[b]);
}
expect: {
var b = "foo", a = [ , "bar" ], b;
console.log(b);
for (b in a)
console.log(b, a[b]);
}
expect_stdout: [
"foo",
"1 bar",
]
}
assign_for_var: {
options = {
join_vars: true,
}
input: {
i = "foo",
a = new Array(i, "bar");
for (var i = 2; --i >= 0;) {
console.log(a[i]);
for (var a in i);
}
}
expect: {
for (var i = "foo", a = new Array(i, "bar"), i = 2; --i >= 0;) {
console.log(a[i]);
for (var a in i);
}
}
expect_stdout: [
"bar",
"foo",
]
}
assign_sequence_var: {
options = {
join_vars: true,
}
input: {
var a = 0, b = 1;
console.log(a),
a++,
b = 2;
var c = 3;
console.log(a, b, c);
}
expect: {
var a = 0, b = 1, c = (console.log(a), a++, b = 2, 3);
console.log(a, b, c);
}
expect_stdout: [
"0",
"1 2 3",
]
}
issue_5175: {
options = {
join_vars: true,
}
input: {
function log(f) {
console.log(f(), A.p);
}
log(function() {
return (A = {}).p = "PASS";
});
}
expect: {
function log(f) {
console.log(f(), A.p);
}
log(function() {
return (A = {}).p = "PASS";
});
}
expect_stdout: "PASS PASS"
}
issue_5831: {
options = {
evaluate: true,
join_vars: true,
}
input: {
var a = [ console.log("PASS") ];
a[0] = 42;
}
expect: {
var a = [ (console.log("PASS"), 42) ];
}
expect_stdout: "PASS"
}
issue_5849: {
options = {
evaluate: true,
join_vars: true,
side_effects: true,
}
input: {
var a;
a = [ 42 ];
a[0] = "PASS";
console.log(a.join(""));
}
expect: {
var a, a = [ "PASS" ];
console.log(a.join(""));
}
expect_stdout: "PASS"
}

View File

@@ -117,6 +117,7 @@ issue_1858: {
collapse_vars: true,
keep_fargs: false,
pure_getters: true,
reduce_vars: true,
unused: true,
}
input: {
@@ -180,10 +181,10 @@ issue_2203_2: {
a: "FAIL",
b: function() {
return function() {
return (String, (Object, function() {
return (Object, function() {
return this;
}())).a;
}();
}()).a;
}(String);
}
}.b());
}
@@ -438,7 +439,7 @@ issue_2506: {
function f0(bar) {
(function() {
(function() {
if (false <= NaN & this >> 1 >= 0)
if (false <= 0/0 & this >> 1 >= 0)
c++;
})(c++);
})();
@@ -924,6 +925,28 @@ duplicate_lambda_defun_name_2: {
expect_stdout: "0"
}
function_argument_mangle: {
mangle = {
keep_fargs: true,
toplevel: true,
}
input: {
A = "PASS";
var a = A;
(function(o) {
console.log(a);
})("FAIL");
}
expect: {
A = "PASS";
var n = A;
(function(o) {
console.log(n);
})("FAIL");
}
expect_stdout: "PASS"
}
function_name_mangle: {
options = {
keep_fargs: false,
@@ -950,7 +973,7 @@ function_name_mangle_ie8: {
unused: true,
}
mangle = {
ie8: true,
ie: true,
toplevel: true,
}
input: {
@@ -1157,8 +1180,8 @@ replace_all_var_scope: {
var a = 100, b = 10;
(function(r, a) {
switch (~a) {
case (b += a):
case a++:
case (b += a):
case a++:
}
})(--b, a);
console.log(a, b);
@@ -1167,8 +1190,8 @@ replace_all_var_scope: {
var a = 100, b = 10;
(function(c) {
switch (~a) {
case (b += a):
case c++:
case (b += a):
case c++:
}
})((--b, a));
console.log(a, b);
@@ -1216,6 +1239,7 @@ issues_3267_1: {
evaluate: true,
inline: true,
keep_fargs: false,
negate_iife: true,
reduce_vars: true,
sequences: true,
side_effects: true,

View File

@@ -83,8 +83,9 @@ labels_5: {
conditionals: true,
dead_code: true,
if_return: true,
unused: true,
}
// should keep the break-s in the following
// should keep `break`s below
input: {
while (foo) {
if (bar) break;
@@ -100,8 +101,8 @@ labels_5: {
if (bar) break;
console.log("foo");
}
out: while (foo) {
if (bar) break out;
while (foo) {
if (bar) break;
console.log("foo");
}
}
@@ -110,6 +111,7 @@ labels_5: {
labels_6: {
options = {
dead_code: true,
unused: true,
}
input: {
out: break out;
@@ -189,23 +191,75 @@ labels_10: {
conditionals: true,
dead_code: true,
if_return: true,
unused: true,
}
input: {
out: while (foo) {
x();
y();
out: while (42) {
console.log("PASS");
break out;
z();
k();
console.log("FAIL");
}
};
expect: {
out: while (foo) {
x();
y();
break out;
while (42) {
console.log("PASS");
break;
}
}
expect_stdout: "PASS"
}
labels_11: {
options = {
conditionals: true,
if_return: true,
unused: true,
}
input: {
L: if (console.log("PASS"))
break L;
}
expect: {
console.log("PASS");
}
expect_stdout: "PASS"
}
labels_12: {
options = {
conditionals: true,
dead_code: true,
if_return: true,
}
input: {
L: try {
if (console.log("foo"))
break L;
throw "bar";
} catch (e) {
console.log(e);
break L;
} finally {
if (console.log("baz"))
break L;
}
}
expect: {
L: try {
if (!console.log("foo"))
throw "bar";
} catch (e) {
console.log(e);
} finally {
if (console.log("baz"))
break L;
}
}
expect_stdout: [
"foo",
"bar",
"baz",
]
}
issue_4466_1: {
@@ -327,3 +381,53 @@ issue_4466_2_toplevel_v8: {
}
expect_stdout: "PASS"
}
issue_5522: {
options = {
dead_code: true,
}
input: {
console.log(function() {
L: try {
return "FAIL";
} finally {
break L;
}
return "PASS";
}());
}
expect: {
console.log(function() {
L: try {
return "FAIL";
} finally {
break L;
}
return "PASS";
}());
}
expect_stdout: "PASS"
}
issue_5524: {
options = {
dead_code: true,
}
input: {
L: try {
FAIL;
} finally {
break L;
}
console.log("PASS");
}
expect: {
L: try {
FAIL;
} finally {
break L;
}
console.log("PASS");
}
expect_stdout: "PASS"
}

File diff suppressed because it is too large Load Diff

View File

@@ -193,9 +193,9 @@ evaluate: {
} while (false);
}
expect: {
for(;;)
for (;;)
a();
for(;;)
for (;;)
c();
d();
}
@@ -265,7 +265,7 @@ issue_1532_2: {
issue_186: {
beautify = {
beautify: false,
ie8: false,
ie: false,
}
input: {
var x = 3;
@@ -284,7 +284,7 @@ issue_186: {
issue_186_ie8: {
beautify = {
beautify: false,
ie8: true,
ie: true,
}
input: {
var x = 3;
@@ -303,7 +303,7 @@ issue_186_ie8: {
issue_186_beautify: {
beautify = {
beautify: true,
ie8: false,
ie: false,
}
input: {
var x = 3;
@@ -330,7 +330,7 @@ issue_186_beautify: {
issue_186_beautify_ie8: {
beautify = {
beautify: true,
ie8: true,
ie: true,
}
input: {
var x = 3;
@@ -360,7 +360,7 @@ issue_186_braces: {
beautify = {
beautify: false,
braces: true,
ie8: false,
ie: false,
}
input: {
var x = 3;
@@ -380,7 +380,7 @@ issue_186_braces_ie8: {
beautify = {
beautify: false,
braces: true,
ie8: true,
ie: true,
}
input: {
var x = 3;
@@ -400,7 +400,7 @@ issue_186_beautify_braces: {
beautify = {
beautify: true,
braces: true,
ie8: false,
ie: false,
}
input: {
var x = 3;
@@ -432,7 +432,7 @@ issue_186_beautify_braces_ie8: {
beautify = {
beautify: true,
braces: true,
ie8: true,
ie: true,
}
input: {
var x = 3;
@@ -501,14 +501,14 @@ do_switch: {
}
}
in_parenthesis_1: {
in_parentheses_1: {
input: {
for (("foo" in {});0;);
}
expect_exact: 'for(("foo"in{});0;);'
}
in_parenthesis_2: {
in_parentheses_2: {
input: {
for ((function(){ "foo" in {}; });0;);
}
@@ -828,6 +828,44 @@ empty_for_in_prop_init: {
]
}
for_of: {
input: {
var a = [ "PASS", 42 ];
a.p = "FAIL";
for (a of (null, a))
console.log(a);
}
expect_exact: 'var a=["PASS",42];a.p="FAIL";for(a of(null,a))console.log(a);'
expect_stdout: true
node_version: ">=0.12"
}
for_async_of: {
input: {
var async = [ "PASS", 42 ];
async.p = "FAIL";
for (async of (null, async))
console.log(async);
}
expect_exact: 'var async=["PASS",42];async.p="FAIL";for(async of(null,async))console.log(async);'
expect_stdout: true
node_version: ">=0.12 <16"
}
for_of_regexp: {
input: {
for (var a of /foo/);
}
expect_exact: "for(var a of/foo/);"
}
for_await_of_regexp: {
input: {
for await (var a of /foo/);
}
expect_exact: "for await(var a of/foo/);"
}
issue_3631_1: {
options = {
dead_code: true,
@@ -1052,7 +1090,6 @@ issue_4084: {
options = {
keep_fargs: false,
loops: true,
passes: 2,
reduce_vars: true,
unused: true,
}
@@ -1261,6 +1298,7 @@ issue_4355: {
dead_code: true,
evaluate: true,
loops: true,
passes: 2,
side_effects: true,
unused: true,
}

View File

@@ -37,6 +37,51 @@ just_enough: {
expect_warnings: []
}
drop_semicolon: {
beautify = {
max_line_len: 5,
semicolons: true,
}
input: {
var a;
console.log(a || 42);
}
expect_exact: [
"var a",
"console.log(",
"a||42",
");",
]
expect_stdout: "42"
expect_warnings: [
"WARN: Output exceeds 5 characters",
]
}
template_newline: {
beautify = {
max_line_len: 2,
}
input: {
console.log(`foo
bar`);
}
expect_exact: [
"console.log(",
"`foo",
"bar`",
");",
]
expect_stdout: [
"foo",
"bar",
]
expect_warnings: [
"WARN: Output exceeds 2 characters",
]
node_version: ">=4"
}
issue_304: {
beautify = {
max_line_len: 10,

File diff suppressed because it is too large Load Diff

View File

@@ -122,13 +122,41 @@ negate_iife_4: {
sequences: true,
}
input: {
(function(){ return t })() ? console.log(true) : console.log(false);
(function(){
(function() {
return t;
})() ? console.log(true) : console.log(false);
(function() {
console.log("something");
})();
}
expect: {
!function(){ return t }() ? console.log(false) : console.log(true), function(){
!function() {
return t;
}() ? console.log(false) : console.log(true), !function() {
console.log("something");
}();
}
}
negate_iife_4_drop_side_effect_free: {
options = {
conditionals: true,
negate_iife: true,
sequences: true,
side_effects: true,
}
input: {
(function() {
return t;
})() ? console.log(true) : console.log(false);
(function() {
console.log("something");
})();
}
expect: {
!function() {
return t;
}() ? console.log(false) : console.log(true), function() {
console.log("something");
}();
}
@@ -176,17 +204,49 @@ negate_iife_5: {
sequences: true,
}
input: {
if ((function(){ return t })()) {
if (function() {
return t;
}()) {
foo(true);
} else {
bar(false);
}
(function(){
(function() {
console.log("something");
})();
}
expect: {
!function(){ return t }() ? bar(false) : foo(true), function(){
!function() {
return t;
}() ? bar(false) : foo(true), !function() {
console.log("something");
}();
}
}
negate_iife_5_drop_side_effect_free: {
options = {
conditionals: true,
negate_iife: true,
sequences: true,
side_effects: true,
}
input: {
if (function() {
return t;
}()) {
foo(true);
} else {
bar(false);
}
(function() {
console.log("something");
})();
}
expect: {
!function() {
return t;
}() ? bar(false) : foo(true), function() {
console.log("something");
}();
}
@@ -389,6 +449,7 @@ issue_1288_side_effects: {
options = {
conditionals: true,
negate_iife: true,
sequences: true,
side_effects: true,
}
input: {
@@ -409,10 +470,10 @@ issue_1288_side_effects: {
})(0);
}
expect: {
w;
w,
x || function() {
x = {};
}();
}(),
y;
}
}

View File

@@ -85,7 +85,7 @@ new_with_unary_prefix: {
expect_exact: 'var bar=(+new Date).toString(32);';
}
dot_parenthesis_1: {
dot_parentheses_1: {
input: {
console.log(new (Math.random().constructor) instanceof Number);
}
@@ -93,7 +93,7 @@ dot_parenthesis_1: {
expect_stdout: "true"
}
dot_parenthesis_2: {
dot_parentheses_2: {
input: {
console.log(typeof new function(){Math.random()}.constructor);
}

386
test/compress/nullish.js Normal file
View File

@@ -0,0 +1,386 @@
parentheses: {
input: {
(console.log("foo") || console.log("bar") ?? console.log("baz")) && console.log("moo");
}
expect_exact:'((console.log("foo")||console.log("bar"))??console.log("baz"))&&console.log("moo");'
expect_stdout: [
"foo",
"bar",
"baz",
]
node_version: ">=14"
}
evaluate: {
options = {
evaluate: true,
side_effects: true,
}
input: {
void console.log("foo" ?? "bar") ?? console.log("baz");
}
expect: {
console.log("foo"),
console.log("baz");
}
expect_stdout: [
"foo",
"baz",
]
node_version: ">=14"
}
conditional_assignment_1: {
options = {
collapse_vars: true,
}
input: {
console.log(function(a, b) {
b ?? (a = "FAIL");
return a;
}("PASS", !console));
}
expect: {
console.log(function(a, b) {
b ?? (a = "FAIL");
return a;
}("PASS", !console));
}
expect_stdout: "PASS"
node_version: ">=14"
}
conditional_assignment_2: {
options = {
conditionals: true,
}
input: {
var a, b = false;
a = "PASS",
b ?? (a = "FAIL"),
console.log(a);
}
expect: {
var a, b = false;
a = "PASS",
b ?? (a = "FAIL"),
console.log(a);
}
expect_stdout: "PASS"
node_version: ">=14"
}
conditional_assignment_3: {
options = {
conditionals: true,
join_vars: true,
}
input: {
var a, b = false;
a = "PASS",
b ?? (a = "FAIL"),
console.log(a);
}
expect: {
var a, b = false, a = "PASS";
b ?? (a = "FAIL"),
console.log(a);
}
expect_stdout: "PASS"
node_version: ">=14"
}
conditional_assignment_4: {
options = {
side_effects: true,
}
input: {
console.log(function(a) {
!console ?? (a = "FAIL");
return a;
}("PASS"));
}
expect: {
console.log(function(a) {
!console ?? (a = "FAIL");
return a;
}("PASS"));
}
expect_stdout: "PASS"
node_version: ">=14"
}
de_morgan_1: {
options = {
booleans: true,
}
input: {
function f(a) {
return a ?? a;
}
console.log(f(null), f(42));
}
expect: {
function f(a) {
return a;
}
console.log(f(null), f(42));
}
expect_stdout: "null 42"
node_version: ">=14"
}
de_morgan_2a: {
options = {
booleans: true,
conditionals: true,
evaluate: true,
}
input: {
function f(a, b) {
return a || (a ?? b);
}
console.log(f(null), f(null, {}));
console.log(f(42), f(42, {}));
}
expect: {
function f(a, b) {
return a || (a ?? b);
}
console.log(f(null), f(null, {}));
console.log(f(42), f(42, {}));
}
expect_stdout: [
"undefined {}",
"42 42",
]
node_version: ">=14"
}
de_morgan_2b: {
options = {
booleans: true,
evaluate: true,
}
input: {
function f(a, b) {
return a && (a ?? b);
}
console.log(f(null), f(null, {}));
console.log(f(42), f(42, {}));
}
expect: {
function f(a, b) {
return a;
}
console.log(f(null), f(null, {}));
console.log(f(42), f(42, {}));
}
expect_stdout: [
"null null",
"42 42",
]
node_version: ">=14"
}
de_morgan_2c: {
options = {
booleans: true,
evaluate: true,
side_effects: true,
}
input: {
function f(a, b) {
return a ?? (a || b);
}
console.log(f(null), f(null, {}));
console.log(f(42), f(42, {}));
}
expect: {
function f(a, b) {
return a ?? b;
}
console.log(f(null), f(null, {}));
console.log(f(42), f(42, {}));
}
expect_stdout: [
"undefined {}",
"42 42",
]
node_version: ">=14"
}
de_morgan_2d: {
options = {
booleans: true,
evaluate: true,
}
input: {
function f(a, b) {
return a ?? (a && b);
}
console.log(f(null), f(null, {}));
console.log(f(42), f(42, {}));
}
expect: {
function f(a, b) {
return a;
}
console.log(f(null), f(null, {}));
console.log(f(42), f(42, {}));
}
expect_stdout: [
"null null",
"42 42",
]
node_version: ">=14"
}
de_morgan_2e: {
options = {
booleans: true,
conditionals: true,
}
input: {
function f(a, b) {
return a ?? (a ?? b);
}
console.log(f(null), f(null, {}));
console.log(f(42), f(42, {}));
}
expect: {
function f(a, b) {
return a ?? b;
}
console.log(f(null), f(null, {}));
console.log(f(42), f(42, {}));
}
expect_stdout: [
"undefined {}",
"42 42",
]
node_version: ">=14"
}
inline_binary_nullish: {
options = {
inline: true,
}
input: {
(function() {
while (console.log("foo"));
})() ?? (function() {
while (console.log("bar"));
})();
}
expect: {
if (null == function() {
while (console.log("foo"));
}())
while (console.log("bar"));
}
expect_stdout: [
"foo",
"bar",
]
node_version: ">=14"
}
issue_4679: {
options = {
comparisons: true,
ie: true,
}
input: {
var a;
if (void 0 === (undefined ?? a))
console.log("PASS");
}
expect: {
var a;
if (void 0 === (undefined ?? a))
console.log("PASS");
}
expect_stdout: "PASS"
node_version: ">=14"
}
issue_5266: {
options = {
inline: true,
side_effects: true,
}
input: {
[
42,
null,
false,
void 0,
"FAIL",
].forEach(function (a) {
a ?? function() {
while (console.log(a));
}();
});
}
expect: {
[
42,
null,
false,
void 0,
"FAIL",
].forEach(function (a) {
if (null == a) {
while (console.log(a));
return;
} else
return;
});
}
expect_stdout: [
"null",
"undefined",
]
node_version: ">=14"
}
issue_5829_1: {
options = {
merge_vars: true,
}
input: {
(function f(a) {
var b;
(!a ?? (b = 0)) || console.log(b || "PASS");
})("FAIL");
}
expect: {
(function f(a) {
var b;
(!a ?? (b = 0)) || console.log(b || "PASS");
})("FAIL");
}
expect_stdout: "PASS"
node_version: ">=14"
}
issue_5829_2: {
options = {
merge_vars: true,
}
input: {
(function f(a) {
var b;
(a ?? (b = 0)) && console.log(b || "PASS");
})("FAIL");
}
expect: {
(function f(a) {
var b;
(a ?? (b = 0)) && console.log(b || "PASS");
})("FAIL");
}
expect_stdout: "PASS"
node_version: ">=14"
}

View File

@@ -1,3 +1,10 @@
literal_infinity: {
input: {
console.log(2e308, -1e2345);
}
expect_exact: "console.log(1/0,-(1/0));"
}
parentheses_for_prototype_functions: {
beautify = {
beautify: true,
@@ -97,6 +104,40 @@ parentheses_for_prototype_functions_galio: {
expect_stdout: true
}
octal: {
beautify = {
beautify: true,
}
input: {
(function() {
console.log(052);
console.log(-052);
console.log(018);
console.log(-018);
console.log(052.toFixed(0));
console.log(-052.toFixed(0));
console.log(018..toFixed(0));
console.log(-018..toFixed(0));
})();
}
expect_exact: [
"(function() {",
" console.log(42);",
" console.log(-42);",
" console.log(18);",
" console.log(-18);",
" console.log(42..toFixed(0));",
" console.log(-42..toFixed(0));",
" console.log(18..toFixed(0));",
" console.log(-18..toFixed(0));",
"})();",
]
expect_stdout: true
}
comparisons: {
options = {
comparisons: true,
@@ -777,7 +818,7 @@ issue_1710: {
expect_stdout: true
}
unary_binary_parenthesis: {
unary_binary_parentheses: {
options = {
evaluate: true,
}
@@ -801,9 +842,9 @@ unary_binary_parenthesis: {
v.forEach(function(x) {
v.forEach(function(y) {
console.log(
+x*y,
+x/y,
+x%y,
x*y,
x/y,
x%y,
-x*y,
-x/y,
-x%y
@@ -1356,7 +1397,7 @@ issue_3695: {
}
expect: {
var a = [];
console.log(+(a * (a[0] = false)));
console.log(a * (a[0] = false));
}
expect_stdout: "NaN"
}

View File

@@ -173,7 +173,9 @@ numeric_literal: {
side_effects: true,
}
mangle = {
properties: true,
properties: {
domprops: true,
},
}
beautify = {
beautify: true,
@@ -280,6 +282,72 @@ shorthand_keywords: {
node_version: ">=6"
}
object_super: {
input: {
var o = {
f() {
return super.p;
},
p: "FAIL",
};
Object.setPrototypeOf(o, { p: "PASS" });
console.log(o.f());
}
expect_exact: 'var o={f(){return super.p},p:"FAIL"};Object.setPrototypeOf(o,{p:"PASS"});console.log(o.f());'
expect_stdout: "PASS"
node_version: ">=4"
}
object_super_async: {
input: {
var o = {
async f() {
return super.p;
},
p: "FAIL",
};
Object.setPrototypeOf(o, { p: "PASS" });
o.f().then(console.log);
}
expect_exact: 'var o={async f(){return super.p},p:"FAIL"};Object.setPrototypeOf(o,{p:"PASS"});o.f().then(console.log);'
expect_stdout: "PASS"
node_version: ">=8"
}
object_super_generator: {
input: {
var o = {
*f() {
yield super.p;
},
p: "FAIL",
};
Object.setPrototypeOf(o, { p: "PASS" });
console.log(o.f().next().value);
}
expect_exact: 'var o={*f(){yield super.p},p:"FAIL"};Object.setPrototypeOf(o,{p:"PASS"});console.log(o.f().next().value);'
expect_stdout: "PASS"
node_version: ">=4"
}
object_super_async_generator: {
input: {
var o = {
async *f() {
return super.p;
},
p: "FAIL",
};
Object.setPrototypeOf(o, { p: "PASS" });
o.f().next().then(function(v) {
console.log(v.value, v.done);
});
}
expect_exact: 'var o={async*f(){return super.p},p:"FAIL"};Object.setPrototypeOf(o,{p:"PASS"});o.f().next().then(function(v){console.log(v.value,v.done)});'
expect_stdout: "PASS true"
node_version: ">=10"
}
issue_4269_1: {
options = {
evaluate: true,
@@ -455,3 +523,25 @@ issue_4415: {
expect_stdout: "PASS"
node_version: ">=4"
}
issue_5213: {
options = {
objects: true,
}
input: {
var a = "FAIL";
console.log({
p: a = "PASS",
0: a,
p: null,
}[0]);
}
expect: {
var a = "FAIL";
console.log({
p: (a = "PASS", null),
0: a,
}[0]);
}
expect_stdout: "PASS"
}

View File

@@ -0,0 +1,649 @@
call: {
input: {
console.log?.(undefined?.(console.log("FAIL")));
}
expect_exact: 'console.log?.((void 0)?.(console.log("FAIL")));'
expect_stdout: "undefined"
node_version: ">=14"
}
dot: {
input: {
console?.log((void 0)?.p);
}
expect_exact: "console?.log((void 0)?.p);"
expect_stdout: "undefined"
node_version: ">=14"
}
dot_in: {
input: {
var o = { in: 42 };
console.log(o.in, o?.in);
}
expect_exact: "var o={in:42};console.log(o.in,o?.in);"
expect_stdout: "42 42"
node_version: ">=14"
}
sub: {
input: {
console?.["log"](null?.[console.log("FAIL")]);
}
expect_exact: 'console?.["log"](null?.[console.log("FAIL")]);'
expect_stdout: "undefined"
node_version: ">=14"
}
ternary_decimal: {
input: {
null ? .42 : console.log("PASS");
}
expect_exact: 'null?.42:console.log("PASS");'
expect_stdout: "PASS"
}
assign_parentheses_call: {
input: {
var o = {};
((() => o)?.()).p = "PASS";
console.log(o.p);
}
expect_exact: 'var o={};((()=>o)?.()).p="PASS";console.log(o.p);'
expect_stdout: "PASS"
node_version: ">=14"
}
assign_parentheses_dot: {
input: {
(console?.log).name.p = console.log("PASS");
}
expect_exact: '(console?.log).name.p=console.log("PASS");'
expect_stdout: "PASS"
node_version: ">=14"
}
assign_no_parentheses: {
input: {
console[console.log?.("PASS")] = 42;
}
expect_exact: 'console[console.log?.("PASS")]=42;'
expect_stdout: "PASS"
node_version: ">=14"
}
call_parentheses: {
input: {
(function(o) {
console.log(o.f("FAIL"), (o.f)("FAIL"), (0, o.f)(42));
console.log(o?.f("FAIL"), (o?.f)("FAIL"), (0, o?.f)(42));
})({
a: "PASS",
f(b) {
return this.a || b;
},
});
}
expect_exact: '(function(o){console.log(o.f("FAIL"),o.f("FAIL"),(0,o.f)(42));console.log(o?.f("FAIL"),(o?.f)("FAIL"),(0,o?.f)(42))})({a:"PASS",f(b){return this.a||b}});'
expect_stdout: [
"PASS PASS 42",
"PASS PASS 42",
]
node_version: ">=14"
}
unary_parentheses: {
input: {
var o = { p: 41 };
(function() {
return o;
}?.()).p++;
console.log(o.p);
}
expect_exact: "var o={p:41};(function(){return o}?.()).p++;console.log(o.p);"
expect_stdout: "42"
node_version: ">=14"
}
collapse_vars_1: {
options = {
collapse_vars: true,
}
input: {
var a;
A = 42;
a?.[42];
console.log(typeof A);
}
expect: {
var a;
A = 42;
a?.[42];
console.log(typeof A);
}
expect_stdout: "number"
node_version: ">=14"
}
collapse_vars_2: {
options = {
collapse_vars: true,
}
input: {
var a;
A = 42;
a?.(42);
console.log(typeof A);
}
expect: {
var a;
A = 42;
a?.(42);
console.log(typeof A);
}
expect_stdout: "number"
node_version: ">=14"
}
properties: {
options = {
evaluate: true,
properties: true,
}
input: {
var a;
console.log(a?.["FAIL"]);
}
expect: {
var a;
console.log(a?.FAIL);
}
expect_stdout: "undefined"
node_version: ">=14"
}
reduce_vars_1: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
}
input: {
var a = 1;
null?.[a = 0];
console.log(a ? "PASS" : "FAIL");
}
expect: {
var a = 1;
null?.[a = 0];
console.log(a ? "PASS" : "FAIL");
}
expect_stdout: "PASS"
node_version: ">=14"
}
reduce_vars_2: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
}
input: {
var a = 1;
null?.(a = 0);
console.log(a ? "PASS" : "FAIL");
}
expect: {
var a = 1;
null?.(a = 0);
console.log(a ? "PASS" : "FAIL");
}
expect_stdout: "PASS"
node_version: ">=14"
}
side_effects: {
options = {
side_effects: true,
}
input: {
var a;
a?.[a = "FAIL"];
console.log(a);
}
expect: {
var a;
a?.[a = "FAIL"];
console.log(a);
}
expect_stdout: "undefined"
node_version: ">=14"
}
trim_1: {
options = {
evaluate: true,
optional_chains: true,
reduce_vars: true,
unsafe: true,
}
input: {
(function(a, b) {
console?.log?.(a?.p, b?.[console.log("FAIL")]);
})?.({ p: "PASS" });
}
expect: {
(function(a, b) {
console?.log?.(a.p, void 0);
})({ p: "PASS" });
}
expect_stdout: "PASS undefined"
node_version: ">=14"
}
trim_2: {
options = {
evaluate: true,
optional_chains: true,
side_effects: true,
}
input: {
(void console.log("PASS"))?.[console.log("FAIL")];
}
expect: {
console.log("PASS");
}
expect_stdout: "PASS"
node_version: ">=14"
}
trim_dot_call_1: {
options = {
evaluate: true,
optional_chains: true,
}
input: {
console.log(null?.f());
}
expect: {
console.log(void 0);
}
expect_stdout: "undefined"
node_version: ">=14"
}
trim_dot_call_2: {
options = {
evaluate: true,
optional_chains: true,
unsafe: true,
}
input: {
try {
(null?.p)();
} catch (e) {
console.log("PASS");
}
}
expect: {
try {
(void 0)();
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "PASS"
node_version: ">=14"
}
trim_dot_call_3: {
options = {
evaluate: true,
optional_chains: true,
unsafe: true,
}
input: {
try {
({ p: null })?.p();
} catch (e) {
console.log("PASS");
}
}
expect: {
try {
null();
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "PASS"
node_version: ">=14"
}
trim_dot_sub: {
options = {
evaluate: true,
optional_chains: true,
}
input: {
console.log(null?.p[42]);
}
expect: {
console.log(void 0);
}
expect_stdout: "undefined"
node_version: ">=14"
}
trim_sub_call_call: {
options = {
evaluate: true,
optional_chains: true,
}
input: {
console.log(null?.[42]()());
}
expect: {
console.log(void 0);
}
expect_stdout: "undefined"
node_version: ">=14"
}
issue_4906: {
options = {
toplevel: true,
unused: true,
}
input: {
do {
var a = a?.[42];
} while (console.log("PASS"));
}
expect: {
do {
var a = a?.[42];
} while (console.log("PASS"));
}
expect_stdout: "PASS"
node_version: ">=14"
}
issue_4928: {
options = {
ie: true,
toplevel: true,
unused: true,
}
input: {
var a = a?.[function f() {
f(a);
}];
console.log(typeof f);
}
expect: {
var a = a?.[function f() {
f(a);
}];
console.log(typeof f);
}
expect_stdout: "undefined"
node_version: ">=14"
}
issue_4947_1: {
options = {
conditionals: true,
}
input: {
console.log(console.foo ? 42..p : console.bar?.p);
}
expect: {
console.log(console.foo ? 42..p : console.bar?.p);
}
expect_stdout: "undefined"
node_version: ">=14"
}
issue_4947_2: {
options = {
conditionals: true,
}
input: {
var log = console.log, fail;
log("PASS") ? log(42) : fail?.(42);
}
expect: {
var log = console.log, fail;
log("PASS") ? log(42) : fail?.(42);
}
expect_stdout: "PASS"
node_version: ">=14"
}
issue_5039: {
options = {
ie: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var a = a?.[function f() {
f;
a;
}];
console.log("PASS");
}
expect: {
var a = a?.[function f() {}];
console.log("PASS");
}
expect_stdout: "PASS"
node_version: ">=14"
}
issue_5091: {
options = {
merge_vars: true,
}
input: {
function f(a) {
var b = a.p;
var c;
b?.[c = "FAIL 2"];
return b || c;
}
console.log(f("FAIL 1") || "PASS");
}
expect: {
function f(a) {
var a = a.p;
var c;
a?.[c = "FAIL 2"];
return a || c;
}
console.log(f("FAIL 1") || "PASS");
}
expect_stdout: "PASS"
node_version: ">=14"
}
issue_5292_dot: {
options = {
side_effects: true,
}
input: {
var o = {
get p() {
console.log("PASS");
}
};
o?.p;
}
expect: {
var o = {
get p() {
console.log("PASS");
}
};
o?.p;
}
expect_stdout: "PASS"
node_version: ">=14"
}
issue_5292_dot_pure_getters: {
options = {
pure_getters: true,
side_effects: true,
}
input: {
var o = {
get p() {
console.log("PASS");
}
};
o?.p;
}
expect: {
var o = {
get p() {
console.log("PASS");
}
};
}
}
issue_5292_dot_pure_getters_strict: {
options = {
pure_getters: "strict",
side_effects: true,
}
input: {
var o = {
get p() {
console.log("PASS");
}
};
o?.p;
}
expect: {
var o = {
get p() {
console.log("PASS");
}
};
o?.p;
}
expect_stdout: "PASS"
node_version: ">=14"
}
issue_5292_sub: {
options = {
side_effects: true,
}
input: {
var o = {
get p() {
console.log("foo");
}
};
o?.[console.log("bar"), "p"];
}
expect: {
var o = {
get p() {
console.log("foo");
}
};
o?.[console.log("bar"), "p"];
}
expect_stdout: [
"bar",
"foo",
]
node_version: ">=14"
}
issue_5292_sub_pure_getters: {
options = {
pure_getters: true,
side_effects: true,
}
input: {
var o = {
get p() {
console.log("foo");
}
};
o?.[console.log("bar"), "p"];
}
expect: {
var o = {
get p() {
console.log("foo");
}
};
console.log("bar");
}
}
issue_5292_sub_pure_getters_strict: {
options = {
pure_getters: "strict",
side_effects: true,
}
input: {
var o = {
get p() {
console.log("foo");
}
};
o?.[console.log("bar"), "p"];
}
expect: {
var o = {
get p() {
console.log("foo");
}
};
o?.[console.log("bar"), "p"];
}
expect_stdout: [
"bar",
"foo",
]
node_version: ">=14"
}
issue_5856: {
options = {
pure_getters: "strict",
reduce_vars: true,
side_effects: true,
}
input: {
try {
var a;
a?.p;
a.q;
console.log("FAIL");
} catch (e) {
console.log("PASS");
}
}
expect: {
try {
var a;
a?.p;
a.q;
console.log("FAIL");
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "PASS"
node_version: ">=14"
}

View File

@@ -97,10 +97,10 @@ return_5: {
}
expect_exact: [
"_is_selected=function(tags,slug){",
"var ref",
"var ref;",
"",
"",
";return null!=(ref=_.find(tags,{slug:slug}))?ref.selected:void 0};",
"return null!=(ref=_.find(tags,{slug:slug}))?ref.selected:void 0};",
]
}
@@ -146,10 +146,10 @@ return_7: {
}
expect_exact: [
"_is_selected=function(e,l){",
"var n",
"var n;",
"",
"",
";return null!=(n=_.find(e,{slug:l}))?n.selected:void 0};",
"return null!=(n=_.find(e,{slug:l}))?n.selected:void 0};",
]
}

View File

@@ -17,7 +17,7 @@ dot_properties: {
properties: true,
}
beautify = {
ie8: true,
ie: true,
}
input: {
a["foo"] = "bar";
@@ -43,7 +43,7 @@ dot_properties_es5: {
properties: true,
}
beautify = {
ie8: false,
ie: false,
}
input: {
a["foo"] = "bar";
@@ -133,6 +133,7 @@ evaluate_string_length: {
mangle_properties_1: {
mangle = {
properties: {
domprops: true,
keep_quoted: false,
},
}
@@ -147,17 +148,18 @@ mangle_properties_1: {
a["a"] = "bar";
a.b = "red";
x = {o: 10};
a.r(x.o, a.a);
a['r']({b: "blue", a: "baz"});
a.run(x.o, a.a);
a['run']({b: "blue", a: "baz"});
}
}
mangle_properties_2: {
mangle = {
properties: {
domprops: true,
reserved: [
"value",
]
],
},
}
input: {
@@ -199,6 +201,24 @@ mangle_properties_2: {
]
}
mangle_properties_3: {
mangle = {
properties: true,
}
input: {
console.log({
[(console, "foo")]: "PASS",
}.foo);
}
expect: {
console.log({
[(console, "o")]: "PASS",
}.o);
}
expect_stdout: "PASS"
node_version: ">=4"
}
mangle_unquoted_properties: {
options = {
evaluate: true,
@@ -206,6 +226,8 @@ mangle_unquoted_properties: {
}
mangle = {
properties: {
builtins: true,
domprops: true,
keep_quoted: true,
},
}
@@ -305,7 +327,9 @@ mangle_debug_suffix_keep_quoted: {
}
mangle = {
properties: {
builtins: true,
debug: "XYZ",
domprops: true,
keep_quoted: true,
reserved: [],
},
@@ -351,6 +375,68 @@ mangle_debug_suffix_keep_quoted: {
}
}
keep_substituted_property: {
options = {
evaluate: true,
properties: true,
reduce_vars: true,
}
mangle = {
properties: {
keep_quoted: true,
},
}
input: {
var o = { p: [] };
function f(b) {
return o[b];
}
function g() {
var a = "p";
return o[a] === f(a);
}
console.log(g() ? "PASS" : "FAIL");
}
expect: {
var o = { p: [] };
function f(n) {
return o[n];
}
function g() {
var n = "p";
return o.p === f(n);
}
console.log(g() ? "PASS" : "FAIL");
}
expect_stdout: "PASS"
}
keep_substituted_property_quotes: {
options = {
evaluate: true,
properties: true,
reduce_vars: true,
}
beautify = {
keep_quoted_props: true,
}
input: {
function f(o) {
var a = "p";
return o[a];
}
console.log(f({ p: "PASS" }));
}
expect: {
function f(o) {
var a = "p";
return o["p"];
}
console.log(f({ p: "PASS" }));
}
expect_stdout: "PASS"
}
first_256_chars_as_properties: {
beautify = {
ascii_only: true,
@@ -897,12 +983,15 @@ issue_2256: {
},
}
input: {
({ "keep": 1 });
g.keep = g.change;
({ "keep": 42 });
global.keep = global.change = "PASS";
console.log(keep);
}
expect: {
g.keep = g.g;
global.keep = global.l = "PASS";
console.log(keep);
}
expect_stdout: "PASS"
}
lhs_prop_1: {
@@ -1378,3 +1467,363 @@ issue_3389: {
}
expect_stdout: "PASS"
}
object_super: {
options = {
properties: true,
}
input: {
({
f(a) {
return a ? console.log("PASS") : super.log("PASS");
},
}).f(console);
}
expect: {
({
f(a) {
return a ? console.log("PASS") : super.log("PASS");
},
}).f(console);
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_4831_1: {
options = {
properties: true,
}
input: {
console.log({
f() {
return arguments;
},
}.f("PASS")[0]);
}
expect: {
console.log([
function() {
return arguments;
},
][0]("PASS")[0]);
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_4831_2: {
options = {
properties: true,
}
input: {
var f = {
f() {
return arguments;
},
}.f;
console.log(f("PASS")[0]);
}
expect: {
var f = {
f() {
return arguments;
},
}.f;
console.log(f("PASS")[0]);
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_4888: {
options = {
properties: true,
}
input: {
console.log(typeof {
__proto__: 42,
}.__proto__);
}
expect: {
console.log(typeof {
__proto__: 42,
}.__proto__);
}
expect_stdout: "object"
}
issue_5093: {
beautify = {
keep_quoted_props: true,
}
input: {
console.log({
a: true,
'42': "PASS",
"null": [],
}[6 * 7]);
}
expect_exact: 'console.log({a:true,"42":"PASS","null":[]}[6*7]);'
expect_stdout: "PASS"
}
issue_5093_quote_keys: {
beautify = {
keep_quoted_props: true,
quote_keys: true,
}
input: {
console.log({
a: true,
'42': "PASS",
"null": [],
}[6 * 7]);
}
expect_exact: 'console.log({"a":true,"42":"PASS","null":[]}[6*7]);'
expect_stdout: "PASS"
}
issue_5093_quote_style: {
beautify = {
keep_quoted_props: true,
quote_style: 3,
}
input: {
console.log({
a: true,
'42': "PASS",
"null": [],
}[6 * 7]);
}
expect_exact: 'console.log({a:true,\'42\':"PASS","null":[]}[6*7]);'
expect_stdout: "PASS"
}
object_methods: {
options = {
properties: true,
}
input: {
({
p() {
console.log("FAIL 1");
},
*q() {
console.log("FAIL 2");
},
async r() {
console.log("FAIL 3");
},
async *s() {
console.log("PASS");
},
}).s().next();
}
expect: {
[
() => {
console.log("FAIL 1");
},
function*() {
console.log("FAIL 2");
},
async () => {
console.log("FAIL 3");
},
async function*() {
console.log("PASS");
},
][3]().next();
}
expect_stdout: "PASS"
node_version: ">=10"
}
issue_5177: {
options = {
properties: true,
}
input: {
var a = "FAIL";
var o = { a: "PASS" };
o.p = {
q() {
return this.a;
},
}.q;
console.log(o.p());
}
expect: {
var a = "FAIL";
var o = { a: "PASS" };
o.p = {
q() {
return this.a;
},
}.q;
console.log(o.p());
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_5682_in_1: {
mangle = {
properties: true,
}
input: {
function f(a) {
return "foo" in a;
}
var o = {};
var p = "foo";
o[p] = 42;
console.log(f(o) ? "PASS" : "FAIL");
}
expect: {
function f(o) {
return "foo" in o;
}
var o = {};
var p = "foo";
o[p] = 42;
console.log(f(o) ? "PASS" : "FAIL");
}
expect_stdout: "PASS"
}
issue_5682_in_2: {
mangle = {
properties: true,
}
input: {
function f(a) {
return "foo" in a;
}
var o = { foo: 42 };
console.log(f(o) ? "PASS" : "FAIL");
}
expect: {
function f(o) {
return "o" in o;
}
var o = { o: 42 };
console.log(f(o) ? "PASS" : "FAIL");
}
expect_stdout: "PASS"
}
issue_5682_dot_1: {
mangle = {
properties: true,
}
input: {
function f(a) {
return a.foo;
}
var o = {};
var p = "foo";
o[p] = "PASS";
console.log(f(o));
}
expect: {
function f(o) {
return o.foo;
}
var o = {};
var p = "foo";
o[p] = "PASS";
console.log(f(o));
}
expect_stdout: "PASS"
}
issue_5682_dot_2: {
mangle = {
properties: true,
}
input: {
function f(a) {
return a.foo;
}
var o = { foo: "PASS" };
console.log(f(o));
}
expect: {
function f(o) {
return o.o;
}
var o = { o: "PASS" };
console.log(f(o));
}
expect_stdout: "PASS"
}
issue_5682_dot_2_computed: {
mangle = {
properties: true,
}
input: {
function f(a) {
return a.foo;
}
var o = { ["foo"]: "PASS" };
console.log(f(o));
}
expect: {
function f(o) {
return o.o;
}
var o = { ["o"]: "PASS" };
console.log(f(o));
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_5682_sub_1: {
mangle = {
properties: true,
}
input: {
function f(a) {
return a["foo"];
}
var o = {};
var p = "foo";
o[p] = "PASS";
console.log(f(o));
}
expect: {
function f(o) {
return o["foo"];
}
var o = {};
var p = "foo";
o[p] = "PASS";
console.log(f(o));
}
expect_stdout: "PASS"
}
issue_5682_sub_2: {
mangle = {
properties: true,
}
input: {
function f(a) {
return a["foo"];
}
var o = { foo: "PASS" };
console.log(f(o));
}
expect: {
function f(o) {
return o["o"];
}
var o = { o: "PASS" };
console.log(f(o));
}
expect_stdout: "PASS"
}

View File

@@ -133,7 +133,7 @@ conditional: {
relational: {
options = {
pure_funcs: [ "foo" ],
side_effects :true,
side_effects: true,
}
input: {
foo() in new foo();
@@ -147,7 +147,7 @@ relational: {
"bar" >= "bar";
}
expect: {
bar();
[] instanceof bar();
bar();
bar(), bar();
bar();
@@ -158,7 +158,7 @@ relational: {
arithmetic: {
options = {
pure_funcs: [ "foo" ],
side_effects :true,
side_effects: true,
}
input: {
foo() + foo();
@@ -183,7 +183,7 @@ arithmetic: {
boolean_and: {
options = {
pure_funcs: [ "foo" ],
side_effects :true,
side_effects: true,
}
input: {
foo() && foo();
@@ -208,7 +208,7 @@ boolean_and: {
boolean_or: {
options = {
pure_funcs: [ "foo" ],
side_effects :true,
side_effects: true,
}
input: {
foo() || foo();
@@ -233,7 +233,7 @@ boolean_or: {
assign: {
options = {
pure_funcs: [ "foo" ],
side_effects :true,
side_effects: true,
}
input: {
var a;
@@ -256,7 +256,7 @@ assign: {
unary: {
options = {
pure_funcs: [ "foo" ],
side_effects :true,
side_effects: true,
}
input: {
typeof foo();
@@ -294,248 +294,6 @@ unary: {
}
}
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,
@@ -680,130 +438,3 @@ issue_3325_2: {
}
expect_stdout: "PASS"
}
issue_3858: {
options = {
collapse_vars: true,
inline: true,
keep_fargs: false,
unused: true,
}
input: {
var f = function(a) {
return /*@__PURE__*/ function(b) {
console.log(b);
}(a);
};
f("PASS");
}
expect: {
var f = function(a) {
return function() {
console.log(a);
}();
};
f("PASS");
}
expect_stdout: "PASS"
}
inline_pure_call_1: {
options = {
collapse_vars: true,
inline: true,
keep_fargs: false,
reduce_vars: true,
sequences: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var f = function(a) {
return /*@__PURE__*/ function(b) {
console.log(b);
}(a);
};
f("PASS");
}
expect: {}
}
inline_pure_call_2: {
options = {
collapse_vars: true,
inline: true,
keep_fargs: false,
reduce_vars: true,
sequences: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var f = function(a) {
return /*@__PURE__*/ function(b) {
console.log(b);
}(a);
};
var a = f("PASS");
}
expect: {}
}
inline_pure_call_3: {
options = {
collapse_vars: true,
evaluate: true,
inline: true,
keep_fargs: false,
passes: 2,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var f = function(a) {
return /*@__PURE__*/ function(b) {
console.log(b);
}(a);
};
var a = f("PASS");
console.log(a);
}
expect: {
var a = function() {
console.log("PASS");
}();
console.log(a);
}
expect_stdout: [
"PASS",
"undefined",
]
}
inline_pure_call_4: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = /*@__PURE__*/ function() {
return console.log("PASS"), 42;
}();
console.log(a);
}
expect: {
var a = function() {
return console.log("PASS"), 42;
}();
console.log(a);
}
expect_stdout: [
"PASS",
"42",
]
}

View File

@@ -248,6 +248,35 @@ issue_2110_2: {
expect_stdout: "function"
}
issue_2110_3: {
options = {
collapse_vars: true,
pure_getters: "strict",
reduce_vars: true,
}
input: {
function g() {
return this;
}
console.log(typeof function() {
function f() {}
f.g = g;
return f.g();
}());
}
expect: {
function g() {
return this;
}
console.log(typeof function() {
function f() {}
f.g = g;
return f.g();
}());
}
expect_stdout: "function"
}
set_immutable_1: {
options = {
collapse_vars: true,
@@ -1191,13 +1220,112 @@ drop_arguments: {
expect_stdout: "PASS"
}
lvalues_def: {
options = {
collapse_vars: true,
pure_getters: true,
side_effects: true,
unused: true,
}
input: {
var a = 0, b = 1;
var a = b++, b = +function() {}();
a && a[a++];
console.log(a, b);
}
expect: {
var a = 0, b = 1;
a = b++, b = +void 0;
a && a++;
console.log(a, b);
}
expect_stdout: true
}
side_effects_assign: {
options = {
evaluate: true,
pure_getters: true,
reduce_funcs: true,
reduce_vars: true,
sequences: true,
side_effects: true,
toplevel: true,
}
input: {
var a = typeof void (a && a.in == 1, 0);
console.log(a);
}
expect: {
var a = "undefined";
console.log(a);
}
expect_stdout: "undefined"
}
issue_2062: {
options = {
booleans: true,
collapse_vars: true,
conditionals: true,
pure_getters: true,
side_effects: true,
}
input: {
var a = 1;
if ([ a || a++ + a--, a++ + a--, a && a.var ]);
console.log(a);
}
expect: {
var a = 1;
a || (a++, a--), a++, a--;
console.log(a);
}
expect_stdout: "1"
}
issue_2878: {
options = {
collapse_vars: true,
pure_getters: true,
sequences: true,
side_effects: true,
}
input: {
var c = 0;
(function(a, b) {
function f2() {
if (a) c++;
}
b = f2();
a = 1;
b && b.b;
f2();
})();
console.log(c);
}
expect: {
var c = 0;
(function(a, b) {
function f2() {
if (a) c++;
}
b = f2(),
a = 1,
f2();
})(),
console.log(c);
}
expect_stdout: "1"
}
issue_3427: {
options = {
assignments: true,
collapse_vars: true,
evaluate: true,
inline: true,
passes: 2,
pure_getters: "strict",
reduce_vars: true,
sequences: true,
side_effects: true,
toplevel: true,
@@ -1213,6 +1341,73 @@ issue_3427: {
expect_stdout: true
}
issue_3490_1: {
options = {
conditionals: true,
dead_code: true,
inline: true,
pure_getters: true,
sequences: true,
side_effects: true,
toplevel: true,
}
input: {
var b = 42, c = "FAIL";
if ({
3: function() {
var a;
return (a && a.p) < this;
}(),
}) c = "PASS";
if (b) while ("" == typeof d);
console.log(c, b);
}
expect: {
var b = 42, c = "FAIL";
var a;
if (c = "PASS", b) while ("" == typeof d);
console.log(c, b);
}
expect_stdout: "PASS 42"
}
issue_4135: {
options = {
evaluate: true,
inline: true,
merge_vars: true,
pure_getters: true,
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var a = 0, b = 0;
--b;
a++;
if (!a)
var c = function() {
var d = 0;
function f() {
d && d.p;
}
f();
this;
}(a++);
console.log(a, b, c);
}
expect: {
var a = 0;
0;
a++;
if (!a)
var c = void a++;
console.log(a, -1, c);
}
expect_stdout: "1 -1 undefined"
}
issue_4440: {
options = {
pure_getters: "strict",
@@ -1241,3 +1436,282 @@ issue_4440: {
}
expect_stdout: "PASS"
}
issue_4730_1: {
options = {
pure_getters: true,
side_effects: true,
}
input: {
var a;
console.log("PASS") + (a && a[a.p]);
}
expect: {
var a;
console.log("PASS");
}
expect_stdout: "PASS"
}
issue_4730_2: {
options = {
pure_getters: true,
side_effects: true,
}
input: {
var a;
!console.log("PASS") || a && a[a.p];
}
expect: {
var a;
console.log("PASS");
}
expect_stdout: "PASS"
}
issue_4751: {
options = {
pure_getters: true,
side_effects: true,
}
input: {
var o = {
get p() {
console.log("PASS");
},
};
o && o.p;
}
expect: {
var o = {
get p() {
console.log("PASS");
},
};
}
}
super_toString: {
options = {
pure_getters: true,
unsafe: true,
}
input: {
console.log({
f() {
return super.toString();
},
}.f());
}
expect: {
console.log({
f() {
return super.toString();
},
}.f());
}
expect_stdout: "[object Object]"
node_version: ">=4"
}
this_toString: {
options = {
pure_getters: true,
unsafe: true,
}
input: {
console.log({
f() {
return this.toString();
},
}.f());
}
expect: {
console.log({
f() {
return "" + this;
},
}.f());
}
expect_stdout: "[object Object]"
node_version: ">=4"
}
issue_4803: {
options = {
hoist_vars: true,
join_vars: true,
pure_getters: "strict",
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var o = {
get f() {
console.log("PASS");
},
} || 42;
for (var k in o)
o[k];
}
expect: {
var k, o = {
get f() {
console.log("PASS");
},
} || 42;
for (k in o)
o[k];
}
expect_stdout: "PASS"
}
nested_property_assignments_1: {
options = {
pure_getters: "strict",
reduce_vars: true,
sequences: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var f;
((f = function() {
console.log("FAIL");
}).p = f).q = console.log("PASS");
}
expect: {
console.log("PASS");
}
expect_stdout: "PASS"
}
nested_property_assignments_2: {
options = {
pure_getters: "strict",
unused: true,
}
input: {
var o = {};
(function() {
var a;
(o.p = a = {}).q = "PASS";
})();
console.log(o.p.q);
}
expect: {
var o = {};
(function() {
(o.p = {}).q = "PASS";
})();
console.log(o.p.q);
}
expect_stdout: "PASS"
}
nested_property_assignments_3: {
options = {
collapse_vars: true,
pure_getters: true,
side_effects: true,
unused: true,
}
input: {
var o = { p: {} };
(function(a) {
console && a;
if (console) {
a = a.p;
a.q = a;
}
})(o);
console.log(o.p.q === o.p ? "PASS" : "FAIL");
}
expect: {
var o = { p: {} };
(function(a) {
console;
if (console)
(a = a.p).q = a;
})(o);
console.log(o.p.q === o.p ? "PASS" : "FAIL");
}
expect_stdout: "PASS"
}
nested_property_assignments_4: {
options = {
pure_getters: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var n, o = { p: { q: { r: "PASS" } } };
(n = o.p).r = n.q.r;
console.log(o.p.r);
}
expect: {
var n, o = { p: { q: { r: "PASS" } } };
(n = o.p).r = n.q.r;
console.log(o.p.r);
}
expect_stdout: "PASS"
}
issue_4939: {
options = {
pure_getters: "strict",
side_effects: true,
}
input: {
({
__proto__: {
get p() {
console.log("PASS");
},
},
}).p;
}
expect: {
({
__proto__: {
get p() {
console.log("PASS");
},
},
}).p;
}
expect_stdout: "PASS"
}
issue_5856: {
options = {
pure_getters: true,
reduce_vars: true,
side_effects: true,
unused: true,
}
input: {
var a = [ "FAIL", "PASS" ];
(function(b) {
var c = b[0];
b[0] = b[1];
b[1] = c;
})(a);
console.log(a[0]);
}
expect: {
var a = [ "FAIL", "PASS" ];
(function(b) {
var c = b[0];
b[0] = b[1];
b[1] = c;
})(a);
console.log(a[0]);
}
expect_stdout: "PASS"
}

File diff suppressed because it is too large Load Diff

View File

@@ -50,6 +50,22 @@ regexp_properties: {
expect_stdout: "abc true false 0 false"
}
instanceof_1: {
input: {
console.log(/foo/ instanceof RegExp);
}
expect_exact: "console.log(/foo/ instanceof RegExp);"
expect_stdout: "true"
}
instanceof_2: {
input: {
console.log(42 + /foo/ instanceof Object);
}
expect_exact: "console.log(42+/foo/ instanceof Object);"
expect_stdout: "false"
}
issue_3434_1: {
options = {
evaluate: true,

View File

@@ -1,11 +1,11 @@
mangle_catch: {
rename = true
options = {
ie8: false,
ie: false,
toplevel: false,
}
mangle = {
ie8: false,
ie: false,
toplevel: false,
}
input: {
@@ -24,11 +24,11 @@ mangle_catch: {
mangle_catch_ie8: {
rename = true
options = {
ie8: true,
ie: true,
toplevel: false,
}
mangle = {
ie8: true,
ie: true,
toplevel: false,
}
input: {
@@ -47,11 +47,11 @@ mangle_catch_ie8: {
mangle_catch_var: {
rename = true
options = {
ie8: false,
ie: false,
toplevel: false,
}
mangle = {
ie8: false,
ie: false,
toplevel: false,
}
input: {
@@ -70,11 +70,11 @@ mangle_catch_var: {
mangle_catch_var_ie8: {
rename = true
options = {
ie8: true,
ie: true,
toplevel: false,
}
mangle = {
ie8: true,
ie: true,
toplevel: false,
}
input: {
@@ -93,11 +93,11 @@ mangle_catch_var_ie8: {
mangle_catch_toplevel: {
rename = true
options = {
ie8: false,
ie: false,
toplevel: true,
}
mangle = {
ie8: false,
ie: false,
toplevel: true,
}
input: {
@@ -116,11 +116,11 @@ mangle_catch_toplevel: {
mangle_catch_ie8_toplevel: {
rename = true
options = {
ie8: true,
ie: true,
toplevel: true,
}
mangle = {
ie8: true,
ie: true,
toplevel: true,
}
input: {
@@ -139,11 +139,11 @@ mangle_catch_ie8_toplevel: {
mangle_catch_var_toplevel: {
rename = true
options = {
ie8: false,
ie: false,
toplevel: true,
}
mangle = {
ie8: false,
ie: false,
toplevel: true,
}
input: {
@@ -162,11 +162,11 @@ mangle_catch_var_toplevel: {
mangle_catch_var_ie8_toplevel: {
rename = true
options = {
ie8: true,
ie: true,
toplevel: true,
}
mangle = {
ie8: true,
ie: true,
toplevel: true,
}
input: {
@@ -185,11 +185,11 @@ mangle_catch_var_ie8_toplevel: {
mangle_catch_redef_1: {
rename = true
options = {
ie8: false,
ie: false,
toplevel: false,
}
mangle = {
ie8: false,
ie: false,
toplevel: false,
}
input: {
@@ -208,11 +208,11 @@ mangle_catch_redef_1: {
mangle_catch_redef_1_ie8: {
rename = true
options = {
ie8: true,
ie: true,
toplevel: false,
}
mangle = {
ie8: true,
ie: true,
toplevel: false,
}
input: {
@@ -231,11 +231,11 @@ mangle_catch_redef_1_ie8: {
mangle_catch_redef_1_toplevel: {
rename = true
options = {
ie8: false,
ie: false,
toplevel: true,
}
mangle = {
ie8: false,
ie: false,
toplevel: true,
}
input: {
@@ -254,11 +254,11 @@ mangle_catch_redef_1_toplevel: {
mangle_catch_redef_1_ie8_toplevel: {
rename = true
options = {
ie8: true,
ie: true,
toplevel: true,
}
mangle = {
ie8: true,
ie: true,
toplevel: true,
}
input: {
@@ -277,11 +277,11 @@ mangle_catch_redef_1_ie8_toplevel: {
mangle_catch_redef_2: {
rename = true
options = {
ie8: false,
ie: false,
toplevel: false,
}
mangle = {
ie8: false,
ie: false,
toplevel: false,
}
input: {
@@ -299,11 +299,11 @@ mangle_catch_redef_2: {
mangle_catch_redef_2_ie8: {
rename = true
options = {
ie8: true,
ie: true,
toplevel: false,
}
mangle = {
ie8: true,
ie: true,
toplevel: false,
}
input: {
@@ -321,11 +321,11 @@ mangle_catch_redef_2_ie8: {
mangle_catch_redef_2_toplevel: {
rename = true
options = {
ie8: false,
ie: false,
toplevel: true,
}
mangle = {
ie8: false,
ie: false,
toplevel: true,
}
input: {
@@ -343,11 +343,11 @@ mangle_catch_redef_2_toplevel: {
mangle_catch_redef_2_ie8_toplevel: {
rename = true
options = {
ie8: true,
ie: true,
toplevel: true,
}
mangle = {
ie8: true,
ie: true,
toplevel: true,
}
input: {
@@ -365,7 +365,7 @@ mangle_catch_redef_2_ie8_toplevel: {
issue_2120_1: {
rename = true
mangle = {
ie8: false,
ie: false,
}
input: {
"aaaaaaaa";
@@ -401,7 +401,7 @@ issue_2120_1: {
issue_2120_2: {
rename = true
mangle = {
ie8: true,
ie: true,
}
input: {
"aaaaaaaa";
@@ -436,7 +436,7 @@ issue_2120_2: {
function_iife_catch: {
rename = true
mangle = {
ie8: false,
ie: false,
}
input: {
function f(n) {
@@ -458,7 +458,7 @@ function_iife_catch: {
function_iife_catch_ie8: {
rename = true
mangle = {
ie8: true,
ie: true,
}
input: {
function f(n) {
@@ -480,7 +480,7 @@ function_iife_catch_ie8: {
function_catch_catch: {
rename = true
mangle = {
ie8: false,
ie: false,
}
input: {
var o = 0;
@@ -509,7 +509,7 @@ function_catch_catch: {
function_catch_catch_ie8: {
rename = true
mangle = {
ie8: true,
ie: true,
}
input: {
var o = 0;
@@ -538,12 +538,12 @@ function_catch_catch_ie8: {
function_do_catch_ie8: {
rename = true
options = {
ie8: true,
ie: true,
side_effects: true,
unused: true,
}
mangle = {
ie8: true,
ie: true,
toplevel: true,
}
input: {
@@ -615,7 +615,7 @@ function_do_catch_ie8: {
issue_3480: {
rename = true,
mangle = {
ie8: false,
ie: false,
toplevel: false,
}
input: {
@@ -647,7 +647,7 @@ issue_3480: {
issue_3480_ie8: {
rename = true,
mangle = {
ie8: true,
ie: true,
toplevel: false,
}
input: {
@@ -679,7 +679,7 @@ issue_3480_ie8: {
issue_3480_toplevel: {
rename = true,
mangle = {
ie8: false,
ie: false,
toplevel: true,
}
input: {
@@ -711,7 +711,7 @@ issue_3480_toplevel: {
issue_3480_ie8_toplevel: {
rename = true,
mangle = {
ie8: true,
ie: true,
toplevel: true,
}
input: {
@@ -739,3 +739,55 @@ issue_3480_ie8_toplevel: {
}
expect_stdout: "PASS"
}
issue_5787_1: {
rename = true
input: {
console.log(function() {
const a = 42;
switch (a) {
case 42:
const a = "PASS";
return a;
}
}());
}
expect: {
console.log(function() {
const a = 42;
switch (a) {
case 42:
const a = "PASS";
return a;
}
}());
}
expect_stdout: true
}
issue_5787_2: {
rename = true
input: {
console.log(function() {
let a = 42;
switch (a) {
case 42:
// Node.js v4 (vm): SyntaxError: Identifier 'a' has already been declared
let a = "PASS";
return a;
}
}());
}
expect: {
console.log(function() {
let a = 42;
switch (a) {
case 42:
let b = "PASS";
return b;
}
}());
}
expect_stdout: "PASS"
node_version: ">=6"
}

File diff suppressed because it is too large Load Diff

View File

@@ -125,6 +125,7 @@ log_nested: {
timers: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
unused: true,
@@ -132,26 +133,22 @@ timers: {
input: {
var count = 0, interval = 1000, duration = 3210;
var timer = setInterval(function() {
console.log(++count);
if (!count++) setTimeout(function() {
clearInterval(timer);
console.log(count <= 4 ? "PASS" : "FAIL");
}, duration);
}, interval);
setTimeout(function() {
clearInterval(timer);
}, duration);
}
expect: {
var count = 0;
var timer = setInterval(function() {
console.log(++count);
if (!count++) setTimeout(function() {
clearInterval(timer);
console.log(count <= 4 ? "PASS" : "FAIL");
}, 3210);
}, 1000);
setTimeout(function() {
clearInterval(timer);
}, 3210);
}
expect_stdout: [
"1",
"2",
"3",
]
expect_stdout: "PASS"
node_version: ">=0.12"
}
@@ -172,3 +169,49 @@ issue_4054: {
}
expect_stdout: "{ p: [Setter] }"
}
issue_4811_1: {
input: {
for (var PASS in this);
console.log(PASS, this, {} < this);
}
expect: {
for (var PASS in this);
console.log(PASS, this, {} < this);
}
expect_stdout: "PASS [object global] true"
}
issue_4811_2: {
options = {
side_effects: true,
}
input: {
(async function() {});
for (var PASS in this);
console.log(PASS, this, {} < this);
}
expect: {
for (var PASS in this);
console.log(PASS, this, {} < this);
}
expect_stdout: "PASS [object global] true"
node_version: ">=8"
}
issue_5197: {
rename = true
input: {
function f(async) {
async(")=>{}");
}
console.log("" + this.__proto__);
}
expect: {
function f(a) {
a(")=>{}");
}
console.log("" + this.__proto__);
}
expect_stdout: "[object global]"
}

View File

@@ -289,8 +289,34 @@ iife: {
typeof function g() {}();
}
expect: {
x = 42, function a() {}(), function b() {}(), function c() {}(),
function d() {}(), function e() {}(), function f() {}(), function g() {}();
x = 42,
function a() {}(),
!function b() {}(),
~function c() {}(),
+function d() {}(),
-function e() {}(),
void function f() {}(),
typeof function g() {}();
}
}
iife_drop_side_effect_free: {
options = {
sequences: true,
side_effects: true,
}
input: {
x = 42;
(function a() {})();
!function b() {}();
~function c() {}();
+function d() {}();
-function e() {}();
void function f() {}();
typeof function g() {}();
}
expect: {
x = 42;
}
}
@@ -564,6 +590,34 @@ delete_seq_3: {
}
delete_seq_4: {
options = {
booleans: true,
evaluate: false,
sequences: true,
side_effects: true,
}
input: {
function f() {}
console.log(delete (f(), undefined));
console.log(delete (f(), void 0));
console.log(delete (f(), Infinity));
console.log(delete (f(), 1 / 0));
console.log(delete (f(), NaN));
console.log(delete (f(), 0 / 0));
}
expect: {
function f() {}
console.log(delete void f()),
console.log(delete void f()),
console.log((f(), delete (1 / 0))),
console.log((f(), delete (1 / 0))),
console.log(delete (f(), NaN)),
console.log((f(), delete(0 / 0)));
}
expect_stdout: true
}
delete_seq_4_evaluate: {
options = {
booleans: true,
evaluate: true,
@@ -592,6 +646,35 @@ delete_seq_4: {
}
delete_seq_5: {
options = {
booleans: true,
evaluate: false,
keep_infinity: true,
sequences: true,
side_effects: true,
}
input: {
function f() {}
console.log(delete (f(), undefined));
console.log(delete (f(), void 0));
console.log(delete (f(), Infinity));
console.log(delete (f(), 1 / 0));
console.log(delete (f(), NaN));
console.log(delete (f(), 0 / 0));
}
expect: {
function f() {}
console.log(delete void f()),
console.log(delete void f()),
console.log(delete (f(), Infinity)),
console.log((f(), delete (1 / 0))),
console.log(delete (f(), NaN)),
console.log((f(), delete (0 / 0)));
}
expect_stdout: true
}
delete_seq_5_evaluate: {
options = {
booleans: true,
evaluate: true,
@@ -663,12 +746,21 @@ side_effects_cascade_1: {
if (a < 0) a = 0;
b.a = a;
}
var m = {}, n = {};
f(13, m);
f("foo", n);
console.log(m.a, n.a);
}
expect: {
function f(a, b) {
(a -= 42) < 0 && (a = 0), b.a = a;
b.a = a = (a -= 42) < 0 ? 0 : a;
}
var m = {}, n = {};
f(13, m),
f("foo", n),
console.log(m.a, n.a);
}
expect_stdout: "0 NaN"
}
side_effects_cascade_2: {
@@ -708,7 +800,7 @@ side_effects_cascade_3: {
}
expect: {
function f(a, b) {
(b += a) || (b = a) || (b -= a, b ^= a),
(b += a) || (b = a) || (b = b - a ^ a),
a--;
}
}
@@ -844,9 +936,7 @@ hoist_decl: {
var d;
}
expect: {
var a;
w();
var b = x(), c, d;
var a, b = (w(), x()), c, d;
for (y(); 0;) z();
}
}
@@ -981,11 +1071,102 @@ call: {
b.c = function() {
console.log(this === b ? "bar" : "baz");
},
a,
b(),
a,
b.c(),
(a, b.c)(),
a,
b["c"](),
(a, b["c"])(),
a,
function() {
console.log(this === a);
}(),
a,
new b(),
a,
new b.c(),
a,
new b.c(),
a,
new b["c"](),
a,
new b["c"](),
a,
new function() {
console.log(this === a);
}(),
console.log((a, typeof b.c)),
console.log((a, typeof b["c"]));
}
expect_stdout: [
"foo",
"bar",
"baz",
"bar",
"baz",
"true",
"foo",
"baz",
"baz",
"baz",
"baz",
"false",
"function",
"function",
]
}
call_drop_side_effect_free: {
options = {
sequences: true,
side_effects: true,
}
input: {
var a = function() {
return this;
}();
function b() {
console.log("foo");
}
b.c = function() {
console.log(this === b ? "bar" : "baz");
};
(a, b)();
(a, b).c();
(a, b.c)();
(a, b)["c"]();
(a, b["c"])();
(a, function() {
console.log(this === a);
})();
new (a, b)();
new (a, b).c();
new (a, b.c)();
new (a, b)["c"]();
new (a, b["c"])();
new (a, function() {
console.log(this === a);
})();
console.log(typeof (a, b).c);
console.log(typeof (a, b)["c"]);
}
expect: {
var a = function() {
return this;
}();
function b() {
console.log("foo");
}
b.c = function() {
console.log(this === b ? "bar" : "baz");
},
b(),
b.c(),
(0, b.c)(),
b["c"](),
(0, b["c"])(),
function() {
console.log(this === a);
}(),
@@ -997,8 +1178,8 @@ call: {
new function() {
console.log(this === a);
}(),
console.log((a, typeof b.c)),
console.log((a, typeof b["c"]));
console.log(typeof b.c),
console.log(typeof b["c"]);
}
expect_stdout: [
"foo",
@@ -1033,6 +1214,26 @@ missing_link: {
expect: {
var a = 100;
a,
a++ + (0, 1),
console.log(a);
}
}
missing_link_drop_side_effect_free: {
options = {
conditionals: true,
evaluate: true,
sequences: true,
side_effects: true,
}
input: {
var a = 100;
a;
a++ + (0 ? 2 : 1);
console.log(a);
}
expect: {
var a = 100;
a++,
console.log(a);
}
@@ -1096,10 +1297,8 @@ issue_3490_1: {
}
expect: {
var b = 42, c = "FAIL";
if (function() {
var a;
a && a.p;
}(), c = "PASS", b) while ("" == typeof d);
var a;
if (a && a.p, c = "PASS", b) while ("" == typeof d);
console.log(c, b);
}
expect_stdout: "PASS 42"
@@ -1129,9 +1328,8 @@ issue_3490_2: {
}
expect: {
var b = 42, c = "FAIL";
for (function() {
var a;
}(), c = "PASS", b; "" == typeof d;);
var a;
for (c = "PASS"; "" == typeof d;);
console.log(c, b);
}
expect_stdout: "PASS 42"

View File

@@ -198,6 +198,36 @@ global_fns: {
]
}
global_constructors: {
options = {
side_effects: true,
unsafe: true,
}
input: {
Map;
new Map(console.log("foo"));
Set;
new Set(console.log("bar"));
WeakMap;
new WeakMap(console.log("baz"));
WeakSet;
new WeakSet(console.log("moo"));
}
expect: {
console.log("foo");
console.log("bar");
console.log("baz");
console.log("moo");
}
expect_stdout: [
"foo",
"bar",
"baz",
"moo",
]
node_version: ">=0.12"
}
unsafe_builtin_1: {
options = {
side_effects: true,
@@ -288,6 +318,32 @@ unsafe_string_replace: {
expect_stdout: "PASS"
}
unsafe_Object_call: {
options = {
side_effects: true,
unsafe: true,
}
input: {
var o = {
f: function(a) {
console.log(a ? this.p : "FAIL 1");
},
p: "FAIL 2",
}, p = "PASS";
Object(o.f)(42);
}
expect: {
var o = {
f: function(a) {
console.log(a ? this.p : "FAIL 1");
},
p: "FAIL 2",
}, p = "PASS";
(0, o.f)(42);
}
expect_stdout: "PASS"
}
drop_value: {
options = {
side_effects: true,
@@ -348,8 +404,6 @@ issue_3983_1: {
}
expect: {
var a = "PASS";
g();
function g() {}
console.log(a);
}
expect_stdout: "PASS"
@@ -458,14 +512,14 @@ issue_4325: {
}
expect: {
(function() {
(function() {
(function(c) {
try {
(void 0).p = 0;
c.p = 0;
} catch (e) {
console.log("PASS");
return;
}
})();
})(void 0);
})();
}
expect_stdout: "PASS"
@@ -506,3 +560,410 @@ issue_4366_2: {
expect_stdout: "PASS"
node_version: ">=4"
}
issue_4668: {
options = {
conditionals: true,
keep_fargs: false,
keep_fnames: true,
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
function f(a) {
var b, c;
function g() {
return a = 0 + a, !d || (a = 0);
}
c = g();
}
console.log(f());
var d = 0;
}
expect: {
console.log(function f() {
(function g() {
0;
})();
}());
}
expect_stdout: "undefined"
}
drop_side_effect_free_call: {
options = {
inline: true,
reduce_vars: true,
side_effects: true,
toplevel: true,
}
input: {
function f(a) {
return "PA" + a;
}
f(42);
console.log(f("SS"));
}
expect: {
function f(a) {
return "PA" + a;
}
console.log(f("SS"));
}
expect_stdout: "PASS"
}
issue_4730_1: {
options = {
pure_getters: "strict",
side_effects: true,
}
input: {
var a;
console.log("PASS") + (a && a[a.p]);
}
expect: {
var a;
console.log("PASS"),
a && a[a.p];
}
expect_stdout: "PASS"
}
issue_4730_2: {
options = {
pure_getters: "strict",
side_effects: true,
}
input: {
var a;
!console.log("PASS") || a && a[a.p];
}
expect: {
var a;
console.log("PASS") && a && a[a.p];
}
expect_stdout: "PASS"
}
issue_4751: {
options = {
pure_getters: "strict",
side_effects: true,
}
input: {
var o = {
get p() {
console.log("PASS");
},
};
o && o.p;
}
expect: {
var o = {
get p() {
console.log("PASS");
},
};
o && o.p;
}
expect_stdout: "PASS"
}
drop_instanceof: {
options = {
side_effects: true,
}
input: {
42 instanceof function() {};
console.log("PASS");
}
expect: {
console.log("PASS");
}
expect_stdout: "PASS"
}
drop_instanceof_reference: {
options = {
reduce_vars: true,
side_effects: true,
toplevel: true,
}
input: {
function f() {}
42 instanceof f;
console.log("PASS");
}
expect: {
function f() {}
console.log("PASS");
}
expect_stdout: "PASS"
}
retain_instanceof: {
options = {
side_effects: true,
}
input: {
try {
42 instanceof "foo";
} catch (e) {
console.log("PASS");
}
}
expect: {
try {
0 instanceof "foo";
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "PASS"
}
drop_access: {
options = {
pure_getters: "strict",
reduce_vars: true,
side_effects: true,
}
input: {
var o = {};
o.p;
try {
(function() {
o.q;
})();
console.log("PASS");
} catch (e) {
console.log("FAIL");
}
}
expect: {
var o = {};
o.p;
try {
console.log("PASS");
} catch (e) {
console.log("FAIL");
}
}
expect_stdout: "PASS"
}
keep_access: {
options = {
pure_getters: "strict",
reduce_vars: true,
side_effects: true,
}
input: {
var o = {};
o.p;
o = null;
try {
(function() {
o.q;
})();
console.log("FAIL");
} catch (e) {
console.log("PASS");
}
}
expect: {
var o = {};
o.p;
o = null;
try {
(function() {
o.q;
})();
console.log("FAIL");
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "PASS"
}
keep_access_after_call: {
options = {
pure_getters: "strict",
reduce_vars: true,
side_effects: true,
}
input: {
var o = {};
o.p;
o.q;
f();
try {
o.r;
console.log("FAIL");
} catch (e) {
console.log("PASS");
}
function f() {
o = null;
}
}
expect: {
var o = {};
o.p;
f();
try {
o.r;
console.log("FAIL");
} catch (e) {
console.log("PASS");
}
function f() {
o = null;
}
}
expect_stdout: "PASS"
}
issue_5860_drop_1: {
options = {
pure_getters: "strict",
reduce_vars: true,
side_effects: true,
}
input: {
var a = {};
a.p;
var a;
a.q;
console.log("PASS");
}
expect: {
var a = {};
a.p;
var a;
console.log("PASS");
}
expect_stdout: "PASS"
}
issue_5860_drop_2: {
options = {
pure_getters: "strict",
reduce_vars: true,
side_effects: true,
}
input: {
a = {};
a.p;
var a;
a.q;
console.log("PASS");
}
expect: {
a = {};
a.p;
var a;
console.log("PASS");
}
expect_stdout: "PASS"
}
issue_5860_keep_1: {
options = {
pure_getters: "strict",
reduce_vars: true,
side_effects: true,
}
input: {
var a = {};
a.p;
a.q;
var a = null;
try {
a.r;
console.log("FAIL");
} catch (e) {
console.log("PASS");
}
}
expect: {
var a = {};
a.p;
var a = null;
try {
a.r;
console.log("FAIL");
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "PASS"
}
issue_5860_keep_2: {
options = {
pure_getters: "strict",
reduce_vars: true,
side_effects: true,
}
input: {
a = {};
a.p;
a.q;
var a = null;
try {
a.r;
console.log("FAIL");
} catch (e) {
console.log("PASS");
}
}
expect: {
a = {};
a.p;
var a = null;
try {
a.r;
console.log("FAIL");
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "PASS"
}
issue_5860_keep_3: {
options = {
pure_getters: "strict",
reduce_vars: true,
side_effects: true,
}
input: {
var a = {};
a.p;
a.q;
a = null;
try {
a.r;
console.log("FAIL");
} catch (e) {
console.log("PASS");
}
}
expect: {
var a = {};
a.p;
a = null;
try {
a.r;
console.log("FAIL");
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "PASS"
}

View File

@@ -1,15 +1,24 @@
decimal: {
input: {
console.log({... 0.42});
}
expect_exact: "console.log({....42});"
expect_stdout: "{}"
node_version: ">=8.3.0"
}
collapse_vars_1: {
options = {
collapse_vars: true,
}
input: {
var a;
[ ...a = "PASS", "PASS"].slice();
[ ...a = "PASS", "PASS" ].slice();
console.log(a);
}
expect: {
var a;
[ ...a = "PASS", "PASS"].slice();
[ ...a = "PASS", "PASS" ].slice();
console.log(a);
}
expect_stdout: "PASS"
@@ -24,7 +33,7 @@ collapse_vars_2: {
var a = "FAIL";
try {
a = "PASS";
[ ...42, "PASS"].slice();
[ ...42, "PASS" ].slice();
} catch (e) {
console.log(a);
}
@@ -33,7 +42,7 @@ collapse_vars_2: {
var a = "FAIL";
try {
a = "PASS";
[ ...42, "PASS"].slice();
[ ...42, "PASS" ].slice();
} catch (e) {
console.log(a);
}
@@ -49,7 +58,7 @@ collapse_vars_3: {
input: {
var a = "FAIL";
try {
[ ...(a = "PASS", 42), "PASS"].slice();
[ ...(a = "PASS", 42), "PASS" ].slice();
} catch (e) {
console.log(a);
}
@@ -57,7 +66,7 @@ collapse_vars_3: {
expect: {
var a = "FAIL";
try {
[ ...(a = "PASS", 42), "PASS"].slice();
[ ...(a = "PASS", 42), "PASS" ].slice();
} catch (e) {
console.log(a);
}
@@ -85,7 +94,7 @@ collapse_vars_4: {
node_version: ">=6"
}
conditionals_farg: {
conditionals_farg_1: {
options = {
conditionals: true,
}
@@ -107,6 +116,28 @@ conditionals_farg: {
node_version: ">=6"
}
conditionals_farg_2: {
options = {
conditionals: true,
pure_getters: "strict",
reduce_vars: true,
}
input: {
var log = console.log;
(function(a) {
return a.length ? log(...a) : log("FAIL");
})([ "PASS" ]);
}
expect: {
var log = console.log;
(function(a) {
return a.length ? log(...a) : log("FAIL");
})([ "PASS" ]);
}
expect_stdout: "PASS"
node_version: ">=6"
}
dont_inline: {
options = {
inline: true,
@@ -125,7 +156,7 @@ dont_inline: {
node_version: ">=6"
}
do_inline: {
do_inline_1: {
options = {
inline: true,
spreads: true,
@@ -142,6 +173,46 @@ do_inline: {
node_version: ">=6"
}
do_inline_2: {
options = {
inline: true,
side_effects: true,
}
input: {
(function() {
(function() {
console.log("PASS");
})(..."");
})();
}
expect: {
[] = [ ..."" ],
console.log("PASS");
}
expect_stdout: "PASS"
node_version: ">=6"
}
do_inline_3: {
options = {
if_return: true,
inline: true,
}
input: {
(function() {
(function() {
while (console.log("PASS"));
})(..."");
})();
}
expect: {
var [] = [ ..."" ];
while (console.log("PASS"));
}
expect_stdout: "PASS"
node_version: ">=6"
}
drop_empty_call_1: {
options = {
side_effects: true,
@@ -179,7 +250,29 @@ drop_empty_call_2: {
node_version: ">=6"
}
convert_hole: {
convert_hole_array: {
options = {
spreads: true,
}
input: {
[ ...[ "PASS", , 42 ] ].forEach(function(a) {
console.log(a);
});
}
expect: {
[ "PASS", void 0, 42 ].forEach(function(a) {
console.log(a);
});
}
expect_stdout: [
"PASS",
"undefined",
"42",
]
node_version: ">=6"
}
convert_hole_call: {
options = {
spreads: true,
}
@@ -272,6 +365,31 @@ reduce_vars_2: {
node_version: ">=6"
}
reduce_vars_3: {
options = {
reduce_funcs: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
function f() {}
function g() {
return (a => a)(...[ f ]);
}
console.log(g() === g() ? "PASS" : "FAIL");
}
expect: {
function f() {}
function g() {
return (a => a)(...[ f ]);
}
console.log(g() === g() ? "PASS" : "FAIL");
}
expect_stdout: "PASS"
node_version: ">=6"
}
convert_setter: {
options = {
objects: true,
@@ -294,7 +412,7 @@ convert_setter: {
console.log(k, o[k]);
}
expect_stdout: "PASS undefined"
node_version: ">=8"
node_version: ">=8.3.0"
}
keep_getter_1: {
@@ -323,7 +441,7 @@ keep_getter_1: {
});
}
expect_stdout: "PASS"
node_version: ">=8"
node_version: ">=8.3.0"
}
keep_getter_2: {
@@ -352,7 +470,7 @@ keep_getter_2: {
"foo",
"bar",
]
node_version: ">=8"
node_version: ">=8.3.0"
}
keep_getter_3: {
@@ -382,7 +500,7 @@ keep_getter_3: {
});
}
expect_stdout: "PASS"
node_version: ">=8"
node_version: ">=8.3.0"
}
keep_getter_4: {
@@ -413,7 +531,7 @@ keep_getter_4: {
});
}
expect_stdout: "PASS"
node_version: ">=8"
node_version: ">=8.3.0"
}
keep_accessor: {
@@ -461,7 +579,7 @@ keep_accessor: {
"q undefined",
"r null",
]
node_version: ">=8"
node_version: ">=8.3.0"
}
object_key_order_1: {
@@ -491,7 +609,7 @@ object_key_order_1: {
"a 3",
"b 2",
]
node_version: ">=8 <=10"
node_version: ">=8.3.0 <=10"
}
object_key_order_2: {
@@ -521,7 +639,7 @@ object_key_order_2: {
"a 3",
"b 2",
]
node_version: ">=8"
node_version: ">=8.3.0"
}
object_key_order_3: {
@@ -551,7 +669,7 @@ object_key_order_3: {
"a 3",
"b 2",
]
node_version: ">=8"
node_version: ">=8.3.0"
}
object_key_order_4: {
@@ -581,7 +699,7 @@ object_key_order_4: {
"a 3",
"b 2",
]
node_version: ">=8"
node_version: ">=8.3.0"
}
object_spread_array: {
@@ -607,7 +725,7 @@ object_spread_array: {
"0 foo",
"1 bar",
]
node_version: ">=8"
node_version: ">=8.3.0"
}
object_spread_string: {
@@ -634,7 +752,7 @@ object_spread_string: {
"1 o",
"2 o",
]
node_version: ">=8"
node_version: ">=8.3.0"
}
unused_var_side_effects: {
@@ -664,7 +782,58 @@ unused_var_side_effects: {
});
}
expect_stdout: "PASS"
node_version: ">=8"
node_version: ">=8.3.0"
}
unsafe_join_1: {
options = {
unsafe: true,
}
input: {
console.log([ ..."foo" ].join());
}
expect: {
console.log([ ..."foo" ].join());
}
expect_stdout: "f,o,o"
node_version: ">=6"
}
unsafe_join_2: {
options = {
evaluate: true,
unsafe: true,
}
input: {
console.log([ "foo", ..."bar" ].join(""));
}
expect: {
console.log([ "foo", ..."bar" ].join(""));
}
expect_stdout: "foobar"
node_version: ">=6"
}
unsafe_join_3: {
options = {
unsafe: true,
}
input: {
try {
[].join(...console);
} catch (e) {
console.log("PASS");
}
}
expect: {
try {
[].join(...console);
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_4329: {
@@ -695,7 +864,7 @@ issue_4329: {
}[0]);
}
expect_stdout: "PASS"
node_version: ">=8"
node_version: ">=8.3.0"
}
issue_4331: {
@@ -773,7 +942,7 @@ issue_4345: {
}[42]);
}
expect_stdout: "PASS"
node_version: ">=8"
node_version: ">=8.3.0"
}
issue_4361: {
@@ -803,7 +972,7 @@ issue_4361: {
"foo",
"undefined",
]
node_version: ">=8"
node_version: ">=8.3.0"
}
issue_4363: {
@@ -824,7 +993,7 @@ issue_4363: {
});
}
expect_stdout: "PASS"
node_version: ">=8"
node_version: ">=8.3.0"
}
issue_4556: {
@@ -847,74 +1016,261 @@ issue_4556: {
node_version: ">=6"
}
issue_4560_1: {
issue_4614: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
pure_getters: "strict",
side_effects: true,
}
input: {
var a = 0;
(function(...{
[a++]: {},
}) {})(2);
console.log(a);
try {
(function(...[]) {
var arguments;
arguments[0];
})();
} catch (e) {
console.log("PASS");
}
}
expect: {
var a = 0;
(function(...{
[a++]: {},
}) {})(2);
console.log(a);
try {
(function(...[]) {
var arguments;
arguments[0];
})();
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "1"
expect_stdout: true
node_version: ">=6"
}
issue_4560_2: {
issue_4849: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = 0;
(function(...{
[a++]: {},
}) {})(2);
console.log(a);
while (function() {
while (!console);
}(new function(a) {
console.log(typeof { ...a });
}(function() {})));
}
expect: {
var a = 0;
(function(...{
[a++]: {},
}) {})(2);
console.log(a);
while (function() {
while (!console);
}(function(a) {
console.log(typeof { ...function() {} });
}()));
}
expect_stdout: "1"
node_version: ">=6"
expect_stdout: "object"
node_version: ">=8.3.0"
}
issue_4560_3: {
issue_4882_1: {
options = {
collapse_vars: true,
reduce_vars: true,
toplevel: true,
objects: true,
spreads: true,
}
input: {
var a = 0, b;
[ ...{
[a++]: b,
} ] = [ "PASS" ];
console.log(b);
var o = {
p: "PASS",
... {
__proto__: {
p: "FAIL 1",
q: "FAIL 2",
},
},
};
console.log(o.p);
console.log(o.q);
}
expect: {
var a = 0, b;
[ ...{
[a++]: b,
} ] = [ "PASS" ];
console.log(b);
var o = {
p: "PASS",
};
console.log(o.p);
console.log(o.q);
}
expect_stdout: [
"PASS",
"undefined",
]
node_version: ">=8.3.0"
}
issue_4882_2: {
options = {
objects: true,
spreads: true,
}
input: {
console.log(null == Object.getPrototypeOf({
... {
__proto__: (console.log(42), null),
},
}) ? "FAIL" : "PASS");
}
expect: {
console.log(null == Object.getPrototypeOf({
... {
__proto__: (console.log(42), null),
},
}) ? "FAIL" : "PASS");
}
expect_stdout: [
"42",
"PASS",
]
node_version: ">=8.3.0"
}
issue_4882_3: {
options = {
objects: true,
spreads: true,
}
input: {
var o = {
__proto__: { p: 42 },
... {
set __proto__(v) {},
},
};
console.log(o.__proto__ === Object.getPrototypeOf(o) ? "FAIL" : "PASS");
console.log(o.p);
}
expect: {
var o = {
__proto__: { p: 42 },
["__proto__"]: void 0,
};
console.log(o.__proto__ === Object.getPrototypeOf(o) ? "FAIL" : "PASS");
console.log(o.p);
}
expect_stdout: [
"PASS",
"42",
]
node_version: ">=8.3.0"
}
issue_5006: {
options = {
arguments: true,
}
input: {
console.log(function(b, c) {
c = "FAIL 2";
return arguments[1];
}(...[], "FAIL 1") || "PASS");
}
expect: {
console.log(function(b, c) {
c = "FAIL 2";
return arguments[1];
}(...[], "FAIL 1") || "PASS");
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5382: {
options = {
side_effects: true,
}
input: {
({
f() {
({ ...this });
},
get p() {
console.log("PASS");
},
}).f();
}
expect: {
({
f() {
({ ...this });
},
get p() {
console.log("PASS");
},
}).f();
}
expect_stdout: "PASS"
node_version: ">=8.3.0"
}
issue_5602: {
options = {
collapse_vars: true,
conditionals: true,
evaluate: true,
if_return: true,
inline: true,
passes: 2,
sequences: true,
spreads: true,
unused: true,
}
input: {
(function() {
try {
var b = function(c) {
if (c)
return FAIL;
var d = 42;
}(...[ null, A = 0 ]);
} catch (e) {
b();
}
})();
console.log(A);
}
expect: {
(function() {
try {
var b = void (A = 0);
} catch (e) {
b();
}
})(),
console.log(A);
}
expect_stdout: "0"
expect_warnings: [
"INFO: Dropping unused variable d [test/compress/spreads.js:6,24]",
"INFO: Collapsing c [test/compress/spreads.js:4,24]",
"INFO: Dropping unused variable c [test/compress/spreads.js:3,33]",
"INFO: pass 0: last_count: Infinity, count: 27",
"WARN: Condition always false [test/compress/spreads.js:4,20]",
"INFO: Collapsing null [test/compress/spreads.js:7,23]",
"INFO: Collapsing 0 [test/compress/spreads.js:3,24]",
"INFO: pass 1: last_count: 27, count: 22",
]
node_version: ">=6"
}
issue_5850: {
options = {
evaluate: true,
join_vars: true,
unused: true,
}
input: {
var a = [ ..."FAIL" ];
a[0] = "P";
a[2] = a[3] = "S";
console.log(a.join(""));
}
expect: {
var a = [ ..."FAIL" ];
a[0] = "P";
a[2] = a[3] = "S";
console.log(a.join(""));
}
node_version: ">=6"
}

View File

@@ -113,7 +113,7 @@ constant_switch_5: {
// the break inside the if ruins our job
// we can still get rid of irrelevant cases.
switch (1) {
case 1:
default:
x();
if (foo) break;
y();
@@ -300,6 +300,37 @@ drop_default_2: {
}
}
drop_default_3: {
options = {
dead_code: true,
evaluate: true,
switches: true,
}
input: {
function f() {
console.log("PASS");
return 42;
}
switch (42) {
case f():
break;
case void console.log("FAIL"):
default:
}
}
expect: {
function f() {
console.log("PASS");
return 42;
}
switch (42) {
case f():
case void console.log("FAIL"):
}
}
expect_stdout: "PASS"
}
keep_default: {
options = {
dead_code: true,
@@ -423,7 +454,6 @@ drop_case_3: {
switch ({}.p) {
default:
case void 0:
break;
case c = "FAIL":
}
console.log(c);
@@ -454,7 +484,168 @@ drop_case_4: {
expect_stdout: "PASS"
}
keep_case: {
drop_case_5: {
options = {
dead_code: true,
evaluate: true,
switches: true,
}
input: {
switch (42) {
case void console.log("PASS 1"):
console.log("FAIL 1");
case 42:
case console.log("FAIL 2"):
console.log("PASS 2");
}
}
expect: {
switch (42) {
default:
void console.log("PASS 1");
console.log("PASS 2");
}
}
expect_stdout: [
"PASS 1",
"PASS 2",
]
}
drop_case_6: {
options = {
dead_code: true,
evaluate: true,
switches: true,
}
input: {
switch (console.log("PASS 1"), 2) {
case 0:
console.log("FAIL 1");
case (console.log("PASS 2"), 1):
console.log("FAIL 2");
}
}
expect: {
switch (console.log("PASS 1"), 2) {
case (console.log("PASS 2"), 1):
}
}
expect_stdout: [
"PASS 1",
"PASS 2",
]
}
drop_case_7: {
options = {
dead_code: true,
evaluate: true,
switches: true,
}
input: {
switch (2) {
case 0:
console.log("FAIL 1");
case (console.log("PASS 1"), 1):
console.log("FAIL 2");
case 2:
console.log("PASS 2");
}
}
expect: {
switch (2) {
default:
console.log("PASS 1"), 1;
console.log("PASS 2");
}
}
expect_stdout: [
"PASS 1",
"PASS 2",
]
}
drop_case_8: {
options = {
dead_code: true,
switches: true,
}
input: {
function log(msg) {
console.log(msg);
return msg;
}
switch (log("foo")) {
case "bar":
log("moo");
break;
case log("baz"):
log("moo");
break;
default:
log("moo");
}
}
expect: {
function log(msg) {
console.log(msg);
return msg;
}
switch (log("foo")) {
case "bar":
case log("baz"):
default:
log("moo");
}
}
expect_stdout: [
"foo",
"baz",
"moo",
]
}
drop_case_9: {
options = {
dead_code: true,
switches: true,
}
input: {
function log(msg) {
console.log(msg);
return msg;
}
switch (log("foo")) {
case log("bar"):
log("moo");
break;
case "baz":
log("moo");
break;
default:
log("moo");
}
}
expect: {
function log(msg) {
console.log(msg);
return msg;
}
switch (log("foo")) {
default:
log("bar");
log("moo");
}
}
expect_stdout: [
"foo",
"bar",
"moo",
]
}
keep_case_1: {
options = {
dead_code: true,
switches: true,
@@ -474,6 +665,76 @@ keep_case: {
}
}
keep_case_2: {
options = {
dead_code: true,
evaluate: true,
switches: true,
}
input: {
switch ("foo") {
case console.log("bar"):
case console.log("baz"), "moo":
}
}
expect: {
switch ("foo") {
case console.log("bar"):
case console.log("baz"), "moo":
}
}
expect_stdout: [
"bar",
"baz",
]
}
keep_case_3: {
options = {
dead_code: true,
evaluate: true,
switches: true,
}
input: {
var a;
switch (void console.log("PASS")) {
case a:
case console.log("FAIL"), 42:
}
}
expect: {
var a;
switch (void console.log("PASS")) {
case a:
case console.log("FAIL"), 42:
}
}
expect_stdout: "PASS"
}
keep_case_4: {
options = {
dead_code: true,
evaluate: true,
switches: true,
}
input: {
var a;
switch (void console.log("PASS")) {
case a:
case void console.log("FAIL"):
}
}
expect: {
var a;
switch (void console.log("PASS")) {
case a:
case void console.log("FAIL"):
}
}
expect_stdout: "PASS"
}
issue_376: {
options = {
dead_code: true,
@@ -661,7 +922,7 @@ issue_1680_1: {
case f(0):
case f(1):
f(2);
case 2:
default:
f(5);
}
}
@@ -924,7 +1185,6 @@ issue_2535: {
}
expect: {
w(), 42;
42;
y();
z();
}
@@ -950,7 +1210,6 @@ issue_1750: {
expect: {
var a = 0, b = 1;
true;
a, true;
b = 2;
console.log(a, b);
}
@@ -1088,7 +1347,8 @@ drop_switch_6: {
}
}
expect: {
A === B;
A;
B;
x();
C !== D;
y();
@@ -1181,3 +1441,250 @@ issue_4059: {
}
expect_stdout: "PASS"
}
issue_5008_1: {
options = {
dead_code: true,
evaluate: true,
reduce_vars: true,
switches: true,
unsafe: true,
}
input: {
console.log(function f() {
switch (f) {
case f:
return "PASS";
default:
return "FAIL";
}
}());
}
expect: {
console.log(function f() {
switch (f) {
default:
return "PASS";
}
}());
}
expect_stdout: "PASS"
}
issue_5008_2: {
options = {
dead_code: true,
evaluate: true,
reduce_vars: true,
switches: true,
unsafe: true,
}
input: {
console.log(function(a) {
switch (a) {
case a:
return "PASS";
default:
return "FAIL";
}
}([]));
}
expect: {
console.log(function(a) {
switch (a) {
default:
return "PASS";
}
}([]));
}
expect_stdout: "PASS"
}
issue_5008_3: {
options = {
dead_code: true,
evaluate: true,
reduce_vars: true,
switches: true,
unsafe: true,
}
input: {
console.log(function(a) {
switch (a) {
case a:
return "PASS";
default:
return "FAIL";
}
}({}));
}
expect: {
console.log(function(a) {
switch (a) {
default:
return "PASS";
}
}({}));
}
expect_stdout: "PASS"
}
issue_5008_4: {
options = {
dead_code: true,
evaluate: true,
reduce_vars: true,
switches: true,
}
input: {
console.log(function(a) {
switch (a) {
case a:
return "PASS";
default:
return "FAIL";
}
}(/foo/));
}
expect: {
console.log(function(a) {
switch (a) {
default:
return "PASS";
}
}(/foo/));
}
expect_stdout: "PASS"
}
issue_5010: {
options = {
dead_code: true,
evaluate: true,
switches: true,
}
input: {
var a;
switch (42) {
case console.log("PASS"):
case a:
console.log("FAIL");
case 42:
}
}
expect: {
var a;
switch (42) {
case console.log("PASS"):
case a:
console.log("FAIL");
}
}
expect_stdout: "PASS"
}
issue_5012: {
options = {
dead_code: true,
evaluate: true,
switches: true,
}
input: {
switch (void 0) {
case console.log("PASS"):
break;
case void 0:
case 42:
console.log("FAIL");
}
}
expect: {
switch (void 0) {
case console.log("PASS"):
break;
default:
console.log("FAIL");
}
}
expect_stdout: "PASS"
}
issue_5543_1: {
options = {
dead_code: true,
switches: true,
}
input: {
var a;
switch (a) {
default:
switch (42) {
case a:
case console.log("PASS"):
}
break;
case null:
switch (false) {
case a:
case console.log("FAIL"):
}
}
}
expect: {
var a;
switch (a) {
default:
switch (42) {
case a:
case console.log("PASS"):
}
break;
case null:
switch (false) {
case a:
case console.log("FAIL"):
}
}
}
expect_stdout: "PASS"
}
issue_5543_2: {
options = {
dead_code: true,
switches: true,
}
input: {
var a;
switch (a) {
default:
switch (42) {
case a:
case console.log("PASS"):
}
break;
case null:
switch (42) {
case a:
case console.log("FAIL"):
}
}
}
expect: {
var a;
switch (a) {
default:
switch (42) {
case a:
case console.log("PASS"):
}
break;
case null:
switch (42) {
case a:
case console.log("FAIL"):
}
}
}
expect_stdout: "PASS"
}

771
test/compress/templates.js Normal file
View File

@@ -0,0 +1,771 @@
simple: {
input: {
console.log(`foo
bar\nbaz`);
}
expect_exact: "console.log(`foo\n bar\\nbaz`);"
expect_stdout: [
"foo",
" bar",
"baz",
]
node_version: ">=4"
}
placeholder: {
input: {
console.log(`foo ${ function(a, b) {
return a * b;
}(6, 7) }`);
}
expect_exact: "console.log(`foo ${function(a,b){return a*b}(6,7)}`);"
expect_stdout: "foo 42"
node_version: ">=4"
}
nested: {
input: {
console.log(`P${`A${"S"}`}S`);
}
expect_exact: 'console.log(`P${`A${"S"}`}S`);'
expect_stdout: "PASS"
node_version: ">=4"
}
tagged: {
input: {
console.log(String.raw`foo\nbar`);
}
expect_exact: "console.log(String.raw`foo\\nbar`);"
expect_stdout: "foo\\nbar"
node_version: ">=4"
}
tagged_chain: {
input: {
function f(strings) {
return strings.join("") || f;
}
console.log(f```${42}``pass`.toUpperCase());
}
expect_exact: 'function f(strings){return strings.join("")||f}console.log(f```${42}``pass`.toUpperCase());'
expect_stdout: "PASS"
node_version: ">=4"
}
tag_parentheses_arrow: {
input: {
console.log((s => s.raw[0])`\tPASS`.slice(2));
}
expect_exact: "console.log((s=>s.raw[0])`\\tPASS`.slice(2));"
expect_stdout: "PASS"
node_version: ">=4"
}
tag_parentheses_binary: {
options = {
collapse_vars: true,
toplevel: true,
unused: true,
}
input: {
var f = function() {
console.log("PASS");
} || console
f``;
}
expect_exact: '(function(){console.log("PASS")}||console)``;'
expect_stdout: "PASS"
node_version: ">=4"
}
tag_parentheses_new: {
input: {
(new function() {
return console.log;
})`foo`;
}
expect_exact: "(new function(){return console.log})`foo`;"
expect_stdout: true
node_version: ">=4"
}
tag_parentheses_sequence: {
input: {
var o = {
f() {
console.log(this === o ? "FAIL" : "PASS");
},
};
(42, o.f)``;
}
expect_exact: 'var o={f(){console.log(this===o?"FAIL":"PASS")}};(42,o.f)``;'
expect_stdout: "PASS"
node_version: ">=4"
}
tag_parentheses_unary: {
input: {
var a;
try {
(~a)``;
(a++)``;
} catch (e) {
console.log("PASS");
}
}
expect_exact: 'var a;try{(~a)``;(a++)``}catch(e){console.log("PASS")}'
expect_stdout: "PASS"
node_version: ">=4"
}
malformed_escape: {
input: {
(function(s) {
s.forEach((c, i) => console.log(i, c, s.raw[i]));
return () => console.log(arguments);
})`\uFo${42}`();
}
expect_exact: "(function(s){s.forEach((c,i)=>console.log(i,c,s.raw[i]));return()=>console.log(arguments)})`\\uFo${42}`();"
expect_stdout: true
node_version: ">=4"
}
booleans: {
options = {
booleans: true,
evaluate: true,
templates: true,
}
input: {
var a;
console.log(`$${a}${a}` ? "PASS" : "FAIL");
}
expect: {
var a;
console.log("$" + a + a ? "PASS" : "FAIL");
}
expect_stdout: "PASS"
node_version: ">=4"
}
escape_placeholder_1: {
options = {
templates: true,
}
input: {
console.log(`\${\n`);
}
expect: {
console.log(`\${
`);
}
expect_stdout: [
"${",
"",
]
node_version: ">=4"
}
escape_placeholder_2: {
options = {
evaluate: true,
templates: true,
}
input: {
console.log(`\n${"${"}\n`);
}
expect: {
console.log(`
\${
`);
}
expect_stdout: [
"",
"${",
"",
]
node_version: ">=4"
}
escape_placeholder_3: {
options = {
evaluate: true,
templates: true,
}
input: {
console.log(`\n$${"{"}\n`);
}
expect: {
console.log(`
\${
`);
}
expect_stdout: [
"",
"${",
"",
]
node_version: ">=4"
}
escape_placeholder_4: {
options = {
evaluate: true,
templates: true,
}
input: {
console.log(`\n${"$"}${"{"}\n`);
}
expect: {
console.log(`
\${
`);
}
expect_stdout: [
"",
"${",
"",
]
node_version: ">=4"
}
evaluate: {
options = {
evaluate: true,
templates: false,
}
input: {
console.log(`foo ${ function(a, b) {
return a * b;
}(6, 7) }`);
}
expect: {
console.log(`foo ${42}`);
}
expect_stdout: "foo 42"
node_version: ">=4"
}
evaluate_templates: {
options = {
evaluate: true,
templates: true,
}
input: {
console.log(`foo ${ function(a, b) {
return a * b;
}(6, 7) }`);
}
expect: {
console.log("foo 42");
}
expect_stdout: "foo 42"
node_version: ">=4"
}
partial_evaluate: {
options = {
evaluate: true,
templates: true,
}
input: {
console.log(`${6 * 7} foo ${console ? `PA` + "SS" : `FA` + `IL`}`);
}
expect: {
console.log("42 foo " + (console ? "PASS" : "FAIL"));
}
expect_stdout: "42 foo PASS"
node_version: ">=4"
}
malformed_evaluate_1: {
options = {
evaluate: true,
templates: true,
}
input: {
console.log(`\67 ${6 * 7}`);
}
expect: {
console.log(`\67 42`);
}
expect_stdout: true
node_version: ">=4"
}
malformed_evaluate_2: {
options = {
evaluate: true,
templates: true,
}
input: {
console.log(`\u0${0}b${5}`);
}
expect: {
console.log(`\u00b` + 5);
}
expect_stdout: true
node_version: ">=4"
}
malformed_evaluate_3: {
options = {
evaluate: true,
templates: true,
}
input: {
console.log(`\u${0}b${5}`);
}
expect: {
console.log(`\u0b5`);
}
expect_stdout: true
node_version: ">=4"
}
malformed_evaluate_4: {
options = {
evaluate: true,
templates: true,
unsafe: true,
}
input: {
console.log(String.raw`\u0${0}b${5}`);
}
expect: {
console.log("\\u00b5");
}
expect_stdout: "\\u00b5"
node_version: ">=8.10.0"
}
unsafe_evaluate: {
options = {
evaluate: true,
templates: true,
unsafe: true,
}
input: {
console.log(String.raw`\uFo`);
}
expect: {
console.log("\\uFo");
}
expect_stdout: "\\uFo"
node_version: ">=8.10.0"
}
side_effects_1: {
options = {
side_effects: true,
}
input: {
`42`;
`${console.log("foo")}`;
console.log`\nbar`;
}
expect: {
console.log("foo");
console.log`\nbar`;
}
expect_stdout: true
node_version: ">=4"
}
side_effects_2: {
options = {
side_effects: true,
}
input: {
var o = {
f() {
console.log(this === o ? "FAIL" : "PASS");
},
};
(42, o.f)``;
}
expect: {
var o = {
f() {
console.log(this === o ? "FAIL" : "PASS");
},
};
(0, o.f)``;
}
expect_stdout: "PASS"
node_version: ">=4"
}
unsafe_side_effects: {
options = {
side_effects: true,
unsafe: true,
}
input: {
`42`;
`${console.log("foo")}`;
String.raw`\nbar`;
}
expect: {
console.log("foo");
}
expect_stdout: "foo"
node_version: ">=4"
}
pure_funcs: {
options = {
pure_funcs: "Math.random",
side_effects: true,
}
input: {
Math.random`${console.log("PASS")}`;
}
expect: {
console.log("PASS");
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_4604: {
options = {
collapse_vars: true,
}
input: {
var a = 0, log = console.log;
a = "FAIL";
(function() {
a = "PASS";
})``;
log(a);
}
expect: {
var a = 0, log = console.log;
a = "FAIL";
(function() {
a = "PASS";
})``;
log(a);
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_4606: {
options = {
evaluate: true,
strings: true,
templates: true,
}
input: {
console.log(`${typeof A} ${"\r"} ${"\\"} ${"`"}`);
}
expect: {
console.log(typeof A + " \r \\ `");
}
expect_stdout: "undefined \r \\ `"
node_version: ">=4"
}
issue_4630: {
options = {
evaluate: true,
templates: true,
}
input: {
console.log(`${/PASS/}`);
}
expect: {
console.log("/PASS/");
}
expect_stdout: "/PASS/"
node_version: ">=4"
}
issue_4676: {
options = {
evaluate: true,
reduce_vars: true,
templates: true,
toplevel: true,
unsafe: true,
unused: true,
}
input: {
function f(a) {
var b = `foo${a = "PASS"}`;
for (var c in f && b)
b.p;
return a;
}
console.log(f("FAIL"));
}
expect: {
console.log(function f(a) {
var b = "fooPASS";
for (var c in f, b)
b.p;
return "PASS";
}());
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_4931: {
options = {
evaluate: true,
templates: true,
unsafe: true,
}
input: {
console.log(String.raw`${typeof A} ${"\r"}`);
console.log(String.raw`${"\\"} ${"`"}`);
}
expect: {
console.log(String.raw`${typeof A} ${"\r"}`);
console.log("\\ `");
}
expect_stdout: [
"undefined \r",
"\\ `",
]
node_version: ">=4"
}
issue_5125_1: {
options = {
evaluate: true,
strings: true,
templates: true,
}
input: {
console.log(`PASS ${typeof A}`);
}
expect: {
console.log("PASS " + typeof A);
}
expect_stdout: "PASS undefined"
node_version: ">=4"
}
issue_5125_2: {
options = {
evaluate: true,
strings: true,
templates: true,
}
input: {
console.log(`PASS
${typeof A}`);
}
expect: {
console.log(`PASS
` + typeof A);
}
expect_stdout: [
"PASS",
"undefined",
]
node_version: ">=4"
}
issue_5125_3: {
options = {
evaluate: true,
strings: true,
templates: true,
}
input: {
console.log(`PASS\n${typeof A}`);
}
expect: {
console.log(`PASS
` + typeof A);
}
expect_stdout: [
"PASS",
"undefined",
]
node_version: ">=4"
}
issue_5125_4: {
options = {
evaluate: true,
strings: true,
templates: true,
}
input: {
console.log(`PASS
${typeof A}`);
}
expect: {
console.log(`PASS
` + typeof A);
}
expect_stdout: [
"PASS",
"",
"undefined",
]
node_version: ">=4"
}
issue_5125_5: {
options = {
evaluate: true,
strings: true,
templates: true,
}
input: {
console.log(`PASS\n\n${typeof A}`);
}
expect: {
console.log(`PASS
` + typeof A);
}
expect_stdout: [
"PASS",
"",
"undefined",
]
node_version: ">=4"
}
issue_5125_6: {
options = {
evaluate: true,
strings: true,
templates: true,
}
input: {
console.log(`${typeof A} ${typeof B} PASS`);
}
expect: {
console.log(typeof A + ` ${typeof B} PASS`);
}
expect_stdout: "undefined undefined PASS"
node_version: ">=4"
}
issue_5125_7: {
options = {
evaluate: true,
strings: true,
templates: true,
}
input: {
console.log(`${typeof A} ${typeof B} ${typeof C} PASS`);
}
expect: {
console.log(typeof A + ` ${typeof B} ${typeof C} PASS`);
}
expect_stdout: "undefined undefined undefined PASS"
node_version: ">=4"
}
issue_5125_8: {
options = {
evaluate: true,
strings: true,
templates: true,
}
input: {
console.log(`${typeof A}${typeof B}${typeof C} PASS`);
}
expect: {
console.log(typeof A + typeof B + typeof C + " PASS");
}
expect_stdout: "undefinedundefinedundefined PASS"
node_version: ">=4"
}
issue_5136: {
options = {
templates: true,
}
input: {
console.log(`${A = []}${A[0] = 42}`);
}
expect: {
console.log(`` + (A = []) + (A[0] = 42));
}
expect_stdout: "42"
node_version: ">=4"
}
issue_5145_1: {
options = {
strings: true,
templates: true,
}
input: {
var a = [];
console.log(`${a}${a[0] = 42}
`);
}
expect: {
var a = [];
console.log(`${a}${a[0] = 42}
`);
}
expect_stdout: [
"42",
"",
]
node_version: ">=4"
}
issue_5145_2: {
options = {
strings: true,
templates: true,
}
input: {
var a = [];
console.log(`${a}${a}${a[0] = 42}
`);
}
expect: {
var a = [];
console.log("" + a + a + (a[0] = 42) + `
`);
}
expect_stdout: [
"42",
"",
]
node_version: ">=4"
}
issue_5199: {
options = {
collapse_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = function() {
console.log(typeof b);
}``;
{
const b = a;
}
}
expect: {
var a = function() {
console.log(typeof b);
}``;
{
const b = a;
}
}
expect_stdout: "undefined"
node_version: ">=4"
}

View File

@@ -95,7 +95,7 @@ while_if_break: {
}
}
expect: {
for(; a && (b && c && d, !e););
for (; a && (b && c && d, !e););
}
}
@@ -127,7 +127,7 @@ if_return: {
if (w) {
if (y) return;
} else if (z) return;
return x == y || (x && w(), y && z()), !0;
return x != y && (x && w(), y) && z(), !0;
}
}
}

Some files were not shown because too many files have changed in this diff Show More