Compare commits

...

677 Commits

Author SHA1 Message Date
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
Alex Lam S.L
ac7b5c07d7 v3.12.6 2021-02-01 01:37:32 +08:00
Alex Lam S.L
0cd4a199b0 fix corner case in conditionals (#4599)
fixes #4598
2021-01-30 16:54:29 +08:00
Alex Lam S.L
35435d4bd3 suppress false positives due to nested objects (#4597) 2021-01-29 13:21:19 +08:00
Alex Lam S.L
d0bb147639 fix corner case in inline (#4596)
fixes #4595
2021-01-27 01:30:05 +08:00
Alex Lam S.L
4723b4541e workaround tty bugs on Node.js (#4594) 2021-01-26 23:07:48 +08:00
Alex Lam S.L
9d23ba0a22 support exponentiation operator (#4593) 2021-01-25 05:48:51 +08:00
Alex Lam S.L
a08d42555a fix infinite recursion in ufuzz code generation (#4592) 2021-01-24 23:37:57 +08:00
Alex Lam S.L
fd7ad8e779 fix corner cases in collapse_vars (#4591)
fixes #4590
2021-01-24 22:15:43 +08:00
Alex Lam S.L
a36c5472d2 fix corner cases with default parameters (#4589)
fixes #4588
2021-01-24 11:00:47 +08:00
Alex Lam S.L
8bfd891c09 support BigInt literals (#4583) 2021-01-24 09:51:18 +08:00
Alex Lam S.L
ef9f7ca3e7 fix corner case in collapse_vars (#4587)
fixes #4586
2021-01-24 07:05:43 +08:00
Alex Lam S.L
acc443b2cf fix corner case in reduce_vars (#4585)
fixes #4584
2021-01-24 03:37:52 +08:00
Alex Lam S.L
f87e7be12c fix corner case in reduce_vars (#4582)
fixes #4581
2021-01-23 02:14:53 +08:00
Alex Lam S.L
c0614654d9 improve ufuzz on destructuring (#4580) 2021-01-23 02:00:26 +08:00
Alex Lam S.L
0358637725 workaround Node.js bug (#4579) 2021-01-22 11:34:30 +08:00
Alex Lam S.L
63b5b6d2b3 suppress false positives in ufuzz (#4578) 2021-01-22 02:33:00 +08:00
Alex Lam S.L
e675262d51 suppress false positives in ufuzz (#4577) 2021-01-21 14:33:31 +08:00
Alex Lam S.L
c1e771a89a fix corner case in rests (#4576)
fixes #4575
2021-01-21 07:23:06 +08:00
Alex Lam S.L
bc7a88baea suppress false positives in ufuzz (#4574) 2021-01-20 21:03:33 +08:00
Alex Lam S.L
018e0350f8 workaround GitHub Actions bug (#4573) 2021-01-20 20:17:58 +08:00
Alex Lam S.L
d37ee4d41c support asynchronous test cases properly (#4529) 2021-01-20 07:27:32 +08:00
Alex Lam S.L
7793c6c389 v3.12.5 2021-01-20 06:30:01 +08:00
Alex Lam S.L
90ec468240 fix corner case in dead_code (#4571)
fixes #4570
2021-01-19 09:33:57 +08:00
Jimb Esser
994293e972 Fix overwriting existing sourcesContent in sourcemaps (#4567) 2021-01-19 07:44:24 +08:00
Alex Lam S.L
b57bae4b9e fix corner case in reduce_vars (#4569)
fixes #4568
2021-01-19 06:34:48 +08:00
Alex Lam S.L
e23a10f7f9 fix corner case in loops (#4565)
fixes #4564
2021-01-18 06:36:59 +08:00
Alex Lam S.L
884ec4e8a5 improve false positive detection in ufuzz (#4566) 2021-01-18 06:35:53 +08:00
Alex Lam S.L
e616916de5 fix corner case in reduce_vars (#4563)
fixes #4562
2021-01-18 01:47:07 +08:00
Alex Lam S.L
8d21516623 fix corner cases in reduce_vars (#4561)
fixes #4560
2021-01-16 16:55:10 +08:00
Alex Lam S.L
74368c3dba fix corner case in unused (#4559)
fixes #4558
2021-01-16 02:37:27 +08:00
Alex Lam S.L
18dbceb36f fix corner case in unused (#4557)
fixes #4556
2021-01-15 12:33:17 +08:00
Alex Lam S.L
65d39a3702 fix corner cases in collapse_vars (#4555)
fixes #4554
2021-01-15 00:22:34 +08:00
Alex Lam S.L
24917e7084 fix corner case in evaluate (#4553)
fixes #4552
2021-01-13 22:17:24 +08:00
Alex Lam S.L
e84957e3da suppress invalid test generation in ufuzz (#4551) 2021-01-13 04:29:39 +08:00
Alex Lam S.L
c11a748908 fix corner case in merge_vars (#4550)
fixes #4548
2021-01-13 03:48:46 +08:00
Alex Lam S.L
90017051f2 document v8 bug (#4549)
closes #4547
2021-01-13 03:48:33 +08:00
Alex Lam S.L
fc816628c1 fix corner case in side_effects (#4545)
fixes #4544
2021-01-13 01:08:16 +08:00
Alex Lam S.L
46ad273df4 enhance rests (#4546) 2021-01-13 00:00:19 +08:00
Alex Lam S.L
b689028e87 fix corner case in unsafe_math (#4543)
fixes #4542
2021-01-12 12:07:01 +08:00
Alex Lam S.L
1e831df1f6 fix corner case in side_effects (#4541)
fixes #4540
2021-01-12 09:12:43 +08:00
Alex Lam S.L
c12486bab4 fix corner case in rests (#4539)
fixes #4538
2021-01-12 09:12:30 +08:00
Alex Lam S.L
52e94a0723 update command line examples (#4536) 2021-01-11 09:12:27 +08:00
Alex Lam S.L
16b97f9558 fix corner case in arguments (#4535)
fixes #4534
2021-01-11 04:17:39 +08:00
Alex Lam S.L
dbfa5d4d14 fix corner case in ie8 (#4532)
fixes #4531
2021-01-11 00:01:49 +08:00
Alex Lam S.L
ba54d074d8 support asynchronous arrow functions (#4530) 2021-01-10 11:34:26 +08:00
Alex Lam S.L
0818d396c5 fix corner case in mangle (#4528)
fixes #4527
2021-01-10 04:20:43 +08:00
Alex Lam S.L
770f3ba5fe fix corner cases with rest parameters (#4526)
fixes #4525
2021-01-09 08:38:51 +08:00
Alex Lam S.L
553034fe52 fix corner case in merge_vars (#4524)
fixes #4523
2021-01-08 15:49:14 +08:00
Alex Lam S.L
7fe8c9150a fix corner case in assignments (#4522)
fixes #4521
2021-01-08 13:03:21 +08:00
Alex Lam S.L
6c419bc083 implement UGLIFY_BUG_REPORT (#4516) 2021-01-07 16:53:29 +08:00
Alex Lam S.L
25321df959 fix corner cases with arguments (#4520)
fixes #4519
2021-01-07 16:53:14 +08:00
Alex Lam S.L
cf1b0165af fix corner case in hoist_vars (#4518)
fixes #4517
2021-01-07 15:05:48 +08:00
Alex Lam S.L
c3d358a5b8 support rest parameters (#4515) 2021-01-07 10:04:09 +08:00
Alex Lam S.L
68497d0258 update issue templates (#4514) 2021-01-06 05:37:30 +08:00
Alex Lam S.L
71c3d04681 fix corner case in side_effects (#4513)
fixes #4512
2021-01-06 02:11:30 +08:00
Alex Lam S.L
4c89550c43 fix corner case indefault_values (#4511)
fixes #4510
2021-01-06 01:26:19 +08:00
Alex Lam S.L
7ebfb22d16 fix corner cases in inline & unused (#4509)
fixes #4508
2021-01-06 00:15:12 +08:00
Alex Lam S.L
6eceac0966 enhance inline & side_effects (#4506) 2021-01-05 15:02:49 +08:00
Alex Lam S.L
fc5aee662d fix corner case in merge_vars (#4505)
fixes #4504
2021-01-05 14:23:46 +08:00
Alex Lam S.L
5fbbb43839 fix corner cases in inline & side_effects (#4503)
fixes #4502
2021-01-04 10:17:32 +08:00
Alex Lam S.L
df2cfcb5fc fix corner case in evaluate (#4501)
fixes #4500
2021-01-04 02:31:20 +08:00
Alex Lam S.L
623a0d920f fix toggling of AST validation (#4499) 2021-01-03 11:09:10 +08:00
Alex Lam S.L
e8c04f8cb6 suppress invalid AST transform in --reduce-test (#4498) 2021-01-03 10:34:46 +08:00
Alex Lam S.L
110c1ac097 fix corner case in default_values (#4497)
fixes #4496
2021-01-02 22:51:53 +08:00
Alex Lam S.L
15ef272790 introduce awaits (#4495) 2021-01-02 20:35:48 +08:00
Alex Lam S.L
b3a706114c enhance if_return & side_effects (#4494) 2021-01-02 12:39:51 +08:00
Alex Lam S.L
cc2d7acaf0 enhance inline, sequences & side_effects (#4493) 2021-01-02 09:43:05 +08:00
Alex Lam S.L
dfb86ccdd1 fix corner case in conditionals (#4492) 2021-01-02 07:53:15 +08:00
Alex Lam S.L
0417a69c3e enhance collapse_vars & dead_code (#4491) 2021-01-01 21:52:14 +08:00
Alex Lam S.L
2dbafbb4ee fix corner case in reduce_vars (#4490)
fixes #4489
2021-01-01 12:56:13 +08:00
Alex Lam S.L
311c074622 fix corner case in functions (#4488)
fixes #4487
2021-01-01 10:39:40 +08:00
Alex Lam S.L
a10c7793bb v3.12.4 2021-01-01 08:47:24 +08:00
Alex Lam S.L
0b7d65d331 fix corner case with arguments (#4486)
fixes #4485
2020-12-31 14:55:05 +08:00
Alex Lam S.L
8b954b022b fix corner case with default values (#4484)
fixes #4483
2020-12-31 01:47:00 +08:00
Alex Lam S.L
0013cbf91f improve false positive detection in ufuzz (#4482) 2020-12-30 21:53:03 +08:00
Alex Lam S.L
1956edd503 fix corner cases with arguments (#4481)
fixes #4480
2020-12-30 00:22:03 +08:00
Alex Lam S.L
560ccc1221 enhance reduce_vars (#4479) 2020-12-29 19:43:12 +08:00
Alex Lam S.L
10a71c182b fix corner case in arguments (#4477)
fixes #4476
2020-12-29 18:58:29 +08:00
Alex Lam S.L
ddc0ed7072 expand test options (#4475)
- fix corner cases in `hoist_vars` & `keep_fnames`
2020-12-29 06:17:52 +08:00
Alex Lam S.L
c00efe56f4 workaround asynchronous tty bugs on Node.js (#4473) 2020-12-28 13:32:07 +08:00
Alex Lam S.L
28bcdbd7df fix corner case in inline (#4472)
fixes #4471
2020-12-28 10:05:59 +08:00
Alex Lam S.L
6a8aed2049 fix corner case in unused (#4469)
fixes #4468
2020-12-27 20:06:50 +08:00
Alex Lam S.L
a8785fb694 workaround v8 bug with labels (#4467)
closes #4466
2020-12-27 13:32:18 +08:00
Alex Lam S.L
dd6d7b3d88 workaround schedule delays on GitHub Actions (#4463) 2020-12-26 17:27:03 +08:00
Alex Lam S.L
94f3819dc6 fix corner case in reduce_vars & unused (#4465)
fixes #4464
2020-12-26 16:52:16 +08:00
Alex Lam S.L
be1f5199f4 fix corner cases in collapse_vars (#4462)
fixes #4460
fixes #4461
2020-12-26 13:40:31 +08:00
Alex Lam S.L
95aea0e33c fix corner case in reduce_vars (#4459)
fixes #4458
2020-12-25 22:50:11 +08:00
Alex Lam S.L
a1b2735dd8 fix corner case in unused (#4457)
fixes #4456
2020-12-25 20:10:58 +08:00
Alex Lam S.L
f345175bc2 fix corner case in merge_vars (#4455)
fixes #4454
2020-12-25 19:27:05 +08:00
Alex Lam S.L
bb45f48ab7 workaround v8 heisenbug (#4453) 2020-12-25 13:14:36 +08:00
Alex Lam S.L
b2f27fd873 fix corner case in functions & reduce_vars (#4452)
fixes #4451
2020-12-25 08:38:24 +08:00
Alex Lam S.L
ced32f9bd8 enhance default_values (#4450) 2020-12-25 07:31:34 +08:00
Alex Lam S.L
dfc3ec9cef fix corner case in pure_getters (#4449)
fixes #4448
2020-12-25 03:58:23 +08:00
Alex Lam S.L
1896694532 fix & enhance collapse_vars (#4447)
fixes #4446
2020-12-24 17:02:18 +08:00
Alex Lam S.L
5f269cd573 fix corner case in collapse_vars (#4445)
fixes #4444
2020-12-24 10:56:22 +08:00
Alex Lam S.L
6988cd9558 replace keep_fargs default to false (#4443) 2020-12-24 09:56:02 +08:00
Alex Lam S.L
2390fae5c4 support default values (#4442) 2020-12-24 06:22:55 +08:00
Alex Lam S.L
56fce2131c fix corner case in pure_getters (#4441)
fixes #4440
2020-12-24 04:09:09 +08:00
Alex Lam S.L
7e575e9d7f fix corner case in if_return (#4439)
fixes #4438
2020-12-24 04:08:57 +08:00
Alex Lam S.L
cb4a02949e fix corner case with NaN (#4437)
fixes #4436
2020-12-23 07:01:50 +08:00
Alex Lam S.L
f85a206b9e fix corner case when parsing expression (#4435) 2020-12-23 02:16:04 +08:00
Alex Lam S.L
bba7cd0a70 v3.12.3 2020-12-22 23:59:53 +08:00
Alex Lam S.L
e1b2026929 improve object function generation in ufuzz (#4434) 2020-12-21 15:32:50 +08:00
Alex Lam S.L
c319030373 fix corner case in reduce_vars (#4433)
fixes #4432
2020-12-21 14:03:18 +08:00
Alex Lam S.L
47b63ed1a0 fix corner case in collapse_vars (#4431)
fixes #4430
2020-12-20 22:54:27 +08:00
Alex Lam S.L
7aefe97083 parse destructuring under strict mode correctly (#4429) 2020-12-20 20:48:51 +08:00
Alex Lam S.L
89198e0ad4 improve destructuring generation in ufuzz (#4428) 2020-12-20 13:38:56 +08:00
Alex Lam S.L
caea6aac81 handle destructuring catch in --reduce-test (#4427) 2020-12-20 11:22:45 +08:00
Alex Lam S.L
f5224ca1f5 fix corner case with destructuring catch (#4426)
fixes #4425
2020-12-20 10:31:32 +08:00
Alex Lam S.L
b7c49b72b3 support async function within object literal (#4424) 2020-12-20 08:19:04 +08:00
Alex Lam S.L
8ce3c7d70f fix corner case in evaluate & reduce_vars (#4423)
fixes #4422
2020-12-20 05:47:15 +08:00
Alex Lam S.L
87cf715213 fix corner case with destructuring catch (#4421)
fixes #4420
2020-12-20 05:47:01 +08:00
Alex Lam S.L
2c9c72e06c suppress false positives in ufuzz (#4419) 2020-12-20 02:31:09 +08:00
Alex Lam S.L
882968c68c fix corner case in inline (#4418)
fixes #4417
2020-12-20 01:24:29 +08:00
Alex Lam S.L
acc2d7d845 fix corner case in objects (#4416)
fixes #4415
2020-12-20 00:14:57 +08:00
Alex Lam S.L
9a5aede941 fix corner case in reduce_vars & unused (#4414)
fixes #4413
2020-12-19 12:47:46 +08:00
Alex Lam S.L
e6dd471f8f support destructuring of catch variable (#4412) 2020-12-19 12:28:38 +08:00
Alex Lam S.L
0f55bd92f1 fix corner case in arguments (#4411)
fixes #4410
2020-12-19 04:53:53 +08:00
Alex Lam S.L
7d9dad0289 fix corner case with parentheses (#4409)
fixes #4408
2020-12-19 01:01:49 +08:00
Alex Lam S.L
44e494f16f fix corner case in merge_vars (#4407)
fixes #4406
2020-12-19 00:52:37 +08:00
Alex Lam S.L
2415a72e75 fix corner case in unused (#4405)
fixes #4404
2020-12-18 23:45:41 +08:00
Alex Lam S.L
9c0718b162 enhance arrows (#4403) 2020-12-18 14:55:20 +08:00
Alex Lam S.L
d2c50ace99 fix corner case in merge_vars (#4402)
fixes #4401
2020-12-18 12:20:43 +08:00
Alex Lam S.L
1b646d3bc4 fix corner case in arguments (#4400)
fixes #4399
2020-12-18 10:12:01 +08:00
Alex Lam S.L
82d2aa4acf fix corner case in arguments (#4398)
fixes #4397
2020-12-18 09:42:07 +08:00
Alex Lam S.L
c1256c399a fix corner case in arguments (#4396)
fixes #4395
2020-12-18 08:41:13 +08:00
Alex Lam S.L
2c637fea8a fix corner case in evaluate & reduce_vars (#4394)
fixes #4393
2020-12-18 07:16:04 +08:00
Alex Lam S.L
4fa54b075c enhance reduce_vars (#4392) 2020-12-18 06:18:47 +08:00
Alex Lam S.L
ab82be82b2 fix corner case in collapse_vars (#4391)
fixes #4390
2020-12-18 03:10:16 +08:00
Alex Lam S.L
02fdcfde01 fix corner case in inline (#4389)
fixes #4388
2020-12-18 00:55:19 +08:00
Alex Lam S.L
a96f087ac3 support arrow function (#4385) 2020-12-17 18:23:41 +08:00
Alex Lam S.L
75e9fd8417 fix corner case in arguments (#4387)
fixes #4386
2020-12-17 13:51:34 +08:00
Alex Lam S.L
f68e267830 fix corner case in reduce_vars (#4384)
fixes #4383
2020-12-17 04:47:48 +08:00
Alex Lam S.L
8b10b93ee1 v3.12.2 2020-12-16 14:11:48 +08:00
Alex Lam S.L
549de028b6 fix corner case in objects (#4381)
fixes #4380
2020-12-15 21:23:55 +08:00
Alex Lam S.L
f579f1aa47 emulate global context in Node.js & web (#4379) 2020-12-14 02:05:07 +08:00
Alex Lam S.L
fcc40d0502 fix corner case in dead_code (#4378)
fixes #4377
2020-12-14 00:03:44 +08:00
Alex Lam S.L
b309527264 maintain compatibility options when testing (#4376) 2020-12-13 14:26:45 +08:00
Alex Lam S.L
5d19bb8d5d fix corner case in booleans (#4375)
fixes #4374
2020-12-13 05:01:38 +08:00
Alex Lam S.L
af97629912 fix corner case in dead_code (#4373)
fixes #4372
2020-12-13 02:24:18 +08:00
Alex Lam S.L
8c000033d3 clarify corner case in object literal (#4371)
closes #4366
2020-12-12 07:42:29 +08:00
Alex Lam S.L
fd0d28e465 fix corner case in spread (#4370) 2020-12-12 06:45:59 +08:00
Alex Lam S.L
2123f38394 fix asynchronous state tracking in ufuzz (#4369) 2020-12-12 05:19:56 +08:00
Alex Lam S.L
58dff9ada3 fix corner cases in unused & varify (#4368)
fixes #4365
2020-12-12 04:45:35 +08:00
Alex Lam S.L
4fdec765bc gate language features in ufuzz automatically (#4367) 2020-12-12 03:43:12 +08:00
Alex Lam S.L
1020d37256 fix corner case in spread (#4364)
fixes #4363
2020-12-12 02:19:11 +08:00
Alex Lam S.L
076739db07 fix corner case in unused (#4362)
fixes #4361
2020-12-12 00:57:05 +08:00
Alex Lam S.L
515e93d88a fix corner case in collapse_vars (#4360)
fixes #4359
2020-12-12 00:07:28 +08:00
Alex Lam S.L
57105b299e fix corner cases with spread syntax (#4358) 2020-12-11 06:59:21 +08:00
Alex Lam S.L
77e1bda426 improve fix for #4355 (#4357) 2020-12-11 00:48:41 +08:00
Alex Lam S.L
a59593cac8 fix corner case in loops & unused (#4356)
fixes #4355
2020-12-10 15:45:39 +08:00
Alex Lam S.L
046bbde9d4 fix corner case in keep_fargs & reduce_vars (#4354)
fixes #4353
2020-12-09 01:41:10 +08:00
Alex Lam S.L
fea9da9866 forbid AST_Await in computed function arguments (#4352)
fixes #4351
2020-12-08 12:59:08 +08:00
Alex Lam S.L
4733159782 fix corner cases with await (#4350)
fixes #4349
2020-12-08 11:26:03 +08:00
Alex Lam S.L
5fba98608c fix corner case in reduce_vars (#4348)
fixes #4347
2020-12-08 08:52:14 +08:00
Alex Lam S.L
c587d7917d introduce spread (#4346)
fixes #4345
2020-12-08 06:51:20 +08:00
Alex Lam S.L
336336f53f fix corner case with parentheses around await (#4344) 2020-12-08 04:29:54 +08:00
Alex Lam S.L
4bde50ce85 fix corner case in side_effects (#4343)
fixes #4342
2020-12-07 17:25:04 +08:00
Alex Lam S.L
fbecedf94c fix corner case in evaluate (#4341)
fixes #4340
2020-12-07 16:05:11 +08:00
Alex Lam S.L
2f31f95095 improve ufuzz (#4339) 2020-12-07 16:04:51 +08:00
Alex Lam S.L
6b603e1a62 fix corner case in unused (#4338)
fixes #4337
2020-12-07 13:23:53 +08:00
Alex Lam S.L
499f8d89ff fix corner case in inline (#4336)
fixes #4335
2020-12-07 11:30:37 +08:00
Alex Lam S.L
9eb65f3af3 extend trailing comma support (#4334) 2020-12-07 10:07:34 +08:00
Alex Lam S.L
2cbbf5c375 support async function (#4333) 2020-12-07 05:22:40 +08:00
Alex Lam S.L
3c384cf9a8 fix corner case in collapse_vars (#4332)
fixes #4331
2020-12-06 18:30:50 +08:00
Alex Lam S.L
37f4f56752 fix corner case in properties (#4330)
fixes #4329
2020-12-06 13:59:04 +08:00
Alex Lam S.L
1e4985ed9e support spread syntax (#4328) 2020-12-06 05:19:31 +08:00
Alex Lam S.L
d2d56e301e v3.12.1 2020-12-01 01:46:27 +08:00
Alex Lam S.L
9d34f8428b fix corner case in side_effects (#4326)
fixes #4325
2020-11-29 10:05:48 +08:00
Alex Lam S.L
f045e2b460 fix corner case in merge_vars (#4324)
fixes #4323
2020-11-29 05:38:24 +08:00
Alex Lam S.L
8791f258e3 fix corner case in inline (#4322)
fixes #4321
2020-11-29 03:48:42 +08:00
Alex Lam S.L
af1cca25bf fix corner case in inline (#4320)
fixes #4319
2020-11-27 01:31:06 +08:00
Alex Lam S.L
9b3a363604 fix infinite recursion in ufuzz (#4318) 2020-11-25 09:33:42 +08:00
Alex Lam S.L
1e8fa1aa1d fix corner case in passes & reduce_vars (#4316)
fixes #4315
2020-11-23 07:05:20 +08:00
Alex Lam S.L
9f67866147 v3.12.0 2020-11-23 01:10:39 +08:00
Alex Lam S.L
645d5a348b workaround Safari quirks (#4314)
fixes #1753
2020-11-21 10:30:46 +08:00
Alex Lam S.L
cf120c7cea fix corner case in merge_vars & reduce_vars (#4313)
fixes #4312
2020-11-21 08:57:59 +08:00
Alex Lam S.L
8d30902ba9 fix corner case in mangle (#4311) 2020-11-21 08:05:40 +08:00
Alex Lam S.L
02459cddf9 gate galio workaround (#4310) 2020-11-21 03:37:33 +08:00
Alex Lam S.L
1b579779be fix corner case in collapse_vars (#4309)
fixes #4308
2020-11-20 06:23:37 +08:00
Alex Lam S.L
b18b70f63b fix corner case in hoist_props (#4307) 2020-11-20 00:02:25 +08:00
Alex Lam S.L
641406d491 fix corner cases in reduce_vars & unused (#4306) 2020-11-19 11:25:36 +08:00
Alex Lam S.L
134ef0b1eb fix corner case in dead_code (#4304) 2020-11-19 08:34:55 +08:00
Alex Lam S.L
db87dcf13e enhance varify (#4303) 2020-11-19 07:58:33 +08:00
Alex Lam S.L
aecbabc587 fix corner case in merge_vars (#4302)
fixes #4301
2020-11-19 05:44:47 +08:00
Alex Lam S.L
fd6544b340 fix corner case reduce_vars (#4300)
fixes #4297
2020-11-19 01:11:28 +08:00
Alex Lam S.L
f6a83f7944 fix corner case in merge_vars (#4299)
fixes #4298
2020-11-18 23:43:55 +08:00
Alex Lam S.L
35283e5dd1 enhance arguments (#4296) 2020-11-18 11:39:32 +08:00
Alex Lam S.L
7a51c17ff0 fix corner case in merge_vars (#4295)
fixes #4294
2020-11-18 09:32:53 +08:00
Alex Lam S.L
aff842f2f9 fix corner case in arguments (#4293)
fixes #4291
2020-11-18 08:54:58 +08:00
Alex Lam S.L
0bedd031da fix corner cases in collapse_vars, unused & varify (#4292)
fixes #4290
2020-11-18 08:22:54 +08:00
Alex Lam S.L
caa92aea5d fix corner case in merge_vars (#4289)
fixes #4288
2020-11-18 04:03:20 +08:00
Alex Lam S.L
383163afa6 fix corner case in collapse_vars (#4287)
fixes #4286
2020-11-17 18:03:31 +08:00
Alex Lam S.L
8a83c8dd46 fix corner cases in collapse_vars & dead_code (#4285)
fixes #4284
2020-11-17 16:23:50 +08:00
Alex Lam S.L
2a612fd472 fix corner case in reduce_vars (#4283)
fixes #4282
2020-11-17 14:43:04 +08:00
Alex Lam S.L
b9798a01a8 fix corner case in reduce_vars (#4281)
fixes #4280
2020-11-17 12:59:44 +08:00
Alex Lam S.L
6dbacb5e3f enhance varify (#4279) 2020-11-17 12:35:00 +08:00
Alex Lam S.L
e5f80afc53 support destructured literals (#4278) 2020-11-17 08:01:24 +08:00
Alex Lam S.L
42e34c870a fix corner case in unused (#4277)
fixes #4276
2020-11-17 02:06:00 +08:00
Alex Lam S.L
e390e7e124 v3.11.6 2020-11-14 22:21:19 +08:00
Alex Lam S.L
6fd5b5b371 fix corner case in loops (#4275)
fixes #4274
2020-11-14 02:08:05 +08:00
Alex Lam S.L
fba27bfb71 fix corner case in evaluate (#4272)
fixes #4271
2020-11-11 00:06:13 +08:00
Alex Lam S.L
41310e6404 fix corner case in objects (#4270)
fixes #4269
2020-11-09 10:47:02 +08:00
Alex Lam S.L
91fc1c82b5 support computed property name in object literal (#4268) 2020-11-08 23:38:32 +08:00
Alex Lam S.L
810cd40356 fix corner case in inline (#4266)
fixes #4265
2020-11-08 18:50:08 +08:00
Alex Lam S.L
1cbd07e789 support shorthand method name in object literal (#4264) 2020-11-08 13:17:53 +08:00
Alex Lam S.L
b82de04775 support shorthand property name in object literal (#4263) 2020-11-08 10:44:44 +08:00
Alex Lam S.L
4bbeb09f7c fix corner case in reduce_vars (#4262)
fixes #4261
2020-11-07 10:00:04 +08:00
Alex Lam S.L
c2f6fd5fde fix corner case in functions (#4260)
fixes #4259
2020-11-06 03:55:25 +08:00
Alex Lam S.L
af4ea3ff69 v3.11.5 2020-11-03 08:59:02 +08:00
Alex Lam S.L
e7643248a3 fix corner case in merge_vars (#4258)
fixes #4257
2020-11-02 01:01:00 +08:00
Alex Lam S.L
68091dbf69 fix corner case in merge_vars (#4256)
fixes #4255
2020-11-01 14:34:07 +08:00
Alex Lam S.L
cbf7269296 fix corner case in merge_vars (#4254)
fixes #4253
2020-11-01 10:37:21 +08:00
Alex Lam S.L
d8563caba7 improve resilience against spurious time-outs (#4252) 2020-10-30 11:06:48 +08:00
Alex Lam S.L
2e0ad40fe6 fix corner case in ie8 (#4251)
fixes #4250
2020-10-30 11:06:31 +08:00
Alex Lam S.L
5d12abc41b fix corner cases in collapse_vars (#4249)
fixes #4248
2020-10-30 10:04:23 +08:00
Alex Lam S.L
79e5c3f564 improve warnings (#4247)
closes #4244
2020-10-27 17:39:33 +08:00
Alex Lam S.L
607f87c5cd fix corner case in booleans (#4246)
fixes #4245
2020-10-26 18:53:58 +08:00
Alex Lam S.L
b2775746a7 v3.11.4 2020-10-25 23:40:42 +00:00
Alex Lam S.L
e478da24c7 fix corner case in collapse_vars (#4243)
fixes #4242
2020-10-24 22:44:20 +08:00
Alex Lam S.L
c5df8355ba fix corner case in loops & unused (#4241)
fixes #4240
2020-10-24 13:33:48 +08:00
Alex Lam S.L
ff38d2471f improve resilience against npm failures (#4239) 2020-10-24 11:22:13 +08:00
Alex Lam S.L
8e86d05c32 fix corner case in merge_vars (#4238)
fixes #4237
2020-10-24 10:19:43 +08:00
Alex Lam S.L
9e40abeded fix corner case in unused (#4236)
fixes #4235
2020-10-22 22:19:47 +08:00
Alex Lam S.L
23ca7d675f fix corner case in functions (#4234)
fixes #4233
2020-10-22 10:13:11 +08:00
Alex Lam S.L
fd8c0212b8 fix corner case in ie8 (#4232)
fixes #4231
2020-10-20 14:02:39 +08:00
Alex Lam S.L
256950c2c0 fix corner case in ie8 (#4230)
fixes #4229
2020-10-20 06:13:23 +08:00
Alex Lam S.L
8ecaa40c6e extend support for Unicode (#4228) 2020-10-19 09:34:17 +08:00
Alex Lam S.L
96bf7fceab support let (#4227) 2020-10-19 08:32:39 +08:00
Alex Lam S.L
6c7226c10e v3.11.3 2020-10-19 07:25:47 +08:00
Alex Lam S.L
dc575919e2 fix corner case in side_effects (#4226)
fixes #4225
2020-10-18 22:13:10 +08:00
Alex Lam S.L
4298201938 flush stdout from ufuzz jobs properly (#4224) 2020-10-16 21:56:54 +08:00
Alex Lam S.L
4f833937fe fix corner case in inline (#4223)
fixes #4222
2020-10-15 21:52:40 +08:00
Alex Lam S.L
3d71e97dd1 fix corner cases in braces & sequences (#4221)
fixes #4220
2020-10-14 23:39:35 +08:00
Alex Lam S.L
7f35d9cee0 fix corner case in reduce_vars (#4219)
fixes #4218
2020-10-14 07:58:04 +08:00
Alex Lam S.L
9f8106e1d8 fix corner case in collapse_vars (#4217)
fixes #4216
2020-10-14 07:18:26 +08:00
Alex Lam S.L
b7b8435721 fix corner case in evaluate (#4215)
fixes #4214
2020-10-14 02:49:45 +08:00
Alex Lam S.L
c0c04c33bb fix corner cases in dead_code & reduce_vars (#4213)
fixes #4212
2020-10-14 00:09:17 +08:00
Alex Lam S.L
0e234a25c5 fix corner case in reduce_vars (#4211)
fixes #4210
2020-10-13 15:52:03 +08:00
Alex Lam S.L
3096f6fdad restore inline functionality disabled by #4204 (#4209) 2020-10-13 09:33:49 +08:00
Alex Lam S.L
176c09c6a5 fix corner case in reduce_vars & unused (#4208)
fixes #4207
2020-10-13 07:32:17 +08:00
Alex Lam S.L
9272f662c0 fix corner case in collapse_vars (#4206)
fixes #4205
2020-10-13 01:30:21 +08:00
Alex Lam S.L
4d33cb2f94 fix corner case in inilne (#4204)
fixes #4202
2020-10-12 23:10:32 +08:00
Alex Lam S.L
00d0eda85b fix corner case in arguments (#4201)
fixes #4200
2020-10-12 19:03:21 +08:00
Alex Lam S.L
1cdf810f0b fix corner case in reduce_vars (#4203)
fixes #4198
2020-10-12 19:02:44 +08:00
Alex Lam S.L
b512726cf3 fix corner case in collapse_vars (#4199)
fixes #4197
2020-10-12 14:13:17 +08:00
Alex Lam S.L
9b7a13c8c7 fix corner case in ie8 & mangle (#4196)
fixes #4195
2020-10-12 12:43:26 +08:00
Alex Lam S.L
74ff6ce261 fix corner case in dead_code (#4194)
fixes #4193
2020-10-12 11:09:26 +08:00
Alex Lam S.L
b1b8898e7c fix corner case in functions (#4192)
fixes #4191
2020-10-12 09:26:56 +08:00
Alex Lam S.L
55451e7b78 support const (#4190) 2020-10-12 01:18:57 +08:00
Alex Lam S.L
ffcce28ce1 v3.11.2 2020-10-11 21:19:25 +08:00
Alex Lam S.L
9c0feb69e5 fix corner case in reduce_vars (#4189)
fixes #4188
2020-10-07 22:01:39 +08:00
Alex Lam S.L
bc6e105174 fix corner case in ie8 (#4187)
fixes #4186
2020-10-06 09:20:41 +08:00
Alex Lam S.L
b91a2459c0 fix corner case in unused (#4185)
fixes #4184
2020-10-05 18:59:03 +08:00
Alex Lam S.L
b7a57fc69d fix corner case in loops (#4183)
fixes #4182
2020-10-05 17:28:46 +08:00
Alex Lam S.L
2dbe40b01b enhance conditionals (#4181) 2020-10-05 15:55:37 +08:00
Alex Lam S.L
813ac3ba96 enhance loops (#4180) 2020-10-05 08:26:59 +08:00
Alex Lam S.L
220dc95c0d clean up scope-related variables (#4179) 2020-10-05 06:56:52 +08:00
Alex Lam S.L
8f0521d51d retrofit try-catch-finally as block-scoped (#4178)
- support optional catch binding
2020-10-05 05:30:14 +08:00
Alex Lam S.L
f9946767c9 retrofit AST_BlockStatement as block-scoped (#4177) 2020-10-05 01:58:50 +08:00
Alex Lam S.L
58ac5b9bd5 extend support for numeral literals (#4176) 2020-10-05 00:05:03 +08:00
Alex Lam S.L
66140b459e enhance side_effects (#4175) 2020-10-04 23:43:49 +08:00
Alex Lam S.L
1786c69070 v3.11.1 2020-10-04 22:12:07 +08:00
Alex Lam S.L
95ef4d5377 fix corner case in mangle (#4174) 2020-10-04 08:24:41 +08:00
Alex Lam S.L
04017215cc support JSON dump beyond AST_Toplevel (#4173) 2020-10-03 22:53:06 +08:00
Alex Lam S.L
142bd1bd1a workaround quirks on latter specs (#4172)
closes #4171
2020-10-03 18:27:17 +08:00
Alex Lam S.L
8cb509d50e fix corner case in merge_vars (#4170)
fixes #4168
2020-10-03 07:03:39 +08:00
Alex Lam S.L
baf4903aa7 fix corner cases of catch variable inlining (#4169) 2020-10-03 07:02:28 +08:00
Alex Lam S.L
35465d590e report immediate ufuzz failure from Pull Request (#4166) 2020-10-02 23:43:38 +08:00
Alex Lam S.L
ccd91b9952 retrofit catch as block-scoped (#4165) 2020-10-02 23:29:58 +08:00
Alex Lam S.L
47a5e6e17a enhance if_return (#4164) 2020-10-02 16:10:25 +08:00
Alex Lam S.L
090ee895e1 enhance inline (#4163) 2020-09-30 21:03:28 +08:00
Alex Lam S.L
1cd1a1e5ee improve resilience against GitHub API (#4161) 2020-09-30 01:13:29 +08:00
Alex Lam S.L
1d835ac17d fix corner case in inline (#4160)
fixes #4159
2020-09-29 07:01:38 +08:00
Alex Lam S.L
9e07ac4102 fix corner case in merge_vars (#4158)
fixes #4157
2020-09-28 14:09:55 +08:00
Alex Lam S.L
92d1391e5e v3.11.0 2020-09-27 20:36:27 +08:00
Alex Lam S.L
b4ff6d0f2d fix corner cases in functions & merge_vars (#4156)
fixes #4155
2020-09-26 15:31:33 +08:00
Alex Lam S.L
9882a9f4af fix corner case in ufuzz scheduling (#4154) 2020-09-26 11:23:56 +08:00
Alex Lam S.L
40f36b9e01 improve ufuzz duty cycle heuristic (#4153) 2020-09-26 07:56:00 +08:00
Alex Lam S.L
6e105c5ca6 enhance merge_vars (#4152) 2020-09-25 22:00:20 +08:00
Alex Lam S.L
af35cd32f2 fix corner case in merge_vars (#4151) 2020-09-25 08:04:51 +08:00
Alex Lam S.L
7de8daa4b1 minor clean up (#4149) 2020-09-23 23:06:12 +08:00
Alex Lam S.L
305a4bdcee minor clean up (#4148) 2020-09-23 16:34:22 +08:00
Alex Lam S.L
3472cf1a90 fix corner case in unused (#4147)
fixes #4146
2020-09-22 20:08:45 +08:00
Alex Lam S.L
6d4c0fa6fa fix corner case in unused (#4145)
fixes #4144
2020-09-22 14:03:27 +08:00
Alex Lam S.L
3cca0d6249 fix corner case in evaluate (#4143)
fixes #4142
2020-09-22 12:11:25 +08:00
Alex Lam S.L
12ac49b970 Merge pull request #4141 from alexlamsl/unused
enhance `unused`
2020-09-22 02:21:43 +01:00
alexlamsl
8c670cae93 enhance unused 2020-09-22 07:48:55 +08:00
Alex Lam S.L
0e3da27727 fix corner case in merge_vars (#4140)
fixes #4139
2020-09-21 23:49:41 +01:00
Alex Lam S.L
13cdc167a2 fix corner case in evaluate (#4138)
fixes #4137
2020-09-22 06:49:32 +08:00
alexlamsl
51803cdcb2 fix corner case in merge_vars
fixes #4139
2020-09-22 05:03:06 +08:00
Alex Lam S.L
8fa470c17c fix corner case in merge_vars (#4136)
fixes #4135
2020-09-20 23:54:14 +08:00
Alex Lam S.L
90410f9fc3 fix corner case in unused (#4134)
fixes #4133
2020-09-20 23:21:59 +08:00
Alex Lam S.L
ef3831437d improve ufuzz duty cycle heuristic (#4132) 2020-09-20 08:29:35 +08:00
Alex Lam S.L
171c544705 fix corner case in merge_vars (#4131)
fixes #4130
2020-09-20 05:36:16 +08:00
Alex Lam S.L
3c609e2f4a enhance unused (#4129) 2020-09-20 01:45:52 +08:00
Alex Lam S.L
f0ae03ed39 report immediate ufuzz failure from Pull Request (#4128) 2020-09-19 20:31:37 +08:00
Alex Lam S.L
31c6b45036 fix corner case in merge_vars (#4127)
fixes #4126
2020-09-19 19:56:21 +08:00
Alex Lam S.L
3ac533e644 enhance merge_vars (#4125) 2020-09-19 11:16:23 +08:00
Alex Lam S.L
38a46c86d7 enhance side_effects (#4124)
- add documentation for `merge_vars`
2020-09-18 21:35:29 +08:00
Alex Lam S.L
0f0759ec15 remove redundant transform (#4123) 2020-09-18 07:04:46 +08:00
Alex Lam S.L
7f501f9fed add tests (#4122) 2020-09-18 00:26:31 +08:00
Alex Lam S.L
72844eb5a4 improve fix for #4119 (#4121) 2020-09-17 23:08:36 +08:00
Alex Lam S.L
09d93cc6c8 fix corner case in evaluate (#4120)
fixes #4119
2020-09-17 21:20:31 +08:00
Alex Lam S.L
dd1374aa8a minor clean up (#4118) 2020-09-17 07:10:45 +08:00
Alex Lam S.L
fdf2e8c5b0 enhance collapse_vars (#4117) 2020-09-17 06:35:22 +08:00
Alex Lam S.L
a9d934ab4e improve handling of switch statements (#4114) 2020-09-17 03:12:08 +08:00
Alex Lam S.L
2a053710bd fix corner case in merge_vars (#4116)
fixes #4115
2020-09-17 03:11:57 +08:00
Alex Lam S.L
219aac6a84 fix corner case in merge_vars (#4113)
fixes #4112
2020-09-16 22:18:28 +08:00
Alex Lam S.L
2039185051 enhance conditionals (#4106) 2020-09-16 05:51:42 +08:00
Alex Lam S.L
ad27c14202 fix corner cases in merge_vars (#4108)
fixes #4107
fixes #4109
fixes #4110
fixes #4111
2020-09-16 04:43:01 +08:00
Alex Lam S.L
a62b086184 enhance merge_vars (#4105) 2020-09-15 22:59:10 +08:00
Alex Lam S.L
335456cf77 fix corner case in merge_vars (#4104)
fixes #4103
2020-09-15 19:47:12 +08:00
Alex Lam S.L
d64d0b0bec fix corner case in merge_vars (#4102)
fixes #4101
2020-09-15 19:18:12 +08:00
Alex Lam S.L
3ac575f2e8 introduce merge_vars (#4100) 2020-09-15 10:01:48 +08:00
Alex Lam S.L
d33a3a3253 enhance unused (#4098) 2020-09-13 01:05:43 +08:00
Alex Lam S.L
d7456a2dc2 enhance if_return (#4097) 2020-09-10 22:31:34 +08:00
Alex Lam S.L
d97672613d fix corner case in reduce_vars (#4095) 2020-09-08 22:12:27 +08:00
Alex Lam S.L
30761eede5 v3.10.4 2020-09-07 00:25:54 +08:00
Alex Lam S.L
fb30aeccaf relax ufuzz job timing constraint (#4094) 2020-09-05 19:29:50 +08:00
Alex Lam S.L
226aa1f76b enhance unsafe_math (#4093) 2020-09-04 10:14:39 +08:00
Alex Lam S.L
6e235602fb fix corner case in loops & unused (#4092)
fixes #4091
2020-09-04 01:51:26 +08:00
Alex Lam S.L
980fcbb56b enhance unused (#4090) 2020-09-03 17:41:33 +08:00
Alex Lam S.L
375ebe316d enhance join_vars (#4089) 2020-09-03 01:41:10 +08:00
Alex Lam S.L
2500930234 enhance reduce_vars (#4088) 2020-09-02 11:30:46 +08:00
Alex Lam S.L
2f0da2ff05 reduce AST_ForIn gracefully (#4087) 2020-09-02 08:51:43 +08:00
Alex Lam S.L
83a3cbf151 fix test case runtime accounting (#4086) 2020-09-02 03:23:08 +08:00
Alex Lam S.L
da8d154571 fix corner case in loops & unused (#4085)
fixes #4084
2020-09-02 03:20:58 +08:00
Alex Lam S.L
e33c727e8b v3.10.3 2020-08-30 13:09:12 +01:00
Alex Lam S.L
f886b3fb2b fix corner case in loops & unused (#4083)
fixes #4082
2020-08-29 02:42:17 +08:00
Alex Lam S.L
b1cc15e85b fix corner case in sequences (#4080)
fixes #4079
2020-08-26 20:41:11 +08:00
Alex Lam S.L
3aa765e429 fix corner case in evaluate (#4078)
fixes #4077
2020-08-26 19:45:38 +08:00
Alex Lam S.L
93d084a1d1 fix corner case in loops & unused (#4076)
fixes #4075
2020-08-26 17:32:20 +08:00
Alex Lam S.L
c7a3e09407 enhance loops & unused (#4074)
- extend `ufuzz` generation of for-in loops
2020-08-26 09:32:55 +08:00
Alex Lam S.L
09525c7530 fix corner case in sequences (#4073) 2020-08-26 01:26:49 +08:00
Alex Lam S.L
a7e15fe73c streamline parenthesis logic (#4072) 2020-08-25 19:45:37 +08:00
Alex Lam S.L
a31c27c7cf fix corner case in collapse_vars (#4071)
fixes #4070
2020-08-25 17:23:36 +08:00
Alex Lam S.L
1caf7c7bd2 minor clean up (#4069) 2020-08-25 10:10:56 +08:00
Alex Lam S.L
0eb0c9b388 fix corner case in evaluate (#4068)
fixes #4067
2020-08-24 14:57:26 +08:00
Alex Lam S.L
7dc61cdc89 tidy up various interfaces (#4066) 2020-08-24 04:39:38 +08:00
Alex Lam S.L
af1b2f30c9 v3.10.2 2020-08-23 23:09:12 +08:00
Alex Lam S.L
37b4fc7e31 update domprops (#4065) 2020-08-23 23:06:15 +08:00
Alex Lam S.L
da85d102e3 enhance mangle.properties (#4064) 2020-08-23 08:45:39 +08:00
Alex Lam S.L
35fe1092d3 simplify traversal logic (#4063) 2020-08-23 05:45:35 +08:00
Alex Lam S.L
f2d486e771 enhance comparisons (#4062) 2020-08-23 01:03:48 +08:00
Alex Lam S.L
fee677786e fix corner case in collapse_vars (#4061) 2020-08-21 10:35:34 +08:00
Alex Lam S.L
aa83ecdb3b fix corner case in switches (#4060)
fixes #4059
2020-08-21 08:05:10 +08:00
Alex Lam S.L
a153176469 enhance conditionals & switches (#4058) 2020-08-21 00:35:39 +08:00
Alex Lam S.L
1c6384b6a5 improve ufuzz duty cycle heuristic (#4057) 2020-08-19 23:29:01 +08:00
Alex Lam S.L
e8db526f51 avoid setters during console.log() in sandbox (#4055)
fixes #4054
2020-08-19 06:14:41 +08:00
Alex Lam S.L
fa13ed4391 reject multiple defaults in switch (#4053)
fixes #4050
2020-08-17 10:09:12 +08:00
Alex Lam S.L
23f0dca992 fix corner cases in collapse_vars & dead_code (#4052)
fixes #4051
2020-08-17 05:54:27 +08:00
Alex Lam S.L
45ab3b51d8 clarify toplevel & global variable aliasing (#4046) 2020-08-10 06:39:28 +08:00
Alex Lam S.L
49670d216b fix corner case in collapse_vars (#4048)
fixes #4047
2020-08-10 05:48:56 +08:00
Alex Lam S.L
e2237d8cd2 improve ufuzz duty cycle heuristic (#4045) 2020-08-09 03:10:19 +08:00
Alex Lam S.L
91f078fe35 workaround incorrect workflow status (#4044) 2020-08-08 05:16:54 +08:00
Alex Lam S.L
a546cb881d improve ufuzz duty cycle on GitHub Actions (#4043) 2020-08-07 18:42:36 +08:00
Alex Lam S.L
84d5dffd9f tweak GitHub Actions (#4042) 2020-08-07 02:15:51 +08:00
Alex Lam S.L
a8e286f7e1 fix corner case in collapse_vars (#4041)
fixes #4040
2020-08-06 20:30:28 +08:00
Alex Lam S.L
9b05494ebc fix corner cases in aliasing of global variables (#4039)
fixes #4038
2020-08-06 09:39:50 +01:00
Alex Lam S.L
30ef20a208 tweak GitHub Actions (#4037) 2020-08-05 22:09:02 +08:00
Alex Lam S.L
a4002ef467 fix corner case in evaluate (#4036)
fixes #4035
2020-08-04 20:05:10 +08:00
157 changed files with 51638 additions and 6683 deletions

View File

@@ -1,25 +0,0 @@
**Bug report or feature request?**
<!-- Note: sub-optimal but correct code is not a bug -->
**Uglify version (`uglifyjs -V`)**
**JavaScript input**
<!--
A complete parsable JS program exhibiting the issue with
UglifyJS alone - without third party tools or libraries.
Ideally the input should be as small as possible.
Post a link to a gist if necessary.
Issues without a reproducible test case will be closed.
-->
**The `uglifyjs` CLI command executed or `minify()` options used.**
**JavaScript output or error produced.**
<!--
Note: `uglify-js` only supports JavaScript.
Those wishing to minify ES6+ should transpile first.
-->

51
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,51 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
<!-- Note: sub-optimal but correct code is not a bug -->
**Uglify version (`uglifyjs -V`)**
**JavaScript input**
<!--
A complete parsable JS program exhibiting the issue with UglifyJS alone
- without third party tools or libraries.
Ideally the input should be as small as possible, but may be large if isolating
the problem proves to be difficult. The most important thing is that the
standalone program reliably exhibits the bug when minified. Provide a link to a
gist if necessary.
Solely providing minified output without the original uglify JS input is not
useful in determining the cause of the problem. Issues without a reproducible
test case will be closed.
-->
**The `uglifyjs` CLI command executed or `minify()` options used.**
<!--
Command-line or API call to UglifyJS without third party tools or libraries.
For users using bundlers or transpilers, you may be able to gather the required
information through setting the `UGLIFY_BUG_REPORT` environment variable:
export UGLIFY_BUG_REPORT=1 (bash)
set UGLIFY_BUG_REPORT=1 (Command Prompt)
$Env:UGLIFY_BUG_REPORT=1 (PowerShell)
before running your usual build process. The resulting "minified" output should
contain the necessary details for this report.
-->
**JavaScript output or error produced.**
<!--
Only minified code that produces different output (or error) from the original
upon execution would be considered a bug.
-->

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:
- '-mb braces'
- '--ie -c'
- '-mc'
- '-p acorn --toplevel -mco spidermonkey'
- '--toplevel -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@v2
- name: Perform uglify, build & test
shell: bash
run: |
. ./test/release/install.sh
./test/release/$SCRIPT $OPTIONS

View File

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

View File

@@ -2,34 +2,43 @@ name: Fuzzing
on:
pull_request:
schedule:
- cron: "*/8 * * * *"
- cron: '*/15 * * * *'
workflow_dispatch:
workflow_run:
branches: [ master ]
types: [ completed ]
workflows: [ 'Build testing', CI ]
env:
BASE_URL: https://api.github.com/repos/${{ github.repository }}
TOKEN: ${{ github.token }}
jobs:
ufuzz:
strategy:
fail-fast: false
matrix:
os: [ ubuntu-latest, windows-latest ]
name: ${{ matrix.os }}
include:
- node: latest
os: macos-latest
- node: '8'
os: ubuntu-latest
- node: '8'
os: ubuntu-latest
- node: '8'
os: windows-latest
- node: '8'
os: windows-latest
name: ${{ matrix.node }} ${{ matrix.os }}
runs-on: ${{ matrix.os }}
env:
NODE: ${{ matrix.node }}
steps:
- uses: actions/checkout@v2
- name: Perform fuzzing
shell: bash
run: |
git clone --branch v1.5.4 --depth 1 https://github.com/jasongin/nvs.git ~/.nvs
while ! timeout 60 bash -c '. ~/.nvs/nvs.sh add 8 && nvs use 8'; do
cd ~/.nvs
while !(git clean -xdf); do echo "'git clean' failed - retrying..."; done
cd -
done
. ~/.nvs/nvs.sh --version
nvs use 8
node --version
npm config set audit false
npm config set optional false
npm config set save false
npm config set strict-ssl false
npm config set update-notifier false
npm --version
while !(npm install); do echo "'npm install' failed - retrying..."; done
node test/ufuzz/job 3600000
. ./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

483
README.md
View File

@@ -4,10 +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` only supports JavaScript (ECMAScript 5).
- To minify ECMAScript 2015 or above, 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
-------
@@ -84,13 +85,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
@@ -107,8 +111,8 @@ 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()`
--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-fnames Do not mangle/drop function names. Useful for
@@ -133,8 +137,16 @@ a double dash to prevent input files being used as option arguments:
`//# sourceMappingURL`.
--timings Display operations run time on STDERR.
--toplevel Compress and/or mangle variables in top level scope.
--v8 Support non-standard Chrome & Node.js
Equivalent to setting `v8: true` in `minify()`
for `mangle` and `output` options.
By default UglifyJS will not try to be v8-proof.
--verbose Print diagnostic messages.
--warn Print warning messages.
--webkit Support non-standard Safari/Webkit.
Equivalent to setting `webkit: true` in `minify()`
for `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
need to pass an argument to this option to
@@ -212,17 +224,16 @@ Example:
To enable the mangler you need to pass `--mangle` (`-m`). The following
(comma-separated) options are supported:
- `toplevel` (default `false`) -- mangle names declared in the top level scope.
- `eval` (default: `false`) mangle names visible in scopes where `eval` or
`with` are used.
- `eval` (default `false`) -- mangle names visible in scopes where `eval` or `with` are used.
- `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:
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:
uglifyjs ... -m reserved=['$','require','exports']
uglifyjs ... -m reserved=['$','require','exports']
to prevent the `require`, `exports` and `$` names from being changed.
to prevent the `require`, `exports` and `$` names from being changed.
### CLI mangling property names (`--mangle-props`)
@@ -483,43 +494,53 @@ 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.
- `ie` (default: `false`) — enable workarounds for Internet Explorer bugs.
- `keep_fnames` (default: `false`) -- pass `true` to prevent discarding or mangling
- `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
- `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.
- `warnings` (default `false`) — pass `true` to return compressor warnings
- `v8` (default: `false`) — enable workarounds for Chrome & Node.js bugs.
- `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.
PhantomJS users should set this option to `true`.
## Minify options structure
```javascript
@@ -545,7 +566,6 @@ if (result.error) throw result.error;
},
nameCache: null, // or specify a name cache object
toplevel: false,
ie8: false,
warnings: false,
}
```
@@ -602,107 +622,121 @@ 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`)
- `shebang` (default `true`) -- support `#!command` as the first line
- `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.
- `assignments` (default: `true`) -- apply optimizations to assignment expressions.
- `arrows` (default: `true`) apply optimizations to arrow functions
- `booleans` (default: `true`) -- various optimizations for boolean context,
- `assignments` (default: `true`) — apply optimizations to assignment expressions
- `awaits` (default: `true`) — apply optimizations to `await` expressions
- `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
- `directives` (default: `true`) -- remove redundant or non-standard directives
- `default_values` (default: `true`) — drop overshadowed default values
- `drop_console` (default: `false`) -- Pass `true` to discard calls to
- `directives` (default: `true`) — remove redundant or non-standard directives
- `drop_console` (default: `false`) — Pass `true` to discard calls to
`console.*` functions. If you wish to drop a specific function call
such as `console.info` and/or retain side effects from function arguments
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 `mangle` enabled, the `compress` option `passes` set to `2` or higher,
and the `compress` option `toplevel` enabled.
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
- `true` — same as `3`
- `keep_fargs` (default: `strict`) -- Discard unused function arguments. Code
which relies on `Function.length` will break if this is done indiscriminately,
i.e. when passing `true`. Pass `false` to always retain function arguments.
- `join_vars` (default: `true`) — join consecutive `var` statements
- `keep_fnames` (default: `false`) -- Pass `true` to prevent the
compressor from discarding function names. Useful for code relying on
`Function.prototype.name`. See also: the `keep_fnames` [mangle option](#mangle-options).
- `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.
- `negate_iife` (default: `true`) -- negate "Immediately-Called Function Expressions"
- `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
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
@@ -714,22 +748,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
- `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`.
- `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.
- `sequences` (default: `true`) -- join consecutive simple statements using the
- `rests` (default: `true`) — apply optimizations to rest parameters
- `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`
@@ -738,64 +774,67 @@ 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.
- `strings` (default: `true`) -- compact string concatenations.
- `spreads` (default: `true`) — flatten spread expressions.
- `switches` (default: `true`) -- de-duplicate and remove unreachable `switch` branches
- `strings` (default: `true`) — compact string concatenations.
- `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)
- `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`)
- `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.
- `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)
- `unsafe` (default: `false`) -- apply "unsafe" transformations (discussion below)
- `typeofs` (default: `true`) — compress `typeof` expressions, e.g.
`typeof foo == "undefined" → void 0 === foo`
- `unsafe_comps` (default: `false`) -- compress expressions like `a <= b` assuming
- `unsafe` (default: `false`) — apply "unsafe" transformations (discussion below)
- `unsafe_comps` (default: `false`) — compress expressions like `a <= b` assuming
none of the operands can be (coerced to) `NaN`.
- `unsafe_Function` (default: `false`) -- compress and mangle `Function(args, code)`
- `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`
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.
- `keep_fnames` (default `false`) -- Pass `true` to not mangle function names.
Useful for code relying on `Function.prototype.name`. See also: the `keep_fnames`
[compress option](#compress-options).
- `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:
@@ -822,18 +861,18 @@ UglifyJS.minify(code, { mangle: { toplevel: true } }).code;
### Mangle properties options
- `builtins` (default: `false`) -- Use `true` to allow the mangling of builtin
- `builtins` (default: `false`) — Use `true` to allow the mangling of builtin
DOM properties. Not recommended to override this setting.
- `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.
- `keep_quoted` (default: `false`) — Only mangle unquoted property names.
- `regex` (default: `null`) -— Pass a RegExp literal to only mangle property
- `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
@@ -842,76 +881,79 @@ 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.
- `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.
- `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.
```js
```javascript
function(node, comment) {
return comment.value.indexOf("@type " + node.TYPE) >= 0;
}
```
- `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`)
- `inline_script` (default `true`) -- escape HTML comments and the slash in
- `indent_start` (default: `0`) — prefix all lines by that many spaces
- `inline_script` (default: `true`) — escape HTML comments and the slash in
occurrences of `</script>` in strings
- `keep_quoted_props` (default `false`) -- when turned on, prevents stripping
- `keep_quoted_props` (default: `false`) when turned on, prevents stripping
quotes from property names in object literals.
- `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)
- `webkit` (default `false`) -- enable workarounds for WebKit bugs.
PhantomJS users should set this option to `true`.
- `width` (default `80`) -- only takes effect when beautification is on, this
- `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.
@@ -1112,29 +1154,25 @@ 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:
```
uglifyjs file.js -m
```
To enable fast minify mode with the API use:
```js
```javascript
UglifyJS.minify(code, { compress: false, mangle: true });
```
#### Source maps and debugging
### Source maps and debugging
Various `compress` transforms that simplify, rearrange, inline and remove code
are known to have an adverse effect on debugging with source maps. This is
@@ -1146,6 +1184,10 @@ disable the Uglify `compress` option and just use `mangle`.
To allow for better optimizations, the compiler makes various assumptions:
- The code does not rely on preserving its runtime performance characteristics.
Typically uglified code will run faster due to less instructions and easier
inlining, but may be slower on rare occasions for a specific platform, e.g.
see [`reduce_funcs`](#compress-options).
- `.toString()` and `.valueOf()` don't have side effects, and for built-in
objects they have not been overridden.
- `undefined`, `NaN` and `Infinity` have not been externally redefined.
@@ -1157,3 +1199,156 @@ 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()`).
- Earlier versions of JavaScript will throw `SyntaxError` with the following:
```javascript
({
p: 42,
get p() {},
});
// SyntaxError: Object literal may not have data and accessor property with
// the same name
```
UglifyJS may modify the input which in turn may suppress those errors.
- Iteration order of keys over an object which contains spread syntax in later
versions of Chrome and Node.js may be altered.
- When `toplevel` is enabled, UglifyJS effectively assumes input code is wrapped
within `function(){ ... }`, thus forbids aliasing of declared global variables:
```javascript
A = "FAIL";
var B = "FAIL";
// can be `global`, `self`, `window` etc.
var top = function() {
return this;
}();
// "PASS"
top.A = "PASS";
console.log(A);
// "FAIL" after compress and/or mangle
top.B = "PASS";
console.log(B);
```
- Use of `arguments` alongside destructuring as function parameters, e.g.
`function({}, arguments) {}` will result in `SyntaxError` in earlier versions
of Chrome and Node.js - UglifyJS may modify the input which in turn may
suppress those errors.
- Earlier versions of Chrome and Node.js will throw `ReferenceError` with the
following:
```javascript
var a;
try {
throw 42;
} catch ({
[a]: b,
// ReferenceError: a is not defined
}) {
let a;
}
```
UglifyJS may modify the input which in turn may suppress those errors.
- Later versions of JavaScript will throw `SyntaxError` with the following:
```javascript
a => {
let a;
};
// SyntaxError: Identifier 'a' has already been declared
```
UglifyJS may modify the input which in turn may suppress those errors.
- Later versions of JavaScript will throw `SyntaxError` with the following:
```javascript
try {
// ...
} catch ({ message: a }) {
var a;
}
// SyntaxError: Identifier 'a' has already been declared
```
UglifyJS may modify the input which in turn may suppress those errors.
- Some versions of Chrome and Node.js will throw `ReferenceError` with the
following:
```javascript
console.log(((a, b = function() {
return a;
// ReferenceError: a is not defined
}()) => b)());
```
UglifyJS may modify the input which in turn may suppress those errors.
- Some arithmetic operations with `BigInt` may throw `TypeError`:
```javascript
1n + 1;
// 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;
async function f() {
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.
- Later versions of Chrome and Node.js will give incorrect results with the
following:
```javascript
console.log({
...console,
get 42() {
return "FAIL";
},
[42]: "PASS",
}[42]);
// Expected: "PASS"
// Actual: "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.

View File

@@ -3,14 +3,14 @@
"use strict";
require("../tools/exit");
require("../tools/tty");
var fs = require("fs");
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", "inlined", "parent_scope", "scope", "uses_eval", "uses_with" ];
var files = {};
var options = {};
var short_forms = {
@@ -95,11 +95,13 @@ 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.",
" --ie Support non-standard Internet Explorer.",
" --keep-fnames Do not mangle/drop function names. Useful for code relying on Function.prototype.name.",
" --name-cache <file> File to hold mangled name mappings.",
" --rename Force symbol expansion.",
@@ -108,10 +110,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"));
}
@@ -138,12 +145,19 @@ function process_option(name, no_value) {
case "enclose":
options[name] = read_value();
break;
case "annotations":
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-fnames":
options.keep_fnames = true;
break;
@@ -192,6 +206,7 @@ function process_option(name, no_value) {
case "no-rename":
options.rename = false;
break;
case "in-situ":
case "reduce-test":
case "self":
break;
@@ -223,10 +238,11 @@ if (options.mangle && options.mangle.properties) {
});
}
}
if (output == "ast") options.output = {
ast: true,
code: false,
};
if (/^ast|spidermonkey$/.test(output)) {
if (typeof options.output != "object") options.output = {};
options.output.ast = true;
options.output.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");
@@ -252,18 +268,35 @@ if (specified["self"]) {
if (!options.wrap) options.wrap = "UglifyJS";
paths = UglifyJS.FILES;
}
if (paths.length) {
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) {
simple_glob(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", function(chunk) {
chunks.push(chunk);
}).on("end", function() {
files = [ chunks.join("") ];
files = { STDIN: chunks.join("") };
run();
});
process.stdin.resume();
@@ -276,19 +309,51 @@ function convert_ast(fn) {
function run() {
var content = options.sourceMap && options.sourceMap.content;
if (content && content != "inline") {
UglifyJS.AST_Node.info("Using input source map: " + content);
UglifyJS.AST_Node.info("Using input source map: {content}", {
content : content,
});
options.sourceMap.content = read_file(content, content);
}
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]);
@@ -342,17 +407,28 @@ function run() {
}
fatal(ex);
} else if (output == "ast") {
if (!options.compress && !options.mangle) result.ast.figure_out_scope({});
if (!options.compress && !options.mangle) {
var toplevel = result.ast;
if (!(toplevel instanceof UglifyJS.AST_Toplevel)) {
if (!(toplevel instanceof UglifyJS.AST_Statement)) toplevel = new UglifyJS.AST_SimpleStatement({
body: toplevel,
});
toplevel = new UglifyJS.AST_Toplevel({
body: [ toplevel ],
});
}
toplevel.figure_out_scope({});
}
print(JSON.stringify(result.ast, function(key, value) {
if (value) switch (key) {
case "thedef":
return symdef(value);
case "enclosed":
return value.length ? value.map(symdef) : undefined;
case "variables":
case "functions":
case "globals":
case "variables":
return value.size() ? value.map(symdef) : undefined;
case "thedef":
return symdef(value);
}
if (skip_key(key)) return;
if (value instanceof UglifyJS.AST_Token) return;
@@ -369,16 +445,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);

1125
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

@@ -33,7 +33,9 @@ function read_source_map(name, toplevel) {
return to_ascii(match[2]);
}
}
AST_Node.warn("inline source map not found: " + name);
AST_Node.warn("inline source map not found: {name}", {
name: name,
});
}
function parse_source_map(content) {
@@ -45,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) {
@@ -73,8 +73,10 @@ function to_json(cache) {
function minify(files, options) {
try {
options = defaults(options, {
annotations: undefined,
compress: {},
enclose: false,
ie: false,
ie8: false,
keep_fnames: false,
mangle: {},
@@ -85,30 +87,34 @@ function minify(files, options) {
sourceMap: false,
timings: false,
toplevel: false,
v8: false,
validate: false,
warnings: false,
webkit: false,
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" ]);
var timings = options.timings && { start: Date.now() };
if (options.rename === undefined) options.rename = options.compress && options.mangle;
if (options.annotations !== undefined) set_shorthand("annotations", options, [ "compress", "output" ]);
if (options.ie8) options.ie = options.ie || options.ie8;
if (options.ie) set_shorthand("ie", options, [ "compress", "mangle", "output" ]);
if (options.keep_fnames) set_shorthand("keep_fnames", options, [ "compress", "mangle" ]);
if (options.toplevel) set_shorthand("toplevel", options, [ "compress", "mangle" ]);
if (options.v8) set_shorthand("v8", options, [ "mangle", "output" ]);
if (options.webkit) set_shorthand("webkit", options, [ "compress", "mangle", "output" ]);
var quoted_props;
if (options.mangle) {
options.mangle = defaults(options.mangle, {
cache: options.nameCache && (options.nameCache.vars || {}),
eval: false,
ie8: false,
ie: false,
keep_fnames: false,
properties: false,
reserved: [],
toplevel: false,
v8: false,
webkit: false,
}, true);
if (options.mangle.properties) {
if (typeof options.mangle.properties != "object") {
@@ -197,32 +203,32 @@ function minify(files, options) {
toplevel.mangle_names(options.mangle);
}
if (timings) timings.properties = Date.now();
if (options.mangle && options.mangle.properties) {
toplevel = mangle_properties(toplevel, options.mangle.properties);
}
if (options.mangle && options.mangle.properties) mangle_properties(toplevel, options.mangle.properties);
if (timings) timings.output = Date.now();
var result = {};
if (options.output.ast) {
result.ast = toplevel;
}
if (!HOP(options.output, "code") || options.output.code) {
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*$/, "");
@@ -260,6 +266,7 @@ function minify(files, options) {
} catch (ex) {
return { error: ex };
} finally {
AST_Node.log_function();
AST_Node.disable_validation();
}
}

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,7 +43,8 @@
"use strict";
function find_builtins(reserved) {
var builtins = function() {
var names = [];
// NaN will be included due to Number.NaN
[
"null",
@@ -67,19 +68,23 @@ function find_builtins(reserved) {
].forEach(function(ctor) {
Object.getOwnPropertyNames(ctor).map(add);
if (ctor.prototype) {
Object.getOwnPropertyNames(new ctor()).map(add);
Object.getOwnPropertyNames(ctor.prototype).map(add);
}
});
return makePredicate(names);
function add(name) {
push_uniq(reserved, name);
names.push(name);
}
}
}();
function reserve_quoted_keys(ast, reserved) {
ast.walk(new TreeWalker(function(node) {
if (node instanceof AST_ObjectKeyVal && node.quote) {
add(node.key);
if (node instanceof AST_ClassProperty) {
if (node.start && node.start.quote) add(node.key);
} else if (node instanceof AST_ObjectProperty) {
if (node.start && node.start.quote) add(node.key);
} else if (node instanceof AST_Sub) {
addStrings(node.property, add);
}
@@ -91,17 +96,14 @@ function reserve_quoted_keys(ast, reserved) {
}
function addStrings(node, add) {
node.walk(new TreeWalker(function(node) {
if (node instanceof AST_Sequence) {
addStrings(node.tail_node(), add);
} else if (node instanceof AST_String) {
add(node.value);
} else if (node instanceof AST_Conditional) {
addStrings(node.consequent, add);
addStrings(node.alternative, add);
}
return true;
}));
if (node instanceof AST_Conditional) {
addStrings(node.consequent, add);
addStrings(node.alternative, add);
} else if (node instanceof AST_Sequence) {
addStrings(node.tail_node(), add);
} else if (node instanceof AST_String) {
add(node.value);
}
}
function mangle_properties(ast, options) {
@@ -110,21 +112,21 @@ function mangle_properties(ast, options) {
cache: null,
debug: false,
keep_quoted: false,
only_cache: false,
regex: null,
reserved: null,
}, true);
var reserved = options.reserved;
if (!Array.isArray(reserved)) reserved = [];
if (!options.builtins) find_builtins(reserved);
var reserved = Object.create(options.builtins ? null : builtins);
if (Array.isArray(options.reserved)) options.reserved.forEach(function(name) {
reserved[name] = true;
});
var cname = -1;
var cache;
if (options.cache) {
cache = options.cache.props;
cache.each(function(mangled_name) {
push_uniq(reserved, mangled_name);
cache.each(function(name) {
reserved[name] = true;
});
} else {
cache = new Dictionary();
@@ -139,72 +141,98 @@ function mangle_properties(ast, options) {
var debug_suffix;
if (debug) debug_suffix = options.debug === true ? "" : options.debug;
var names_to_mangle = [];
var unmangleable = [];
var names_to_mangle = Object.create(null);
var unmangleable = Object.create(reserved);
// step 1: find candidates to mangle
ast.walk(new TreeWalker(function(node) {
if (node instanceof AST_ObjectKeyVal) {
add(node.key);
} else if (node instanceof AST_ObjectProperty) {
// setter or getter, since KeyVal is handled above
add(node.key.name);
if (node instanceof AST_Binary) {
if (node.operator == "in") addStrings(node.left, add);
} else if (node.TYPE == "Call") {
var exp = node.expression;
if (exp instanceof AST_Dot) switch (exp.property) {
case "defineProperty":
case "getOwnPropertyDescriptor":
if (node.args.length < 2) break;
exp = exp.expression;
if (!(exp instanceof AST_SymbolRef)) break;
if (exp.name != "Object") break;
if (!exp.definition().undeclared) break;
addStrings(node.args[1], add);
break;
case "hasOwnProperty":
if (node.args.length < 1) break;
addStrings(node.args[0], add);
break;
}
} else if (node instanceof AST_ClassProperty) {
if (typeof node.key == "string") 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);
} else if (node instanceof AST_Sub) {
addStrings(node.property, add);
} else if (node instanceof AST_Call
&& node.expression.print_to_string() == "Object.defineProperty") {
addStrings(node.args[1], add);
}
}));
// step 2: transform the tree, renaming properties
return ast.transform(new TreeTransformer(function(node) {
if (node instanceof AST_ObjectKeyVal) {
node.key = mangle(node.key);
} else if (node instanceof AST_ObjectProperty) {
// setter or getter
node.key.name = mangle(node.key.name);
// step 2: renaming properties
ast.walk(new TreeWalker(function(node) {
if (node instanceof AST_Binary) {
if (node.operator == "in") mangleStrings(node.left);
} else if (node.TYPE == "Call") {
var exp = node.expression;
if (exp instanceof AST_Dot) switch (exp.property) {
case "defineProperty":
case "getOwnPropertyDescriptor":
if (node.args.length < 2) break;
exp = exp.expression;
if (!(exp instanceof AST_SymbolRef)) break;
if (exp.name != "Object") break;
if (!exp.definition().undeclared) break;
mangleStrings(node.args[1]);
break;
case "hasOwnProperty":
if (node.args.length < 1) break;
mangleStrings(node.args[0]);
break;
}
} else if (node instanceof AST_ClassProperty) {
if (typeof node.key == "string") node.key = mangle(node.key);
} else if (node instanceof AST_Dot) {
node.property = mangle(node.property);
} else if (!options.keep_quoted && node instanceof AST_Sub) {
node.property = mangleStrings(node.property);
} else if (node instanceof AST_Call
&& node.expression.print_to_string() == "Object.defineProperty") {
node.args[1] = mangleStrings(node.args[1]);
} 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);
}
}));
// only function declarations after this line
function can_mangle(name) {
if (unmangleable.indexOf(name) >= 0) return false;
if (reserved.indexOf(name) >= 0) return false;
if (options.only_cache) return cache.has(name);
if (unmangleable[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;
if (reserved.indexOf(name) >= 0) return false;
return cache.has(name) || names_to_mangle.indexOf(name) >= 0;
return cache.has(name) || names_to_mangle[name];
}
function add(name) {
if (can_mangle(name)) push_uniq(names_to_mangle, name);
if (!should_mangle(name)) push_uniq(unmangleable, name);
if (can_mangle(name)) names_to_mangle[name] = true;
if (!should_mangle(name)) unmangleable[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) {
// debug mode: use a prefix and suffix to preserve readability, e.g. o.foo -> o._$foo$NNN_.
// debug mode: use a prefix and suffix to preserve readability, e.g. o.foo ---> o._$foo$NNN_.
var debug_mangled = "_$" + name + "$" + debug_suffix + "_";
if (can_mangle(debug_mangled)) mangled = debug_mangled;
}
@@ -212,23 +240,20 @@ function mangle_properties(ast, options) {
if (!mangled) do {
mangled = base54(++cname);
} while (!can_mangle(mangled));
if (/^#/.test(name)) mangled = "#" + mangled;
cache.set(name, mangled);
}
return mangled;
}
function mangleStrings(node) {
return node.transform(new TreeTransformer(function(node) {
if (node instanceof AST_Sequence) {
var last = node.expressions.length - 1;
node.expressions[last] = mangleStrings(node.expressions[last]);
} else if (node instanceof AST_String) {
node.value = mangle(node.value);
} else if (node instanceof AST_Conditional) {
node.consequent = mangleStrings(node.consequent);
node.alternative = mangleStrings(node.alternative);
}
return node;
}));
if (node instanceof AST_Sequence) {
mangleStrings(node.expressions.tail_node());
} else if (node instanceof AST_String) {
node.value = mangle(node.value);
} else if (node instanceof AST_Conditional) {
mangleStrings(node.consequent);
mangleStrings(node.alternative);
}
}
}

View File

@@ -45,10 +45,10 @@
function SymbolDef(id, scope, orig, init) {
this.eliminated = 0;
this.exported = false;
this.global = false;
this.id = id;
this.init = init;
this.lambda = orig instanceof AST_SymbolLambda;
this.mangled_name = null;
this.name = orig.name;
this.orig = [ orig ];
@@ -59,24 +59,20 @@ function SymbolDef(id, scope, orig, init) {
}
SymbolDef.prototype = {
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);
forEach: function(fn) {
this.orig.forEach(fn);
this.references.forEach(fn);
},
mangle: function(options) {
var cache = options.cache && options.cache.props;
if (this.global && cache && cache.has(this.name)) {
this.mangled_name = cache.get(this.name);
} else if (!this.mangled_name && !this.unmangleable(options)) {
var def;
if (def = this.redefined()) {
var def = this.redefined();
if (def) {
this.mangled_name = def.mangled_name || def.name;
} else {
this.mangled_name = next_mangled_name(this.scope, options, this);
this.mangled_name = next_mangled_name(this, options);
}
if (this.global && cache) {
cache.set(this.name, this.mangled_name);
@@ -84,42 +80,114 @@ SymbolDef.prototype = {
}
},
redefined: function() {
return this.defun && this.defun.variables.get(this.name);
}
var self = this;
var scope = self.defun;
if (!scope) return;
var name = self.name;
var def = scope.variables.get(name)
|| scope instanceof AST_Toplevel && scope.globals.get(name)
|| self.orig[0] instanceof AST_SymbolConst && find_if(function(def) {
return def.name == name;
}, scope.enclosed);
if (def && def !== self) return def.redefined() || def;
},
unmangleable: function(options) {
return this.global && !options.toplevel
|| this.exported
|| this.undeclared
|| !options.eval && this.scope.pinned()
|| options.keep_fnames
&& (this.orig[0] instanceof AST_SymbolClass
|| this.orig[0] instanceof AST_SymbolDefClass
|| this.orig[0] instanceof AST_SymbolDefun
|| this.orig[0] instanceof AST_SymbolLambda);
},
};
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 scope = self.parent_scope = null;
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 (node instanceof AST_Catch) {
var save_scope = scope;
scope = new AST_Scope(node);
scope.init_scope_vars(save_scope);
descend();
scope = save_scope;
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_Scope) {
node.init_scope_vars(scope);
var save_scope = scope;
var save_defun = defun;
defun = scope = node;
if (node instanceof AST_Definitions) {
var save_exported = exported;
exported = tw.parent() instanceof AST_ExportDeclaration;
descend();
scope = save_scope;
defun = save_defun;
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);
});
if (node.rest) node.rest.walk(tw);
walk_body(node, tw);
});
return true;
}
if (node instanceof AST_SwitchBranch) {
node.init_vars(scope);
descend();
return true;
}
if (node instanceof AST_Try) {
walk_scope(function() {
walk_body(node, tw);
});
if (node.bcatch) node.bcatch.walk(tw);
if (node.bfinally) node.bfinally.walk(tw);
return true;
}
if (node instanceof AST_With) {
for (var s = scope; s; s = s.parent_scope) s.uses_with = true;
return;
var s = scope;
do {
s = s.resolve();
if (s.uses_with) break;
s.uses_with = true;
} while (s = s.parent_scope);
walk_scope(descend);
return true;
}
if (node instanceof AST_BlockScope) {
walk_scope(descend);
return true;
}
if (node instanceof AST_Symbol) {
node.scope = scope;
@@ -128,73 +196,162 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
node.thedef = node;
node.references = [];
}
if (node instanceof AST_SymbolDefun) {
// This should be defined in the parent scope, as we encounter the
// AST_Defun node before getting to its AST_Symbol.
(node.scope = defun.parent_scope.resolve()).def_function(node, defun);
if (node instanceof AST_SymbolCatch) {
scope.def_variable(node).defun = defun;
} else if (node instanceof AST_SymbolConst) {
var def = scope.def_variable(node);
def.defun = defun;
if (exported) def.exported = true;
} else if (node instanceof AST_SymbolDefun) {
var def = defun.def_function(node, tw.parent());
if (exported) def.exported = true;
entangle(defun, scope);
} else if (node instanceof AST_SymbolFunarg) {
defun.def_variable(node);
entangle(defun, scope);
} else if (node instanceof AST_SymbolLambda) {
var def = defun.def_function(node, node.name == "arguments" ? undefined : defun);
if (options.ie8) def.defun = defun.parent_scope.resolve();
if (options.ie) def.defun = defun.parent_scope.resolve();
} else if (node instanceof AST_SymbolLet) {
var def = scope.def_variable(node);
if (exported) def.exported = true;
} else if (node instanceof AST_SymbolVar) {
defun.def_variable(node, node.TYPE == "SymbolVar" ? null : undefined);
if (defun !== scope) {
node.mark_enclosed(options);
var def = scope.find_variable(node);
if (node.thedef !== def) {
node.thedef = def;
}
node.reference(options);
}
} else if (node instanceof AST_SymbolCatch) {
scope.def_variable(node).defun = defun;
var def = defun.def_variable(node, node instanceof AST_SymbolImport ? undefined : null);
if (exported) def.exported = true;
entangle(defun, scope);
}
function walk_scope(descend) {
node.init_vars(scope);
var save_defun = defun;
var save_scope = scope;
if (node instanceof AST_Scope) defun = node;
scope = node;
descend();
scope = save_scope;
defun = save_defun;
}
function entangle(defun, scope) {
if (defun === scope) return;
node.mark_enclosed(options);
var def = scope.find_variable(node.name);
if (node.thedef === def) return;
node.thedef = def;
def.orig.push(node);
node.mark_enclosed(options);
}
});
self.next_def_id = 0;
self.make_def = function(orig, init) {
return new SymbolDef(++next_def_id, this, orig, init);
};
self.walk(tw);
// pass 2: find back references and eval
self.globals = new Dictionary();
var in_arg = [];
var tw = new TreeWalker(function(node) {
if (node instanceof AST_Catch) {
if (!(node.argname instanceof AST_Destructured)) return;
in_arg.push(node);
node.argname.walk(tw);
in_arg.pop();
walk_body(node, tw);
return true;
}
if (node instanceof AST_Lambda) {
in_arg.push(node);
node.argnames.forEach(function(argname) {
argname.walk(tw);
});
if (node.rest) node.rest.walk(tw);
in_arg.pop();
walk_lambda(node, tw);
return true;
}
if (node instanceof AST_LoopControl) {
if (node.label) node.label.thedef.references.push(node);
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 redef = def.redefined();
if (redef) for (var s = node.scope; s; s = s.parent_scope) {
push_uniq(s.enclosed, redef);
if (s === redef.scope) break;
}
} else if (node instanceof AST_SymbolConst) {
// ensure compression works if `const` reuses a scope variable
var redef = def.redefined();
if (redef) redef.const_redefs = true;
}
if (node.name != "arguments") return true;
var parent = node instanceof AST_SymbolVar && tw.parent();
if (parent instanceof AST_VarDef && !parent.value) return true;
var sym = node.scope.resolve().find_variable("arguments");
if (sym && is_arguments(sym)) sym.scope.uses_arguments = 3;
return true;
}
if (node instanceof AST_SymbolRef) {
var name = node.name;
var sym = node.scope.find_variable(name);
for (var i = in_arg.length; i > 0 && sym;) {
i = in_arg.lastIndexOf(sym.scope, i - 1);
if (i < 0) break;
var decl = sym.orig[0];
if (decl instanceof AST_SymbolCatch
|| decl instanceof AST_SymbolFunarg
|| decl instanceof AST_SymbolLambda) {
node.in_arg = true;
break;
}
sym = sym.scope.parent_scope.find_variable(name);
}
if (!sym) {
sym = self.def_global(node);
} else if (sym.scope instanceof AST_Lambda && name == "arguments") {
sym.scope.uses_arguments = true;
} else if (name == "arguments" && is_arguments(sym)) {
var parent = tw.parent();
if (is_lhs(node, parent)) {
sym.scope.uses_arguments = 3;
} else if (sym.scope.uses_arguments < 2
&& !(parent instanceof AST_PropAccess && parent.expression === node)) {
sym.scope.uses_arguments = 2;
} else if (!sym.scope.uses_arguments) {
sym.scope.uses_arguments = true;
}
}
if (name == "eval") {
var parent = tw.parent();
if (parent.TYPE == "Call" && parent.expression === node) {
for (var s = node.scope; s && !s.uses_eval; s = s.parent_scope) {
var s = node.scope;
do {
s = s.resolve();
if (s.uses_eval) break;
s.uses_eval = true;
}
} while (s = s.parent_scope);
} else if (sym.undeclared) {
self.uses_eval = true;
}
}
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;
}
// ensure mangling works if catch reuses a scope variable
if (node instanceof AST_SymbolCatch) {
var def = node.definition().redefined();
if (def) for (var s = node.scope; s; s = s.parent_scope) {
push_uniq(s.enclosed, def);
if (s === def.scope) break;
}
return true;
}
});
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) {
@@ -205,8 +362,9 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
}
if (node instanceof AST_SymbolLambda) {
var def = node.thedef;
redefine(node, node.scope.parent_scope.resolve());
if (typeof node.thedef.init !== "undefined") {
if (!redefine(node, node.scope.parent_scope.resolve())) {
delete def.defun;
} else if (typeof node.thedef.init !== "undefined") {
node.thedef.init = false;
} else if (def.init) {
node.thedef.init = def.init;
@@ -215,13 +373,22 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
}
}));
function is_arguments(sym) {
return sym.orig[0] instanceof AST_SymbolFunarg
&& !(sym.orig[1] instanceof AST_SymbolFunarg || sym.orig[2] instanceof AST_SymbolFunarg)
&& !is_arrow(sym.scope);
}
function redefine(node, scope) {
var name = node.name;
var old_def = node.thedef;
if (!all(old_def.orig, function(sym) {
return !(sym instanceof AST_SymbolConst || sym instanceof AST_SymbolLet);
})) return false;
var new_def = scope.find_variable(name);
if (new_def) {
var redef;
while (redef = new_def.redefined()) new_def = redef;
var redef = new_def.redefined();
if (redef) new_def = redef;
} else {
new_def = self.globals.get(name);
}
@@ -230,22 +397,18 @@ 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.orig.concat(old_def.references).forEach(function(node) {
old_def.forEach(function(node) {
node.redef = old_def;
node.thedef = new_def;
node.reference(options);
});
if (old_def.lambda) new_def.lambda = true;
if (new_def.undeclared) self.variables.set(name, new_def);
return true;
}
});
AST_Scope.DEFMETHOD("make_def", function(orig, init) {
var top = this;
while (top.parent_scope) top = top.parent_scope;
return new SymbolDef(++top.next_def_id, this, orig, init);
});
AST_Toplevel.DEFMETHOD("def_global", function(node) {
var globals = this.globals, name = node.name;
if (globals.has(name)) {
@@ -259,31 +422,51 @@ AST_Toplevel.DEFMETHOD("def_global", function(node) {
}
});
AST_Scope.DEFMETHOD("init_scope_vars", function(parent_scope) {
this.variables = new Dictionary(); // map name to AST_SymbolVar (variables defined in this scope; includes functions)
this.functions = new Dictionary(); // map name to AST_SymbolDefun (functions defined in this scope)
this.uses_with = false; // will be set to true if this or some nested scope uses the `with` statement
this.uses_eval = false; // will be set to true if this or nested scope uses the global `eval`
this.parent_scope = parent_scope; // the parent scope
this.enclosed = []; // a list of variables from this or outer scope(s) that are referenced from this or inner scopes
this.cname = -1; // the current index for mangling functions/variables
});
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
}
AST_Lambda.DEFMETHOD("init_scope_vars", function() {
AST_Scope.prototype.init_scope_vars.apply(this, arguments);
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
}
AST_BlockScope.DEFMETHOD("init_vars", function(parent_scope) {
init_block_vars(this, parent_scope);
});
AST_Scope.DEFMETHOD("init_vars", function(parent_scope) {
init_scope_vars(this, parent_scope);
});
AST_Arrow.DEFMETHOD("init_vars", function(parent_scope) {
init_scope_vars(this, parent_scope);
return this;
});
AST_AsyncArrow.DEFMETHOD("init_vars", function(parent_scope) {
init_scope_vars(this, parent_scope);
});
AST_Lambda.DEFMETHOD("init_vars", function(parent_scope) {
init_scope_vars(this, parent_scope);
this.uses_arguments = false;
this.def_variable(new AST_SymbolFunarg({
name: "arguments",
start: this.start,
end: this.end
end: this.end,
}));
return this;
});
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) {
if (!options) {
delete s._var_names;
} else if (options.keep_fnames) {
s.functions.each(function(d) {
push_uniq(def.scope.enclosed, d);
});
@@ -297,24 +480,23 @@ AST_Symbol.DEFMETHOD("reference", function(options) {
this.mark_enclosed(options);
});
AST_Scope.DEFMETHOD("find_variable", function(name) {
if (name instanceof AST_Symbol) name = name.name;
AST_BlockScope.DEFMETHOD("find_variable", function(name) {
return this.variables.get(name)
|| (this.parent_scope && this.parent_scope.find_variable(name));
|| this.parent_scope && this.parent_scope.find_variable(name);
});
AST_Scope.DEFMETHOD("def_function", function(symbol, init) {
AST_BlockScope.DEFMETHOD("def_function", function(symbol, init) {
var def = this.def_variable(symbol, init);
if (!def.init || def.init instanceof AST_Defun) def.init = init;
if (!def.init || def.init instanceof AST_LambdaDefinition) def.init = init;
this.functions.set(symbol.name, def);
return def;
});
AST_Scope.DEFMETHOD("def_variable", function(symbol, init) {
AST_BlockScope.DEFMETHOD("def_variable", function(symbol, init) {
var def = this.variables.get(symbol.name);
if (def) {
def.orig.push(symbol);
if (def.init instanceof AST_Function) def.init = init;
if (def.init instanceof AST_LambdaExpression) def.init = init;
} else {
def = this.make_def(symbol, init);
this.variables.set(symbol.name, def);
@@ -323,17 +505,12 @@ AST_Scope.DEFMETHOD("def_variable", function(symbol, init) {
return symbol.thedef = def;
});
AST_Lambda.DEFMETHOD("resolve", return_this);
AST_Scope.DEFMETHOD("resolve", function() {
return this.parent_scope.resolve();
});
AST_Toplevel.DEFMETHOD("resolve", return_this);
function names_in_use(scope, options) {
var names = scope.names_in_use;
if (!names) {
scope.names_in_use = names = Object.create(scope.mangled_names || null);
scope.cname = -1;
scope.cname_holes = [];
scope.names_in_use = names = Object.create(null);
var cache = options.cache && options.cache.props;
scope.enclosed.forEach(function(def) {
if (def.unmangleable(options)) names[def.name] = true;
@@ -345,12 +522,13 @@ function names_in_use(scope, options) {
return names;
}
function next_mangled_name(scope, options, def) {
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 scopes = [ scope ];
def.references.forEach(function(sym) {
def.forEach(function(sym) {
var scope = sym.scope;
do {
if (scopes.indexOf(scope) < 0) {
@@ -366,7 +544,7 @@ function next_mangled_name(scope, options, def) {
name = base54(holes[i]);
if (names[name]) continue;
holes.splice(i, 1);
scope.names_in_use[name] = true;
in_use[name] = true;
return name;
}
while (true) {
@@ -375,7 +553,7 @@ function next_mangled_name(scope, options, def) {
if (!names[name]) break;
holes.push(scope.cname);
}
scope.names_in_use[name] = true;
in_use[name] = true;
return name;
}
@@ -387,25 +565,19 @@ AST_Symbol.DEFMETHOD("unmangleable", function(options) {
// labels are always mangleable
AST_Label.DEFMETHOD("unmangleable", return_false);
AST_Symbol.DEFMETHOD("unreferenced", function() {
return !this.definition().references.length && !this.scope.pinned();
});
AST_Symbol.DEFMETHOD("definition", function() {
return this.thedef;
});
AST_Symbol.DEFMETHOD("global", function() {
return this.definition().global;
});
function _default_mangler_options(options) {
options = defaults(options, {
eval : false,
ie8 : false,
ie : false,
keep_fnames : false,
reserved : [],
toplevel : false,
v8 : false,
webkit : false,
});
if (!Array.isArray(options.reserved)) options.reserved = [];
// Never mangle arguments
@@ -424,7 +596,7 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
var lname = -1;
if (options.cache && options.cache.props) {
var mangled_names = this.mangled_names = Object.create(null);
var mangled_names = names_in_use(this, options);
options.cache.props.each(function(mangled_name) {
mangled_names[mangled_name] = true;
});
@@ -436,10 +608,29 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
// lname is incremented when we get to the AST_Label
var save_nesting = lname;
descend();
lname = save_nesting;
if (!options.v8 || !in_label(tw)) lname = save_nesting;
return true;
}
if (node instanceof AST_Scope) {
if (node instanceof AST_BlockScope) {
if (options.webkit && node instanceof AST_IterationStatement && node.init instanceof AST_Let) {
node.init.definitions.forEach(function(defn) {
defn.name.match_symbol(function(sym) {
if (!(sym instanceof AST_SymbolLet)) return;
var def = sym.definition();
var scope = sym.scope.parent_scope;
var redef = scope.def_variable(sym);
sym.thedef = def;
scope.to_mangle.push(redef);
def.redefined = function() {
return redef;
};
});
}, true);
}
node.to_mangle = [];
node.variables.each(function(def) {
if (!defer_redef(def)) node.to_mangle.push(def);
});
descend();
if (options.cache && node instanceof AST_Toplevel) {
node.globals.each(mangle);
@@ -449,9 +640,7 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
sym.scope = node;
sym.reference(options);
}
node.variables.each(function(def) {
if (!defer_redef(def)) mangle(def);
});
node.to_mangle.forEach(mangle);
return true;
}
if (node instanceof AST_Label) {
@@ -462,13 +651,6 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
node.mangled_name = name;
return true;
}
if (!options.ie8 && node instanceof AST_Catch) {
var def = node.argname.definition();
var redef = defer_redef(def, node.argname);
descend();
if (!redef) mangle(def);
return true;
}
});
this.walk(tw);
redefined.forEach(mangle);
@@ -478,12 +660,20 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
def.mangle(options);
}
function defer_redef(def, node) {
function defer_redef(def) {
var sym = def.orig[0];
var redef = def.redefined();
if (!redef) return false;
if (!redef) {
if (!(sym instanceof AST_SymbolConst)) return false;
var scope = def.scope.resolve();
if (def.scope === scope) return false;
if (def.scope.parent_scope.find_variable(sym.name)) return false;
redef = scope.def_variable(sym);
scope.to_mangle.push(redef);
}
redefined.push(def);
def.references.forEach(reference);
if (node) reference(node);
if (sym instanceof AST_SymbolCatch || sym instanceof AST_SymbolConst) reference(sym);
return true;
function reference(sym) {
@@ -492,16 +682,23 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
sym.thedef = def;
}
}
function in_label(tw) {
var level = 0, parent;
while (parent = tw.parent(level++)) {
if (parent instanceof AST_Block) return parent instanceof AST_Toplevel && !options.toplevel;
if (parent instanceof AST_LabeledStatement) return true;
}
}
});
AST_Toplevel.DEFMETHOD("find_colliding_names", function(options) {
var cache = options.cache && options.cache.props;
var avoid = Object.create(null);
var avoid = Object.create(RESERVED_WORDS);
options.reserved.forEach(to_avoid);
this.globals.each(add_def);
this.walk(new TreeWalker(function(node) {
if (node instanceof AST_Scope) node.variables.each(add_def);
if (node instanceof AST_SymbolCatch) add_def(node.definition());
if (node instanceof AST_BlockScope) node.variables.each(add_def);
}));
return avoid;
@@ -525,15 +722,14 @@ AST_Toplevel.DEFMETHOD("expand_names", function(options) {
var cname = 0;
this.globals.each(rename);
this.walk(new TreeWalker(function(node) {
if (node instanceof AST_Scope) node.variables.each(rename);
if (node instanceof AST_SymbolCatch) rename(node.definition());
if (node instanceof AST_BlockScope) node.variables.each(rename);
}));
function next_name() {
var name;
do {
name = base54(cname++);
} while (avoid[name] || RESERVED_WORDS[name]);
} while (avoid[name]);
return name;
}
@@ -544,7 +740,7 @@ AST_Toplevel.DEFMETHOD("expand_names", function(options) {
var redef = def.redefined();
var name = redef ? redef.rename || redef.name : next_name();
def.rename = name;
def.orig.concat(def.references).forEach(function(sym) {
def.forEach(function(sym) {
if (sym.definition() === def) sym.name = name;
});
}
@@ -558,22 +754,24 @@ AST_Sequence.DEFMETHOD("tail_node", function() {
AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options) {
options = _default_mangler_options(options);
base54.reset();
var fn = AST_Symbol.prototype.add_source_map;
try {
AST_Node.prototype.print = function(stream, force_parens) {
this._print(stream, force_parens);
if (this instanceof AST_Symbol && !this.unmangleable(options)) {
base54.consider(this.name, -1);
} else if (options.properties) {
if (this instanceof AST_Dot) {
base54.consider(this.property, -1);
} else if (this instanceof AST_Sub) {
skip_string(this.property);
}
}
AST_Symbol.prototype.add_source_map = function() {
if (!this.unmangleable(options)) base54.consider(this.name, -1);
};
if (options.properties) {
AST_Dot.prototype.add_source_map = function() {
base54.consider(this.property, -1);
};
AST_Sub.prototype.add_source_map = function() {
skip_string(this.property);
};
}
base54.consider(this.print_to_string(), 1);
} finally {
AST_Node.prototype.print = AST_Node.prototype._print;
AST_Symbol.prototype.add_source_map = fn;
delete AST_Dot.prototype.add_source_map;
delete AST_Sub.prototype.add_source_map;
}
base54.sort();
@@ -604,6 +802,7 @@ var base54 = (function() {
var leading = init("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_");
var chars, frequency;
function reset() {
chars = null;
frequency = Object.create(freq);
}
base54.consider = function(str, delta) {
@@ -615,19 +814,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

@@ -144,7 +144,9 @@ function SourceMap(options) {
add(source, gen_line, gen_col, orig_line, orig_col, name);
} : add,
setSourceContent: sources_content ? function(source, content) {
sources_content[source] = content;
if (!(source in sources_content)) {
sources_content[source] = content;
}
} : noop,
toString: function() {
return JSON.stringify({

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);
@@ -116,7 +116,7 @@ TreeTransformer.prototype = new TreeWalker;
if (self.bfinally) self.bfinally = self.bfinally.transform(tw);
});
DEF(AST_Catch, function(self, tw) {
self.argname = self.argname.transform(tw);
if (self.argname) self.argname = self.argname.transform(tw);
self.body = do_list(self.body, tw);
});
DEF(AST_Definitions, function(self, tw) {
@@ -126,11 +126,36 @@ TreeTransformer.prototype = new TreeWalker;
self.name = self.name.transform(tw);
if (self.value) self.value = self.value.transform(tw);
});
DEF(AST_DefaultValue, function(self, tw) {
self.name = self.name.transform(tw);
self.value = self.value.transform(tw);
});
DEF(AST_Lambda, function(self, tw) {
if (self.name) self.name = self.name.transform(tw);
self.argnames = do_list(self.argnames, tw);
if (self.rest) self.rest = self.rest.transform(tw);
self.body = do_list(self.body, tw);
});
function transform_arrow(self, tw) {
self.argnames = do_list(self.argnames, tw);
if (self.rest) self.rest = self.rest.transform(tw);
if (self.value) {
self.value = self.value.transform(tw);
} else {
self.body = do_list(self.body, tw);
}
}
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);
@@ -138,6 +163,12 @@ TreeTransformer.prototype = new TreeWalker;
DEF(AST_Sequence, function(self, tw) {
self.expressions = do_list(self.expressions, tw);
});
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);
});
@@ -145,6 +176,9 @@ TreeTransformer.prototype = new TreeWalker;
self.expression = self.expression.transform(tw);
self.property = self.property.transform(tw);
});
DEF(AST_Spread, function(self, tw) {
self.expression = self.expression.transform(tw);
});
DEF(AST_Unary, function(self, tw) {
self.expression = self.expression.transform(tw);
});
@@ -160,12 +194,43 @@ TreeTransformer.prototype = new TreeWalker;
DEF(AST_Array, function(self, tw) {
self.elements = do_list(self.elements, tw);
});
DEF(AST_DestructuredArray, function(self, tw) {
self.elements = do_list(self.elements, tw);
if (self.rest) self.rest = self.rest.transform(tw);
});
DEF(AST_DestructuredKeyVal, function(self, tw) {
if (self.key instanceof AST_Node) self.key = self.key.transform(tw);
self.value = self.value.transform(tw);
});
DEF(AST_DestructuredObject, function(self, tw) {
self.properties = do_list(self.properties, tw);
if (self.rest) self.rest = self.rest.transform(tw);
});
DEF(AST_Object, function(self, tw) {
self.properties = do_list(self.properties, tw);
});
DEF(AST_ObjectProperty, function(self, tw) {
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

@@ -112,51 +112,29 @@ function return_this() { return this; }
function return_null() { return null; }
var List = (function() {
function List(a, f, backwards) {
var ret = [], top = [], i;
function doit() {
function List(a, f) {
var ret = [];
for (var i = 0; i < a.length; i++) {
var val = f(a[i], i);
var is_last = val instanceof Last;
if (is_last) val = val.v;
if (val instanceof AtTop) {
val = val.v;
if (val instanceof Splice) {
top.push.apply(top, backwards ? val.v.slice().reverse() : val.v);
} else {
top.push(val);
}
} else if (val !== skip) {
if (val instanceof Splice) {
ret.push.apply(ret, backwards ? val.v.slice().reverse() : val.v);
} else {
ret.push(val);
}
}
return is_last;
}
if (Array.isArray(a)) {
if (backwards) {
for (i = a.length; --i >= 0;) if (doit()) break;
ret.reverse();
top.reverse();
if (val === skip) continue;
if (val instanceof Splice) {
ret.push.apply(ret, val.v);
} else {
for (i = 0; i < a.length; ++i) if (doit()) break;
ret.push(val);
}
} else {
for (i in a) if (HOP(a, i)) if (doit()) break;
}
return top.concat(ret);
return ret;
}
List.is_op = function(val) {
return val === skip || val instanceof AtTop || val instanceof Last || val instanceof Splice;
return val === skip || val instanceof Splice;
};
List.splice = function(val) {
return new Splice(val);
};
List.at_top = function(val) { return new AtTop(val); };
List.splice = function(val) { return new Splice(val); };
List.last = function(val) { return new Last(val); };
var skip = List.skip = {};
function AtTop(val) { this.v = val; }
function Splice(val) { this.v = val; }
function Last(val) { this.v = val; }
function Splice(val) {
this.v = val;
}
return List;
})();
@@ -165,8 +143,9 @@ function push_uniq(array, el) {
}
function string_template(text, props) {
return text.replace(/\{(.+?)\}/g, function(str, p) {
return props && props[p];
return text.replace(/\{([^}]+)\}/g, function(str, p) {
var value = props[p];
return value instanceof AST_Node ? value.print_to_string() : value;
});
}
@@ -259,21 +238,27 @@ 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) {
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 (p.TYPE == "Call") {
if (p.expression === node) continue;
if (is_arrow(p)) {
return arrow && p.value === node;
} else if (p instanceof AST_Binary) {
if (p.left === node) continue;
} else if (p.TYPE == "Call") {
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;
}

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.10.1",
"version": "3.14.1",
"engines": {
"node": ">=0.8.0"
},
@@ -23,7 +23,7 @@
"LICENSE"
],
"devDependencies": {
"acorn": "~7.1.0",
"acorn": "~8.2.1",
"semver": "~6.3.0"
},
"scripts": {

View File

@@ -16,7 +16,7 @@ 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://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

@@ -1,6 +1,6 @@
"use strict";
require("../tools/exit");
require("../tools/tty");
var assert = require("assert");
var child_process = require("child_process");
@@ -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).");
@@ -63,7 +68,6 @@ function make_code(ast, options) {
function parse_test(file) {
var script = fs.readFileSync(file, "utf8");
// TODO try/catch can be removed after fixing https://github.com/mishoo/UglifyJS/issues/348
try {
var ast = U.parse(script, {
filename: file
@@ -210,7 +214,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 = run_code(result.code, toplevel);
var actual = sandbox.run_code(result.code, toplevel);
if (typeof expected != "string" && typeof actual != "string" && expected.name == actual.name) {
actual = expected;
}
@@ -245,11 +249,6 @@ function reminify(orig_options, input_code, input_formatted, stdout) {
return true;
}
function run_code(code, toplevel) {
var result = sandbox.run_code(code, toplevel);
return typeof result == "string" ? result.replace(/\u001b\[\d+m/g, "") : result;
}
function test_case(test) {
log(" Running test [{name}]", { name: test.name });
U.AST_Node.enable_validation();
@@ -263,6 +262,7 @@ function test_case(test) {
var input = to_toplevel(test.input, test.mangle);
var input_code = make_code(input);
var input_formatted = make_code(test.input, {
annotations: true,
beautify: true,
comments: "all",
keep_quoted_props: true,
@@ -312,11 +312,10 @@ function test_case(test) {
if (test.mangle) {
output.compute_char_frequency(test.mangle);
output.mangle_names(test.mangle);
if (test.mangle.properties) {
output = U.mangle_properties(output, test.mangle.properties);
}
if (test.mangle.properties) U.mangle_properties(output, test.mangle.properties);
}
var output_code = make_code(output, output_options);
U.AST_Node.log_function();
if (expect != output_code) {
log([
"!!! failed",
@@ -382,13 +381,13 @@ function test_case(test) {
}
}
if (test.expect_stdout && (!test.node_version || semver.satisfies(process.version, test.node_version))) {
var stdout = [ run_code(input_code), run_code(input_code, true) ];
var stdout = [ sandbox.run_code(input_code), sandbox.run_code(input_code, true) ];
var toplevel = sandbox.has_toplevel({
compress: test.options,
mangle: test.mangle
});
var actual = stdout[toplevel ? 1 : 0];
if (test.expect_stdout === true) {
if (test.expect_stdout === true || test.expect_stdout instanceof Error && test.expect_stdout.name === actual.name) {
test.expect_stdout = actual;
}
if (!sandbox.same_stdout(test.expect_stdout, actual)) {
@@ -411,7 +410,7 @@ function test_case(test) {
});
return false;
}
actual = run_code(output_code, toplevel);
actual = sandbox.run_code(output_code, toplevel);
if (!sandbox.same_stdout(test.expect_stdout, actual)) {
log([
"!!! failed",

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

@@ -78,12 +78,13 @@ replace_index_strict: {
]
}
replace_index_keep_fargs: {
replace_index_drop_fargs_1: {
options = {
arguments: true,
evaluate: true,
keep_fargs: false,
properties: true,
reduce_vars: true,
}
input: {
var arguments = [];
@@ -101,6 +102,13 @@ replace_index_keep_fargs: {
var arguments;
console.log(arguments[1], arguments["1"], arguments["foo"]);
})("bar", 42);
(function() {
var arguments = {
1: "foo",
foo: "bar",
};
console.log(arguments[1], arguments["1"], arguments["foo"]);
})("bar", 42);
}
expect: {
var arguments = [];
@@ -112,10 +120,17 @@ replace_index_keep_fargs: {
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;
console.log(argument_1, argument_1, arguments.foo);
})("bar", 42);
(function() {
var arguments;
var arguments = {
1: "foo",
foo: "bar",
};
console.log(arguments[1], arguments[1], arguments.foo);
})("bar", 42);
}
@@ -125,10 +140,11 @@ replace_index_keep_fargs: {
"42 42 undefined",
"a a undefined",
"42 42 undefined",
"foo foo bar",
]
}
replace_index_keep_fargs_strict: {
replace_index_drop_fargs_2: {
options = {
arguments: true,
evaluate: true,
@@ -238,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,
@@ -412,7 +447,7 @@ issue_3273_global_strict_reduce_vars: {
]
}
issue_3273_keep_fargs_false: {
issue_3273_drop_fargs_1: {
options = {
arguments: true,
keep_fargs: false,
@@ -435,10 +470,10 @@ issue_3273_keep_fargs_false: {
expect_stdout: "1"
}
issue_3273_keep_fargs_strict: {
issue_3273_drop_fargs_2: {
options = {
arguments: true,
keep_fargs: "strict",
keep_fargs: false,
reduce_vars: true,
}
input: {
@@ -633,7 +668,8 @@ issue_3282_2_passes: {
issue_3420_1: {
options = {
arguments: true,
keep_fargs: "strict",
keep_fargs: false,
reduce_vars: true,
}
input: {
console.log(function() {
@@ -655,7 +691,8 @@ issue_3420_1: {
issue_3420_2: {
options = {
arguments: true,
keep_fargs: "strict",
keep_fargs: false,
reduce_vars: true,
}
input: {
var foo = function() {
@@ -675,7 +712,8 @@ issue_3420_2: {
issue_3420_3: {
options = {
arguments: true,
keep_fargs: "strict",
keep_fargs: false,
reduce_vars: true,
}
input: {
"use strict";
@@ -697,7 +735,8 @@ issue_3420_3: {
issue_3420_4: {
options = {
arguments: true,
keep_fargs: "strict",
keep_fargs: false,
reduce_vars: true,
}
input: {
!function() {
@@ -722,7 +761,8 @@ issue_3420_4: {
issue_3420_5: {
options = {
arguments: true,
keep_fargs: "strict",
keep_fargs: false,
reduce_vars: true,
}
input: {
"use strict";
@@ -749,7 +789,8 @@ issue_3420_5: {
issue_3420_6: {
options = {
arguments: true,
keep_fargs: "strict",
keep_fargs: false,
reduce_vars: true,
}
input: {
console.log(function() {
@@ -767,7 +808,8 @@ issue_3420_6: {
issue_3420_7: {
options = {
arguments: true,
keep_fargs: "strict",
keep_fargs: false,
reduce_vars: true,
}
input: {
"use strict";
@@ -783,3 +825,230 @@ issue_3420_7: {
}
expect_stdout: "true"
}
issue_4200: {
options = {
arguments: true,
keep_fargs: false,
}
input: {
var o = {
get p() {
return arguments[0];
},
};
console.log(o.p);
}
expect: {
var o = {
get p() {
return arguments[0];
},
};
console.log(o.p);
}
expect_stdout: "undefined"
}
issue_4291_1: {
options = {
arguments: true,
keep_fargs: false,
reduce_vars: true,
}
input: {
console.log(function() {
arguments[0] = "PASS";
return arguments;
}()[0]);
}
expect: {
console.log(function() {
arguments[0] = "PASS";
return arguments;
}()[0]);
}
expect_stdout: "PASS"
}
issue_4291_2: {
options = {
arguments: true,
keep_fargs: false,
reduce_vars: true,
}
input: {
var a = function() {
if (arguments[0])
arguments[1] = "PASS";
return arguments;
}(42);
console.log(a[1], a[0], a.length);
}
expect: {
var a = function() {
if (arguments[0])
arguments[1] = "PASS";
return arguments;
}(42);
console.log(a[1], a[0], a.length);
}
expect_stdout: "PASS 42 1"
}
issue_4397: {
options = {
arguments: true,
keep_fargs: false,
reduce_vars: true,
}
input: {
console.log(typeof function() {
arguments += 0;
return arguments[0];
}());
}
expect: {
console.log(typeof function() {
arguments += 0;
return arguments[0];
}());
}
expect_stdout: "string"
}
issue_4410_1: {
options = {
arguments: true,
conditionals: true,
evaluate: true,
reduce_vars: true,
}
input: {
(function(a) {
console.log(arguments[0] === (a = 0) ? "FAIL" : "PASS");
})(1);
}
expect: {
(function(a) {
console.log(a === (a = 0) ? "FAIL" : "PASS");
})(1);
}
expect_stdout: "PASS"
}
issue_4410_2: {
options = {
arguments: true,
conditionals: true,
evaluate: true,
reduce_vars: true,
}
input: {
(function f(a) {
console.log(arguments[0] === (a = 0) ? "FAIL" : "PASS");
})(1);
}
expect: {
(function f(a) {
console.log(arguments[0] === (a = 0) ? "FAIL" : "PASS");
})(1);
}
expect_stdout: "PASS"
}
issue_4410_3: {
options = {
arguments: true,
}
input: {
var a = 1;
(function f(b) {
a-- && f();
for (var c = 2; c--;)
switch (arguments[0]) {
case b = 42:
case 42:
console.log("PASS");
}
})(null);
}
expect: {
var a = 1;
(function f(b) {
a-- && f();
for (var c = 2; c--;)
switch (arguments[0]) {
case b = 42:
case 42:
console.log("PASS");
}
})(null);
}
expect_stdout: "PASS"
}
issue_4432: {
options = {
arguments: true,
reduce_vars: true,
}
input: {
console.log(function(a) {
for (a in { FAIL: 42 });
return arguments[0];
}() || "PASS");
}
expect: {
console.log(function(a) {
for (a in { FAIL: 42 });
return arguments[0];
}() || "PASS");
}
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

@@ -13,9 +13,10 @@ holes_and_undefined: {
}
}
constant_join: {
constant_join_1: {
options = {
evaluate: true,
side_effects: true,
strings: true,
unsafe: true,
}
@@ -57,7 +58,7 @@ constant_join: {
var c5 = [ boo() + bar() + "foo", 1, 2, 3, "bar", bar() + "foo" ].join();
var c6 = [ "1,2,,,foo,bar", baz() ].join();
var d = "foo-3bar-baz";
var e = [].join(foo + bar);
var e = (foo, bar, "");
var f = "";
var g = "";
}
@@ -354,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"
}

886
test/compress/arrows.js Normal file
View File

@@ -0,0 +1,886 @@
no_funarg: {
input: {
(() => console.log(42))();
}
expect_exact: "(()=>console.log(42))();"
expect_stdout: "42"
node_version: ">=4"
}
single_funarg: {
input: {
(a => console.log(a))(42);
}
expect_exact: "(a=>console.log(a))(42);"
expect_stdout: "42"
node_version: ">=4"
}
multiple_funargs: {
input: {
((a, b) => console.log(a, b))("foo", "bar");
}
expect_exact: '((a,b)=>console.log(a,b))("foo","bar");'
expect_stdout: "foo bar"
node_version: ">=4"
}
destructured_funarg: {
input: {
(([ a, b, c ]) => console.log(a, b, c))("foo");
}
expect_exact: '(([a,b,c])=>console.log(a,b,c))("foo");'
expect_stdout: "f o o"
node_version: ">=6"
}
await_parentheses: {
input: {
async function f() {
await (a => a);
}
}
expect_exact: "async function f(){await(a=>a)}"
}
for_parentheses_init: {
input: {
for (a => (a in a); console.log(42););
}
expect_exact: "for((a=>a in a);console.log(42););"
expect_stdout: "42"
node_version: ">=4"
}
for_parentheses_condition: {
input: {
for (console.log(42); a => (a in a);)
break;
}
expect_exact: "for(console.log(42);a=>a in a;)break;"
expect_stdout: "42"
node_version: ">=4"
}
for_parentheses_step: {
input: {
for (; console.log(42); a => (a in a));
}
expect_exact: "for(;console.log(42);a=>a in a);"
expect_stdout: "42"
node_version: ">=4"
}
for_assign_parentheses_init: {
input: {
for (f = a => (a in a); console.log(42););
}
expect_exact: "for((f=a=>a in a);console.log(42););"
expect_stdout: "42"
node_version: ">=4"
}
for_assign_parentheses_condition: {
input: {
for (console.log(42); f = a => (a in a);)
break;
}
expect_exact: "for(console.log(42);f=a=>a in a;)break;"
expect_stdout: "42"
node_version: ">=4"
}
for_assign_parentheses_step: {
input: {
for (; console.log(42); f = a => (a in a));
}
expect_exact: "for(;console.log(42);f=a=>a in a);"
expect_stdout: "42"
node_version: ">=4"
}
for_declaration_parentheses_init: {
input: {
for (var f = a => (a in a); console.log(42););
}
expect_exact: "for(var f=(a=>a in a);console.log(42););"
expect_stdout: "42"
node_version: ">=4"
}
for_statement_parentheses_init: {
input: {
for (a => {
a in a;
}; console.log(42););
}
expect_exact: "for(a=>{a in a};console.log(42););"
expect_stdout: "42"
node_version: ">=4"
}
body_call: {
input: {
(() => {
console.log("foo");
console.log("bar");
})();
}
expect_exact: '(()=>{console.log("foo");console.log("bar")})();'
expect_stdout: [
"foo",
"bar",
]
node_version: ">=4"
}
body_conditional: {
input: {
console.log((a => {}) ? "PASS" : "FAIL");
}
expect_exact: 'console.log((a=>{})?"PASS":"FAIL");'
expect_stdout: "PASS"
node_version: ">=4"
}
destructured_object_value: {
input: {
console.log((a => ({} = a))(42));
}
expect_exact: "console.log((a=>({}=a))(42));"
expect_stdout: "42"
node_version: ">=6"
}
function_value: {
input: {
console.log((a => function() {
return a;
})(42)());
}
expect_exact: "console.log((a=>function(){return a})(42)());"
expect_stdout: "42"
node_version: ">=4"
}
in_value: {
input: {
console.log((a => a in {
foo: 42,
})("foo"));
}
expect_exact: 'console.log((a=>a in{foo:42})("foo"));'
expect_stdout: "true"
node_version: ">=4"
}
object_value: {
input: {
console.log((() => ({
4: 2,
}))()[4]);
}
expect_exact: "console.log((()=>({4:2}))()[4]);"
expect_stdout: "2"
node_version: ">=4"
}
object_first_in_value: {
input: {
console.log((a => ({
p: a,
}.p ? "FAIL" : "PASS"))());
}
expect_exact: 'console.log((a=>({p:a}).p?"FAIL":"PASS")());'
expect_stdout: "PASS"
node_version: ">=4"
}
sequence_value: {
input: {
console.log((a => (console.log("foo"), a))("bar"));
}
expect_exact: 'console.log((a=>(console.log("foo"),a))("bar"));'
expect_stdout: [
"foo",
"bar",
]
node_version: ">=4"
}
side_effects_value: {
options = {
side_effects: true,
}
input: {
console.log((a => function() {
return a;
})(42)());
}
expect: {
console.log((a => function() {
return a;
})(42)());
}
expect_stdout: "42"
node_version: ">=4"
}
arrow_property: {
input: {
console.log((a => 42).prototype);
}
expect_exact: "console.log((a=>42).prototype);"
expect_stdout: "undefined"
node_version: ">=4"
}
assign_arrow: {
input: {
var f = a => a;
console.log(f(42));
}
expect_exact: "var f=a=>a;console.log(f(42));"
expect_stdout: "42"
node_version: ">=4"
}
binary_arrow: {
input: {
console.log(4 || (() => 2));
}
expect_exact: "console.log(4||(()=>2));"
expect_stdout: "4"
node_version: ">=4"
}
unary_arrow: {
input: {
console.log(+(() => 42));
}
expect_exact: "console.log(+(()=>42));"
expect_stdout: "NaN"
node_version: ">=4"
}
trailing_comma: {
input: {
((a,) => console.log(a))(42);
}
expect_exact: "(a=>console.log(a))(42);"
expect_stdout: "42"
node_version: ">=4"
}
drop_arguments: {
options = {
arguments: true,
keep_fargs: false,
reduce_vars: true,
}
input: {
console.log(function() {
return () => arguments[0];
}("PASS")("FAIL"));
}
expect: {
console.log(function(argument_0) {
return () => argument_0;
}("PASS")("FAIL"));
}
expect_stdout: "PASS"
node_version: ">=4"
}
funarg_arguments: {
options = {
inline: true,
}
input: {
console.log((arguments => arguments)(42));
}
expect: {
console.log(42);
}
expect_stdout: "42"
node_version: ">=4"
}
inline_arguments: {
options = {
inline: true,
}
input: {
console.log(function() {
return () => arguments[0];
}("PASS")("FAIL"));
}
expect: {
console.log(function() {
return () => arguments[0];
}("PASS")("FAIL"));
}
expect_stdout: "PASS"
node_version: ">=4"
}
var_arguments: {
options = {
inline: true,
properties: true,
reduce_vars: true,
side_effects: true,
unused: true,
}
input: {
console.log(function() {
return () => {
var arguments = [ "PASS" ];
return arguments;
};
}("FAIL 1")("FAIL 2")[0]);
}
expect: {
console.log("PASS");
}
expect_stdout: "PASS"
node_version: ">=4"
}
negate: {
options = {
conditionals: true,
}
input: {
if (!console ? 0 : () => 1)
console.log("PASS");
}
expect: {
(console ? () => 1 : 0) && console.log("PASS");
}
expect_stdout: "PASS"
node_version: ">=4"
}
inline_this: {
options = {
inline: true,
}
input: {
var o = {
p: function() {
return function() {
return () => this.q;
}();
},
q: "FAIL",
};
q = "PASS";
console.log(o.p()());
}
expect: {
var o = {
p: function() {
return function() {
return () => this.q;
}();
},
q: "FAIL",
};
q = "PASS";
console.log(o.p()());
}
expect_stdout: "PASS"
node_version: ">=4"
}
trim_body: {
options = {
arrows: true,
if_return: true,
side_effects: true,
}
input: {
var f = a => {
return a;
};
var g = b => void b;
console.log(f("PASS"), g("FAIL"));
}
expect: {
var f = a => a;
var g = b => {};
console.log(f("PASS"), g("FAIL"));
}
expect_stdout: "PASS undefined"
node_version: ">=4"
}
collapse_value: {
options = {
arrows: true,
collapse_vars: true,
keep_fargs: false,
unsafe: true,
unused: true,
}
input: {
var a = 42;
console.log((b => Math.floor(b))(a));
}
expect: {
var a = 42;
console.log((() => Math.floor(a))());
}
expect_stdout: "42"
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: {
((a, b) => {})(console.log(42));
}
expect_stdout: "42"
node_version: ">=4"
}
reduce_iife_1: {
options = {
evaluate: true,
keep_fargs: false,
reduce_vars: true,
unused: true,
}
input: {
(a => console.log(a + a))(21);
}
expect: {
(() => console.log(42))();
}
expect_stdout: "42"
node_version: ">=4"
}
reduce_iife_2: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = 21;
(() => console.log(a + a))();
}
expect: {
(() => console.log(42))();
}
expect_stdout: "42"
node_version: ">=4"
}
reduce_iife_3: {
options = {
evaluate: true,
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var a = "foo";
(() => {
console.log(a);
console.log(a);
})();
a = "bar";
}
expect: {
(() => {
console.log("foo");
console.log("foo");
})();
}
expect_stdout: [
"foo",
"foo",
]
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,
toplevel: true,
unused: true,
}
input: {
function f() {
return (() => f)();
}
console.log(typeof f());
}
expect: {
console.log(typeof function f() {
return (() => f)();
}());
}
expect_stdout: "function"
node_version: ">=4"
}
issue_4388: {
options = {
inline: true,
toplevel: true,
}
input: {
(arguments => console.log(arguments && arguments))();
}
expect: {
(arguments => console.log(arguments && arguments))();
}
expect_stdout: "undefined"
node_version: ">=4"
}
issue_4390: {
options = {
collapse_vars: true,
}
input: {
function log() {
console.log.apply(console, arguments);
}
var a = 42, b = "FAIL";
b = "PASS";
(c => log(b, c))(a);
log(b);
}
expect: {
function log() {
console.log.apply(console, arguments);
}
var a = 42, b = "FAIL";
b = "PASS";
(c => log(b, c))(a);
log(b);
}
expect_stdout: [
"PASS 42",
"PASS",
]
node_version: ">=4"
}
issue_4401: {
options = {
merge_vars: true,
}
input: {
(function() {
var a = (b => b(a))(console.log || a);
var c = console.log;
c && c(typeof b);
})();
}
expect: {
(function() {
var a = (b => b(a))(console.log || a);
var c = console.log;
c && c(typeof b);
})();
}
expect_stdout: [
"undefined",
"undefined",
]
node_version: ">=4"
}
issue_4448: {
options = {
pure_getters: "strict",
side_effects: true,
}
input: {
var A;
try {
(arguments => {
arguments[0];
})(A);
} catch (e) {
console.log("PASS");
}
}
expect: {
var A;
try {
(arguments => {
arguments[0];
})(A);
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_4476: {
options = {
arguments: true,
}
input: {
(function(a, b) {
(a => {
console.log(arguments[0], a);
})(b);
})("foo", "bar");
}
expect: {
(function(a, b) {
(a => {
console.log(arguments[0], a);
})(b);
})("foo", "bar");
}
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"
}

View File

@@ -1,35 +0,0 @@
ascii_only_true: {
options = {}
beautify = {
ascii_only : true,
ie8 : false,
beautify : false,
}
input: {
function f() {
return "\x000\x001\x007\x008\x00" +
"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" +
"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" +
"\x20\x21\x22\x23 ... \x7d\x7e\x7f\x80\x81 ... \xfe\xff\u0fff\uffff";
}
}
expect_exact: 'function f(){return"\\x000\\x001\\x007\\x008\\0"+"\\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\b\\t\\n\\v\\f\\r\\x0e\\x0f"+"\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f"+\' !"# ... }~\\x7f\\x80\\x81 ... \\xfe\\xff\\u0fff\\uffff\'}'
}
ascii_only_false: {
options = {}
beautify = {
ascii_only : false,
ie8 : false,
beautify : false,
}
input: {
function f() {
return "\x000\x001\x007\x008\x00" +
"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" +
"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" +
"\x20\x21\x22\x23 ... \x7d\x7e\x7f\x80\x81 ... \xfe\xff\u0fff\uffff";
}
}
expect_exact: 'function f(){return"\\x000\\x001\\x007\\x008\\0"+"\\0\x01\x02\x03\x04\x05\x06\x07\\b\\t\\n\\v\\f\\r\x0e\x0f"+"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"+\' !"# ... }~\x7f\x80\x81 ... \xfe\xff\u0fff\uffff\'}'
}

View File

@@ -76,9 +76,8 @@ asm_mixed: {
start = start | 0;
end = end | 0;
var sum = 0.0, p = 0, q = 0;
for (p = start << 3, q = end << 3; (p | 0) < (q | 0); p = p + 8 | 0) {
for (p = start << 3, q = end << 3; (p | 0) < (q | 0); p = p + 8 | 0)
sum = sum + +log(values[p >> 3]);
}
return +sum;
}
function geometricMean(start, end) {
@@ -91,11 +90,12 @@ asm_mixed: {
function no_asm_GeometricMean(stdlib, foreign, buffer) {
function logSum(start, end) {
start |= 0, end |= 0;
for (var sum = 0, p = 0, q = 0, p = start << 3, q = end << 3; (0 | p) < (0 | q); p = p + 8 | 0) sum += +log(values[p >> 3]);
for (var sum = 0, p = 0, q = 0, p = start << 3, q = end << 3; (0 | p) < (0 | q); p = p + 8 | 0)
sum += +log(values[p >> 3]);
return +sum;
}
function geometricMean(start, end) {
return start |= 0, end |= 0, +exp(logSum(start, end) / (end - start | 0));
return start |= 0, end |= 0, +exp(+logSum(start, end) / (end - start | 0));
}
var exp = stdlib.Math.exp, log = stdlib.Math.log, values = new stdlib.Float64Array(buffer);
return { geometricMean: geometricMean };

View File

@@ -461,3 +461,288 @@ issue_3949_2: {
}
expect_stdout: "100"
}
issue_4521: {
options = {
assignments: true,
dead_code: true,
}
input: {
var a = (a = 42 | a) ? console.log(a) : 0;
}
expect: {
var a = (a |= 42) ? console.log(a) : 0;
}
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: {
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_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"
}
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: {
A = "FAIL";
var a = A, 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"
}

2048
test/compress/awaits.js Normal file

File diff suppressed because it is too large Load Diff

92
test/compress/bigint.js Normal file
View File

@@ -0,0 +1,92 @@
arithmetic: {
input: {
console.log(((1n + 0x2n) * (0o3n - -4n)) >> (5n - 6n));
}
expect_exact: "console.log((1n+0x2n)*(0o3n- -4n)>>5n-6n);"
expect_stdout: "42n"
node_version: ">=10"
}
minus_dot: {
input: {
console.log(typeof -42n.toString(), typeof (-42n).toString());
}
expect_exact: "console.log(typeof-42n.toString(),typeof(-42n).toString());"
expect_stdout: "number string"
node_version: ">=10"
}
evaluate: {
options = {
evaluate: true,
unsafe: true,
}
input: {
console.log((0xDEAD_BEEFn).toString(16));
}
expect: {
console.log(0xdeadbeefn.toString(16));
}
expect_stdout: "deadbeef"
node_version: ">=10"
}
Number: {
options = {
unsafe: true,
}
input: {
console.log(Number(-0xfeed_dead_beef_badn));
}
expect: {
console.log(+("" + -0xfeed_dead_beef_badn));
}
expect_stdout: "-1148098955808013200"
node_version: ">=10"
}
issue_4590: {
options = {
collapse_vars: true,
}
input: {
A = 1;
0n || console.log("PASS");
}
expect: {
A = 1;
0n || console.log("PASS");
}
expect_stdout: "PASS"
node_version: ">=10"
}
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"
}

View File

@@ -29,6 +29,404 @@ 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_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_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"
}
issue_3465_1: {
options = {
booleans: true,
@@ -153,3 +551,149 @@ issue_3690: {
}
expect_stdout: "PASS"
}
issue_4374: {
options = {
booleans: true,
conditionals: true,
if_return: true,
reduce_vars: true,
unused: true,
}
input: {
(function() {
console.log(f());
function f(a) {
if (null) return 0;
if (a) return 1;
return 0;
}
})();
}
expect: {
(function() {
console.log(function(a) {
return !null && a ? 1 : 0;
}());
})();
}
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"
}

2068
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

@@ -123,6 +123,29 @@ self_comparison_3: {
]
}
self_comparison_4: {
options = {
booleans: true,
comparisons: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var o = {};
console.log(o == o, o != o);
console.log(o === o, o !== o);
}
expect: {
console.log(!0, !1);
console.log(!0, !1);
}
expect_stdout: [
"true false",
"true false",
]
}
issue_2857_1: {
options = {
comparisons: true,

View File

@@ -238,6 +238,41 @@ concat_8: {
expect_stdout: true
}
concat_9: {
options = {
booleans: true,
evaluate: true,
reduce_vars: true,
strings: true,
toplevel: true,
}
input: {
var a = "foo";
console.log(
12 + (34 + a),
null + (34 + a),
12 + (null + a),
false + (34 + a),
12 + (false + a),
"bar" + (34 + a),
12 + ("bar" + a)
);
}
expect: {
var a = "foo";
console.log(
"1234" + a,
"null34" + a,
"12null" + a,
!1 + (34 + a),
12 + (!1 + a),
"bar34" + a,
"12bar" + a
);
}
expect_stdout: true
}
issue_3689: {
options = {
strings: true,

View File

@@ -55,14 +55,15 @@ ifs_3_should_warn: {
}
input: {
var x, y;
if (x && !(x + "1") && y) { // 1
// 1
if (x && !(x + "1") && y) {
var qq;
foo();
} else {
bar();
}
if (x || !!(x + "1") || y) { // 2
// 2
if (x || !!(x + "1") || y) {
foo();
} else {
var jj;
@@ -71,9 +72,25 @@ ifs_3_should_warn: {
}
expect: {
var x, y;
var qq; bar(); // 1
var jj; foo(); // 2
// 1
var qq; bar();
// 2
foo(); var jj;
}
expect_warnings: [
"WARN: + in boolean context always true [test/compress/conditionals.js:3,18]",
"WARN: Boolean && always false [test/compress/conditionals.js:3,12]",
"WARN: Condition left of && always false [test/compress/conditionals.js:3,12]",
"WARN: Condition always false [test/compress/conditionals.js:3,12]",
"WARN: Dropping unreachable code [test/compress/conditionals.js:3,34]",
"WARN: + in boolean context always true [test/compress/conditionals.js:10,19]",
"WARN: Boolean || always true [test/compress/conditionals.js:10,12]",
"WARN: Condition left of || always true [test/compress/conditionals.js:10,12]",
"WARN: Condition always true [test/compress/conditionals.js:10,12]",
"WARN: Dropping unreachable code [test/compress/conditionals.js:12,15]",
"WARN: Dropping side-effect-free statement [test/compress/conditionals.js:3,12]",
"WARN: Dropping side-effect-free statement [test/compress/conditionals.js:10,12]",
]
}
ifs_4: {
@@ -783,6 +800,55 @@ cond_12: {
}
}
cond_13: {
options = {
conditionals: true,
}
input: {
x ? y(a) : z(a);
x ? y.f(a) : z.f(a);
x ? y.f(a) : z.g(a);
x ? y.f()(a) : z.g()(a);
x ? y.f.u(a) : z.g.u(a);
x ? y.f().u(a) : z.g().u(a);
}
expect: {
(x ? y : z)(a);
(x ? y : z).f(a);
x ? y.f(a) : z.g(a);
(x ? y.f() : z.g())(a);
(x ? y.f : z.g).u(a);
(x ? y.f() : z.g()).u(a);
}
}
cond_14: {
options = {
booleans: true,
conditionals: true,
side_effects: true,
}
input: {
function f(a) {
if (a)
if (a)
console.log("PASS");
else
console.log("FAIL");
}
f(null);
f(42);
}
expect: {
function f(a) {
a && console.log("PASS");
}
f(null);
f(42);
}
expect_stdout: "PASS"
}
ternary_boolean_consequent: {
options = {
booleans: true,
@@ -1137,7 +1203,7 @@ issue_1645_2: {
expect_stdout: true
}
condition_symbol_matches_consequent: {
condition_matches_consequent: {
options = {
conditionals: true,
}
@@ -1166,6 +1232,35 @@ condition_symbol_matches_consequent: {
expect_stdout: "3 7 true 4"
}
condition_matches_alternative: {
options = {
conditionals: true,
}
input: {
function foo(x, y) {
return x.p ? y[0] : x.p;
}
function bar() {
return g ? h : g;
}
var g = 4;
var h = 5;
console.log(foo({ p: 3 }, [ null ]), foo({ p: 0 }, [ 7 ]), foo({ p: true } , [ false ]), bar());
}
expect: {
function foo(x, y) {
return x.p && y[0];
}
function bar() {
return g && h;
}
var g = 4;
var h = 5;
console.log(foo({ p: 3 }, [ null ]), foo({ p: 0 }, [ 7 ]), foo({ p: true } , [ false ]), bar());
}
expect_stdout: "null 0 false 5"
}
delete_conditional_1: {
options = {
booleans: true,
@@ -1793,3 +1888,39 @@ issue_3808_2: {
}
expect_stdout: " PASS"
}
object_super: {
options = {
conditionals: true,
}
input: {
Object.setPrototypeOf({
f(a) {
a ? this.g("FAIL") : super.g("FAIL");
},
g(b) {
console.log(b);
},
}, {
g() {
console.log("PASS");
},
}).f();
}
expect: {
Object.setPrototypeOf({
f(a) {
a ? this.g("FAIL") : super.g("FAIL");
},
g(b) {
console.log(b);
},
}, {
g() {
console.log("PASS");
},
}).f();
}
expect_stdout: "PASS"
node_version: ">=4"
}

1694
test/compress/const.js Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -53,13 +53,17 @@ dead_code_2_should_warn: {
g();
x = 10;
throw new Error("foo");
var x;
function g(){};
{
var x;
function g(){};
}
}
f();
}
expect_stdout: true
node_version: "<=4"
expect_warnings: [
"WARN: Dropping unreachable code [test/compress/dead-code.js:8,12]",
]
}
dead_code_constant_boolean_should_warn_more: {
@@ -85,15 +89,27 @@ 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 moo;
var x = 10, y;
var moo;
bar();
}
expect_stdout: true
expect_warnings: [
"WARN: + in boolean context always true [test/compress/dead-code.js:1,33]",
"WARN: Boolean || always true [test/compress/dead-code.js:1,16]",
"WARN: Dropping unreachable code [test/compress/dead-code.js:1,45]",
"WARN: Boolean expression always true [test/compress/dead-code.js:6,47]",
"WARN: Boolean && always false [test/compress/dead-code.js:6,28]",
"WARN: Dropping unreachable code [test/compress/dead-code.js:6,63]",
"WARN: Dropping side-effect-free statement [test/compress/dead-code.js:1,15]",
"WARN: Dropping side-effect-free statement [test/compress/dead-code.js:6,28]",
]
node_version: "<=4"
}
@@ -712,7 +728,7 @@ issue_2749: {
expect: {
var a = 2, c = "PASS";
while (a--)
b = void 0, b ? c = "FAIL" : b = 1;
b = void 0, b ? c = "FAIL" : 1;
var b;
console.log(c);
}
@@ -923,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,
@@ -1341,3 +1536,100 @@ issue_3967: {
}
expect_stdout: "PASS"
}
issue_4051: {
options = {
dead_code: true,
}
input: {
try {
delete (A = A);
} catch (e) {
console.log("PASS");
}
}
expect: {
try {
delete (A = A);
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "PASS"
}
issue_4366: {
options = {
dead_code: true,
}
input: {
function f() {
return "PASS";
({
p: 42,
get p() {},
});
}
console.log(f());
}
expect: {
function f() {
return "PASS";
}
console.log(f());
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_4570: {
options = {
dead_code: true,
inline: true,
}
input: {
var a = function(b) {
return a += b;
}() ? 0 : a;
console.log(a);
}
expect: {
var a = (a += void 0) ? 0 : a;
console.log(a);
}
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"
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -4,15 +4,16 @@ unused_funarg_1: {
unused: true,
}
input: {
function f(a, b, c, d, e) {
console.log(function f(a, b, c, d, e) {
return a + b;
}
}(14, 28));
}
expect: {
function f(a, b) {
console.log(function(a, b) {
return a + b;
}
}(14, 28));
}
expect_stdout: "42"
}
unused_funarg_2: {
@@ -21,15 +22,16 @@ unused_funarg_2: {
unused: true,
}
input: {
function f(a, b, c, d, e) {
console.log(function f(a, b, c, d, e) {
return a + c;
}
}(14, 21, 28));
}
expect: {
function f(a, b, c) {
console.log(function(a, c) {
return a + c;
}
}(14, 28));
}
expect_stdout: "42"
}
unused_nested_function: {
@@ -357,37 +359,6 @@ drop_toplevel_vars: {
}
}
drop_toplevel_vars_fargs: {
options = {
keep_fargs: false,
toplevel: "vars",
unused: true,
}
input: {
var a, b = 1, c = g;
function f(d) {
return function() {
c = 2;
};
}
a = 2;
function g() {}
function h() {}
console.log(b = 3);
}
expect: {
function f() {
return function() {
2;
};
}
2;
function g() {}
function h() {}
console.log(3);
}
}
drop_toplevel_all: {
options = {
toplevel: true,
@@ -625,13 +596,14 @@ drop_fargs: {
unused: true,
}
input: {
function f(a) {
console.log(function f(a) {
var b = a;
}
}());
}
expect: {
function f() {}
console.log(function() {}());
}
expect_stdout: "undefined"
}
drop_fnames: {
@@ -823,9 +795,9 @@ issue_1656: {
beautify: true,
}
input: {
for(var a=0;;);
for (var a=0;;);
}
expect_exact: "for (;;) ;"
expect_exact: "for (;;);"
}
issue_1709: {
@@ -1138,7 +1110,7 @@ issue_1838: {
}
expect_exact: [
"function f() {",
" for (a; c; ) ;",
" for (a; c; );",
"}",
]
}
@@ -1730,7 +1702,7 @@ chained_3: {
expect: {
console.log(function(a, b) {
var c = b;
b++;
+b;
return c;
}(0, 2));
}
@@ -1997,7 +1969,7 @@ issue_3146_4: {
expect_stdout: "PASS"
}
issue_3192: {
issue_3192_1: {
options = {
unused: true,
}
@@ -2025,6 +1997,26 @@ issue_3192: {
]
}
issue_3192_2: {
options = {
keep_fargs: false,
unused: true,
}
input: {
"use strict";
(function(a) {
console.log(a = "foo", arguments[0]);
})("bar");
}
expect: {
"use strict";
(function() {
console.log("foo", arguments[0]);
})("bar");
}
expect_stdout: "foo bar"
}
issue_3233: {
options = {
pure_getters: "strict",
@@ -2146,6 +2138,7 @@ issue_3497: {
issue_3515_1: {
options = {
collapse_vars: true,
evaluate: true,
reduce_vars: true,
unused: true,
}
@@ -2161,8 +2154,7 @@ issue_3515_1: {
expect: {
var c = 0;
(function() {
this[c++] = 0;
for (var key20 in !0);
for (var key20 in !(this[c++] = 0));
})();
console.log(c);
}
@@ -2198,6 +2190,7 @@ issue_3515_2: {
issue_3515_3: {
options = {
collapse_vars: true,
evaluate: true,
unused: true,
}
input: {
@@ -2265,6 +2258,7 @@ function_assign: {
issue_3598: {
options = {
collapse_vars: true,
evaluate: true,
reduce_vars: true,
unused: true,
}
@@ -2351,7 +2345,7 @@ function_argument_reference: {
function_parameter_ie8: {
options = {
ie8: true,
ie: true,
reduce_vars: true,
unused: true,
}
@@ -2377,6 +2371,7 @@ function_parameter_ie8: {
issue_3664: {
options = {
pure_getters: "strict",
side_effects: true,
unused: true,
}
input: {
@@ -2387,7 +2382,7 @@ issue_3664: {
}
expect: {
console.log(function() {
var b = ([ b && console.log("FAIL") ].p = 0, 0);
var a, b = (a = (a = [ b && console.log("FAIL") ]).p = 0, 0);
return "PASS";
}());
}
@@ -2397,6 +2392,7 @@ issue_3664: {
issue_3673: {
options = {
pure_getters: "strict",
sequences: true,
side_effects: true,
toplevel: true,
unused: true,
@@ -2407,8 +2403,6 @@ issue_3673: {
console.log("PASS");
}
expect: {
var a;
(a = [ a ]).p = 42;
console.log("PASS");
}
expect_stdout: "PASS"
@@ -2416,7 +2410,7 @@ issue_3673: {
issue_3746: {
options = {
keep_fargs: "strict",
keep_fargs: false,
side_effects: true,
unused: true,
}
@@ -2678,8 +2672,7 @@ issue_3956: {
})();
}
expect: {
var c, d;
c += 0,
var d;
console.log(NaN),
d = 1 ^ console.log(1),
console.log(d);
@@ -2694,7 +2687,7 @@ issue_3956: {
issue_3962_1: {
options = {
evaluate: true,
keep_fargs: "strict",
keep_fargs: false,
reduce_vars: true,
toplevel: true,
unused: true,
@@ -2712,13 +2705,13 @@ issue_3962_1: {
}
expect: {
var a = 0;
a = (function(c) {
(function(c) {
do {
console;
0..toString();
} while (0);
if (c) console.log("PASS");
}((a--, 1)), 0);
})(1);
void 0;
}
expect_stdout: "PASS"
@@ -2726,7 +2719,7 @@ issue_3962_1: {
issue_3962_2: {
options = {
keep_fargs: "strict",
keep_fargs: false,
reduce_vars: true,
side_effects: true,
toplevel: true,
@@ -2745,13 +2738,13 @@ issue_3962_2: {
}
expect: {
var a = 0;
a = (function(c) {
(function(c) {
do {
console;
0..toString();
} while (0);
if (c) console.log("PASS");
}((a--, 1)), 0);
})(1);
}
expect_stdout: "PASS"
}
@@ -2808,7 +2801,9 @@ issue_4017: {
var a = 0;
console.log(function() {
c &= 0;
var c = (a++, A = a, 0);
var c;
a++,
A = a;
}());
}
expect_stdout: "undefined"
@@ -2834,11 +2829,11 @@ issue_4025: {
console.log(a, b, d);
}
expect: {
var d, c = 0;
var c = 0;
try {
console.log(c);
} finally {
d = c + 1;
var d = c + 1;
c = 0;
}
console.log(1, 1, d);
@@ -2848,3 +2843,652 @@ issue_4025: {
"1 1 1",
]
}
forin_var_1: {
options = {
unused: true,
}
input: {
var k;
for (k in [ 1, 2 ])
console.log(k);
for (k in { PASS: 3 })
console.log(k);
console.log(k);
}
expect: {
for (var k in [ 1, 2 ])
console.log(k);
for (k in { PASS: 3 })
console.log(k);
console.log(k);
}
expect_stdout: [
"0",
"1",
"PASS",
"PASS",
]
}
forin_var_2: {
options = {
unused: true,
}
input: {
console.log(function() {
switch (0) {
case function() {
for (a in 0);
}:
var b = 0;
}
for (var c = 0; a;);
var a;
}());
}
expect: {
console.log(function() {
switch (0) {
case function() {
for (a in 0);
}:
}
for (; a;);
var a;
}());
}
expect_stdout: "undefined"
}
issue_4133: {
options = {
evaluate: true,
merge_vars: true,
pure_getters: "strict",
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = 1;
var b = [ a-- ], c = b && b[c];
console.log(a);
}
expect: {
var b = 1;
console.log(0);
}
expect_stdout: "0"
}
issue_4144: {
options = {
keep_fargs: false,
reduce_vars: true,
unused: true,
}
input: {
(function(a, b) {
var b = console, c = ++b;
})(console.log("PASS"), 0);
}
expect: {
(function(b) {
b = console,
++b;
})(console.log("PASS"));
}
expect_stdout: "PASS"
}
issue_4146: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
function f(a, b) {
function g() {}
var a = g;
var c = b;
c.p;
console.log(typeof a);
}
f("FAIL", 42);
}
expect: {
(function(a, b) {
a = function () {};
var c = b;
c.p;
console.log(typeof a);
})(0, 42);
}
expect_stdout: "function"
}
var_catch_redefined: {
options = {
toplevel: true,
unused: true,
}
input: {
var a = "FAIL";
try {
throw "PASS";
} catch (a) {
function f() {
return a;
}
console.log(a);
}
f();
}
expect: {
var a = "FAIL";
try {
throw "PASS";
} catch (a) {
function f() {
return a;
}
console.log(a);
}
f();
}
expect_stdout: "PASS"
}
single_use_catch_redefined: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = 1;
try {
throw 2;
} catch (a) {
function g() {
return a;
}
}
console.log(g());
}
expect: {
var a = 1;
try {
throw 2;
} catch (a) {
function g() {
return a;
}
}
console.log(g());
}
expect_stdout: true
}
issue_4184: {
options = {
reduce_vars: true,
unused: true,
}
input: {
(function() {
var a = function() {}, b = [ a, 1 && b, a = {} ];
try {
throw 42;
} catch (a) {
{
console.log(a);
}
}
})();
}
expect: {
(function() {
var b = [ function() {}, 1 && b, {} ];
try {
throw 42;
} catch (a) {
console.log(a);
}
})();
}
expect_stdout: "42"
}
issue_4235: {
options = {
inline: true,
reduce_vars: true,
unused: true,
varify: true,
}
input: {
(function() {
{
const f = 0;
}
(function f() {
var f = console.log(f);
})();
})();
}
expect: {
void function() {
var f;
console.log(f);
}();
}
expect_stdout: "undefined"
}
issue_4404: {
options = {
pure_getters: "strict",
unused: true,
}
input: {
function f(a) {
arguments[0] = "PASS";
console.log(a);
}
f("FAIL");
}
expect: {
function f(a) {
arguments[0] = "PASS";
console.log(a);
}
f("FAIL");
}
expect_stdout: "PASS"
}
issue_4413: {
options = {
reduce_vars: true,
unused: true,
}
input: {
console.log(function f(arguments) {
var arguments = function() {};
return arguments.length;
}());
}
expect: {
console.log(function(arguments) {
return function() {}.length;
}());
}
expect_stdout: "0"
}
issue_4464_1: {
options = {
reduce_vars: true,
unused: true,
}
input: {
function f(a) {
var a = function() {};
return [ arguments, a ];
}
console.log(typeof f()[1]);
}
expect: {
function f(a) {
a = function() {};
return [ arguments, a ];
}
console.log(typeof f()[1]);
}
expect_stdout: "function"
}
issue_4464_2: {
options = {
reduce_vars: true,
unused: true,
}
input: {
function f(a) {
var a = function() {};
return [ arguments, a ];
}
console.log(typeof f(42)[0][0]);
}
expect: {
function f(a) {
a = function() {};
return [ arguments, a ];
}
console.log(typeof f(42)[0][0]);
}
expect_stdout: "function"
}
issue_4464_3: {
options = {
reduce_vars: true,
unused: true,
}
input: {
(function a(a) {
var a = function() {};
return [ arguments[0], a ];
})(42).forEach(function(b) {
console.log(typeof b);
});
}
expect: {
(function(a) {
a = function() {};
return [ arguments[0], a ];
})(42).forEach(function(b) {
console.log(typeof b);
});
}
expect_stdout: [
"function",
"function",
]
}
issue_4558_1: {
options = {
evaluate: true,
pure_getters: true,
reduce_vars: true,
sequences: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var a = 0;
var b = 1, b = c >>>= a;
var c = 0;
b && 0[a++],
console.log(a);
}
expect: {
var a = 0;
var b = c >>>= a;
var c;
b && a++,
console.log(a);
}
expect_stdout: "0"
}
issue_4558_2: {
options = {
evaluate: true,
ie: true,
reduce_vars: true,
unused: true,
}
input: {
(function() {
var a = 1;
var b = (a = NaN) || (console.log("PASS"), 2);
return a;
})();
}
expect: {
(function() {
var a;
(a = NaN) || console.log("PASS");
return a;
})();
}
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,
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 {
void 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"
}

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: {
@@ -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,15 @@ 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"
}
issue_1649: {
@@ -2800,7 +2827,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",
@@ -2833,3 +2860,365 @@ issue_3997: {
}
expect_stdout: "string"
}
issue_4035: {
options = {
evaluate: true,
reduce_vars: true,
}
input: {
var a = 0;
(function() {
var b = --a;
console.log(delete (0 + b));
console.log(delete (1 * b));
console.log(delete (b + 0));
console.log(delete (b - 0));
console.log(delete (b / 1));
})();
}
expect: {
var a = 0;
(function() {
var b = --a;
console.log((0 + b, true));
console.log((1 * b, true));
console.log((0 + b, true));
console.log((b - 0, true));
console.log((b / 1, true));
})();
}
expect_stdout: [
"true",
"true",
"true",
"true",
"true",
]
}
issue_4067: {
options = {
evaluate: true,
reduce_vars: true,
unsafe: true,
}
input: {
(function(a) {
(function(b) {
b[0] += 0;
console.log(+a);
})(a);
})([]);
}
expect: {
(function(a) {
(function(b) {
b[0] += 0;
console.log(+a);
})(a);
})([]);
}
expect_stdout: "NaN"
}
issue_4077: {
options = {
evaluate: true,
unsafe: true,
}
input: {
console.log((a = []) - (a[0]++, 1) || "PASS");
}
expect: {
console.log((a = []) - (a[0]++, 1) || "PASS");
}
expect_stdout: "PASS"
}
issue_4119_1: {
options = {
conditionals: true,
dead_code: true,
evaluate: true,
reduce_vars: true,
toplevel: true,
unsafe: true,
}
input: {
var a, b;
b = a = [];
a[0] += 0;
if (+b + 1) {
console.log("FAIL");
} else {
console.log("PASS");
}
}
expect: {
var a, b;
b = a = [];
a[0] += 0;
+b + 1 ? console.log("FAIL") : console.log("PASS");
}
expect_stdout: "PASS"
}
issue_4119_2: {
options = {
conditionals: true,
evaluate: true,
reduce_vars: true,
unsafe: true,
}
input: {
var a;
(function(b) {
a[0] += 0;
console.log(+b + 1 ? "FAIL" : "PASS");
})(a = []);
}
expect: {
var a;
(function(b) {
a[0] += 0;
console.log(+b + 1 ? "FAIL" : "PASS");
})(a = []);
}
expect_stdout: "PASS"
}
issue_4119_3: {
options = {
conditionals: true,
evaluate: true,
reduce_vars: true,
toplevel: true,
unsafe: true,
}
input: {
var a, b;
b = a = {
p: 42,
};
delete a.p;
console.log(b.p ? "FAIL" : "PASS");
}
expect: {
var a, b;
b = a = {
p: 42,
};
delete a.p;
console.log(b.p ? "FAIL" : "PASS");
}
expect_stdout: "PASS"
}
issue_4119_4: {
options = {
booleans: true,
conditionals: true,
evaluate: true,
reduce_vars: true,
toplevel: true,
}
input: {
var a, b;
b = a = {
p: 42,
};
delete a.p;
console.log(!b ? "FAIL" : "PASS");
}
expect: {
var a, b;
b = a = {
p: 42,
};
delete a.p;
console.log((b, 0, "PASS"));
}
expect_stdout: "PASS"
}
issue_4214: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
function f(a) {
return function() {
try {
return a;
} finally {
var b = 0;
}
}(a++ && this());
}
var c = f();
console.log(c);
}
expect: {
var c = function(a) {
return function() {
try {
return a;
} finally {}
}(a++ && this());
}();
console.log(c);
}
expect_stdout: "NaN"
}
issue_4271: {
options = {
evaluate: true,
unsafe: true,
}
input: {
({
p: null,
q: (console.log("foo"), 42),
p: function() {}
})[console.log("bar"), "p"] && console.log("PASS");
}
expect: {
({
p: null,
q: (console.log("foo"), 42),
p: function() {}
})[console.log("bar"), "p"],
console.log("PASS");
}
expect_stdout: [
"foo",
"bar",
"PASS",
]
}
issue_4393: {
options = {
evaluate: true,
reduce_vars: true,
}
input: {
(function f(a) {
a = "PASS";
console.log(arguments[0]);
})("FAIL");
}
expect: {
(function f(a) {
a = "PASS";
console.log(arguments[0]);
})("FAIL");
}
expect_stdout: "PASS"
}
issue_4422: {
options = {
evaluate: true,
reduce_vars: true,
unused: true,
}
input: {
console.log(function f(a) {
a = "FAIL 1";
arguments[0] = "PASS";
return a;
}("FAIL 2"));
}
expect: {
console.log(function(a) {
a = "FAIL 1";
arguments[0] = "PASS";
return a;
}("FAIL 2"));
}
expect_stdout: "PASS"
}
issue_4480: {
options = {
evaluate: true,
reduce_vars: true,
unused: true,
}
input: {
var a = function f(b) {
b = "FAIL";
arguments[0] = "PASS";
var arguments = 0;
console.log(b);
}(a);
}
expect: {
var a = function(b) {
b = "FAIL";
arguments[0] = "PASS";
var arguments = 0;
console.log(b);
}(a);
}
expect_stdout: "PASS"
}
issue_4552: {
options = {
evaluate: true,
keep_fnames: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = function f(b) {
return function() {
b++;
try {
return b;
} catch (e) {}
}();
}();
console.log(a);
}
expect: {
var a = function f(b) {
return function() {
b++;
try {
return b;
} catch (e) {}
}();
}();
console.log(a);
}
expect_stdout: "NaN"
}
issue_4886: {
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"
}

View File

@@ -0,0 +1,147 @@
precedence_1: {
input: {
console.log(-4 ** 3 ** 2);
}
expect_exact: "console.log((-4)**3**2);"
expect_stdout: "-262144"
node_version: ">=8"
}
precedence_2: {
input: {
console.log(-4 ** (3 ** 2));
}
expect_exact: "console.log((-4)**3**2);"
expect_stdout: "-262144"
node_version: ">=8"
}
precedence_3: {
input: {
console.log(-(4 ** 3) ** 2);
}
expect_exact: "console.log((-(4**3))**2);"
expect_stdout: "4096"
node_version: ">=8"
}
precedence_4: {
input: {
console.log((-4 ** 3) ** 2);
}
expect_exact: "console.log(((-4)**3)**2);"
expect_stdout: "4096"
node_version: ">=8"
}
await: {
input: {
(async a => a * await a ** ++a % a)(2).then(console.log);
}
expect_exact: "(async a=>a*(await a)**++a%a)(2).then(console.log);"
expect_stdout: "1"
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"
}
evaluate: {
options = {
evaluate: true,
}
input: {
console.log(1 + 2 ** 3 - 4);
}
expect: {
console.log(5);
}
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, 1073741824, 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"
}

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

@@ -0,0 +1,498 @@
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";'
}
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(){}"
}
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";
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -297,6 +297,33 @@ name_collision_3: {
expect_stdout: "true 4 6"
}
name_collision_4: {
options = {
hoist_props: true,
reduce_vars: true,
}
input: {
console.log(function() {
var o = {
p: 0,
q: "PASS",
};
return function(o_p) {
if (!o.p) return o_p;
}(o.q);
}());
}
expect: {
console.log(function() {
var o_p$0 = 0, o_q = "PASS";
return function(o_p) {
if (!o_p$0) return o_p;
}(o_q);
}());
}
expect_stdout: "PASS"
}
contains_this_1: {
options = {
evaluate: true,
@@ -750,6 +777,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,
@@ -1041,3 +1094,50 @@ 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_p = 42;
console.log(function() {
({});
}());
}
expect_stdout: "undefined"
}

View File

@@ -89,6 +89,31 @@ sequences_funs: {
}
}
catch_var: {
options = {
dead_code: true,
hoist_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var a = "PASS";
try {
a;
} catch (a) {
var a = 0;
a;
}
console.log(a);
}
expect: {
var a = "PASS";
console.log(a);
}
expect_stdout: "PASS"
}
issue_2295: {
options = {
collapse_vars: true,
@@ -109,3 +134,264 @@ issue_2295: {
}
}
}
issue_4487: {
options = {
functions: true,
hoist_vars: true,
keep_fnames: true,
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 f;
console.log(typeof f);
}
a();
}
expect_stdout: "undefined"
}
issue_4489: {
options = {
collapse_vars: true,
evaluate: true,
hoist_vars: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
A = 0;
var o = !0 || null;
for (var k in o);
console.log(k);
}
expect: {
!(A = 0);
for (var k in true);
console.log(k);
}
expect_stdout: "undefined"
}
issue_4517: {
options = {
collapse_vars: true,
hoist_vars: true,
join_vars: true,
reduce_vars: true,
unused: true,
}
input: {
console.log(function() {
var a = 2;
A = a;
var b = typeof !1;
return A + b;
}());
}
expect: {
console.log(function() {
var a = 2;
A = a;
return A + typeof !1;
}());
}
expect_stdout: "2boolean"
}
issue_4736: {
options = {
collapse_vars: true,
evaluate: true,
hoist_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(1073741824);
})();
})();
}
expect_stdout: "1073741824"
}
issue_4839: {
options = {
evaluate: true,
hoist_vars: true,
keep_fargs: false,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var o = function(a, b) {
return b && b;
}("foo");
for (var k in o)
throw "FAIL";
console.log("PASS");
}
expect: {
var k, o = void 0;
for (k in o)
throw "FAIL";
console.log("PASS");
}
expect_stdout: "PASS"
}
issue_4859: {
options = {
evaluate: true,
hoist_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) {
var d = 1 / 0, d = Infinity;
console.log(d);
return f;
})();
}
expect_stdout: "Infinity"
}
issue_4893_1: {
options = {
collapse_vars: true,
evaluate: true,
hoist_vars: true,
reduce_vars: 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 f() {
null.p += 42;
f;
})();
} 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() {
var b;
b = null;
b.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"
}

File diff suppressed because it is too large Load Diff

View File

@@ -594,3 +594,157 @@ iife_if_return_simple: {
}
expect_stdout: "PASS"
}
nested_if_break: {
options = {
if_return: true,
}
input: {
for (var i = 0; i < 3; i++)
L1: if ("number" == typeof i) {
if (0 === i) break L1;
console.log(i);
}
}
expect: {
for (var i = 0; i < 3; i++)
L1: if ("number" == typeof i)
if (0 !== i) console.log(i);
}
expect_stdout: [
"1",
"2",
]
}
nested_if_continue: {
options = {
conditionals: true,
if_return: true,
join_vars: true,
loops: true,
}
input: {
function f(n) {
var i = 0;
do {
if ("number" == typeof n) {
if (0 === n) {
console.log("even", i);
continue;
}
if (1 === n) {
console.log("odd", i);
continue;
}
i++;
}
} while (0 <= (n -= 2));
}
f(37);
f(42);
}
expect: {
function f(n) {
for (var i = 0;
"number" == typeof n
&& (0 !== n
? 1 !== n
? i++
: console.log("odd", i)
: console.log("even", i)),
0 <= (n -= 2););
}
f(37);
f(42);
}
expect_stdout: [
"odd 18",
"even 21",
]
}
nested_if_return: {
options = {
conditionals: true,
if_return: true,
}
input: {
function f() {
if (A) {
if (B)
return B;
if (C)
return D;
if (E)
return F;
if (G)
return H;
if (I) {
if (J)
return K;
return;
}
if (L) {
if (M)
return;
return N;
}
}
}
}
expect: {
function f() {
if (A)
return B || (C ? D : E ? F : G ? H : I ? J ? K : void 0 : L && !M ? N : void 0);
}
}
}
issue_866_1: {
options = {
conditionals: true,
if_return: true,
sequences: false,
};
input: {
function f(a) {
if (a)
return "";
console.log(a);
}
}
expect: {
function f(a) {
if (a)
return "";
console.log(a);
}
}
}
issue_866_2: {
options = {
conditionals: true,
if_return: true,
sequences: true,
}
input: {
(function() {
if (a)
if (b)
c;
else
return d;
})();
}
expect: {
(function() {
if (a) {
if (!b)
return d;
c;
}
})();
}
}

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

@@ -0,0 +1,213 @@
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";'
}
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);
}
}
mangle: {
rename = false
mangle = {
toplevel: true,
}
input: {
import foo, { bar } from "baz";
consoe.log(moo);
import * as moo from "moz";
}
expect: {
import o, { bar as m } from "baz";
consoe.log(r);
import * as r from "moz";
}
}
rename_mangle: {
rename = true
mangle = {
toplevel: true,
}
input: {
import foo, { bar } from "baz";
consoe.log(moo);
import * as moo from "moz";
}
expect: {
import o, { bar as m } from "baz";
consoe.log(r);
import * as r from "moz";
}
}
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";
}
}

View File

@@ -39,7 +39,7 @@ non_hoisted_function_after_return: {
"WARN: Dropping unreachable code [test/compress/issue-1034.js:4,16]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:7,16]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:10,12]",
"WARN: Dropping unused function UnusedFunction [test/compress/issue-1034.js:11,21]"
"WARN: Dropping unused function UnusedFunction [test/compress/issue-1034.js:11,21]",
]
}
@@ -84,19 +84,16 @@ non_hoisted_function_after_return_2a: {
}
}
expect_warnings: [
"WARN: Dropping unreachable code [test/compress/issue-1034.js:4,16]",
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:4,16]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:7,16]",
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:7,16]",
"WARN: Dropping initialization in unreachable code [test/compress/issue-1034.js:4,16]",
"WARN: Dropping initialization in unreachable code [test/compress/issue-1034.js:7,16]",
"WARN: Dropping unused variable a [test/compress/issue-1034.js:4,20]",
"WARN: Dropping unused function nope [test/compress/issue-1034.js:11,21]",
"INFO: pass 0: last_count: Infinity, count: 36",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:9,12]",
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:9,12]",
"INFO: pass 0: last_count: Infinity, count: 35",
"WARN: Dropping initialization in unreachable code [test/compress/issue-1034.js:9,12]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:12,12]",
"INFO: Dropping unused variable b [test/compress/issue-1034.js:7,20]",
"INFO: Dropping unused variable c [test/compress/issue-1034.js:9,16]",
"INFO: pass 1: last_count: 36, count: 18",
"INFO: pass 1: last_count: 35, count: 18",
]
}
@@ -138,10 +135,7 @@ non_hoisted_function_after_return_2b: {
}
}
expect_warnings: [
"WARN: Dropping unreachable code [test/compress/issue-1034.js:6,16]",
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:6,16]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:8,12]",
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:8,12]",
"WARN: Dropping initialization in unreachable code [test/compress/issue-1034.js:8,12]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:12,12]",
]
}
@@ -242,19 +236,16 @@ non_hoisted_function_after_return_2a_strict: {
}
expect_stdout: "5 6"
expect_warnings: [
"WARN: Dropping unreachable code [test/compress/issue-1034.js:5,16]",
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:5,16]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:8,16]",
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:8,16]",
"WARN: Dropping initialization in unreachable code [test/compress/issue-1034.js:5,16]",
"WARN: Dropping initialization in unreachable code [test/compress/issue-1034.js:8,16]",
"WARN: Dropping unused variable a [test/compress/issue-1034.js:5,20]",
"WARN: Dropping unused function nope [test/compress/issue-1034.js:12,21]",
"INFO: pass 0: last_count: Infinity, count: 47",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:10,12]",
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:10,12]",
"INFO: pass 0: last_count: Infinity, count: 46",
"WARN: Dropping initialization in unreachable code [test/compress/issue-1034.js:10,12]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:13,12]",
"INFO: Dropping unused variable b [test/compress/issue-1034.js:8,20]",
"INFO: Dropping unused variable c [test/compress/issue-1034.js:10,16]",
"INFO: pass 1: last_count: 47, count: 29",
"INFO: pass 1: last_count: 46, count: 29",
]
}
@@ -301,10 +292,7 @@ non_hoisted_function_after_return_2b_strict: {
}
expect_stdout: "5 6"
expect_warnings: [
"WARN: Dropping unreachable code [test/compress/issue-1034.js:7,16]",
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:7,16]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:9,12]",
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:9,12]",
"WARN: Dropping initialization in unreachable code [test/compress/issue-1034.js:9,12]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:13,12]",
]
}

View File

@@ -16,7 +16,7 @@ multiple_functions: {
( function() {
// NOTE: other compression steps will reduce this
// down to just `window`.
if ( window );
if ( !window );
function f() {}
function g() {}
} )();
@@ -38,7 +38,7 @@ single_function: {
}
expect: {
( function() {
if ( window );
if ( !window );
function f() {}
} )();
}
@@ -67,7 +67,7 @@ deeply_nested: {
// NOTE: other compression steps will reduce this
// down to just `window`.
if ( window )
if (document);
if ( !document );
function f() {}
function g() {}
function h() {}

View File

@@ -151,15 +151,18 @@ Infinity_not_in_with_scope: {
unused: true,
}
input: {
var o = { Infinity: 'oInfinity' };
var o = { Infinity: "FAIL" };
var vInfinity = "Infinity";
vInfinity = Infinity;
console.log(vInfinity);
}
expect: {
var o = { Infinity: 'oInfinity' }
var vInfinity = "Infinity"
vInfinity = 1/0
var o = { Infinity: "FAIL" };
var vInfinity = "Infinity";
vInfinity = 1/0;
console.log(vInfinity);
}
expect_stdout: "Infinity"
}
Infinity_in_with_scope: {
@@ -167,15 +170,18 @@ Infinity_in_with_scope: {
unused: true,
}
input: {
var o = { Infinity: 'oInfinity' };
var o = { Infinity: "PASS" };
var vInfinity = "Infinity";
with (o) { vInfinity = Infinity; }
console.log(vInfinity);
}
expect: {
var o = { Infinity: 'oInfinity' }
var vInfinity = "Infinity"
with (o) vInfinity = Infinity
var o = { Infinity: "PASS" };
var vInfinity = "Infinity";
with (o) vInfinity = Infinity;
console.log(vInfinity);
}
expect_stdout: "PASS"
}
assorted_Infinity_NaN_undefined_in_with_scope: {

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

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

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: {
@@ -371,7 +371,7 @@ mangle_catch_redef_3: {
mangle_catch_redef_3_toplevel: {
mangle = {
ie8: false,
ie: false,
toplevel: true,
}
input: {
@@ -394,7 +394,7 @@ mangle_catch_redef_3_toplevel: {
mangle_catch_redef_3_ie8: {
mangle = {
ie8: true,
ie: true,
toplevel: false,
}
input: {
@@ -417,7 +417,7 @@ mangle_catch_redef_3_ie8: {
mangle_catch_redef_3_ie8_toplevel: {
mangle = {
ie8: true,
ie: true,
toplevel: true,
}
input: {

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

@@ -17,7 +17,7 @@ issue_269_1: {
expect: {
var x = {};
console.log(
x + "", +x, !!x,
"" + x, +("" + x), !!x,
"", 0, false
);
}

View File

@@ -426,6 +426,7 @@ wrap_iife_in_return_call: {
pure_annotation_1: {
options = {
annotations: true,
inline: true,
side_effects: true,
}
@@ -439,6 +440,7 @@ pure_annotation_1: {
pure_annotation_2: {
options = {
annotations: true,
collapse_vars: true,
inline: true,
side_effects: true,
@@ -463,15 +465,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 +492,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

@@ -63,42 +63,81 @@ eval_unused: {
unused: true,
}
input: {
function f1(a, eval, c, d, e) {
return a('c') + eval;
}
function f2(a, b, c, d, e) {
return a + eval('c');
}
function f3(a, eval, c, d, e) {
return a + eval('c');
function o(k) {
return { c: 14 }[k];
}
console.log(function f1(a, eval, c, d, e) {
return a("c") + eval;
}(o, 28, true));
console.log(function f2(a, b, c, d, e) {
return a + eval("c");
}(14, true, 28));
console.log(function f3(a, eval, c, d, e) {
return a + eval("c");
}(28, o, true));
}
expect: {
function f1(a, eval) {
return a('c') + eval;
}
function f2(a, b, c, d, e) {
return a + eval('c');
}
function f3(a, eval, c, d, e) {
return a + eval('c');
function o(k) {
return { c: 14 }[k];
}
console.log(function(a, eval) {
return a("c") + eval;
}(o, 28));
console.log(function f2(a, b, c, d, e) {
return a + eval("c");
}(14, true, 28));
console.log(function f3(a, eval, c, d, e) {
return a + eval("c");
}(28, o, true));
}
expect_stdout: [
"42",
"42",
"42",
]
}
eval_mangle: {
mangle = {
};
input: {
function f1(a, eval, c, d, e) {
return a('c') + eval;
}
function f2(a, b, c, d, e) {
return a + eval('c');
}
function f3(a, eval, c, d, e) {
return a + eval('c');
}
mangle = {}
beautify = {
beautify: true,
}
expect_exact: 'function f1(n,c,e,a,f){return n("c")+c}function f2(a,b,c,d,e){return a+eval("c")}function f3(a,eval,c,d,e){return a+eval("c")}'
input: {
function o(k) {
return { cc: 14 }[k + "c"];
}
console.log(function f1(a, eval, c, d, e) {
return a("c") + eval;
}(o, 28, true));
console.log(function f2(a, b, c, d, e) {
return a + eval("c");
}(14, true, 28));
console.log(function f3(a, eval, c, d, e) {
return a + eval("c");
}(28, o, true));
}
expect_exact: [
"function o(o) {",
" return {",
" cc: 14",
' }[o + "c"];',
"}",
"",
"console.log(function o(c, e, n, r, t) {",
' return c("c") + e;',
"}(o, 28, true));",
"",
"console.log(function f2(a, b, c, d, e) {",
' return a + eval("c");',
"}(14, true, 28));",
"",
"console.log(function f3(a, eval, c, d, e) {",
' return a + eval("c");',
"}(28, o, true));",
]
expect_stdout: [
"42",
"42",
"42",
]
}

View File

@@ -277,8 +277,8 @@ join_object_assignments_forin: {
}
expect: {
console.log(function() {
var o = { a: "PASS" };
for (var a in o)
var o = { a: "PASS" }, a;
for (a in o)
return o[a];
}());
}
@@ -790,7 +790,7 @@ issue_3795: {
dead_code: true,
evaluate: true,
join_vars: true,
keep_fargs: "strict",
keep_fargs: false,
loops: true,
passes: 2,
reduce_vars: true,
@@ -1015,7 +1015,7 @@ issue_3856: {
console.log(function() {
(function() {
var a, b;
if (a) return !!a;
if (a) return a, 1;
for (a = 0; !console;);
return 0;
})();
@@ -1024,7 +1024,7 @@ issue_3856: {
expect_stdout: "undefined"
}
issue_3916: {
issue_3916_1: {
options = {
join_vars: true,
}
@@ -1044,8 +1044,8 @@ issue_3916: {
var o = {
p: "PASS",
__proto__: 42,
q: "FAIL",
};
o.q = "FAIL";
o.__proto__ = {
p: "FAIL",
q: "PASS",
@@ -1055,3 +1055,131 @@ 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;
console.log(a),
a++;
var b = 2, c = 3;
console.log(a, b, c);
}
expect_stdout: [
"0",
"1 2 3",
]
}

View File

@@ -18,43 +18,6 @@ keep_fargs_false: {
function j(e) {}
console.log(h(), i().length, j.length);
}
expect: {
console.log(function f() {
return f.length;
}(), function g() {
return g;
}().length);
function h() {
return h.length;
}
function i() {
return i;
}
function j() {}
console.log(h(), i().length, j.length);
}
}
keep_fargs_strict: {
options = {
keep_fargs: "strict",
unused: true,
}
input: {
console.log(function f(a) {
return f.length;
}(), function g(b) {
return g;
}().length);
function h(c) {
return h.length;
}
function i(d) {
return i;
}
function j(e) {}
console.log(h(), i().length, j.length);
}
expect: {
console.log(function f(a) {
return f.length;
@@ -117,61 +80,11 @@ keep_fargs_true: {
]
}
replace_index: {
options = {
arguments: true,
evaluate: true,
keep_fargs: "strict",
properties: true,
}
input: {
var arguments = [];
console.log(arguments[0]);
(function() {
console.log(arguments[1], arguments["1"], arguments["foo"]);
})("bar", 42);
(function(a, b) {
console.log(arguments[1], arguments["1"], arguments["foo"]);
})("bar", 42);
(function(arguments) {
console.log(arguments[1], arguments["1"], arguments["foo"]);
})("bar", 42);
(function() {
var arguments;
console.log(arguments[1], arguments["1"], arguments["foo"]);
})("bar", 42);
}
expect: {
var arguments = [];
console.log(arguments[0]);
(function(argument_0, argument_1) {
console.log(argument_1, argument_1, arguments.foo);
})("bar", 42);
(function(a, b) {
console.log(b, b, arguments.foo);
})("bar", 42);
(function(arguments) {
console.log(arguments[1], arguments[1], arguments.foo);
})("bar", 42);
(function() {
var arguments;
console.log(arguments[1], arguments[1], arguments.foo);
})("bar", 42);
}
expect_stdout: [
"undefined",
"42 42 undefined",
"42 42 undefined",
"a a undefined",
"42 42 undefined",
]
}
replace_index_strict: {
options = {
arguments: true,
evaluate: true,
keep_fargs: "strict",
keep_fargs: false,
properties: true,
reduce_vars: true,
}
@@ -202,8 +115,9 @@ replace_index_strict: {
issue_1858: {
options = {
collapse_vars: true,
keep_fargs: "strict",
keep_fargs: false,
pure_getters: true,
reduce_vars: true,
unused: true,
}
input: {
@@ -224,7 +138,7 @@ issue_1858: {
issue_2187_2: {
options = {
collapse_vars: true,
keep_fargs: "strict",
keep_fargs: false,
unused: true,
}
input: {
@@ -245,7 +159,7 @@ issue_2187_2: {
issue_2203_2: {
options = {
collapse_vars: true,
keep_fargs: "strict",
keep_fargs: false,
unused: true,
}
input: {
@@ -280,7 +194,7 @@ issue_2203_2: {
issue_2298: {
options = {
collapse_vars: true,
keep_fargs: "strict",
keep_fargs: false,
passes: 2,
reduce_funcs: true,
reduce_vars: true,
@@ -306,7 +220,6 @@ issue_2298: {
expect: {
!function() {
(function() {
0;
try {
!function() {
(void 0)[1] = "foo";
@@ -324,7 +237,7 @@ issue_2298: {
issue_2319_1: {
options = {
collapse_vars: true,
keep_fargs: "strict",
keep_fargs: false,
unused: true,
}
input: {
@@ -347,7 +260,7 @@ issue_2319_1: {
issue_2319_2: {
options = {
collapse_vars: true,
keep_fargs: "strict",
keep_fargs: false,
unused: true,
}
input: {
@@ -372,7 +285,7 @@ issue_2319_2: {
issue_2319_3: {
options = {
collapse_vars: true,
keep_fargs: "strict",
keep_fargs: false,
unused: true,
}
input: {
@@ -397,7 +310,7 @@ issue_2319_3: {
issue_2425_1: {
options = {
collapse_vars: true,
keep_fargs: "strict",
keep_fargs: false,
unused: true,
}
input: {
@@ -420,7 +333,7 @@ issue_2425_1: {
issue_2425_2: {
options = {
collapse_vars: true,
keep_fargs: "strict",
keep_fargs: false,
unused: true,
}
input: {
@@ -443,7 +356,7 @@ issue_2425_2: {
issue_2425_3: {
options = {
collapse_vars: true,
keep_fargs: "strict",
keep_fargs: false,
unused: true,
}
input: {
@@ -466,7 +379,7 @@ issue_2425_3: {
issue_2436_13: {
options = {
collapse_vars: true,
keep_fargs: "strict",
keep_fargs: false,
passes: 2,
reduce_vars: true,
unused: true,
@@ -500,7 +413,7 @@ issue_2436_13: {
issue_2506: {
options = {
collapse_vars: true,
keep_fargs: "strict",
keep_fargs: false,
passes: 2,
reduce_vars: true,
unused: true,
@@ -539,7 +452,7 @@ issue_2506: {
issue_2226_1: {
options = {
keep_fargs: "strict",
keep_fargs: false,
side_effects: true,
unused: true,
}
@@ -586,7 +499,7 @@ issue_2226_1: {
issue_2226_2: {
options = {
collapse_vars: true,
keep_fargs: "strict",
keep_fargs: false,
sequences: true,
side_effects: true,
unused: true,
@@ -608,7 +521,7 @@ issue_2226_2: {
issue_2226_3: {
options = {
collapse_vars: true,
keep_fargs: "strict",
keep_fargs: false,
side_effects: true,
unused: true,
}
@@ -628,7 +541,7 @@ issue_2226_3: {
issue_3192: {
options = {
keep_fargs: "strict",
keep_fargs: false,
unused: true,
}
input: {
@@ -658,7 +571,7 @@ issue_3192: {
if_increment: {
options = {
evaluate: true,
keep_fargs: "strict",
keep_fargs: false,
reduce_vars: true,
unused: true,
}
@@ -680,7 +593,7 @@ if_increment: {
try_increment: {
options = {
evaluate: true,
keep_fargs: "strict",
keep_fargs: false,
reduce_vars: true,
unused: true,
}
@@ -704,7 +617,7 @@ try_increment: {
issue_2630_3: {
options = {
inline: true,
keep_fargs: "strict",
keep_fargs: false,
reduce_vars: true,
unused: true,
}
@@ -741,7 +654,7 @@ issue_2630_3: {
issue_3364: {
options = {
functions: true,
keep_fargs: "strict",
keep_fargs: false,
reduce_vars: true,
toplevel: true,
unused: true,
@@ -806,7 +719,7 @@ issue_3364: {
defun_label: {
options = {
keep_fargs: "strict",
keep_fargs: false,
passes: 2,
reduce_funcs: true,
reduce_vars: true,
@@ -838,7 +751,7 @@ defun_label: {
iife_func_side_effects: {
options = {
keep_fargs: "strict",
keep_fargs: false,
reduce_funcs: true,
reduce_vars: true,
unused: true,
@@ -890,7 +803,7 @@ iife_func_side_effects: {
issue_1595_1: {
options = {
evaluate: true,
keep_fargs: "strict",
keep_fargs: false,
reduce_funcs: true,
reduce_vars: true,
unused: true,
@@ -910,7 +823,7 @@ issue_1595_1: {
issue_1595_2: {
options = {
evaluate: true,
keep_fargs: "strict",
keep_fargs: false,
reduce_funcs: true,
reduce_vars: true,
unused: true,
@@ -930,7 +843,7 @@ issue_1595_2: {
issue_1595_3: {
options = {
evaluate: true,
keep_fargs: "strict",
keep_fargs: false,
passes: 2,
reduce_funcs: true,
reduce_vars: true,
@@ -951,7 +864,7 @@ issue_1595_3: {
issue_1595_4: {
options = {
evaluate: true,
keep_fargs: "strict",
keep_fargs: false,
reduce_funcs: true,
reduce_vars: true,
unused: true,
@@ -973,7 +886,7 @@ issue_1595_4: {
duplicate_lambda_defun_name_1: {
options = {
keep_fargs: "strict",
keep_fargs: false,
reduce_vars: true,
}
input: {
@@ -993,7 +906,7 @@ duplicate_lambda_defun_name_1: {
duplicate_lambda_defun_name_2: {
options = {
keep_fargs: "strict",
keep_fargs: false,
passes: 2,
reduce_vars: true,
unused: true,
@@ -1014,7 +927,7 @@ duplicate_lambda_defun_name_2: {
function_name_mangle: {
options = {
keep_fargs: "strict",
keep_fargs: false,
keep_fnames: true,
reduce_vars: true,
unused: true,
@@ -1032,13 +945,13 @@ function_name_mangle: {
function_name_mangle_ie8: {
options = {
keep_fargs: "strict",
keep_fargs: false,
keep_fnames: true,
reduce_vars: true,
unused: true,
}
mangle = {
ie8: true,
ie: true,
toplevel: true,
}
input: {
@@ -1053,7 +966,7 @@ function_name_mangle_ie8: {
issue_3420_1: {
options = {
keep_fargs: "strict",
keep_fargs: false,
unused: true,
}
input: {
@@ -1076,7 +989,7 @@ issue_3420_1: {
issue_3420_2: {
options = {
inline: true,
keep_fargs: "strict",
keep_fargs: false,
unused: true,
}
input: {
@@ -1097,7 +1010,7 @@ issue_3420_2: {
issue_3420_3: {
options = {
inline: true,
keep_fargs: "strict",
keep_fargs: false,
reduce_vars: true,
unused: true,
}
@@ -1119,7 +1032,7 @@ issue_3420_3: {
issue_3423_1: {
options = {
keep_fargs: "strict",
keep_fargs: false,
unused: true,
}
input: {
@@ -1139,7 +1052,7 @@ issue_3423_1: {
issue_3423_2: {
options = {
keep_fargs: "strict",
keep_fargs: false,
unused: true,
}
input: {
@@ -1166,7 +1079,7 @@ collapse_vars_repeated: {
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: "strict",
keep_fargs: false,
loops: true,
properties: true,
reduce_funcs: true,
@@ -1213,7 +1126,7 @@ collapse_vars_repeated: {
chained_3: {
options = {
collapse_vars: true,
keep_fargs: "strict",
keep_fargs: false,
unused: true,
}
input: {
@@ -1237,7 +1150,7 @@ replace_all_var_scope: {
rename = true
options = {
collapse_vars: true,
keep_fargs: "strict",
keep_fargs: false,
unused: true,
}
mangle = {}
@@ -1245,8 +1158,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);
@@ -1255,8 +1168,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);
@@ -1266,7 +1179,7 @@ replace_all_var_scope: {
issue_1583: {
options = {
keep_fargs: "strict",
keep_fargs: false,
passes: 2,
reduce_funcs: true,
reduce_vars: true,
@@ -1303,7 +1216,7 @@ issues_3267_1: {
dead_code: true,
evaluate: true,
inline: true,
keep_fargs: "strict",
keep_fargs: false,
reduce_vars: true,
sequences: true,
side_effects: true,
@@ -1332,7 +1245,7 @@ issues_3267_1: {
trailing_argument_side_effects: {
options = {
keep_fargs: "strict",
keep_fargs: false,
unused: true,
}
input: {
@@ -1356,7 +1269,7 @@ trailing_argument_side_effects: {
recursive_iife_1: {
options = {
keep_fargs: "strict",
keep_fargs: false,
reduce_vars: true,
unused: true,
}
@@ -1375,7 +1288,7 @@ recursive_iife_1: {
recursive_iife_2: {
options = {
keep_fargs: "strict",
keep_fargs: false,
reduce_vars: true,
unused: true,
}
@@ -1453,3 +1366,37 @@ issue_3619: {
}
expect_stdout: "PASS"
}
issue_4353_1: {
options = {
keep_fargs: false,
reduce_vars: true,
unused: true,
}
input: {
console.log(function f(a) {}.length);
}
expect: {
console.log(function(a) {}.length);
}
expect_stdout: "1"
}
issue_4353_2: {
options = {
keep_fargs: false,
reduce_vars: true,
unused: true,
}
input: {
(function f(a) {
while (console.log("PASS"));
})();
}
expect: {
(function() {
while (console.log("PASS"));
})();
}
expect_stdout: "PASS"
}

View File

@@ -207,3 +207,123 @@ labels_10: {
}
}
}
issue_4466_1: {
mangle = {
v8: false,
}
input: {
A: if (console.log("PASS"))
B:;
else
C:;
}
expect: {
e: if (console.log("PASS"))
l:;
else
l:;
}
expect_stdout: "PASS"
node_version: ">=12"
}
issue_4466_1_v8: {
mangle = {
v8: true,
}
input: {
A: if (console.log("PASS"))
B:;
else
C:;
}
expect: {
e: if (console.log("PASS"))
l:;
else
o:;
}
expect_stdout: "PASS"
node_version: ">=12"
}
issue_4466_2: {
mangle = {
toplevel: false,
v8: false,
}
input: {
if (console.log("PASS"))
A:;
else
B:;
}
expect: {
if (console.log("PASS"))
e:;
else
e:;
}
expect_stdout: "PASS"
}
issue_4466_2_v8: {
mangle = {
toplevel: false,
v8: true,
}
input: {
if (console.log("PASS"))
A:;
else
B:;
}
expect: {
if (console.log("PASS"))
e:;
else
l:;
}
expect_stdout: "PASS"
}
issue_4466_2_toplevel: {
mangle = {
toplevel: true,
v8: false,
}
input: {
if (console.log("PASS"))
A:;
else
B:;
}
expect: {
if (console.log("PASS"))
e:;
else
e:;
}
expect_stdout: "PASS"
}
issue_4466_2_toplevel_v8: {
mangle = {
toplevel: true,
v8: true,
}
input: {
if (console.log("PASS"))
A:;
else
B:;
}
expect: {
if (console.log("PASS"))
e:;
else
e:;
}
expect_stdout: "PASS"
}

1749
test/compress/let.js Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -193,15 +193,15 @@ evaluate: {
} while (false);
}
expect: {
for(;;)
for (;;)
a();
for(;;)
for (;;)
c();
d();
}
}
issue_1532: {
issue_1532_1: {
options = {
evaluate: true,
loops: true,
@@ -210,24 +210,62 @@ issue_1532: {
function f(x, y) {
do {
if (x) break;
foo();
console.log(y);
} while (false);
}
f(null, "PASS");
f(42, "FAIL");
}
expect: {
function f(x, y) {
for (; !x && (console.log(y), false););
}
f(null, "PASS");
f(42, "FAIL");
}
expect_stdout: "PASS"
}
issue_1532_2: {
options = {
evaluate: true,
loops: true,
}
input: {
function f(x, y) {
do {
if (x) {
console.log(x);
break;
}
console.log(y);
} while (false);
}
f(null, "PASS");
f(42, "FAIL");
}
expect: {
function f(x, y) {
do {
if (x) break;
foo();
} while (false);
if (x) {
console.log(x);
break;
}
} while (console.log(y), false);
}
f(null, "PASS");
f(42, "FAIL");
}
expect_stdout: [
"PASS",
"42",
]
}
issue_186: {
beautify = {
beautify: false,
ie8: false,
ie: false,
}
input: {
var x = 3;
@@ -246,7 +284,7 @@ issue_186: {
issue_186_ie8: {
beautify = {
beautify: false,
ie8: true,
ie: true,
}
input: {
var x = 3;
@@ -265,7 +303,7 @@ issue_186_ie8: {
issue_186_beautify: {
beautify = {
beautify: true,
ie8: false,
ie: false,
}
input: {
var x = 3;
@@ -292,7 +330,7 @@ issue_186_beautify: {
issue_186_beautify_ie8: {
beautify = {
beautify: true,
ie8: true,
ie: true,
}
input: {
var x = 3;
@@ -322,7 +360,7 @@ issue_186_braces: {
beautify = {
beautify: false,
braces: true,
ie8: false,
ie: false,
}
input: {
var x = 3;
@@ -342,7 +380,7 @@ issue_186_braces_ie8: {
beautify = {
beautify: false,
braces: true,
ie8: true,
ie: true,
}
input: {
var x = 3;
@@ -362,7 +400,7 @@ issue_186_beautify_braces: {
beautify = {
beautify: true,
braces: true,
ie8: false,
ie: false,
}
input: {
var x = 3;
@@ -394,7 +432,7 @@ issue_186_beautify_braces_ie8: {
beautify = {
beautify: true,
braces: true,
ie8: true,
ie: true,
}
input: {
var x = 3;
@@ -463,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;);
}
@@ -509,8 +547,8 @@ dead_code_condition: {
console.log(a);
}
expect: {
var c;
var a = 0, b = 5;
var c;
a += 1, 0,
console.log(a);
}
@@ -756,10 +794,78 @@ empty_for_in_side_effects: {
expect_warnings: [
"WARN: Dropping unused variable b [test/compress/loops.js:4,16]",
"INFO: Dropping unused loop variable a [test/compress/loops.js:1,17]",
"WARN: Side effects in object of for-in loop [test/compress/loops.js:1,17]",
"WARN: Side effects in object of for-in loop [test/compress/loops.js:2,17]",
]
}
empty_for_in_prop_init: {
options = {
loops: true,
pure_getters: "strict",
unused: true,
}
input: {
console.log(function f() {
var a = "bar";
for ((a, f)[a] in console.log("foo"));
return a;
}());
}
expect: {
console.log(function() {
var a = "bar";
console.log("foo");
return a;
}());
}
expect_stdout: [
"foo",
"bar",
]
expect_warnings: [
"INFO: Dropping unused loop variable f [test/compress/loops.js:3,21]",
"WARN: Side effects in object of for-in loop [test/compress/loops.js:3,30]",
]
}
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,
@@ -933,3 +1039,312 @@ issue_3634_2: {
}
expect_stdout: "1"
}
issue_4075: {
options = {
loops: true,
unused: true,
}
input: {
var a = "FAIL";
(function() {
for (a in { PASS: 0 });
})()
console.log(a);
}
expect: {
var a = "FAIL";
(function() {
for (a in { PASS: 0 });
})()
console.log(a);
}
expect_stdout: "PASS"
}
issue_4082: {
options = {
keep_fargs: false,
loops: true,
unused: true,
}
input: {
var a = "PASS";
(function(a) {
for (a in "foo")
var b;
})();
console.log(a);
}
expect: {
var a = "PASS";
(function(a) {
for (a in "foo");
})();
console.log(a);
}
expect_stdout: "PASS"
}
issue_4084: {
options = {
keep_fargs: false,
loops: true,
reduce_vars: true,
unused: true,
}
input: {
console.log(function() {
function f(a) {
var b = a++;
for (a in "foo");
}
f();
return typeof a;
}());
}
expect: {
console.log(function() {
(function() {
0;
})();
return typeof a;
}());
}
expect_stdout: "undefined"
}
issue_4091_1: {
options = {
loops: true,
toplevel: true,
unused: true,
}
input: {
try {
throw "FAIL";
} catch (e) {
for (var e in 42);
}
console.log(e && e);
}
expect: {
try {
throw "FAIL";
} catch (e) {
var e;
}
console.log(e && e);
}
expect_stdout: "undefined"
}
issue_4091_2: {
options = {
loops: true,
toplevel: true,
unused: true,
}
input: {
try {
throw "FAIL";
} catch (e) {
for (e in 42);
var e;
}
console.log(e && e);
}
expect: {
try {
throw "FAIL";
} catch (e) {
var e;
}
console.log(e && e);
}
expect_stdout: "undefined"
}
issue_4182_1: {
options = {
loops: true,
}
input: {
(function() {
do {
try {
return;
} finally {
continue;
}
console.log("FAIL");
} while (0);
console.log("PASS");
})();
}
expect: {
(function() {
do {
try {
return;
} finally {
continue;
}
console.log("FAIL");
} while (0);
console.log("PASS");
})();
}
expect_stdout: "PASS"
}
issue_4182_2: {
options = {
loops: true,
}
input: {
(function() {
L: do {
do {
try {
return;
} finally {
continue L;
}
console.log("FAIL");
} while (0);
console.log("FAIL");
} while (0);
console.log("PASS");
})();
}
expect: {
(function() {
L: do {
do {
try {
return;
} finally {
continue L;
}
} while (console.log("FAIL"), 0);
console.log("FAIL");
} while (0);
console.log("PASS");
})();
}
expect_stdout: "PASS"
}
do_continue: {
options = {
loops: true,
}
input: {
try {
do {
continue;
} while ([ A ]);
} catch (e) {
console.log("PASS");
}
}
expect: {
try {
do {
continue;
} while ([ A ]);
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "PASS"
}
issue_4240: {
options = {
loops: true,
reduce_funcs: true,
reduce_vars: true,
unused: true,
}
input: {
(function(a) {
function f() {
var o = { PASS: 42 };
for (a in o);
}
(function() {
if (f());
})();
console.log(a);
})();
}
expect: {
(function(a) {
(function() {
if (function() {
for (a in { PASS: 42 });
}());
})();
console.log(a);
})();
}
expect_stdout: "PASS"
}
issue_4355: {
options = {
dead_code: true,
evaluate: true,
loops: true,
passes: 2,
side_effects: true,
unused: true,
}
input: {
while (function() {
var a;
for (a in console.log("PASS"))
var b = 0;
}())
var c;
}
expect: {
(function() {
console.log("PASS");
})();
var c;
}
expect_stdout: "PASS"
}
issue_4564: {
options = {
loops: true,
unused: true,
}
input: {
try {
throw null;
} catch (a) {
var a;
(function() {
for (a in "foo");
})();
console.log(a);
}
}
expect: {
try {
throw null;
} catch (a) {
var a;
(function() {
for (a in "foo");
})();
console.log(a);
}
}
expect_stdout: "2"
}

3379
test/compress/merge_vars.js Normal file

File diff suppressed because it is too large Load Diff

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);
}

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

@@ -0,0 +1,282 @@
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"
}
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"
}

View File

@@ -1,49 +1,141 @@
hex_numbers_in_parentheses_for_prototype_functions: {
literal_infinity: {
input: {
console.log(2e308, -1e2345);
}
expect_exact: "console.log(1/0,-(1/0));"
}
parentheses_for_prototype_functions: {
beautify = {
beautify: true,
}
input: {
function f() {
(-2);
(-2).toFixed(0);
(function() {
console.log((-2));
console.log((-2).toFixed(0));
(2);
(2).toFixed(0);
console.log((2));
console.log((2).toFixed(0));
(0.2);
(0.2).toFixed(0);
console.log((0.2));
console.log((0.2).toFixed(0));
(2.34e20);
(2.34e20).toFixed(0);
console.log((2.34e20));
console.log((2.34e20).toFixed(0));
(0.00000002);
(0.00000002).toFixed(0);
console.log((0.00000002));
console.log((0.00000002).toFixed(0));
(1000000000000000128);
(1000000000000000128).toFixed(0);
console.log((1000000000000000128));
console.log((1000000000000000128).toFixed(0));
(-1000000000000000128);
(-1000000000000000128).toFixed(0);
}
console.log((-1000000000000000128));
console.log((-1000000000000000128).toFixed(0));
})();
}
expect_exact: [
"function f() {",
" -2;",
" (-2).toFixed(0);",
" 2;",
" 2..toFixed(0);",
" .2;",
" .2.toFixed(0);",
" 234e18;",
" 234e18.toFixed(0);",
" 2e-8;",
" 2e-8.toFixed(0);",
" 0xde0b6b3a7640080;",
" (0xde0b6b3a7640080).toFixed(0);",
" -0xde0b6b3a7640080;",
" (-0xde0b6b3a7640080).toFixed(0);",
"}",
"(function() {",
" console.log(-2);",
" console.log((-2).toFixed(0));",
" console.log(2);",
" console.log(2..toFixed(0));",
" console.log(.2);",
" console.log(.2.toFixed(0));",
" console.log(234e18);",
" console.log(234e18.toFixed(0));",
" console.log(2e-8);",
" console.log(2e-8.toFixed(0));",
" console.log(0xde0b6b3a7640080);",
" console.log(0xde0b6b3a7640080.toFixed(0));",
" console.log(-0xde0b6b3a7640080);",
" console.log((-0xde0b6b3a7640080).toFixed(0));",
"})();",
]
expect_stdout: true
}
parentheses_for_prototype_functions_galio: {
beautify = {
beautify: true,
galio: true,
}
input: {
(function() {
console.log((-2));
console.log((-2).toFixed(0));
console.log((2));
console.log((2).toFixed(0));
console.log((0.2));
console.log((0.2).toFixed(0));
console.log((2.34e20));
console.log((2.34e20).toFixed(0));
console.log((0.00000002));
console.log((0.00000002).toFixed(0));
console.log((1000000000000000128));
console.log((1000000000000000128).toFixed(0));
console.log((-1000000000000000128));
console.log((-1000000000000000128).toFixed(0));
})();
}
expect_exact: [
"(function() {",
" console.log(-2);",
" console.log((-2).toFixed(0));",
" console.log(2);",
" console.log(2..toFixed(0));",
" console.log(.2);",
" console.log(.2.toFixed(0));",
" console.log(234e18);",
" console.log(234e18.toFixed(0));",
" console.log(2e-8);",
" console.log(2e-8.toFixed(0));",
" console.log(0xde0b6b3a7640080);",
" console.log((0xde0b6b3a7640080).toFixed(0));",
" console.log(-0xde0b6b3a7640080);",
" console.log((-0xde0b6b3a7640080).toFixed(0));",
"})();",
]
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: {
@@ -91,7 +183,7 @@ evaluate_1: {
expect: {
console.log(
x + 1 + 2,
2 * x,
2 * +x,
+x + 1 + 2,
1 + x + 2 + 3,
3 | x,
@@ -130,7 +222,7 @@ evaluate_1_unsafe_math: {
expect: {
console.log(
x + 1 + 2,
2 * x,
2 * +x,
+x + 3,
1 + x + 2 + 3,
3 | x,
@@ -148,45 +240,52 @@ evaluate_1_unsafe_math: {
evaluate_2: {
options = {
evaluate: true,
reduce_vars: true,
unsafe_math: false,
}
input: {
var x = "42", y = null;
[
x + 1 + 2,
x * 1 * 2,
+x + 1 + 2,
1 + x + 2 + 3,
1 | x | 2 | 3,
1 + x-- + 2 + 3,
1 + (x*y + 2) + 3,
1 + (2 + x + 3),
1 + (2 + ~x + 3),
-y + (2 + ~x + 3),
1 & (2 & x & 3),
1 + (2 + (x |= 0) + 3),
].forEach(function(n) {
console.log(typeof n, n);
});
function f(num) {
var x = "" + num, y = null;
[
x + 1 + 2,
x * 1 * 2,
+x + 1 + 2,
1 + x + 2 + 3,
1 | x | 2 | 3,
1 + x-- + 2 + 3,
1 + (x*y + 2) + 3,
1 + (2 + x + 3),
1 + (2 + ~x + 3),
-y + (2 + ~x + 3),
1 & (2 & x & 3),
1 + (2 + (x |= 0) + 3),
].forEach(function(n) {
console.log(typeof n, n);
});
}
f(42);
}
expect: {
var x = "42", y = null;
[
x + 1 + 2,
2 * x,
+x + 1 + 2,
1 + x + 2 + 3,
3 | x,
1 + x-- + 2 + 3,
x*y + 2 + 1 + 3,
1 + (2 + x + 3),
2 + ~x + 3 + 1,
2 + ~x + 3 - y,
0 & x,
2 + (x |= 0) + 3 + 1,
].forEach(function(n) {
console.log(typeof n, n);
});
function f(num) {
var x = "" + num, y = null;
[
x + "12",
2 * x,
+x + 1 + 2,
1 + x + "23",
3 | x,
1 + x-- + 2 + 3,
x*y + 2 + 1 + 3,
2 + x + 3 + 1,
2 + ~x + 3 + 1,
2 + ~x + 3,
0 & x,
2 + (x |= 0) + 3 + 1,
].forEach(function(n) {
console.log(typeof n, n);
});
}
f(42);
}
expect_stdout: [
"string 4212",
@@ -207,45 +306,52 @@ evaluate_2: {
evaluate_2_unsafe_math: {
options = {
evaluate: true,
reduce_vars: true,
unsafe_math: true,
}
input: {
var x = "42", y = null;
[
x + 1 + 2,
x * 1 * 2,
+x + 1 + 2,
1 + x + 2 + 3,
1 | x | 2 | 3,
1 + x-- + 2 + 3,
1 + (x*y + 2) + 3,
1 + (2 + x + 3),
1 + (2 + ~x + 3),
-y + (2 + ~x + 3),
1 & (2 & x & 3),
1 + (2 + (x |= 0) + 3),
].forEach(function(n) {
console.log(typeof n, n);
});
function f(num) {
var x = "" + num, y = null;
[
x + 1 + 2,
x * 1 * 2,
+x + 1 + 2,
1 + x + 2 + 3,
1 | x | 2 | 3,
1 + x-- + 2 + 3,
1 + (x*y + 2) + 3,
1 + (2 + x + 3),
1 + (2 + ~x + 3),
-y + (2 + ~x + 3),
1 & (2 & x & 3),
1 + (2 + (x |= 0) + 3),
].forEach(function(n) {
console.log(typeof n, n);
});
}
f(42);
}
expect: {
var x = "42", y = null;
[
x + 1 + 2,
2 * x,
+x + 3,
1 + x + 2 + 3,
3 | x,
6 + x--,
x*y + 6,
1 + (2 + x + 3),
6 + ~x,
5 + ~x - y,
0 & x,
6 + (x |= 0),
].forEach(function(n) {
console.log(typeof n, n);
});
function f(num) {
var x = "" + num, y = null;
[
x + "12",
2 * x,
+x + 3,
1 + x + "23",
3 | x,
6 + x--,
x*y + 6,
6 + x,
6 + ~x,
5 + ~x,
0 & x,
6 + (x |= 0),
].forEach(function(n) {
console.log(typeof n, n);
});
}
f(42);
}
expect_stdout: [
"string 4212",
@@ -273,7 +379,7 @@ evaluate_3: {
console.log(1 + Number(x) + 2);
}
expect: {
console.log(+x + 3);
console.log(+("" + x) + 3);
}
}
@@ -310,45 +416,52 @@ evaluate_4: {
evaluate_5: {
options = {
evaluate: true,
reduce_vars: true,
unsafe_math: false,
}
input: {
var a = "1";
[
+a + 2 + 3,
+a + 2 - 3,
+a - 2 + 3,
+a - 2 - 3,
2 + +a + 3,
2 + +a - 3,
2 - +a + 3,
2 - +a - 3,
2 + 3 + +a,
2 + 3 - +a,
2 - 3 + +a,
2 - 3 - +a,
].forEach(function(n) {
console.log(typeof n, n);
});
function f(num) {
var a = "" + num;
[
+a + 2 + 3,
+a + 2 - 3,
+a - 2 + 3,
+a - 2 - 3,
2 + +a + 3,
2 + +a - 3,
2 - +a + 3,
2 - +a - 3,
2 + 3 + +a,
2 + 3 - +a,
2 - 3 + +a,
2 - 3 - +a,
].forEach(function(n) {
console.log(typeof n, n);
});
}
f(1);
}
expect: {
var a = "1";
[
+a + 2 + 3,
+a + 2 - 3,
a - 2 + 3,
a - 2 - 3,
+a + 2 + 3,
+a + 2 - 3,
2 - a + 3,
2 - a - 3,
+a + 5,
5 - a,
+a - 1,
-1 - a,
].forEach(function(n) {
console.log(typeof n, n);
});
function f(num) {
var a = "" + num;
[
+a + 2 + 3,
+a + 2 - 3,
a - 2 + 3,
a - 2 - 3,
+a + 2 + 3,
+a + 2 - 3,
2 - a + 3,
2 - a - 3,
+a + 5,
5 - a,
+a - 1,
-1 - a,
].forEach(function(n) {
console.log(typeof n, n);
});
}
f(1);
}
expect_stdout: [
"number 6",
@@ -369,45 +482,52 @@ evaluate_5: {
evaluate_5_unsafe_math: {
options = {
evaluate: true,
reduce_vars: true,
unsafe_math: true,
}
input: {
var a = "1";
[
+a + 2 + 3,
+a + 2 - 3,
+a - 2 + 3,
+a - 2 - 3,
2 + +a + 3,
2 + +a - 3,
2 - +a + 3,
2 - +a - 3,
2 + 3 + +a,
2 + 3 - +a,
2 - 3 + +a,
2 - 3 - +a,
].forEach(function(n) {
console.log(typeof n, n);
});
function f(num) {
var a = "" + num;
[
+a + 2 + 3,
+a + 2 - 3,
+a - 2 + 3,
+a - 2 - 3,
2 + +a + 3,
2 + +a - 3,
2 - +a + 3,
2 - +a - 3,
2 + 3 + +a,
2 + 3 - +a,
2 - 3 + +a,
2 - 3 - +a,
].forEach(function(n) {
console.log(typeof n, n);
});
}
f(1);
}
expect: {
var a = "1";
[
+a + 5,
+a + -1,
a - -1,
a - 5,
+a + 5,
+a + -1,
5 - a,
-1 - a,
+a + 5,
5 - a,
+a - 1,
-1 - a,
].forEach(function(n) {
console.log(typeof n, n);
});
function f(num) {
var a = "" + num;
[
+a + 5,
+a + -1,
a - -1,
a - 5,
+a + 5,
+a + -1,
5 - a,
-1 - a,
+a + 5,
5 - a,
+a - 1,
-1 - a,
].forEach(function(n) {
console.log(typeof n, n);
});
}
f(1);
}
expect_stdout: [
"number 6",
@@ -546,37 +666,44 @@ evaluate_6_unsafe_math: {
evaluate_7: {
options = {
evaluate: true,
reduce_vars: true,
unsafe_math: false,
}
input: {
var x = "42", y;
[
+x + 2 + (3 + !y),
+x + 2 + (3 - !y),
+x + 2 - (3 + !y),
+x + 2 - (3 - !y),
+x - 2 + (3 + !y),
+x - 2 + (3 - !y),
+x - 2 - (3 + !y),
+x - 2 - (3 - !y),
].forEach(function(n) {
console.log(typeof n, n);
});
function f(num, y) {
var x = "" + num;
[
+x + 2 + (3 + !y),
+x + 2 + (3 - !y),
+x + 2 - (3 + !y),
+x + 2 - (3 - !y),
+x - 2 + (3 + !y),
+x - 2 + (3 - !y),
+x - 2 - (3 + !y),
+x - 2 - (3 - !y),
].forEach(function(n) {
console.log(typeof n, n);
});
}
f(42);
}
expect: {
var x = "42", y;
[
+x + 2 + (3 + !y),
+x + 2 + (3 - !y),
+x + 2 - (3 + !y),
+x + 2 - (3 - !y),
x - 2 + (3 + !y),
x - 2 + (3 - !y),
x - 2 - (3 + !y),
x - 2 - (3 - !y),
].forEach(function(n) {
console.log(typeof n, n);
});
function f(num, y) {
var x = "" + num;
[
+x + 2 + (3 + !y),
+x + 2 + (3 - !y),
+x + 2 - (3 + !y),
+x + 2 - (3 - !y),
x - 2 + (3 + !y),
x - 2 + (3 - !y),
x - 2 - (3 + !y),
x - 2 - (3 - !y),
].forEach(function(n) {
console.log(typeof n, n);
});
}
f(42);
}
expect_stdout: [
"number 48",
@@ -593,37 +720,44 @@ evaluate_7: {
evaluate_7_unsafe_math: {
options = {
evaluate: true,
reduce_vars: true,
unsafe_math: true,
}
input: {
var x = "42", y;
[
+x + 2 + (3 + !y),
+x + 2 + (3 - !y),
+x + 2 - (3 + !y),
+x + 2 - (3 - !y),
+x - 2 + (3 + !y),
+x - 2 + (3 - !y),
+x - 2 - (3 + !y),
+x - 2 - (3 - !y),
].forEach(function(n) {
console.log(typeof n, n);
});
function f(num, y) {
var x = "" + num;
[
+x + 2 + (3 + !y),
+x + 2 + (3 - !y),
+x + 2 - (3 + !y),
+x + 2 - (3 - !y),
+x - 2 + (3 + !y),
+x - 2 + (3 - !y),
+x - 2 - (3 + !y),
+x - 2 - (3 - !y),
].forEach(function(n) {
console.log(typeof n, n);
});
}
f(42);
}
expect: {
var x = "42", y;
[
+x + 5 + !y,
+x + 5 - !y,
+x + -1 - !y,
+x + -1 + !y,
x - -1 + !y,
x - -1 - !y,
x - 5 - !y,
x - 5 + !y,
].forEach(function(n) {
console.log(typeof n, n);
});
function f(num, y) {
var x = "" + num;
[
+x + 5 + !y,
+x + 5 - !y,
+x + -1 - !y,
+x + -1 + !y,
x - -1 + !y,
x - -1 - !y,
x - 5 - !y,
x - 5 + !y,
].forEach(function(n) {
console.log(typeof n, n);
});
}
f(42);
}
expect_stdout: [
"number 48",
@@ -637,6 +771,22 @@ evaluate_7_unsafe_math: {
]
}
evaluate_8_unsafe_math: {
options = {
evaluate: true,
unsafe_math: true,
}
input: {
var a = [ "42" ];
console.log(a * (1 / 7));
}
expect: {
var a = [ "42" ];
console.log(+a / 7);
}
expect_stdout: "6"
}
NaN_redefined: {
options = {
evaluate: true,
@@ -668,7 +818,7 @@ issue_1710: {
expect_stdout: true
}
unary_binary_parenthesis: {
unary_binary_parentheses: {
options = {
evaluate: true,
}
@@ -1251,3 +1401,101 @@ issue_3695: {
}
expect_stdout: "NaN"
}
issue_4137: {
options = {
evaluate: true,
}
input: {
console.log(+(A = []) * (A[0] = 1));
}
expect: {
console.log(+(A = []) * (A[0] = 1));
}
expect_stdout: "0"
}
issue_4142: {
options = {
evaluate: true,
}
input: {
console.log("" + +(0 === console));
}
expect: {
console.log("" + +(0 === console));
}
expect_stdout: "0"
}
issue_4542_1: {
options = {
evaluate: true,
unsafe_math: true,
}
input: {
console.log(function(a) {
return a / (1 / (a[0] = 2));
}([ 3 ]));
}
expect: {
console.log(function(a) {
return a / (1 / (a[0] = 2));
}([ 3 ]));
}
expect_stdout: "4"
}
issue_4542_2: {
options = {
evaluate: true,
unsafe_math: true,
}
input: {
console.log(function(a) {
return a / (1 / --a[0]);
}([ 3 ]));
}
expect: {
console.log(function(a) {
return a / (1 / --a[0]);
}([ 3 ]));
}
expect_stdout: "4"
}
issue_4542_3: {
options = {
evaluate: true,
unsafe_math: true,
}
input: {
console.log(function(a) {
return a / (0 / (a[0] = 0, 1));
}([ 1 ]));
}
expect: {
console.log(function(a) {
return a / (0 / (a[0] = 0, 1));
}([ 1 ]));
}
expect_stdout: "NaN"
}
issue_4542_4: {
options = {
evaluate: true,
unsafe_math: true,
}
input: {
console.log(function(a) {
return a / (1 / (a.length = 1));
}([ 2, 3 ]));
}
expect: {
console.log(function(a) {
return a / (1 / (a.length = 1));
}([ 2, 3 ]));
}
expect_stdout: "2"
}

View File

@@ -45,8 +45,8 @@ duplicate_key_strict: {
"use strict";
var o = {
a: 1,
b: 2,
a: 3,
b: 2,
};
for (var k in o)
console.log(k, o[k]);
@@ -221,3 +221,303 @@ numeric_literal: {
"8 7 8",
]
}
evaluate_computed_key: {
options = {
evaluate: true,
objects: true,
}
input: {
console.log({
["foo" + "bar"]: "PASS",
}.foobar);
}
expect: {
console.log({
foobar: "PASS",
}.foobar);
}
expect_stdout: "PASS"
node_version: ">=4"
}
keep_computed_key: {
options = {
side_effects: true,
}
input: {
({
[console.log("PASS")]: 42,
});
}
expect: {
console.log("PASS");
}
expect_stdout: "PASS"
node_version: ">=4"
}
shorthand_keywords: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
unsafe: true,
unused: true,
}
input: {
var async = 1, get = 2, set = 3, o = {
async,
get,
set,
};
console.log(o.async, o.get, o.set);
}
expect: {
console.log(1, 2, 3);
}
expect_stdout: "1 2 3"
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,
objects: true,
}
input: {
console.log({
get 0() {
return "FAIL";
},
[0]: "PASS",
}[0]);
}
expect: {
console.log({
get 0() {
return "FAIL";
},
[0]: "PASS",
}[0]);
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_4269_2: {
options = {
evaluate: true,
objects: true,
}
input: {
console.log({
get [0]() {
return "FAIL";
},
0: "PASS",
}[0]);
}
expect: {
console.log({
get [0]() {
return "FAIL";
},
0: "PASS",
}[0]);
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_4269_3: {
options = {
evaluate: true,
objects: true,
}
input: {
console.log({
["foo"]: "bar",
get 42() {
return "FAIL";
},
42: "PASS",
}[42]);
}
expect: {
console.log({
foo: "bar",
get [42]() {
return "FAIL";
},
42: "PASS",
}[42]);
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_4269_4: {
options = {
evaluate: true,
objects: true,
}
input: {
console.log({
get 42() {
return "FAIL";
},
["foo"]: "bar",
42: "PASS",
}[42]);
}
expect: {
console.log({
get 42() {
return "FAIL";
},
foo: "bar",
[42]: "PASS",
}[42]);
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_4269_5: {
options = {
evaluate: true,
objects: true,
}
input: {
console.log({
get 42() {
return "FAIL";
},
[console]: "bar",
42: "PASS",
}[42]);
}
expect: {
console.log({
get 42() {
return "FAIL";
},
[console]: "bar",
42: "PASS",
}[42]);
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_4380: {
options = {
evaluate: true,
objects: true,
}
input: {
console.log({
get 0() {
return "FAIL 1";
},
0: "FAIL 2",
[0]: "PASS",
}[0]);
}
expect: {
console.log({
get 0() {
return "FAIL 1";
},
[0]: ("FAIL 2", "PASS"),
}[0]);
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_4415: {
options = {
evaluate: true,
objects: true,
}
input: {
console.log({
["00"]: "FAIL",
}[0] || "PASS");
}
expect: {
console.log({
"00": "FAIL",
}[0] || "PASS");
}
expect_stdout: "PASS"
node_version: ">=4"
}

View File

@@ -0,0 +1,355 @@
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"
}
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"
}
issue_4906: {
options = {
toplevel: true,
unused: true,
}
input: {
do {
var a = a?.[42];
} while (console.log("PASS"));
}
expect: {
do {} 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: {
(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(b) {
var b = b.p;
var c;
b?.[c = "FAIL 2"];
return b || c;
}
console.log(f("FAIL 1") || "PASS");
}
expect_stdout: "PASS"
node_version: ">=14"
}

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";
@@ -130,7 +130,7 @@ evaluate_string_length: {
}
}
mangle_properties: {
mangle_properties_1: {
mangle = {
properties: {
keep_quoted: false,
@@ -152,6 +152,53 @@ mangle_properties: {
}
}
mangle_properties_2: {
mangle = {
properties: {
reserved: [
"value",
]
},
}
input: {
var o = {
prop1: 1,
};
Object.defineProperty(o, "prop2", {
value: 2,
});
Object.defineProperties(o, {
prop3: {
value: 3,
},
});
console.log("prop1", o.prop1, "prop1" in o);
console.log("prop2", o.prop2, o.hasOwnProperty("prop2"));
console.log("prop3", o.prop3, Object.getOwnPropertyDescriptor(o, "prop3").value);
}
expect: {
var o = {
o: 1,
};
Object.defineProperty(o, "p", {
value: 2,
});
Object.defineProperties(o, {
r: {
value: 3,
},
});
console.log("prop1", o.o, "o" in o);
console.log("prop2", o.p, o.hasOwnProperty("p"));
console.log("prop3", o.r, Object.getOwnPropertyDescriptor(o, "r").value);
}
expect_stdout: [
"prop1 1 true",
"prop2 2 true",
"prop3 3 3",
]
}
mangle_unquoted_properties: {
options = {
evaluate: true,
@@ -1076,11 +1123,7 @@ new_this: {
}
}.f(42);
}
expect: {
new function(a) {
this.a = a;
}(42);
}
expect: {}
}
issue_2513: {
@@ -1335,3 +1378,135 @@ 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"
}

View File

@@ -133,7 +133,7 @@ conditional: {
relational: {
options = {
pure_funcs: [ "foo" ],
side_effects :true,
side_effects: true,
}
input: {
foo() in new foo();
@@ -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: "strict",
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: "strict",
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: "strict",
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: "strict",
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,
@@ -848,9 +877,8 @@ collapse_vars_1_true: {
}
expect: {
function f(a, b) {
for (;;) {
for (;;)
if (a.g() || b.p) break;
}
}
}
}
@@ -980,6 +1008,7 @@ collapse_vars_2_strict: {
collapse_rhs_true: {
options = {
collapse_vars: true,
evaluate: true,
pure_getters: true,
}
input: {
@@ -1016,6 +1045,7 @@ collapse_rhs_true: {
collapse_rhs_false: {
options = {
collapse_vars: true,
evaluate: true,
pure_getters: false,
}
input: {
@@ -1052,6 +1082,7 @@ collapse_rhs_false: {
collapse_rhs_strict: {
options = {
collapse_vars: true,
evaluate: true,
pure_getters: "strict",
}
input: {
@@ -1088,6 +1119,7 @@ collapse_rhs_strict: {
collapse_rhs_setter: {
options = {
collapse_vars: true,
evaluate: true,
pure_getters: "strict",
}
input: {
@@ -1188,13 +1220,111 @@ 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,
}
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,
@@ -1209,3 +1339,329 @@ issue_3427: {
expect: {}
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";
if (function() {
var a;
}(), 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",
side_effects: true,
unused: true,
}
input: {
try {
(function() {
arguments = null;
console.log(arguments.p = "FAIL");
})();
} catch (e) {
console.log("PASS");
}
}
expect: {
try {
(function() {
arguments = null;
console.log(arguments.p = "FAIL");
})();
} catch (e) {
console.log("PASS");
}
}
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,
pure_getters: "strict",
reduce_vars: true,
side_effects: true,
toplevel: 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"
}
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"
}

View File

@@ -120,7 +120,7 @@ modified: {
expect: {
function f0() {
var b = 2;
b++;
+b;
console.log(2);
console.log(4);
}
@@ -1292,6 +1292,7 @@ toplevel_on_loops_3: {
loops: true,
reduce_funcs: true,
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
@@ -1624,7 +1625,7 @@ defun_label: {
expect_stdout: true
}
double_reference: {
double_reference_1: {
options = {
reduce_funcs: true,
reduce_vars: true,
@@ -1638,6 +1639,32 @@ double_reference: {
g();
}
}
expect: {
function f() {
var g = function g() {
g();
};
g();
}
}
}
double_reference_2: {
options = {
functions: true,
passes: 2,
reduce_funcs: true,
reduce_vars: true,
unused: true,
}
input: {
function f() {
var g = function g() {
g();
};
g();
}
}
expect: {
function f() {
(function g() {
@@ -1647,6 +1674,60 @@ double_reference: {
}
}
double_reference_3: {
options = {
reduce_funcs: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var x = function f() {
return f;
};
function g() {
return x();
}
console.log(g() === g());
}
expect: {
var x = function f() {
return f;
};
function g() {
return x();
}
console.log(g() === g());
}
expect_stdout: "true"
}
double_reference_4: {
options = {
comparisons: true,
functions: true,
inline: true,
passes: 2,
reduce_funcs: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var x = function f() {
return f;
};
function g() {
return x();
}
console.log(g() === g());
}
expect: {
console.log(true);
}
expect_stdout: "true"
}
iife_arguments_1: {
options = {
reduce_funcs: true,
@@ -1686,8 +1767,35 @@ iife_arguments_2: {
}
expect: {
(function() {
console.log(function f() {
var x = function f() {
return f;
};
console.log(x() === arguments[0]);
})();
}
expect_stdout: true
}
iife_arguments_3: {
options = {
functions: true,
passes: 2,
reduce_funcs: true,
reduce_vars: true,
unused: true,
}
input: {
(function() {
var x = function f() {
return f;
};
console.log(x() === arguments[0]);
})();
}
expect: {
(function() {
console.log(function x() {
return x;
}() === arguments[0]);
})();
}
@@ -1892,7 +2000,7 @@ issue_1606: {
var a, b;
function g(){};
b = 2;
x(b);
x(2);
}
}
}
@@ -1965,72 +2073,7 @@ issue_1670_2: {
issue_1670_3: {
options = {
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
reduce_funcs: true,
reduce_vars: true,
side_effects: true,
switches: true,
typeofs: true,
unused: true,
}
input: {
(function f() {
switch (1) {
case 0:
var a = true;
break;
case 1:
if (typeof a === "undefined") console.log("PASS");
else console.log("FAIL");
}
})();
}
expect: {
(function() {
var a;
void 0 === a ? console.log("PASS") : console.log("FAIL");
})();
}
expect_stdout: "PASS"
}
issue_1670_4: {
options = {
conditionals: true,
dead_code: true,
evaluate: true,
passes: 2,
reduce_funcs: true,
reduce_vars: true,
side_effects: true,
switches: true,
unused: true,
}
input: {
(function f() {
switch (1) {
case 0:
var a = true;
break;
case 1:
if (typeof a === "undefined") console.log("PASS");
else console.log("FAIL");
}
})();
}
expect: {
(function() {
console.log("PASS");
})();
}
expect_stdout: "PASS"
}
issue_1670_5: {
options = {
dead_code: true,
evaluate: true,
keep_fargs: false,
@@ -2060,13 +2103,15 @@ issue_1670_5: {
expect_stdout: "1"
}
issue_1670_6: {
issue_1670_4: {
options = {
conditionals: true,
dead_code: true,
evaluate: true,
keep_fargs: false,
reduce_funcs: true,
reduce_vars: true,
sequences: true,
side_effects: true,
switches: true,
unused: true,
@@ -2084,10 +2129,9 @@ issue_1670_6: {
})(1);
}
expect: {
(function(a) {
a = 1;
console.log(a);
})(1);
(function() {
console.log(1);
})();
}
expect_stdout: "1"
}
@@ -2264,7 +2308,7 @@ redefine_farg_1: {
function f(a) {
return typeof a;
}
function g() {
function g(a) {
return "number";
}
function h(a, b) {
@@ -2306,7 +2350,7 @@ redefine_farg_2: {
console.log(typeof [], "number",function(a, b) {
a = b;
return typeof a;
}([]));
}());
}
expect_stdout: "object number undefined"
}
@@ -2351,6 +2395,7 @@ delay_def: {
evaluate: true,
reduce_funcs: true,
reduce_vars: true,
side_effects: true,
unused: true,
}
input: {
@@ -3048,7 +3093,7 @@ accessor_1: {
a = 2;
return a;
},
b: 1
b: 1,
}.b, a);
}
expect: {
@@ -3058,7 +3103,7 @@ accessor_1: {
a = 2;
return a;
},
b: 1
b: 1,
}.b, a);
}
expect_stdout: "1 1"
@@ -3078,7 +3123,7 @@ accessor_2: {
var B = {
get c() {
console.log(A);
}
},
};
B.c;
}
@@ -3086,7 +3131,7 @@ accessor_2: {
({
get c() {
console.log(1);
}
},
}).c;
}
expect_stdout: "1"
@@ -3132,7 +3177,7 @@ obj_var_1: {
var obj = {
bar: function() {
return C + C;
}
},
};
console.log(obj.bar());
}
@@ -3140,7 +3185,7 @@ obj_var_1: {
console.log({
bar: function() {
return 2;
}
},
}.bar());
}
expect_stdout: "2"
@@ -3164,7 +3209,7 @@ obj_var_2: {
var obj = {
bar: function() {
return C + C;
}
},
};
console.log(obj.bar());
}
@@ -4378,6 +4423,7 @@ perf_2: {
perf_3: {
options = {
passes: 2,
reduce_funcs: true,
reduce_vars: true,
toplevel: true,
@@ -4386,10 +4432,10 @@ perf_3: {
input: {
var foo = function(x, y, z) {
return x < y ? x * y + z : x * z - y;
}
};
var indirect_foo = function(x, y, z) {
return foo(x, y, z);
}
};
var sum = 0;
for (var i = 0; i < 100; ++i)
sum += indirect_foo(i, i + 1, 3 * i);
@@ -4418,10 +4464,10 @@ perf_4: {
input: {
var foo = function(x, y, z) {
return x < y ? x * y + z : x * z - y;
}
};
var indirect_foo = function(x, y, z) {
return foo(x, y, z);
}
};
var sum = 0;
for (var i = 0; i < 100; ++i)
sum += indirect_foo(i, i + 1, 3 * i);
@@ -4430,10 +4476,10 @@ perf_4: {
expect: {
var foo = function(x, y, z) {
return x < y ? x * y + z : x * z - y;
}
};
var indirect_foo = function(x, y, z) {
return foo(x, y, z);
}
};
var sum = 0;
for (var i = 0; i < 100; ++i)
sum += indirect_foo(i, i + 1, 3 * i);
@@ -4522,9 +4568,9 @@ perf_7: {
var indirect_foo = function(x, y, z) {
var foo = function(x, y, z) {
return x < y ? x * y + z : x * z - y;
}
};
return foo(x, y, z);
}
};
var sum = 0;
for (var i = 0; i < 100; ++i)
sum += indirect_foo(i, i + 1, 3 * i);
@@ -4554,9 +4600,9 @@ perf_8: {
var indirect_foo = function(x, y, z) {
var foo = function(x, y, z) {
return x < y ? x * y + z : x * z - y;
}
};
return foo(x, y, z);
}
};
var sum = 0;
for (var i = 0; i < 100; ++i)
sum += indirect_foo(i, i + 1, 3 * i);
@@ -4567,7 +4613,7 @@ perf_8: {
return function(x, y, z) {
return x < y ? x * y + z : x * z - y;
}(x, y, z);
}
};
var sum = 0;
for (var i = 0; i < 100; ++i)
sum += indirect_foo(i, i + 1, 3 * i);
@@ -5265,11 +5311,11 @@ defun_catch_4: {
try {
throw 42;
} catch (a) {
function a() {}
console.log(a);
}
}
expect_stdout: "42"
node_version: "<=4"
expect_stdout: true
}
defun_catch_5: {
@@ -5291,10 +5337,10 @@ defun_catch_5: {
throw 42;
} catch (a) {
console.log(a);
function a() {}
}
}
expect_stdout: "42"
node_version: "<=4"
expect_stdout: true
}
defun_catch_6: {
@@ -5481,7 +5527,7 @@ lvalues_def_1: {
}
expect: {
var b = 1;
var a = b++, b = NaN;
var a = +b, b = NaN;
console.log(a, b);
}
expect_stdout: "1 NaN"
@@ -6819,7 +6865,7 @@ issue_3622: {
options = {
evaluate: true,
inline: true,
keep_fargs: "strict",
keep_fargs: false,
reduce_vars: true,
sequences: true,
toplevel: true,
@@ -7087,7 +7133,7 @@ issue_3894: {
issue_3922: {
options = {
evaluate: true,
keep_fargs: "strict",
keep_fargs: false,
pure_getters: "strict",
reduce_vars: true,
side_effects: true,
@@ -7402,7 +7448,327 @@ issue_4030: {
}
expect: {
A = "PASS";
console.log("PASS");
console.log(A);
}
expect_stdout: "PASS"
}
global_assign: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
A = "FAIL";
this.A = "PASS";
console.log(A);
}
expect: {
A = "FAIL";
this.A = "PASS";
console.log(A);
}
expect_stdout: "PASS"
}
issue_4188_1: {
options = {
reduce_vars: true,
unused: true,
}
input: {
(function() {
try {
while (A)
var a = function() {}, b = a;
} catch (a) {
console.log(function() {
return typeof a;
}(), typeof b);
}
})();
}
expect: {
(function() {
try {
while (A)
var a = function() {}, b = a;
} catch (a) {
console.log(function() {
return typeof a;
}(), typeof b);
}
})();
}
expect_stdout: "object undefined"
}
issue_4188_2: {
options = {
reduce_vars: true,
unused: true,
}
input: {
(function() {
try {
throw 42;
} catch (a) {
console.log(function() {
return typeof a;
}(), typeof b);
}
while (!console)
var a = function() {}, b = a;
})();
}
expect: {
(function() {
try {
throw 42;
} catch (a) {
console.log(function() {
return typeof a;
}(), typeof b);
}
while (!console)
var a = function() {}, b = a;
})();
}
expect_stdout: "number undefined"
}
issue_4568: {
options = {
booleans: true,
conditionals: true,
dead_code: true,
evaluate: true,
loops: true,
passes: 2,
reduce_vars: true,
sequences: true,
unused: true,
}
input: {
(function(a) {
a && console.log("FAIL");
if (1)
do {
if (!console.log("PASS")) break;
} while (1);
})(!(0 !== delete NaN));
}
expect: {
(function(a) {
for (a && console.log("FAIL"), 1; console.log("PASS"); ) 1;
})(!(0 !== delete NaN));
}
expect_stdout: "PASS"
}
issue_4937: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
function f() {
while (console.log("PASS"));
}
do {
function g() {
f();
}
} while (!g);
f();
}
expect: {
function f() {
while (console.log("PASS"));
}
do {
function g() {
f();
}
} while (!g);
f();
}
expect_stdout: "PASS"
}
issue_4943_1: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
}
input: {
var a, b = 1;
(function f() {
a = "foo";
b-- && f();
console.log(a);
a = "bar";
})();
}
expect: {
var a, b = 1;
(function f() {
a = "foo";
b-- && f();
console.log(a);
a = "bar";
})();
}
expect_stdout: [
"foo",
"bar",
]
}
issue_4943_2: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a, b = 1;
(function f() {
a = "foo";
b-- && f();
console.log(a);
a = "bar";
})();
}
expect: {
var a, b = 1;
(function f() {
a = "foo";
b-- && f();
console.log(a);
a = "bar";
})();
}
expect_stdout: [
"foo",
"bar",
]
}
issue_4949: {
options = {
reduce_vars: true,
unused: true,
}
input: {
(function f(a) {
a = 0;
console.log(a++, arguments[0]);
})(0);
}
expect: {
(function(a) {
a = 0;
console.log(a++, arguments[0]);
})(0);
}
expect_stdout: "0 1"
}
issue_5048: {
options = {
reduce_funcs: true,
reduce_vars: true,
unused: true,
}
input: {
console.log(function() {
var a = function() {
return a + 42;
};
}());
}
expect: {
console.log(function() {}());
}
expect_stdout: "undefined"
}
issue_5050: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
}
input: {
function f() {
console.log(a);
}
this;
var a = 1;
f(console.log(2), f(), a = 3);
}
expect: {
function f() {
console.log(a);
}
this;
var a = 1;
f(console.log(2), f(), a = 3);
}
expect_stdout: [
"2",
"1",
"3",
]
}
issue_5055_1: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
}
input: {
var a = "PASS";
function f() {
console.log(a || "FAIL");
}
f(0 && (a = 0)(f(this)));
}
expect: {
var a = "PASS";
function f() {
console.log(a || "FAIL");
}
f(0);
}
expect_stdout: "PASS"
}
issue_5055_2: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = "PASS";
function f() {
console.log(a || "FAIL");
}
f(0 && (a = 0)(f(this)));
}
expect: {
var a = "PASS";
function f() {
console.log(a || "FAIL");
}
f(0 && (a = 0)(f()));
}
expect_stdout: "PASS"
}

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: {

1071
test/compress/rests.js Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -13,6 +13,23 @@ console_log: {
]
}
console_log_console: {
input: {
var log = console.log;
log(console);
log(typeof console.log);
}
expect: {
var log = console.log;
log(console);
log(typeof console.log);
}
expect_stdout: [
"{ log: 'function(){}' }",
"function",
]
}
typeof_arguments: {
options = {
evaluate: true,
@@ -80,3 +97,107 @@ log_global: {
}
expect_stdout: "[object global]"
}
log_nested: {
options = {
unused: true,
}
input: {
var o = { p: 42 };
for (var i = 0; i < 10; i++)
o = {
p: o,
q: function foo() {},
};
console.log(o);
}
expect: {
var o = { p: 42 };
for (var i = 0; i < 10; i++)
o = {
p: o,
q: function() {},
};
console.log(o);
}
expect_stdout: true
}
timers: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var count = 0, interval = 1000, duration = 3210;
var timer = setInterval(function() {
console.log(++count);
}, interval);
setTimeout(function() {
clearInterval(timer);
}, duration);
}
expect: {
var count = 0;
var timer = setInterval(function() {
console.log(++count);
}, 1000);
setTimeout(function() {
clearInterval(timer);
}, 3210);
}
expect_stdout: [
"1",
"2",
"3",
]
node_version: ">=0.12"
}
issue_4054: {
input: {
console.log({
set p(v) {
throw "FAIL";
},
});
}
expect: {
console.log({
set p(v) {
throw "FAIL";
},
});
}
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"
}

View File

@@ -564,6 +564,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 +620,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 +720,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: {
@@ -877,7 +943,7 @@ for_init_var: {
expect_stdout: "PASS"
}
forin: {
forin_1: {
options = {
sequences: true,
}
@@ -895,6 +961,49 @@ forin: {
expect_stdout: "PASS"
}
forin_2: {
options = {
evaluate: true,
inline: true,
reduce_vars: true,
sequences: true,
toplevel: true,
unused: true,
}
input: {
var o = {
p: 1,
q: 2,
};
var k = "k";
for ((console.log("exp"), o)[function() {
console.log("prop");
return k;
}()] in function() {
console.log("obj");
return o;
}())
console.log(o.k, o[o.k]);
}
expect: {
var o = {
p: 1,
q: 2,
};
for ((console.log("exp"), o)[console.log("prop"), "k"] in console.log("obj"), o)
console.log(o.k, o[o.k]);
}
expect_stdout: [
"obj",
"exp",
"prop",
"p 1",
"exp",
"prop",
"q 2",
]
}
call: {
options = {
sequences: true,
@@ -1112,3 +1221,25 @@ issue_3703: {
}
expect_stdout: "PASS"
}
issue_4079: {
options = {
sequences: true,
side_effects: true,
}
input: {
try {
typeof (0, A);
} catch (e) {
console.log("PASS");
}
}
expect: {
try {
A;
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "PASS"
}

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,
@@ -245,6 +275,31 @@ unsafe_builtin_2: {
expect_stdout: "object PASS PASS"
}
unsafe_builtin_3: {
options = {
conditionals: true,
side_effects: true,
toplevel: true,
unsafe: true,
}
input: {
var o = {};
if (42 < Math.random())
o.p = "FAIL";
else
o.p = "PASS";
for (var k in o)
console.log(k, o[k]);
}
expect: {
var o = {};
o.p = 42 < Math.random() ? "FAIL" : "PASS";
for (var k in o)
console.log(k, o[k]);
}
expect_stdout: "p PASS"
}
unsafe_string_replace: {
options = {
side_effects: true,
@@ -323,8 +378,6 @@ issue_3983_1: {
}
expect: {
var a = "PASS";
g();
function g() {}
console.log(a);
}
expect_stdout: "PASS"
@@ -391,3 +444,204 @@ issue_4008: {
"PASS",
]
}
trim_new: {
options = {
side_effects: true,
}
input: {
new function(a) {
console.log(a);
}("PASS");
}
expect: {
(function(a) {
console.log(a);
})("PASS");
}
expect_stdout: "PASS"
}
issue_4325: {
options = {
keep_fargs: false,
passes: 2,
pure_getters: "strict",
reduce_vars: true,
side_effects: true,
unused: true,
}
input: {
(function f() {
(function(b, c) {
try {
c.p = 0;
} catch (e) {
console.log("PASS");
return b;
}
c;
})(f++);
})();
}
expect: {
(function() {
(function(c) {
try {
c.p = 0;
} catch (e) {
console.log("PASS");
return;
}
})(void 0);
})();
}
expect_stdout: "PASS"
}
issue_4366_1: {
options = {
side_effects: true,
}
input: {
({
p: 42,
get p() {},
q: console.log("PASS"),
});
}
expect: {
console.log("PASS");
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_4366_2: {
options = {
side_effects: true,
}
input: {
({
set p(v) {},
q: console.log("PASS"),
p: 42,
});
}
expect: {
console.log("PASS");
}
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"
}

1106
test/compress/spreads.js Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,6 @@
constant_switch_1: {
options = {
conditionals: true,
dead_code: true,
evaluate: true,
side_effects: true,
@@ -19,6 +20,7 @@ constant_switch_1: {
constant_switch_2: {
options = {
conditionals: true,
dead_code: true,
evaluate: true,
side_effects: true,
@@ -39,6 +41,7 @@ constant_switch_2: {
constant_switch_3: {
options = {
conditionals: true,
dead_code: true,
evaluate: true,
side_effects: true,
@@ -60,6 +63,7 @@ constant_switch_3: {
constant_switch_4: {
options = {
conditionals: true,
dead_code: true,
evaluate: true,
side_effects: true,
@@ -86,6 +90,7 @@ constant_switch_4: {
constant_switch_5: {
options = {
conditionals: true,
dead_code: true,
evaluate: true,
side_effects: true,
@@ -108,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();
@@ -120,6 +125,7 @@ constant_switch_5: {
constant_switch_6: {
options = {
conditionals: true,
dead_code: true,
evaluate: true,
side_effects: true,
@@ -154,6 +160,7 @@ constant_switch_6: {
constant_switch_7: {
options = {
conditionals: true,
dead_code: true,
evaluate: true,
side_effects: true,
@@ -197,6 +204,7 @@ constant_switch_7: {
constant_switch_8: {
options = {
conditionals: true,
dead_code: true,
evaluate: true,
side_effects: true,
@@ -226,6 +234,7 @@ constant_switch_8: {
constant_switch_9: {
options = {
conditionals: true,
dead_code: true,
evaluate: true,
side_effects: true,
@@ -291,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,
@@ -315,6 +355,7 @@ keep_default: {
issue_1663: {
options = {
conditionals: true,
dead_code: true,
evaluate: true,
side_effects: true,
@@ -413,7 +454,6 @@ drop_case_3: {
switch ({}.p) {
default:
case void 0:
break;
case c = "FAIL":
}
console.log(c);
@@ -444,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,
@@ -464,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,
@@ -551,6 +822,7 @@ issue_441_2: {
issue_1674: {
options = {
conditionals: true,
dead_code: true,
evaluate: true,
side_effects: true,
@@ -650,7 +922,7 @@ issue_1680_1: {
case f(0):
case f(1):
f(2);
case 2:
default:
f(5);
}
}
@@ -876,6 +1148,7 @@ beautify: {
issue_1758: {
options = {
conditionals: true,
dead_code: true,
switches: true,
}
@@ -898,20 +1171,20 @@ issue_1758: {
issue_2535: {
options = {
conditionals: true,
dead_code: true,
evaluate: true,
switches: true,
}
input: {
switch(w(), 42) {
case 13: x();
case 42: y();
default: z();
case 13: x();
case 42: y();
default: z();
}
}
expect: {
w(), 42;
42;
y();
z();
}
@@ -919,6 +1192,7 @@ issue_2535: {
issue_1750: {
options = {
conditionals: true,
dead_code: true,
evaluate: true,
switches: true,
@@ -936,7 +1210,6 @@ issue_1750: {
expect: {
var a = 0, b = 1;
true;
a, true;
b = 2;
console.log(a, b);
}
@@ -963,6 +1236,7 @@ drop_switch_1: {
drop_switch_2: {
options = {
conditionals: true,
dead_code: true,
switches: true,
}
@@ -1007,6 +1281,7 @@ drop_switch_3: {
drop_switch_4: {
options = {
conditionals: true,
dead_code: true,
switches: true,
}
@@ -1028,3 +1303,308 @@ drop_switch_4: {
}
expect_stdout: "PASS"
}
drop_switch_5: {
options = {
conditionals: true,
dead_code: true,
switches: true,
}
input: {
switch (A) {
case B:
x();
default:
}
switch (C) {
default:
y();
case D:
}
}
expect: {
A === B && x();
C !== D && y();
}
}
drop_switch_6: {
options = {
conditionals: true,
dead_code: true,
switches: true,
}
input: {
switch (A) {
case B:
default:
x();
}
switch (C) {
default:
case D:
y();
}
}
expect: {
A;
B;
x();
C !== D;
y();
}
}
drop_switch_7: {
options = {
conditionals: true,
dead_code: true,
switches: true,
}
input: {
switch (A) {
case B:
w();
default:
x();
}
switch (C) {
default:
y();
case D:
z();
}
}
expect: {
A === B && w();
x();
C !== D && y();
z();
}
}
drop_switch_8: {
options = {
conditionals: true,
dead_code: true,
switches: true,
}
input: {
switch (A) {
case B:
w();
break;
default:
x();
}
switch (C) {
default:
y();
break;
case D:
z();
}
}
expect: {
(A === B ? w : x)();
(C !== D ? y : z)();
}
}
issue_4059: {
options = {
conditionals: true,
dead_code: true,
evaluate: true,
switches: true,
}
input: {
switch (0) {
default:
case 1:
break;
case a:
break;
var a;
}
console.log("PASS");
}
expect: {
switch (0) {
default:
break;
case a:
break;
var a;
}
console.log("PASS");
}
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"
}

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

@@ -0,0 +1,436 @@
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"
}
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(`\u0${0}b5`);
}
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"
}
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"
}
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,
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"
}

View File

@@ -95,7 +95,7 @@ while_if_break: {
}
}
expect: {
for(; a && (b && c && d, !e););
for (; a && (b && c && d, !e););
}
}

View File

@@ -1,3 +1,37 @@
ascii_only_false: {
options = {}
beautify = {
ascii_only: false,
}
input: {
console.log(
"\x000\x001\x007\x008\x00",
"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
"\x20\x21\x22\x23 ... \x7d\x7e\x7f\x80\x81 ... \xfe\xff\u0fff\uffff"
);
}
expect_exact: 'console.log("\\x000\\x001\\x007\\x008\\0","\\0\x01\x02\x03\x04\x05\x06\x07\\b\\t\\n\\v\\f\\r\x0e\x0f","\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",\' !"# ... }~\x7f\x80\x81 ... \xfe\xff\u0fff\uffff\');'
expect_stdout: true
}
ascii_only_true: {
options = {}
beautify = {
ascii_only: true,
}
input: {
console.log(
"\x000\x001\x007\x008\x00",
"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
"\x20\x21\x22\x23 ... \x7d\x7e\x7f\x80\x81 ... \xfe\xff\u0fff\uffff"
);
}
expect_exact: 'console.log("\\x000\\x001\\x007\\x008\\0","\\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\b\\t\\n\\v\\f\\r\\x0e\\x0f","\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f",\' !"# ... }~\\x7f\\x80\\x81 ... \\xfe\\xff\\u0fff\\uffff\');'
expect_stdout: true
}
unicode_parse_variables: {
options = {}
input: {
@@ -16,7 +50,7 @@ unicode_parse_variables: {
}
}
unicode_escaped_identifier: {
unicode_escaped_identifier_1: {
input: {
var \u0061 = "\ud800\udc00";
console.log(a);
@@ -25,6 +59,17 @@ unicode_escaped_identifier: {
expect_stdout: "\ud800\udc00"
}
unicode_escaped_identifier_2: {
input: {
var \u{61} = "foo";
var \u{10000} = "bar";
console.log(a, \u{10000});
}
expect_exact: 'var a="foo";var \u{10000}="bar";console.log(a,\u{10000});'
expect_stdout: "foo bar"
node_version: ">=4"
}
unicode_identifier_ascii_only: {
beautify = {
ascii_only: true,
@@ -141,3 +186,35 @@ issue_2569: {
}
expect_exact: 'new RegExp("[\\udc42-\\udcaa\\udd74-\\udd96\\ude45-\\ude4f\\udea3-\\udecc]");'
}
surrogate_pair: {
beautify = {
ascii_only: false,
}
input: {
var \u{2f800} = {
\u{2f801}: "\u{100000}",
};
\u{2f800}.\u{2f802} = "\u{100001}";
console.log(typeof \u{2f800}, \u{2f800}.\u{2f801}, \u{2f800}["\u{2f802}"]);
}
expect_exact: 'var \ud87e\udc00={"\ud87e\udc01":"\udbc0\udc00"};\ud87e\udc00.\ud87e\udc02="\udbc0\udc01";console.log(typeof \ud87e\udc00,\ud87e\udc00.\ud87e\udc01,\ud87e\udc00["\ud87e\udc02"]);'
expect_stdout: "object \udbc0\udc00 \udbc0\udc01"
node_version: ">=4"
}
surrogate_pair_ascii: {
beautify = {
ascii_only: true,
}
input: {
var \u{2f800} = {
\u{2f801}: "\u{100000}",
};
\u{2f800}.\u{2f802} = "\u{100001}";
console.log(typeof \u{2f800}, \u{2f800}.\u{2f801}, \u{2f800}["\u{2f802}"]);
}
expect_exact: 'var \\u{2f800}={"\\ud87e\\udc01":"\\udbc0\\udc00"};\\u{2f800}.\\u{2f802}="\\udbc0\\udc01";console.log(typeof \\u{2f800},\\u{2f800}.\\u{2f801},\\u{2f800}["\\ud87e\\udc02"]);'
expect_stdout: "object \udbc0\udc00 \udbc0\udc01"
node_version: ">=4"
}

615
test/compress/varify.js Normal file
View File

@@ -0,0 +1,615 @@
reduce_merge_const: {
options = {
merge_vars: true,
reduce_vars: true,
toplevel: true,
unused: true,
varify: true,
}
input: {
const a = console;
console.log(typeof a);
var b = typeof a;
console.log(b);
}
expect: {
var b = console;
console.log(typeof b);
b = typeof b;
console.log(b);
}
expect_stdout: [
"object",
"object",
]
}
reduce_merge_let: {
options = {
merge_vars: true,
reduce_vars: true,
toplevel: true,
unused: true,
varify: true,
}
input: {
"use strict";
let a = console;
console.log(typeof a);
var b = typeof a;
console.log(b);
}
expect: {
"use strict";
var b = console;
console.log(typeof b);
b = typeof b;
console.log(b);
}
expect_stdout: [
"object",
"object",
]
node_version: ">=4"
}
reduce_block_const: {
options = {
reduce_vars: true,
toplevel: true,
varify: true,
}
input: {
{
const a = typeof console;
console.log(a);
}
}
expect: {
var a = typeof console;
console.log(a);
}
expect_stdout: "object"
}
reduce_block_let: {
options = {
reduce_vars: true,
toplevel: true,
varify: true,
}
input: {
"use strict";
{
let a = typeof console;
console.log(a);
}
}
expect: {
"use strict";
var a = typeof console;
console.log(a);
}
expect_stdout: "object"
node_version: ">=4"
}
hoist_props_const: {
options = {
hoist_props: true,
passes: 2,
reduce_vars: true,
toplevel: true,
varify: true,
}
input: {
{
const o = {
p: "PASS",
};
console.log(o.p);
}
}
expect: {
var o_p = "PASS";
console.log(o_p);
}
expect_stdout: "PASS"
}
hoist_props_let: {
options = {
hoist_props: true,
passes: 2,
reduce_vars: true,
toplevel: true,
varify: true,
}
input: {
"use strict";
{
let o = {
p: "PASS",
};
console.log(o.p);
}
}
expect: {
"use strict";
var o_p = "PASS";
console.log(o_p);
}
expect_stdout: "PASS"
node_version: ">=4"
}
scope_adjustment_const: {
options = {
conditionals: true,
inline: true,
reduce_vars: true,
toplevel: true,
unused: true,
varify: true,
}
input: {
for (var k in [ 42 ])
console.log(function f() {
if (k) {
const a = 0;
}
}());
}
expect: {
for (var k in [ 42 ])
console.log(void (k && 0));
}
expect_stdout: "undefined"
}
scope_adjustment_let: {
options = {
conditionals: true,
inline: true,
reduce_vars: true,
toplevel: true,
unused: true,
varify: true,
}
input: {
"use strict";
for (var k in [ 42 ])
console.log(function f() {
if (k) {
let a = 0;
}
}());
}
expect: {
"use strict";
for (var k in [ 42 ])
console.log(void (k && 0));
}
expect_stdout: "undefined"
node_version: ">=4"
}
issue_4191_const: {
options = {
functions: true,
reduce_vars: true,
toplevel: true,
unused: true,
varify: true,
}
input: {
const a = function() {};
console.log(typeof a, a());
}
expect: {
function a() {};
console.log(typeof a, a());
}
expect_stdout: "function undefined"
}
issue_4191_let: {
options = {
functions: true,
reduce_vars: true,
toplevel: true,
unused: true,
varify: true,
}
input: {
"use strict";
let a = function() {};
console.log(typeof a, a());
}
expect: {
"use strict";
function a() {};
console.log(typeof a, a());
}
expect_stdout: "function undefined"
node_version: ">=4"
}
forin_const_1: {
options = {
join_vars: true,
reduce_vars: true,
toplevel: true,
varify: true,
}
input: {
const o = {
foo: 42,
bar: "PASS",
};
for (const k in o)
console.log(k, o[k]);
}
expect: {
var o = {
foo: 42,
bar: "PASS",
};
for (const k in o)
console.log(k, o[k]);
}
expect_stdout: true
node_version: ">=4"
}
forin_const_2: {
options = {
join_vars: true,
reduce_vars: true,
toplevel: true,
varify: true,
}
input: {
const o = {
p: 42,
q: "PASS",
};
for (const [ k ] in o)
console.log(k, o[k]);
}
expect: {
var o = {
p: 42,
q: "PASS",
}, k;
for ([ k ] in o)
console.log(k, o[k]);
}
expect_stdout: [
"p 42",
"q PASS",
]
node_version: ">=6"
}
forin_let_1: {
options = {
join_vars: true,
reduce_vars: true,
toplevel: true,
varify: true,
}
input: {
"use strict";
let o = {
foo: 42,
bar: "PASS",
};
for (let k in o)
console.log(k, o[k]);
}
expect: {
"use strict";
var o = {
foo: 42,
bar: "PASS",
}, k;
for (k in o)
console.log(k, o[k]);
}
expect_stdout: [
"foo 42",
"bar PASS",
]
node_version: ">=4"
}
forin_let_2: {
options = {
join_vars: true,
reduce_vars: true,
toplevel: true,
varify: true,
}
input: {
let o = {
p: 42,
q: "PASS",
};
for (let [ k ] in o)
console.log(k, o[k]);
}
expect: {
var o = {
p: 42,
q: "PASS",
}, k;
for ([ k ] in o)
console.log(k, o[k]);
}
expect_stdout: [
"p 42",
"q PASS",
]
node_version: ">=6"
}
loop_scope_1: {
options = {
toplevel: true,
varify: true,
}
input: {
"use strict";
var o = { foo: 1, bar: 2 };
for (let i in o) {
console.log(i);
}
for (const j in o)
setTimeout(() => console.log(j), 0);
for (let k in o)
setTimeout(function() {
console.log(k);
}, 0);
}
expect: {
"use strict";
var o = { foo: 1, bar: 2 };
for (var i in o)
console.log(i);
for (const j in o)
setTimeout(() => console.log(j), 0);
for (let k in o)
setTimeout(function() {
console.log(k);
}, 0);
}
expect_stdout: [
"foo",
"bar",
"foo",
"bar",
"foo",
"bar",
]
node_version: ">=4"
}
loop_scope_2: {
options = {
reduce_vars: true,
toplevel: true,
varify: true,
}
input: {
"use strict";
var a = [ "foo", "bar" ];
for (var i = 0; i < a.length; i++) {
const x = a[i];
console.log(x);
let y = a[i];
setTimeout(() => console.log(y), 0);
const z = a[i];
setTimeout(function() {
console.log(z);
}, 0);
}
}
expect: {
"use strict";
var a = [ "foo", "bar" ];
for (var i = 0; i < a.length; i++) {
var x = a[i];
console.log(x);
let y = a[i];
setTimeout(() => console.log(y), 0);
const z = a[i];
setTimeout(function() {
console.log(z);
}, 0);
}
}
expect_stdout: [
"foo",
"bar",
"foo",
"foo",
"bar",
"bar",
]
node_version: ">=4"
}
issue_4290_1_const: {
options = {
reduce_vars: true,
toplevel: true,
varify: true,
}
input: {
const a = 0;
var a;
}
expect: {
const a = 0;
var a;
}
expect_stdout: true
}
issue_4290_1_let: {
options = {
reduce_vars: true,
toplevel: true,
varify: true,
}
input: {
"use strict";
let a = 0;
var a;
}
expect: {
"use strict";
let a = 0;
var a;
}
expect_stdout: true
node_version: ">=4"
}
drop_forin_let: {
options = {
loops: true,
toplevel: true,
unused: true,
varify: true,
}
input: {
"use strict";
for (let a in console.log("PASS"));
}
expect: {
"use strict";
console.log("PASS");
}
expect_stdout: "PASS"
node_version: ">=4"
}
default_init: {
options = {
join_vars: true,
reduce_vars: true,
unused: true,
varify: true,
}
input: {
A = "PASS";
(function() {
"use strict";
let a;
a = A;
console.log(a);
})();
}
expect: {
A = "PASS";
(function() {
"use strict";
var a = A;
console.log(a);
})();
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_4933_1: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
varify: true,
}
input: {
console.log(f());
function f() {
var a;
for (console in a = [ f ]) {
const b = a;
}
}
}
expect: {
console.log(function f() {
var a;
for (console in a = [ f ]) {
const b = a;
}
}());
}
expect_stdout: "undefined"
}
issue_4933_2: {
options = {
passes: 2,
reduce_vars: true,
toplevel: true,
unused: true,
varify: true,
}
input: {
console.log(f());
function f() {
var a;
for (console in a = [ f ]) {
const b = a;
}
}
}
expect: {
console.log(function f() {
for (console in [ f ]);
}());
}
expect_stdout: "undefined"
}
issue_4954: {
options = {
functions: true,
reduce_vars: true,
unused: true,
varify: true,
}
input: {
"use strict";
(function() {
{
let a = console;
console.log(typeof a);
}
{
let a = function() {};
a && console.log(typeof a);
}
})();
}
expect: {
"use strict";
(function() {
var a = console;
console.log(typeof a);
{
let a = function() {};
a && console.log(typeof a);
}
})();
}
expect_stdout: [
"object",
"function",
]
node_version: ">=4"
}

View File

@@ -61,7 +61,7 @@ lambda_name_mangle: {
lambda_name_mangle_ie8: {
mangle = {
ie8: true,
ie: true,
toplevel: true,
}
input: {
@@ -95,7 +95,7 @@ function_name_mangle_ie8: {
unused: true,
}
mangle = {
ie8: true,
ie: true,
toplevel: true,
}
input: {

1277
test/compress/yields.js Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,6 @@
exports["Compressor"] = Compressor;
exports["defaults"] = defaults;
exports["is_statement"] = is_statement;
exports["JS_Parse_Error"] = JS_Parse_Error;
exports["List"] = List;
exports["mangle_properties"] = mangle_properties;

View File

@@ -1 +1 @@
++null
console.log(4 || (null = 4));

View File

@@ -0,0 +1 @@
console.log(5 || ([]?.length ^= 5));

View File

@@ -0,0 +1,8 @@
function f() {
var { eval } = null;
}
function g() {
"use strict";
var { eval } = 42;
}

View File

@@ -0,0 +1 @@
for await (; console.log(42););

View File

@@ -0,0 +1,3 @@
var a = [ 1 ], b;
for (b = 2 of a)
console.log(b);

View File

@@ -0,0 +1,3 @@
var a = [ 1 ];
for (var b = 2 of a)
console.log(b);

View File

@@ -0,0 +1,4 @@
switch (0) {
default:
default:
}

View File

@@ -1,11 +1,11 @@
{
"version": 3,
"sources": [
"input.js"
],
"names": [],
"mappings": ";;;;;;;;;;;;;;eAAc,OAAO,CAAC,KAAD,C;IAAd,G,YAAA,G;;gBACS,OAAO,CAAC,OAAD,C;IAAhB,K,aAAA,K;;AAEP,GAAG,CAAC,CAAJ,OAAA,GAAG,qBAAM,GAAG,CAAC,CAAJ,CAAM,KAAK,CAAC,CAAZ,CAAN,EAAH",
"sourcesContent": [
"const {foo} = require(\"bar\");\nconst {hello} = require(\"world\");\n\nfoo.x(...foo.y(hello.z));\n"
]
}
{
"version": 3,
"sources": [
"input.js"
],
"names": [],
"mappings": ";;;;;;;;;;;;;;eAAc,OAAO,CAAC,KAAD,C;IAAd,G,YAAA,G;;gBACS,OAAO,CAAC,OAAD,C;IAAhB,K,aAAA,K;;AAEP,GAAG,CAAC,CAAJ,OAAA,GAAG,qBAAM,GAAG,CAAC,CAAJ,CAAM,KAAK,CAAC,CAAZ,CAAN,EAAH",
"sourcesContent": [
"const {foo} = require(\"bar\");\nconst {hello} = require(\"world\");\n\nfoo.x(...foo.y(hello.z));\n"
]
}

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