Compare commits

...

171 Commits

Author SHA1 Message Date
Alex Lam S.L
2c5e23506b v3.14.5 2021-12-13 08:11:48 +08:00
Alex Lam S.L
07f35ea2c9 suppress false positives in ufuzz (#5216)
closes #5212
closes #5215
2021-12-12 06:19:06 +08:00
Alex Lam S.L
57a9519c3d fix corner case in objects (#5214)
fixes #5213
2021-12-10 06:02:22 +08:00
Alex Lam S.L
9e4c4c995c minor clean-up (#5210) 2021-12-10 04:48:06 +08:00
Alex Lam S.L
d11c82f8ca minor clean-up (#5209) 2021-12-09 05:14:57 +08:00
Alex Lam S.L
bc27966a19 workaround v8 performance quirks (#5207) 2021-12-08 13:40:47 +08:00
Alex Lam S.L
8f39491e96 workaround Unicode compatibility in testing (#5206) 2021-12-07 18:56:57 +08:00
Alex Lam S.L
065c50ebde improve sandbox resilience against process aborts (#5205) 2021-12-07 04:54:58 +08:00
Alex Lam S.L
d2e7c4af20 improve testing compatibility with Node.js (#5204) 2021-12-06 22:42:45 +08:00
Alex Lam S.L
033d8d9405 reduce memory pressure via bit fields (#5203) 2021-12-06 11:30:05 +08:00
Alex Lam S.L
b0799105c2 improve Dictionary performance (#5202)
- workaround `__proto__` quirks on v8
2021-12-05 14:58:52 +08:00
Alex Lam S.L
860aa9531b v3.14.4 2021-12-01 02:34:20 +08:00
Alex Lam S.L
2547542873 workaround sporadic slowdown in GitHub Actions (#5201) 2021-11-28 08:45:29 +08:00
Alex Lam S.L
3f8f0e246e fix corner case in collapse_vars (#5200)
fixes #5199
2021-11-28 01:43:43 +08:00
Alex Lam S.L
12227ebbb0 workaround toString() quirks on global context (#5198)
closes #5197
2021-11-27 23:17:51 +08:00
Alex Lam S.L
1b4bd7082b fix corner case in hoist_vars (#5196)
fixes #5195
2021-11-25 04:49:38 +08:00
Alex Lam S.L
0b6c185818 enhance merge_vars (#5194)
closes #5182
2021-11-24 19:08:40 +08:00
Alex Lam S.L
bfd0ac7f4b fix corner case in ie (#5193)
fixes #5192
2021-11-24 17:29:26 +08:00
Alex Lam S.L
1a8f2ecc65 enhance collapse_vars (#5186)
closes #5182
2021-11-24 17:28:36 +08:00
Alex Lam S.L
dc9e1ff0b1 fix corner case in unused (#5190)
fixes #5189
2021-11-23 20:10:05 +08:00
Alex Lam S.L
ea10498902 fix corner case in hoist_vars (#5188)
fixes #5187
2021-11-23 18:00:47 +08:00
Alex Lam S.L
69636dad69 improve sandbox async detection (#5185)
closes #5184
2021-11-23 02:29:54 +08:00
Alex Lam S.L
3ee1b0d00d enhance hoist_props & reduce_vars (#5183)
closes #5182
2021-11-23 00:31:10 +08:00
Alex Lam S.L
1e3ca4c6f7 enhance side_effects & unused (#5181) 2021-11-22 11:14:28 +08:00
Alex Lam S.L
839f4361f4 minor clean-up (#5180) 2021-11-19 16:34:11 +08:00
Alex Lam S.L
ae5c3ee8a1 fix corner cases in properties (#5178)
fixes #5177
2021-11-17 04:21:44 +08:00
Alex Lam S.L
77f7ae5ba2 fix corner case in join_vars (#5176)
fixes #5175
2021-11-15 21:35:54 +08:00
Alex Lam S.L
2d0f8bcff5 fix corner case in inline (#5174)
fixes #5173
2021-11-15 07:14:08 +08:00
Alex Lam S.L
f97e107c09 enhance reduce_vars (#5171) 2021-11-13 22:18:56 +08:00
Alex Lam S.L
e9932e1314 fix corner case in collapse_vars (#5169)
fixes #5168
2021-11-13 22:18:18 +08:00
Alex Lam S.L
eaa84d32df include Node.js v16 in CI tests (#5170)
- fix compatibility issues on v0.10 & v0.12
2021-11-13 18:34:18 +08:00
Alex Lam S.L
6e4aa0326f enhance reduce_vars (#5164)
- fix corner case in `join_vars`
2021-11-04 18:36:39 +08:00
Alex Lam S.L
f9a4b36dd1 fix corner cases in reduce_vars & rests (#5166)
fixes #5165
2021-11-03 21:29:01 +08:00
Alex Lam S.L
3acb5a329e enhance join_vars (#5162) 2021-11-02 11:33:24 +08:00
Alex Lam S.L
6d94242318 enhance reduce_vars (#5163) 2021-11-02 11:32:26 +08:00
Alex Lam S.L
bca83cb9df v3.14.3 2021-11-02 05:03:46 +08:00
Alex Lam S.L
a841d45bc3 fix corner case in awaits (#5160)
fixes #5159
2021-10-31 23:46:55 +08:00
Alex Lam S.L
eb93d92357 fix corner case in awaits (#5158)
fixes #5157
2021-10-29 23:33:10 +08:00
Alex Lam S.L
a0250ec923 fix corner case in dead_code (#5154)
fixes #5153
2021-10-25 06:18:16 +08:00
Alex Lam S.L
25801627be parse let as symbol names correctly (#5151)
fixes #5149
2021-10-21 02:14:29 +08:00
Alex Lam S.L
32ae994f88 fix issues in tests flagged by LGTM (#5150) 2021-10-21 02:07:23 +08:00
Alex Lam S.L
03aec89f60 fix corner cases in strings & templates (#5147)
fixes #5145
2021-10-16 18:02:23 +08:00
Alex Lam S.L
faf0190546 document ECMAScript quirks (#5148)
- exclude Node.js v0.8 from CI as npm registry no longer works

closes #5146
2021-10-16 13:28:13 +08:00
Alex Lam S.L
c8b0f685ee fix corner case in merge_vars (#5143)
fixes #5142
2021-10-05 00:42:46 +08:00
Alex Lam S.L
87b99162fb fix corner case in inline (#5141)
fixes #5140
2021-10-02 06:54:42 +08:00
Alex Lam S.L
940887f20f fix corner case in evaluate (#5139)
fixes #5138
2021-10-01 02:52:21 +08:00
Alex Lam S.L
0b2573c3fa fix corner case in templates (#5137)
fixes #5136
2021-09-30 21:43:34 +08:00
Alex Lam S.L
157521066f avoid potential RegExp denial-of-service (#5135)
closes #5133
closes #5134
2021-09-30 01:49:46 +08:00
Alex Lam S.L
f766babf5e enhance templates (#5131)
closes #5125
2021-09-23 18:26:26 +08:00
Alex Lam S.L
436a29367c enhance dead_code (#5130) 2021-09-22 03:11:45 +08:00
Alex Lam S.L
55418fd460 fix corner case in rests (#5129)
fixes #5128
2021-09-20 05:02:35 +08:00
Alex Lam S.L
85786889bd v3.14.2 2021-09-07 21:52:59 +08:00
Alex Lam S.L
4b88dfb8d9 tweak test & warnings (#5123)
closes #5116
closes #5117
closes #5122
2021-09-07 01:33:23 +08:00
Alex Lam S.L
c3aef23614 fix corner case in reduce_vars (#5121)
fixes #5120
2021-08-25 10:39:35 +08:00
Alex Lam S.L
db94d21980 fix corner case in side_effects (#5118) 2021-08-23 08:51:59 +08:00
Alex Lam S.L
9634a9d1fd fix corner cases in optional_chains (#5110) 2021-08-20 10:10:10 +08:00
Alex Lam S.L
befb99bd71 fix corner case in inline (#5115)
fixes #5114
2021-08-18 15:57:08 +08:00
Alex Lam S.L
02eb8baa1c fix corner case in collapse_vars (#5113)
fixes #5112
2021-08-18 10:54:24 +08:00
Alex Lam S.L
c09f63aefb fix corner case in rests (#5109)
fixes #5108
2021-08-09 08:59:33 +08:00
Alex Lam S.L
fdcc6d3a9c fix corner case in dead_code (#5107)
fixes #5106
2021-08-06 08:35:11 +08:00
Alex Lam S.L
4fe2cac35e enhance inline (#5105) 2021-07-27 21:47:01 +08:00
Alex Lam S.L
e219a9a78a v3.14.1 2021-07-27 16:53:57 +08:00
Alex Lam S.L
c80eabd61e fix ie8 option alias (#5103)
fixes #5102
2021-07-26 16:45:43 +08:00
Alex Lam S.L
9b82f9be91 fix corner case in unused (#5101)
fixes #5100
2021-07-26 16:44:34 +08:00
Alex Lam S.L
657d525c80 fix corner case in reduce_vars (#5099)
fixes #5098
2021-07-24 07:10:14 +08:00
Alex Lam S.L
6a3fe9d1df fix corner cases in reduce_vars (#5097)
fixes #5096
2021-07-23 17:17:20 +08:00
Alex Lam S.L
ec7fadcb5b v3.14.0 2021-07-22 21:13:43 +08:00
Alex Lam S.L
65adeba55d extend keep_quoted_props over numeric keys (#5094)
fixes #5093
2021-07-22 06:12:57 +08:00
Alex Lam S.L
7fac839c62 fix corner case in merge_vars (#5092)
fixes #5091
2021-07-21 02:47:53 +08:00
Alex Lam S.L
8926a2f327 fix corner case in unused (#5090)
fixes #5089
2021-07-21 01:10:58 +08:00
Alex Lam S.L
85968dee54 fix corner case in inline (#5088)
fixes #5087
2021-07-19 22:35:45 +08:00
Alex Lam S.L
a7e7865e6b fix corner case in unused (#5086)
fixes #5085
2021-07-18 19:38:09 +08:00
Alex Lam S.L
ef5f7fc25e workaround various IE quirks (#5084)
fixes #5081
2021-07-17 20:20:56 +08:00
Alex Lam S.L
902997b73d fix corner case in inline (#5083)
fixes #5082
2021-07-16 22:13:33 +08:00
Alex Lam S.L
f18804fa06 fix corner case in unused (#5080)
fixes #5079
2021-07-14 23:02:45 +08:00
Alex Lam S.L
8e2dff632e suppress false positives in ufuzz (#5078) 2021-07-13 04:10:59 +08:00
Alex Lam S.L
92c3fddd7a fix corner case in unused & yields (#5077)
fixes #5076
2021-07-12 23:16:12 +08:00
Alex Lam S.L
0d350b78bf fix corner cases in unused (#5075)
fixes #5074
2021-07-12 07:43:13 +08:00
Alex Lam S.L
1ad830facb fix corner cases in unused (#5073)
fixes #5071
2021-07-11 14:52:38 +08:00
Alex Lam S.L
64ebf6efe9 fix corner case in awaits & side_effects (#5072)
fixes #5070
2021-07-11 13:43:08 +08:00
Alex Lam S.L
08391b8e1c fix corner case in hoist_props (#5069) 2021-07-11 10:59:57 +08:00
Alex Lam S.L
d147d5d7f0 fix corner case in inline (#5068)
fixes #5067
2021-07-11 04:11:10 +08:00
Alex Lam S.L
aae1fcd12d fix corner case in unused (#5066)
fixes #5065
2021-07-11 00:43:01 +08:00
Alex Lam S.L
f67dd31cbb enhance unused (#5064) 2021-07-10 19:58:57 +08:00
Alex Lam S.L
450aabaaa0 fix corner cases in rests & unused (#5063) 2021-07-10 00:28:23 +08:00
Alex Lam S.L
ea7829daf5 fix corner case in reduce_vars (#5062)
fixes #5061
2021-07-08 16:31:04 +08:00
Alex Lam S.L
6577d641ac enhance evaluate & reduce_vars (#5060) 2021-07-08 00:29:23 +08:00
Alex Lam S.L
2340feff87 support destructured shorthand for default parameters (#5059)
closes #4990
2021-07-07 22:45:24 +08:00
Alex Lam S.L
0c48b84540 fix corner cases in inline & unused (#5058)
fixes #5057
2021-07-07 10:29:16 +08:00
Alex Lam S.L
1fefe3f1d1 fix corner case in reduce_vars (#5056)
fixes #5055
2021-07-07 02:23:09 +08:00
Alex Lam S.L
0668fad5e9 fix corner case with class (#5054)
fixes #5053
2021-07-06 16:04:11 +08:00
Alex Lam S.L
d0e3f6955d enhance functions (#5052) 2021-07-06 02:43:09 +08:00
Alex Lam S.L
6961c57d1e fix corner case in reduce_vars (#5051)
fixes #5050
2021-07-05 11:57:58 +08:00
Alex Lam S.L
f5dbb672b9 fix corner case in reduce_funcs (#5049)
fixes #5048
2021-07-04 15:09:05 +08:00
Alex Lam S.L
f4ae267920 fix corner case in reduce_vars (#5047)
fixes #5046
2021-07-04 13:45:09 +08:00
Alex Lam S.L
972b9f0bef enhance functions & reduce_vars (#5045) 2021-07-04 06:19:08 +08:00
Alex Lam S.L
668f96623c tweak beautify output (#5044) 2021-07-03 23:10:39 +08:00
Alex Lam S.L
1b745494ce enhance booleans (#5043) 2021-07-01 03:05:52 +08:00
Alex Lam S.L
611abff49f fix corner case in booleans (#5042)
fixes #5041
2021-07-01 00:52:54 +08:00
Alex Lam S.L
4ba8b66c5a fix corner case in ie8 (#5040)
fixes #5039
2021-06-30 02:14:07 +08:00
Alex Lam S.L
798121c9f3 enhance reduce_vars (#5038) 2021-06-29 03:51:44 +08:00
Alex Lam S.L
b23b333d9d v3.13.10 2021-06-27 22:59:34 +08:00
Alex Lam S.L
7621527a5f fix corner case in functions (#5037)
fixes #5036
2021-06-25 03:43:52 +08:00
Alex Lam S.L
1a064b6e74 fix corner case in functions (#5035)
fixes #5034
2021-06-24 19:43:46 +08:00
Alex Lam S.L
82772ccb12 workaround Safari quirks (#5033)
closes #5032
2021-06-24 17:09:19 +08:00
Alex Lam S.L
7cbcd11440 fix corner case in dead_code (#5031)
fixes #5030
2021-06-23 22:56:28 +08:00
Alex Lam S.L
980dbde171 fix corner cases in booleans (#5029)
fixes #5028
2021-06-23 07:42:57 +08:00
Alex Lam S.L
8b05677c15 fix corner case in collapse_vars (#5026)
fixes #5025
2021-06-23 05:03:11 +08:00
Alex Lam S.L
95090dbf24 fix corner case in side_effects (#5024)
fixes #5023
2021-06-23 00:36:07 +08:00
Alex Lam S.L
7c5b6f349e enhance booleans (#5022)
closes #5021
2021-06-23 00:35:50 +08:00
Alex Lam S.L
e9c902b044 fix corner cases in dead_code & inline (#5020)
fixes #5019
2021-06-21 22:28:54 +08:00
Alex Lam S.L
111366fca0 fix corner case in collapse_vars (#5018)
fixes #5017
2021-06-21 11:12:45 +08:00
Alex Lam S.L
e368d39715 fix corner cases in reduce_vars & side_effects (#5016)
fixes #5015
2021-06-21 03:13:05 +08:00
Alex Lam S.L
fd8dec61ad enhance dead_code (#5014) 2021-06-20 15:30:04 +08:00
Alex Lam S.L
7880568d15 fix corner case in switches (#5013)
fixes #5012
2021-06-15 23:51:53 +08:00
Alex Lam S.L
21fc8f4630 fix corner case in switches (#5011)
fixes #5010
2021-06-15 20:59:53 +08:00
Alex Lam S.L
bf76e35772 fix corner case in switches (#5009)
fixes #5008
2021-06-15 18:27:55 +08:00
Alex Lam S.L
ac1262dc97 fix corner case in arguments (#5007)
fixes #5006
2021-06-15 12:53:22 +08:00
Alex Lam S.L
498ac83541 enhance switches (#5005)
closes #5004
2021-06-15 10:32:39 +08:00
Alex Lam S.L
6fc7a2ab6a fix corner case in side_effects (#5002)
fixes #5001
2021-06-13 20:29:14 +08:00
Alex Lam S.L
f8b2215145 fix corner cases in parse & unused (#5000) 2021-06-13 00:10:01 +08:00
Alex Lam S.L
70ceda5398 minor clean-up (#4998) 2021-06-12 09:20:06 +08:00
Alex Lam S.L
ce75477670 fix corner case in reduce_vars (#4997)
fixes #4996
2021-06-10 08:03:17 +08:00
Alex Lam S.L
e70b84895c fix corner cases in loops & unused (#4995)
fixes #4994
2021-06-10 07:58:33 +08:00
Alex Lam S.L
8dbf0b042e v3.13.9 2021-06-05 05:21:10 +08:00
Alex Lam S.L
83f7887e5d fix corner case in unused (#4993)
fixes #4992
2021-06-03 20:23:14 +08:00
Alex Lam S.L
dff7b48921 workaround GitHub Actions issues (#4991) 2021-06-02 02:43:34 +08:00
Alex Lam S.L
f4f0d2a2dd workaround transient npm failures (#4989) 2021-05-30 17:19:29 +08:00
Alex Lam S.L
06e3dbc089 improve handling of declaration statements (#4980) 2021-05-30 16:32:48 +08:00
Alex Lam S.L
55a230daa8 fix corner case in awaits (#4988)
fixes #4987
2021-05-30 13:40:13 +08:00
Alex Lam S.L
23b9f36bd8 fix corner case in hoist_props (#4986)
fixes #4985
2021-05-30 12:00:32 +08:00
Alex Lam S.L
7e88d52fae fix corner case in dead_code (#4984) 2021-05-30 11:07:55 +08:00
Alex Lam S.L
b9d5bba5fb fix corner case in dead_code (#4983)
fixes #4982
2021-05-30 09:00:48 +08:00
Alex Lam S.L
8d23496e0f fix corner case in dead_code (#4981) 2021-05-30 03:16:18 +08:00
Alex Lam S.L
260431f4e0 improve handling of lexical scope (#4979) 2021-05-29 12:48:34 +08:00
Alex Lam S.L
7fa1dea9d0 fix corner cases in collapse_vars (#4978)
fixes #4977
2021-05-29 08:57:24 +08:00
Alex Lam S.L
d40631fd44 fix corner cases in awaits (#4976)
fixes #4974
fixes #4975
2021-05-29 01:47:54 +08:00
Alex Lam S.L
d320a6cde2 fix corner case in awaits (#4973)
fixes #4972
2021-05-28 10:53:10 +08:00
Alex Lam S.L
8cd95dd263 enhance awaits (#4971) 2021-05-28 08:47:37 +08:00
Alex Lam S.L
749a828fc5 fix corner case in collapse_vars (#4970) 2021-05-28 06:32:43 +08:00
Alex Lam S.L
ab42a90edb enhance awaits (#4969) 2021-05-28 00:57:14 +08:00
Alex Lam S.L
362abe0ffb enhance unused (#4968) 2021-05-26 22:25:07 +08:00
Alex Lam S.L
e3798d9a76 fix corner case in arguments (#4967) 2021-05-26 22:24:26 +08:00
Alex Lam S.L
c8d10b7cde v3.13.8 2021-05-26 19:17:50 +08:00
Alex Lam S.L
7caab39e26 fix corner case in mangle (#4966)
fixes #4965
2021-05-26 06:21:52 +08:00
Alex Lam S.L
eff45eac0e fix corner case in ie8 (#4963)
fixes #4962
2021-05-26 00:12:31 +08:00
Alex Lam S.L
1e787c556b fix corner case in mangle (#4961)
fixes #4960
2021-05-24 11:46:58 +08:00
Alex Lam S.L
df47632ecc fix corner case in ie8 (#4959)
fixes #4958
2021-05-24 11:24:02 +08:00
Alex Lam S.L
eb08fed120 fix corner case in merge_vars (#4957)
fixes #4956
2021-05-24 09:56:02 +08:00
Alex Lam S.L
8b0c836515 fix corner cases in rename & varify (#4955)
fixes #4954
2021-05-24 06:54:48 +08:00
Alex Lam S.L
5d4e6e3bdc enhance sourceMap (#4953) 2021-05-23 23:57:44 +08:00
Alex Lam S.L
d2a45ba441 fix corner case in parsing private field/method (#4952)
fixes #4951
2021-05-22 10:12:37 +08:00
Alex Lam S.L
de376c3d33 fix corner case in reduce_vars (#4950)
fixes #4949
2021-05-21 18:49:07 +08:00
Alex Lam S.L
4a19575e74 fix corner case in conditionals (#4948)
fixes #4947
2021-05-20 18:08:22 +08:00
Alex Lam S.L
e0695ef549 enhance pure_funcs (#4945) 2021-05-20 07:09:47 +08:00
Alex Lam S.L
d6152e6a76 fix corner case in collapse_vars (#4946) 2021-05-20 05:11:39 +08:00
Alex Lam S.L
d930c705f6 v3.13.7 2021-05-19 02:38:19 +08:00
Alex Lam S.L
254937754c fix corner case in reduce_vars (#4944)
fixes #4943
2021-05-18 05:52:24 +08:00
Alex Lam S.L
ae4dbcb5b9 document v8 quirks (#4942)
closes #4941
2021-05-16 02:13:30 +08:00
Alex Lam S.L
e13615549e fix corner case in pure_getters (#4940)
fixes #4939
2021-05-16 02:12:58 +08:00
Alex Lam S.L
a7698f8845 fix corner case in reduce_vars (#4938)
fixes #4937
2021-05-15 22:38:09 +08:00
Alex Lam S.L
bbed9b13b1 fix corner case in collapse_vars (#4936)
fixes #4935
2021-05-15 22:34:14 +08:00
Alex Lam S.L
2cff7c94e8 fix corner case in reduce_vars (#4934)
fixes #4933
2021-05-15 01:49:46 +08:00
Alex Lam S.L
7576048118 fix corner case in unsafe evaluate (#4932)
fixes #4931
2021-05-14 22:51:19 +08:00
Alex Lam S.L
3c1898fd65 suppress invalid test case generation (#4930) 2021-05-13 19:57:36 +08:00
Alex Lam S.L
e04429350f fix corner case in ie8 (#4929)
fixes #4928
2021-05-13 09:26:57 +08:00
Alex Lam S.L
60f3b55156 fix corner case with optional chain operator (#4927) 2021-05-12 10:12:19 +08:00
Alex Lam S.L
689f8f504d enhance mangle (#4926) 2021-05-11 23:41:32 +08:00
Alex Lam S.L
ae51f76ba7 fix corner case in unused (#4925)
fixes #4924
2021-05-11 20:50:58 +08:00
Alex Lam S.L
7eef86ed05 workaround GitHub Actions issue (#4923) 2021-05-11 18:21:21 +08:00
Alex Lam S.L
b1cfa71131 enhance unused (#4922) 2021-05-11 10:30:20 +08:00
97 changed files with 10919 additions and 2199 deletions

View File

@@ -10,7 +10,7 @@ jobs:
matrix:
options:
- '-mb braces'
- '--ie8 -c'
- '--ie -c'
- '-mc'
- '-p acorn --toplevel -mco spidermonkey'
- '--toplevel -mc passes=3,pure_getters,unsafe'

View File

@@ -7,14 +7,9 @@ jobs:
test:
strategy:
matrix:
node: [ '0.8', '0.10', '0.12', '4', '6', '8', '10', '12', '14', latest ]
node: [ '0.10', '0.12', '4', '6', '8', '10', '12', '14', '16', latest ]
os: [ ubuntu-latest, windows-latest ]
script: [ compress, mocha, release/benchmark, release/jetstream ]
exclude:
- node: '0.8'
script: release/benchmark
- node: '0.8'
script: release/jetstream
name: ${{ matrix.node }} ${{ matrix.os }} ${{ matrix.script }}
runs-on: ${{ matrix.os }}
env:

View File

@@ -2,11 +2,14 @@ name: Fuzzing
on:
pull_request:
schedule:
- cron: '*/5 * * * *'
- cron: '*/15 * * * *'
workflow_dispatch:
workflow_run:
branches: [ master ]
types: [ completed ]
workflows: [ 'Build testing', CI ]
env:
BASE_URL: https://api.github.com/repos/${{ github.repository }}
CAUSE: ${{ github.event_name }}
RUN_NUM: ${{ github.run_number }}
TOKEN: ${{ github.token }}
jobs:
ufuzz:
@@ -34,8 +37,8 @@ jobs:
shell: bash
run: |
. ./test/release/install.sh
if [[ $CAUSE == "schedule" ]]; then
node test/ufuzz/job $BASE_URL $TOKEN $RUN_NUM
else
if [[ $GITHUB_EVENT_NAME == "pull_request" ]]; then
node test/ufuzz/job 5000
else
node test/ufuzz/job $BASE_URL $TOKEN $GITHUB_RUN_NUMBER
fi

View File

@@ -111,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
@@ -502,7 +502,7 @@ if (result.error) throw result.error;
- `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
of function names. Useful for code relying on `Function.prototype.name`.
@@ -566,7 +566,6 @@ if (result.error) throw result.error;
},
nameCache: null, // or specify a name cache object
toplevel: false,
ie8: false,
warnings: false,
}
```
@@ -795,9 +794,8 @@ to be `false` and all symbol names will be omitted.
variables (`"vars"`) in the top level scope (`false` by default, `true` to drop
both unreferenced functions and variables)
- `typeofs` (default: `true`) — Transforms `typeof foo == "undefined"` into
`foo === void 0`. Note: recommend to set this value to `false` for IE10 and
earlier versions due to known issues.
- `typeofs` (default: `true`) — compress `typeof` expressions, e.g.
`typeof foo == "undefined" → void 0 === foo`
- `unsafe` (default: `false`) — apply "unsafe" transformations (discussion below)
@@ -1201,6 +1199,17 @@ To allow for better optimizations, the compiler makes various assumptions:
- Object properties can be added, removed and modified (not prevented with
`Object.defineProperty()`, `Object.defineProperties()`, `Object.freeze()`,
`Object.preventExtensions()` or `Object.seal()`).
- If array destructuring is present, index-like properties in `Array.prototype`
have not been overridden:
```javascript
Object.prototype[0] = 42;
var [ a ] = [];
var { 0: b } = {};
// 42 undefined
console.log([][0], a);
// 42 42
console.log({}[0], b);
```
- Earlier versions of JavaScript will throw `SyntaxError` with the following:
```javascript
({
@@ -1327,3 +1336,30 @@ To allow for better optimizations, the compiler makes various assumptions:
// 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

@@ -10,7 +10,9 @@ var info = require("../package.json");
var path = require("path");
var UglifyJS = require("../tools/node");
var skip_keys = [ "cname", "fixed", "inlined", "parent_scope", "scope", "uses_eval", "uses_with" ];
var skip_keys = [ "cname", "fixed", "in_arg", "inlined", "length_read", "parent_scope", "redef", "scope", "unused" ];
var truthy_keys = [ "optional", "pure", "terminal", "uses_arguments", "uses_eval", "uses_with" ];
var files = {};
var options = {};
var short_forms = {
@@ -101,7 +103,7 @@ function process_option(name, no_value) {
" --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.",
@@ -110,6 +112,7 @@ 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.",
@@ -145,9 +148,11 @@ function process_option(name, no_value) {
options[name] = read_value();
break;
case "annotations":
case "ie":
case "ie8":
case "timings":
case "toplevel":
case "v8":
case "validate":
case "webkit":
options[name] = true;
@@ -344,9 +349,9 @@ function run() {
var list = annotations[node.start.file];
var pure = list[node.start.pos];
if (!pure) {
var pos = node.start.parens;
if (pos) for (var i = 0; !pure && i < pos.length; i++) {
pure = list[pos[i]];
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;
@@ -427,7 +432,7 @@ function run() {
case "thedef":
return symdef(value);
}
if (skip_key(key)) return;
if (skip_property(key, value)) return;
if (value instanceof UglifyJS.AST_Token) return;
if (value instanceof UglifyJS.Dictionary) return;
if (value instanceof UglifyJS.AST_Node) {
@@ -516,7 +521,7 @@ function read_file(path, default_value) {
}
function parse_js(value, options, flag) {
if (!options || typeof options != "object") options = {};
if (!options || typeof options != "object") options = Object.create(null);
if (typeof value == "string") try {
UglifyJS.parse(value, {
expression: true
@@ -556,8 +561,10 @@ function parse_js(value, options, flag) {
return options;
}
function skip_key(key) {
return skip_keys.indexOf(key) >= 0;
function skip_property(key, value) {
return skip_keys.indexOf(key) >= 0
// only skip truthy_keys if their value is falsy
|| truthy_keys.indexOf(key) >= 0 && !value;
}
function symdef(def) {

View File

@@ -50,41 +50,39 @@ function DEFNODE(type, props, methods, base) {
if (base && base.PROPS) props = props.concat(base.PROPS);
var code = [
"return function AST_", type, "(props){",
// not essential, but speeds up compress by a few percent
"this._bits=0;",
"if(props){",
];
props.forEach(function(prop) {
code.push("this.", prop, "=props.", prop, ";");
});
code.push("}");
var proto = base && new base;
if (proto && proto.initialize || methods && methods.initialize) code.push("this.initialize();");
code.push("}");
var proto = Object.create(base && base.prototype);
if (methods.initialize || proto.initialize) code.push("this.initialize();");
code.push("};");
var ctor = new Function(code.join(""))();
if (proto) {
ctor.prototype = proto;
ctor.BASE = base;
}
if (base) base.SUBCLASSES.push(ctor);
ctor.prototype = proto;
ctor.prototype.CTOR = ctor;
ctor.PROPS = props || null;
ctor.SELF_PROPS = self_props;
ctor.SUBCLASSES = [];
if (type) {
ctor.prototype.TYPE = ctor.TYPE = type;
}
if (methods) for (var name in methods) if (HOP(methods, name)) {
if (/^\$/.test(name)) {
ctor[name.substr(1)] = methods[name];
} else {
ctor.prototype[name] = methods[name];
}
ctor.prototype.TYPE = ctor.TYPE = type;
if (base) {
ctor.BASE = base;
base.SUBCLASSES.push(ctor);
}
ctor.DEFMETHOD = function(name, method) {
this.prototype[name] = method;
};
if (typeof exports !== "undefined") {
exports["AST_" + type] = ctor;
ctor.PROPS = props;
ctor.SELF_PROPS = self_props;
ctor.SUBCLASSES = [];
for (var name in methods) if (HOP(methods, name)) {
if (/^\$/.test(name)) {
ctor[name.substr(1)] = methods[name];
} else {
ctor.DEFMETHOD(name, methods[name]);
}
}
if (typeof exports !== "undefined") exports["AST_" + type] = ctor;
return ctor;
}
@@ -139,6 +137,52 @@ var AST_Node = DEFNODE("Node", "start end", {
},
}, null);
DEF_BITPROPS(AST_Node, [
"_optimized",
"_squeezed",
// AST_Call
"call_only",
"collapse_scanning",
// AST_SymbolRef
"defined",
"evaluating",
"falsy",
// AST_SymbolRef
"in_arg",
// AST_Return
"in_bool",
// AST_SymbolRef
"is_undefined",
// AST_LambdaExpression
// AST_LambdaDefinition
"inlined",
// AST_Lambda
"length_read",
// AST_Yield
"nested",
// AST_Lambda
"new",
// AST_Call
// AST_PropAccess
"optional",
// AST_ClassProperty
"private",
// AST_Call
"pure",
// AST_Assign
"redundant",
// AST_ClassProperty
"static",
// AST_Call
// AST_PropAccess
"terminal",
"truthy",
// AST_Scope
"uses_eval",
// AST_Scope
"uses_with",
]);
(AST_Node.log_function = function(fn, verbose) {
if (typeof fn != "function") {
AST_Node.info = AST_Node.warn = noop;
@@ -257,7 +301,7 @@ var AST_SimpleStatement = DEFNODE("SimpleStatement", "body", {
},
}, AST_Statement);
var AST_BlockScope = DEFNODE("BlockScope", "enclosed functions make_def parent_scope variables", {
var AST_BlockScope = DEFNODE("BlockScope", "_var_names enclosed functions make_def parent_scope variables", {
$documentation: "Base class for all statements introducing a lexical scope",
$propdoc: {
enclosed: "[SymbolDef*/S] a list of all symbol definitions that are accessed from this scope or any subscopes",
@@ -488,7 +532,7 @@ var AST_With = DEFNODE("With", "expression", {
/* -----[ scope and functions ]----- */
var AST_Scope = DEFNODE("Scope", "uses_eval uses_with", {
var AST_Scope = DEFNODE("Scope", "fn_defs may_call_this uses_eval uses_with", {
$documentation: "Base class for all statements introducing a lexical scope",
$propdoc: {
uses_eval: "[boolean/S] tells whether this scope contains a direct call to the global `eval`",
@@ -547,13 +591,13 @@ var AST_Toplevel = DEFNODE("Toplevel", "globals", {
}
}, AST_Scope);
var AST_Lambda = DEFNODE("Lambda", "argnames length_read rest uses_arguments", {
var AST_Lambda = DEFNODE("Lambda", "argnames length_read rest safe_ids uses_arguments", {
$documentation: "Base class for functions",
$propdoc: {
argnames: "[(AST_DefaultValue|AST_Destructured|AST_SymbolFunarg)*] array of function arguments and/or destructured literals",
length_read: "[boolean/S] whether length property of this function is accessed",
rest: "[(AST_Destructured|AST_SymbolFunarg)?] rest parameter, or null if absent",
uses_arguments: "[boolean/S] whether this function accesses the arguments array",
uses_arguments: "[boolean|number/S] whether this function accesses the arguments array",
},
each_argname: function(visit) {
var tw = new TreeWalker(function(node) {
@@ -1293,13 +1337,14 @@ function must_be_expressions(node, prop, allow_spread, allow_hole) {
});
}
var AST_Call = DEFNODE("Call", "args expression optional pure", {
var AST_Call = DEFNODE("Call", "args expression optional pure terminal", {
$documentation: "A function call expression",
$propdoc: {
args: "[AST_Node*] array of arguments",
expression: "[AST_Node] expression to invoke as function",
optional: "[boolean] whether the expression is optional chaining",
pure: "[string/S] marker for side-effect-free call expression",
pure: "[boolean/S] marker for side-effect-free call expression",
terminal: "[boolean] whether the chain has ended",
},
walk: function(visitor) {
var node = this;
@@ -1320,6 +1365,7 @@ var AST_New = DEFNODE("New", null, {
$documentation: "An object instantiation. Derives from a function call since it has exactly the same properties",
_validate: function() {
if (this.optional) throw new Error("optional must be false");
if (this.terminal) throw new Error("terminal must be false");
},
}, AST_Call);
@@ -1342,23 +1388,23 @@ var AST_Sequence = DEFNODE("Sequence", "expressions", {
},
});
var AST_PropAccess = DEFNODE("PropAccess", "expression optional property", {
function root_expr(prop) {
while (prop instanceof AST_PropAccess) prop = prop.expression;
return prop;
}
var AST_PropAccess = DEFNODE("PropAccess", "expression optional property terminal", {
$documentation: "Base class for property access expressions, i.e. `a.foo` or `a[\"foo\"]`",
$propdoc: {
expression: "[AST_Node] the “container” expression",
optional: "[boolean] whether the expression is optional chaining",
property: "[AST_Node|string] the property to access. For AST_Dot this is always a plain string, while for AST_Sub it's an arbitrary AST_Node",
terminal: "[boolean] whether the chain has ended",
},
getProperty: function() {
get_property: function() {
var p = this.property;
if (p instanceof AST_Constant) {
return p.value;
}
if (p instanceof AST_UnaryPrefix
&& p.operator == "void"
&& p.expression instanceof AST_Constant) {
return;
}
if (p instanceof AST_Constant) return p.value;
if (p instanceof AST_UnaryPrefix && p.operator == "void" && p.expression instanceof AST_Constant) return;
return p;
},
_validate: function() {
@@ -1692,7 +1738,7 @@ var AST_ObjectMethod = DEFNODE("ObjectMethod", null, {
_validate: function() {
if (!(this.value instanceof AST_LambdaExpression)) throw new Error("value must be AST_LambdaExpression");
if (is_arrow(this.value)) throw new Error("value cannot be AST_Arrow or AST_AsyncArrow");
if (this.value.name != null) throw new Error("name of class method's lambda must be null");
if (this.value.name != null) throw new Error("name of object method's lambda must be null");
},
}, AST_ObjectKeyVal);
@@ -1749,7 +1795,7 @@ var AST_SymbolVar = DEFNODE("SymbolVar", null, {
$documentation: "Symbol defining a variable",
}, AST_SymbolDeclaration);
var AST_SymbolFunarg = DEFNODE("SymbolFunarg", null, {
var AST_SymbolFunarg = DEFNODE("SymbolFunarg", "unused", {
$documentation: "Symbol naming a function argument",
}, AST_SymbolVar);
@@ -1763,11 +1809,11 @@ var AST_SymbolLambda = DEFNODE("SymbolLambda", null, {
var AST_SymbolDefClass = DEFNODE("SymbolDefClass", null, {
$documentation: "Symbol defining a class",
}, AST_SymbolLet);
}, AST_SymbolConst);
var AST_SymbolClass = DEFNODE("SymbolClass", null, {
$documentation: "Symbol naming a class expression",
}, AST_SymbolLet);
}, AST_SymbolConst);
var AST_SymbolCatch = DEFNODE("SymbolCatch", null, {
$documentation: "Symbol naming the exception in catch",
@@ -2001,7 +2047,7 @@ TreeWalker.prototype = {
},
find_parent: function(type) {
var stack = this.stack;
for (var i = stack.length; --i >= 0;) {
for (var i = stack.length - 1; --i >= 0;) {
var x = stack[i];
if (x instanceof type) return x;
}

File diff suppressed because it is too large Load Diff

View File

@@ -76,6 +76,7 @@ function minify(files, options) {
annotations: undefined,
compress: {},
enclose: false,
ie: false,
ie8: false,
keep_fnames: false,
mangle: {},
@@ -96,17 +97,18 @@ function minify(files, options) {
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) set_shorthand("ie8", options, [ "compress", "mangle", "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, [ "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: [],

View File

@@ -556,7 +556,9 @@
return node;
},
ChainExpression: function(M) {
return from_moz(M.expression);
var node = from_moz(M.expression);
node.terminal = true;
return node;
},
};
@@ -868,7 +870,7 @@
def_to_moz(AST_PropAccess, function To_Moz_MemberExpression(M) {
var computed = M instanceof AST_Sub;
return {
var expr = {
type: "MemberExpression",
object: to_moz(M.expression),
computed: computed,
@@ -878,6 +880,10 @@
name: M.property,
},
};
return M.terminal ? {
type: "ChainExpression",
expression: expr,
} : expr;
});
def_to_moz(AST_Unary, function To_Moz_Unary(M) {
@@ -1134,58 +1140,54 @@
}
function map(moztype, mytype, propmap) {
var moz_to_me = "function From_Moz_" + moztype + "(M){\n";
moz_to_me += "return new U2." + mytype.name + "({\n" +
"start: my_start_token(M),\n" +
"end: my_end_token(M)";
var me_to_moz = "function To_Moz_" + moztype + "(M){\n";
me_to_moz += "return {\n" +
"type: " + JSON.stringify(moztype);
var moz_to_me = [
"start: my_start_token(M)",
"end: my_end_token(M)",
];
var me_to_moz = [
"type: " + JSON.stringify(moztype),
];
if (propmap) propmap.split(/\s*,\s*/).forEach(function(prop) {
var m = /([a-z0-9$_]+)(=|@|>|%)([a-z0-9$_]+)/i.exec(prop);
if (!m) throw new Error("Can't understand property map: " + prop);
var moz = m[1], how = m[2], my = m[3];
moz_to_me += ",\n" + my + ": ";
me_to_moz += ",\n" + moz + ": ";
switch (how) {
case "@":
moz_to_me += "M." + moz + ".map(from_moz)";
me_to_moz += "M." + my + ".map(to_moz)";
moz_to_me.push(my + ": M." + moz + ".map(from_moz)");
me_to_moz.push(moz + ": M." + my + ".map(to_moz)");
break;
case ">":
moz_to_me += "from_moz(M." + moz + ")";
me_to_moz += "to_moz(M." + my + ")";
moz_to_me.push(my + ": from_moz(M." + moz + ")");
me_to_moz.push(moz + ": to_moz(M." + my + ")");
break;
case "=":
moz_to_me += "M." + moz;
me_to_moz += "M." + my;
moz_to_me.push(my + ": M." + moz);
me_to_moz.push(moz + ": M." + my);
break;
case "%":
moz_to_me += "from_moz(M." + moz + ").body";
me_to_moz += "to_moz_block(M)";
moz_to_me.push(my + ": from_moz(M." + moz + ").body");
me_to_moz.push(moz + ": to_moz_block(M)");
break;
default:
throw new Error("Can't understand operator in propmap: " + prop);
}
});
moz_to_me += "\n})\n}";
me_to_moz += "\n}\n}";
//moz_to_me = parse(moz_to_me).print_to_string({ beautify: true });
//me_to_moz = parse(me_to_moz).print_to_string({ beautify: true });
//console.log(moz_to_me);
moz_to_me = new Function("U2", "my_start_token", "my_end_token", "from_moz", "return(" + moz_to_me + ")")(
exports, my_start_token, my_end_token, from_moz
);
me_to_moz = new Function("to_moz", "to_moz_block", "to_moz_scope", "return(" + me_to_moz + ")")(
to_moz, to_moz_block, to_moz_scope
);
MOZ_TO_ME[moztype] = moz_to_me;
def_to_moz(mytype, me_to_moz);
MOZ_TO_ME[moztype] = new Function("U2", "my_start_token", "my_end_token", "from_moz", [
"return function From_Moz_" + moztype + "(M) {",
" return new U2.AST_" + mytype.TYPE + "({",
moz_to_me.join(",\n"),
" });",
"};",
].join("\n"))(exports, my_start_token, my_end_token, from_moz);
def_to_moz(mytype, new Function("to_moz", "to_moz_block", "to_moz_scope", [
"return function To_Moz_" + moztype + "(M) {",
" return {",
me_to_moz.join(",\n"),
" };",
"};",
].join("\n"))(to_moz, to_moz_block, to_moz_scope));
}
var FROM_MOZ_STACK = null;

View File

@@ -56,7 +56,7 @@ function OutputStream(options) {
braces : false,
comments : false,
galio : false,
ie8 : false,
ie : false,
indent_level : 4,
indent_start : 0,
inline_script : true,
@@ -193,7 +193,7 @@ function OutputStream(options) {
case "\t": return "\\t";
case "\b": return "\\b";
case "\f": return "\\f";
case "\x0B": return options.ie8 ? "\\x0B" : "\\v";
case "\x0B": return options.ie ? "\\x0B" : "\\v";
case "\u2028": return "\\u2028";
case "\u2029": return "\\u2029";
case "\ufeff": return "\\ufeff";
@@ -790,35 +790,44 @@ function OutputStream(options) {
if (p instanceof AST_Unary) return true;
});
function need_chain_parens(node, parent) {
if (!node.terminal) return false;
if (!(parent instanceof AST_Call || parent instanceof AST_PropAccess)) return false;
return parent.expression === node;
}
PARENS(AST_PropAccess, function(output) {
var node = this;
var p = output.parent();
if (p instanceof AST_New && p.expression === node) {
// i.e. new (foo().bar)
//
// if there's one call into this subtree, then we need
// parens around it too, otherwise the call will be
// interpreted as passing the arguments to the upper New
// expression.
do {
node = node.expression;
} while (node instanceof AST_PropAccess);
return node.TYPE == "Call";
}
// i.e. new (foo().bar)
//
// if there's one call into this subtree, then we need
// parens around it too, otherwise the call will be
// interpreted as passing the arguments to the upper New
// expression.
if (p instanceof AST_New && p.expression === node && root_expr(node).TYPE == "Call") return true;
// (foo?.bar)()
// (foo?.bar).baz
// new (foo?.bar)()
return need_chain_parens(node, p);
});
PARENS(AST_Call, function(output) {
var node = this;
var p = output.parent();
if (p instanceof AST_New) return p.expression === this;
if (p instanceof AST_New) return p.expression === node;
// https://bugs.webkit.org/show_bug.cgi?id=123506
if (output.option("webkit")) {
if (output.option("webkit")
&& node.expression instanceof AST_Function
&& p instanceof AST_PropAccess
&& p.expression === node) {
var g = output.parent(1);
return this.expression instanceof AST_Function
&& p instanceof AST_PropAccess
&& p.expression === this
&& g instanceof AST_Assign
&& g.left === p;
if (g instanceof AST_Assign && g.left === p) return true;
}
// (foo?.())()
// (foo?.()).bar
// new (foo?.())()
return need_chain_parens(node, p);
});
PARENS(AST_New, function(output) {
@@ -965,7 +974,6 @@ function OutputStream(options) {
DEFPRINT(AST_Do, function(output) {
var self = this;
output.print("do");
output.space();
make_block(self.body, output);
output.space();
output.print("while");
@@ -982,7 +990,6 @@ function OutputStream(options) {
output.with_parens(function() {
self.condition.print(output);
});
output.space();
force_statement(self.body, output);
});
DEFPRINT(AST_For, function(output) {
@@ -1012,7 +1019,6 @@ function OutputStream(options) {
self.step.print(output);
}
});
output.space();
force_statement(self.body, output);
});
function print_for_enum(prefix, infix) {
@@ -1027,7 +1033,6 @@ function OutputStream(options) {
output.space();
self.object.print(output);
});
output.space();
force_statement(self.body, output);
};
}
@@ -1041,7 +1046,6 @@ function OutputStream(options) {
output.with_parens(function() {
self.expression.print(output);
});
output.space();
force_statement(self.body, output);
});
DEFPRINT(AST_ExportDeclaration, function(output) {
@@ -1148,8 +1152,9 @@ function OutputStream(options) {
});
}
function print_arrow(self, output) {
if (self.argnames.length == 1 && self.argnames[0] instanceof AST_SymbolFunarg && !self.rest) {
self.argnames[0].print(output);
var argname = self.argnames.length == 1 && !self.rest && self.argnames[0];
if (argname instanceof AST_SymbolFunarg && argname.name != "yield") {
argname.print(output);
} else {
print_funargs(self, output);
}
@@ -1280,7 +1285,7 @@ function OutputStream(options) {
function make_then(self, output) {
var b = self.body;
if (output.option("braces") && !(b instanceof AST_Const || b instanceof AST_Let)
|| output.option("ie8") && b instanceof AST_Do)
|| output.option("ie") && b instanceof AST_Do)
return make_block(b, output);
// The squeezer replaces "block"-s that contain only a single
// statement with the statement itself; technically, the AST
@@ -1310,16 +1315,16 @@ function OutputStream(options) {
output.with_parens(function() {
self.condition.print(output);
});
output.space();
if (self.alternative) {
make_then(self, output);
output.space();
output.print("else");
output.space();
if (self.alternative instanceof AST_If)
if (self.alternative instanceof AST_If) {
output.space();
self.alternative.print(output);
else
} else {
force_statement(self.alternative, output);
}
} else {
force_statement(self.body, output);
}
@@ -1460,7 +1465,7 @@ function OutputStream(options) {
parent = output.parent(level++);
if (parent instanceof AST_Call && parent.expression === node) return;
} while (parent instanceof AST_PropAccess && parent.expression === node);
output.print(typeof self.pure == "string" ? "/*" + self.pure + "*/" : "/*@__PURE__*/");
output.print("/*@__PURE__*/");
}
function print_call_args(self, output) {
if (self.expression instanceof AST_Call || self.expression instanceof AST_Lambda) {
@@ -1505,7 +1510,7 @@ function OutputStream(options) {
var expr = self.expression;
expr.print(output);
var prop = self.property;
if (output.option("ie8") && RESERVED_WORDS[prop]) {
if (output.option("ie") && RESERVED_WORDS[prop]) {
output.print(self.optional ? "?.[" : "[");
output.add_mapping(self.end);
output.print_string(prop);
@@ -1619,7 +1624,19 @@ function OutputStream(options) {
var self = this;
var key = print_property_key(self, output);
var value = self.value;
if (key && value instanceof AST_SymbolDeclaration && key == get_symbol_name(value)) return;
if (key) {
if (value instanceof AST_DefaultValue) {
if (value.name instanceof AST_Symbol && key == get_symbol_name(value.name)) {
output.space();
output.print("=");
output.space();
value.value.print(output);
return;
}
} else if (value instanceof AST_Symbol) {
if (key == get_symbol_name(value)) return;
}
}
output.colon();
value.print(output);
});
@@ -1668,28 +1685,21 @@ function OutputStream(options) {
function print_property_key(self, output) {
var key = self.key;
if (key instanceof AST_Node) {
output.with_square(function() {
key.print(output);
});
} else if (output.option("quote_keys")) {
output.print_string(key);
if (key instanceof AST_Node) return output.with_square(function() {
key.print(output);
});
var quote = self.start && self.start.quote;
if (output.option("quote_keys") || quote && output.option("keep_quoted_props")) {
output.print_string(key, quote);
} else if ("" + +key == key && key >= 0) {
output.print(make_num(key));
} else if (self.private) {
output.print_name(key);
} else if (RESERVED_WORDS[key] ? !output.option("ie") : is_identifier_string(key)) {
output.print_name(key);
return key;
} else {
var quote = self.start && self.start.quote;
if (self.private) {
output.print_name(key);
} else if (RESERVED_WORDS[key] ? !output.option("ie8") : is_identifier_string(key)) {
if (quote && output.option("keep_quoted_props")) {
output.print_string(key, quote);
} else {
output.print_name(key);
return key;
}
} else {
output.print_string(key, quote);
}
output.print_string(key, quote);
}
}
DEFPRINT(AST_ObjectKeyVal, function(output) {
@@ -1821,6 +1831,7 @@ function OutputStream(options) {
} else if (stat instanceof AST_EmptyStatement) {
output.force_semicolon();
} else {
output.space();
stat.print(output);
}
}
@@ -1869,6 +1880,7 @@ function OutputStream(options) {
}
function make_block(stmt, output) {
output.space();
if (stmt instanceof AST_EmptyStatement) {
print_braced_empty(stmt, output);
} else if (stmt instanceof AST_BlockStatement) {
@@ -1920,7 +1932,11 @@ function OutputStream(options) {
output.add_mapping(this.start);
});
DEFMAP([ AST_DestructuredKeyVal, AST_ObjectProperty ], function(output) {
DEFMAP([
AST_ClassProperty,
AST_DestructuredKeyVal,
AST_ObjectProperty,
], function(output) {
if (typeof this.key == "string") output.add_mapping(this.start, this.key);
});
})();

View File

@@ -44,10 +44,10 @@
"use strict";
var KEYWORDS = "break case catch class const continue debugger default delete do else extends finally for function if in instanceof let new return switch throw try typeof var void while with";
var KEYWORDS = "break case catch class const continue debugger default delete do else extends finally for function if in instanceof new return switch throw try typeof var void while with";
var KEYWORDS_ATOM = "false null true";
var RESERVED_WORDS = [
"abstract async await boolean byte char double enum export final float goto implements import int interface long native package private protected public short static super synchronized this throws transient volatile yield",
"abstract async await boolean byte char double enum export final float goto implements import int interface let long native package private protected public short static super synchronized this throws transient volatile yield",
KEYWORDS_ATOM,
KEYWORDS,
].join(" ");
@@ -124,7 +124,7 @@ var PUNC_AFTER_EXPRESSION = PUNC_SEPARATORS + PUNC_CLOSERS;
var PUNC_BEFORE_EXPRESSION = PUNC_OPENERS + PUNC_SEPARATORS;
var PUNC_CHARS = PUNC_BEFORE_EXPRESSION + "`" + PUNC_CLOSERS;
var WHITESPACE_CHARS = NEWLINE_CHARS + " \u00a0\t\f\u000b\u200b\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\uFEFF";
var NON_IDENTIFIER_CHARS = makePredicate(characters("./'\"" + OPERATOR_CHARS + PUNC_CHARS + WHITESPACE_CHARS));
var NON_IDENTIFIER_CHARS = makePredicate(characters("./'\"#" + OPERATOR_CHARS + PUNC_CHARS + WHITESPACE_CHARS));
NEWLINE_CHARS = makePredicate(characters(NEWLINE_CHARS));
OPERATOR_CHARS = makePredicate(characters(OPERATOR_CHARS));
@@ -242,10 +242,10 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
read_template : with_eof_error("Unterminated template literal", function(strings) {
var s = "";
for (;;) {
var ch = next(true, true);
var ch = read();
switch (ch) {
case "\\":
ch += next(true, true);
ch += read();
break;
case "`":
strings.push(s);
@@ -260,6 +260,11 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
}
s += ch;
}
function read() {
var ch = next(true, true);
return ch == "\r" ? "\n" : ch;
}
}),
};
var prev_was_dot = false;
@@ -468,7 +473,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
});
function read_name() {
var backslash = false, name = "", ch, escaped = false, hex;
var backslash = false, ch, escaped = false, name = peek() == "#" ? next() : "";
while (ch = peek()) {
if (!backslash) {
if (ch == "\\") escaped = backslash = true, next();
@@ -483,7 +488,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
}
}
if (KEYWORDS[name] && escaped) {
hex = name.charCodeAt(0).toString(16).toUpperCase();
var hex = name.charCodeAt(0).toString(16).toUpperCase();
name = "\\u" + "0000".substr(hex.length) + hex + name.slice(1);
}
return name;
@@ -618,7 +623,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
if (PUNC_CHARS[ch]) return token("punc", next());
if (looking_at("=>")) return token("punc", next() + next());
if (OPERATOR_CHARS[ch]) return read_operator();
if (code == 92 || !NON_IDENTIFIER_CHARS[ch]) return read_word();
if (code == 35 || code == 92 || !NON_IDENTIFIER_CHARS[ch]) return read_word();
break;
}
parse_error("Unexpected character '" + ch + "'");
@@ -862,6 +867,15 @@ function parse($TEXT, options) {
next();
return import_();
}
break;
case "let":
if (is_vardefs()) {
next();
var node = let_();
semicolon();
return node;
}
break;
case "yield":
if (S.in_generator) return simple_statement();
break;
@@ -947,12 +961,6 @@ function parse($TEXT, options) {
next();
return if_();
case "let":
next();
var node = let_();
semicolon();
return node;
case "return":
if (S.in_function == 0 && !options.bare_returns)
croak("'return' outside of function");
@@ -1192,7 +1200,7 @@ function parse($TEXT, options) {
if (await || !is("punc", ";")) {
init = is("keyword", "const")
? (next(), const_(true))
: is("keyword", "let")
: is("name", "let") && is_vardefs()
? (next(), let_(true))
: is("keyword", "var")
? (next(), var_(true))
@@ -1308,6 +1316,11 @@ function parse($TEXT, options) {
}
if (node instanceof AST_SymbolFunarg) return node;
if (node instanceof AST_SymbolRef) return new AST_SymbolFunarg(node);
if (node instanceof AST_Yield) return new AST_SymbolFunarg({
start: node.start,
name: "yield",
end: node.end,
});
token_error(node.start, "Invalid arrow parameter");
}
@@ -1334,21 +1347,19 @@ function parse($TEXT, options) {
if (is("punc", "{")) {
body = block_();
value = null;
if (S.input.has_directive("use strict")) {
argnames.forEach(strict_verify_symbol);
}
} else {
body = [];
handle_regexp();
value = maybe_assign();
}
var is_strict = S.input.has_directive("use strict");
S.input.pop_directives_stack();
--S.in_function;
S.in_loop = loop;
S.labels = labels;
S.in_generator = was_gen;
S.in_async = was_async;
return new (async ? AST_AsyncArrow : AST_Arrow)({
var node = new (async ? AST_AsyncArrow : AST_Arrow)({
start: start,
argnames: argnames,
rest: rest,
@@ -1356,6 +1367,8 @@ function parse($TEXT, options) {
value: value,
end: prev(),
});
if (is_strict) node.each_argname(strict_verify_symbol);
return node;
}
var function_ = function(ctor) {
@@ -1388,23 +1401,24 @@ function parse($TEXT, options) {
S.in_loop = 0;
S.labels = [];
var body = block_();
if (S.input.has_directive("use strict")) {
if (name) strict_verify_symbol(name);
argnames.forEach(strict_verify_symbol);
if (argnames.rest) strict_verify_symbol(argnames.rest);
}
var is_strict = S.input.has_directive("use strict");
S.input.pop_directives_stack();
--S.in_function;
S.in_loop = loop;
S.labels = labels;
S.in_generator = was_gen;
S.in_async = was_async;
return new ctor({
var node = new ctor({
name: name,
argnames: argnames,
rest: argnames.rest || null,
body: body
});
if (is_strict) {
if (name) strict_verify_symbol(name);
node.each_argname(strict_verify_symbol);
}
return node;
};
function if_() {
@@ -1534,12 +1548,18 @@ function parse($TEXT, options) {
}
var export_decl = embed_tokens(function() {
if (is("name", "async")) {
if (is("name")) switch (S.token.value) {
case "async":
next();
expect_token("keyword", "function");
if (!is("operator", "*")) return function_(AST_AsyncDefun);
next();
return function_(AST_AsyncGeneratorDefun);
case "let":
next();
var node = let_();
semicolon();
return node;
} else if (is("keyword")) switch (S.token.value) {
case "class":
next();
@@ -1554,11 +1574,6 @@ function parse($TEXT, options) {
if (!is("operator", "*")) return function_(AST_Defun);
next();
return function_(AST_GeneratorDefun);
case "let":
next();
var node = let_();
semicolon();
return node;
case "var":
next();
var node = var_();
@@ -1719,6 +1734,11 @@ function parse($TEXT, options) {
return a;
}
function is_vardefs() {
var token = peek();
return is_token(token, "name") || is_token(token, "punc", "[") || is_token(token, "punc", "{");
}
var const_ = function(no_in) {
return new AST_Const({
start : prev(),
@@ -1817,10 +1837,7 @@ function parse($TEXT, options) {
if (is("punc")) {
switch (start.value) {
case "`":
var tmpl = template(null);
tmpl.start = start;
tmpl.end = prev();
return subscripts(tmpl, allow_calls);
return subscripts(template(null), allow_calls);
case "(":
next();
if (is("punc", ")")) {
@@ -2132,7 +2149,7 @@ function parse($TEXT, options) {
}
function strict_verify_symbol(sym) {
if (sym.name == "arguments" || sym.name == "eval")
if (sym.name == "arguments" || sym.name == "eval" || sym.name == "let")
token_error(sym.start, "Unexpected " + sym.name + " in strict mode");
}
@@ -2229,6 +2246,7 @@ function parse($TEXT, options) {
}
function template(tag) {
var start = tag ? tag.start : S.token;
var read = S.input.context().read_template;
var strings = [];
var expressions = [];
@@ -2239,72 +2257,73 @@ function parse($TEXT, options) {
}
next();
return new AST_Template({
start: start,
expressions: expressions,
strings: strings,
tag: tag,
end: prev(),
});
}
var subscripts = function(expr, allow_calls, optional) {
function subscripts(expr, allow_calls) {
var start = expr.start;
if (is("punc", "[")) {
next();
var prop = expression();
expect("]");
return subscripts(new AST_Sub({
start: start,
optional: optional,
expression: expr,
property: prop,
end: prev(),
}), allow_calls);
}
if (allow_calls && is("punc", "(")) {
next();
var call = new AST_Call({
start: start,
optional: optional,
expression: expr,
args: expr_list(")", !options.strict),
end: prev(),
});
return subscripts(call, true);
}
if (optional || is("punc", ".")) {
if (!optional) next();
return subscripts(new AST_Dot({
start: start,
optional: optional,
expression: expr,
property: as_name(),
end: prev(),
}), allow_calls);
}
if (is("punc", "`")) {
var tmpl = template(expr);
tmpl.start = expr.start;
tmpl.end = prev();
return subscripts(tmpl, allow_calls);
}
if (is("operator", "?") && is_token(peek(), "punc", ".")) {
next();
next();
return subscripts(expr, allow_calls, true);
var optional = null;
while (true) {
if (is("operator", "?") && is_token(peek(), "punc", ".")) {
next();
next();
optional = expr;
}
if (is("punc", "[")) {
next();
var prop = expression();
expect("]");
expr = new AST_Sub({
start: start,
optional: optional === expr,
expression: expr,
property: prop,
end: prev(),
});
} else if (allow_calls && is("punc", "(")) {
next();
expr = new AST_Call({
start: start,
optional: optional === expr,
expression: expr,
args: expr_list(")", !options.strict),
end: prev(),
});
} else if (optional === expr || is("punc", ".")) {
if (optional !== expr) next();
expr = new AST_Dot({
start: start,
optional: optional === expr,
expression: expr,
property: as_name(),
end: prev(),
});
} else if (is("punc", "`")) {
if (optional) croak("Invalid template on optional chain");
expr = template(expr);
} else {
break;
}
}
if (optional) expr.terminal = true;
if (expr instanceof AST_Call && !expr.pure) {
var start = expr.start;
var comments = start.comments_before;
var i = HOP(start, "comments_before_length") ? start.comments_before_length : comments.length;
while (--i >= 0) {
var match = /[@#]__PURE__/.exec(comments[i].value);
if (match) {
expr.pure = match[0];
if (/[@#]__PURE__/.test(comments[i].value)) {
expr.pure = true;
break;
}
}
}
return expr;
};
}
function maybe_unary(no_in) {
var start = S.token;

View File

@@ -44,7 +44,7 @@
"use strict";
var builtins = function() {
var names = [];
var names = new Dictionary();
// NaN will be included due to Number.NaN
[
"null",
@@ -72,10 +72,10 @@ var builtins = function() {
Object.getOwnPropertyNames(ctor.prototype).map(add);
}
});
return makePredicate(names);
return names;
function add(name) {
names.push(name);
names.set(name, true);
}
}();
@@ -116,9 +116,9 @@ function mangle_properties(ast, options) {
reserved: null,
}, true);
var reserved = Object.create(options.builtins ? null : builtins);
var reserved = options.builtins ? new Dictionary() : builtins.clone();
if (Array.isArray(options.reserved)) options.reserved.forEach(function(name) {
reserved[name] = true;
reserved.set(name, true);
});
var cname = -1;
@@ -126,7 +126,7 @@ function mangle_properties(ast, options) {
if (options.cache) {
cache = options.cache.props;
cache.each(function(name) {
reserved[name] = true;
reserved.set(name, true);
});
} else {
cache = new Dictionary();
@@ -141,8 +141,8 @@ function mangle_properties(ast, options) {
var debug_suffix;
if (debug) debug_suffix = options.debug === true ? "" : options.debug;
var names_to_mangle = Object.create(null);
var unmangleable = Object.create(reserved);
var names_to_mangle = new Dictionary();
var unmangleable = reserved.clone();
// step 1: find candidates to mangle
ast.walk(new TreeWalker(function(node) {
@@ -211,20 +211,20 @@ function mangle_properties(ast, options) {
// only function declarations after this line
function can_mangle(name) {
if (unmangleable[name]) return false;
if (unmangleable.has(name)) return false;
if (/^-?[0-9]+(\.[0-9]+)?(e[+-][0-9]+)?$/.test(name)) return false;
return true;
}
function should_mangle(name) {
if (reserved[name]) return false;
if (reserved.has(name)) return false;
if (regex && !regex.test(name)) return false;
return cache.has(name) || names_to_mangle[name];
return cache.has(name) || names_to_mangle.has(name);
}
function add(name) {
if (can_mangle(name)) names_to_mangle[name] = true;
if (!should_mangle(name)) unmangleable[name] = true;
if (can_mangle(name)) names_to_mangle.set(name, true);
if (!should_mangle(name)) unmangleable.set(name, true);
}
function mangle(name) {

View File

@@ -44,9 +44,9 @@
"use strict";
function SymbolDef(id, scope, orig, init) {
this._bits = 0;
this.defun = undefined;
this.eliminated = 0;
this.exported = false;
this.global = false;
this.id = id;
this.init = init;
this.mangled_name = null;
@@ -54,8 +54,8 @@ function SymbolDef(id, scope, orig, init) {
this.orig = [ orig ];
this.references = [];
this.replaced = 0;
this.safe_ids = undefined;
this.scope = scope;
this.undeclared = false;
}
SymbolDef.prototype = {
@@ -80,15 +80,16 @@ SymbolDef.prototype = {
}
},
redefined: function() {
var scope = this.defun;
var self = this;
var scope = self.defun;
if (!scope) return;
var name = this.name;
var name = self.name;
var def = scope.variables.get(name)
|| scope instanceof AST_Toplevel && scope.globals.get(name)
|| this.orig[0] instanceof AST_SymbolConst && find_if(function(def) {
|| self.orig[0] instanceof AST_SymbolConst && find_if(function(def) {
return def.name == name;
}, scope.enclosed);
if (def && def !== this) return def.redefined() || def;
if (def && def !== self) return def.redefined() || def;
},
unmangleable: function(options) {
return this.global && !options.toplevel
@@ -103,6 +104,15 @@ SymbolDef.prototype = {
},
};
DEF_BITPROPS(SymbolDef, [
"const_redefs",
"cross_loop",
"direct_access",
"exported",
"global",
"undeclared",
]);
var unary_side_effects = makePredicate("delete ++ --");
function is_lhs(node, parent) {
@@ -117,7 +127,7 @@ function is_lhs(node, parent) {
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
@@ -210,7 +220,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
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;
@@ -350,7 +360,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
self.walk(tw);
// pass 3: fix up any scoping issue with IE8
if (options.ie8) self.walk(new TreeWalker(function(node) {
if (options.ie) self.walk(new TreeWalker(function(node) {
if (node instanceof AST_SymbolCatch) {
var scope = node.thedef.defun;
if (scope.name instanceof AST_SymbolLambda && scope.name.name == node.name) {
@@ -362,7 +372,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
if (node instanceof AST_SymbolLambda) {
var def = node.thedef;
if (!redefine(node, node.scope.parent_scope.resolve())) {
delete def.defun;
def.defun = undefined;
} else if (typeof node.thedef.init !== "undefined") {
node.thedef.init = false;
} else if (def.init) {
@@ -396,13 +406,14 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
} else {
new_def = scope.def_variable(node);
}
if (new_def.undeclared) self.variables.set(name, new_def);
if (name == "arguments" && is_arguments(old_def) && node instanceof AST_SymbolLambda) return true;
old_def.defun = new_def.scope;
old_def.forEach(function(node) {
node.redef = old_def;
node.thedef = new_def;
node.reference(options);
});
if (new_def.undeclared) self.variables.set(name, new_def);
return true;
}
});
@@ -463,7 +474,7 @@ AST_Symbol.DEFMETHOD("mark_enclosed", function(options) {
for (var s = this.scope; s; s = s.parent_scope) {
push_uniq(s.enclosed, def);
if (!options) {
delete s._var_names;
s._var_names = undefined;
} else if (options.keep_fnames) {
s.functions.each(function(d) {
push_uniq(def.scope.enclosed, d);
@@ -508,12 +519,12 @@ function names_in_use(scope, options) {
if (!names) {
scope.cname = -1;
scope.cname_holes = [];
scope.names_in_use = names = Object.create(null);
scope.names_in_use = names = new Dictionary();
var cache = options.cache && options.cache.props;
scope.enclosed.forEach(function(def) {
if (def.unmangleable(options)) names[def.name] = true;
if (def.unmangleable(options)) names.set(def.name, true);
if (def.global && cache && cache.has(def.name)) {
names[cache.get(def.name)] = true;
names.set(cache.get(def.name), true);
}
});
}
@@ -524,34 +535,33 @@ function next_mangled_name(def, options) {
var scope = def.scope;
var in_use = names_in_use(scope, options);
var holes = scope.cname_holes;
var names = Object.create(null);
var names = new Dictionary();
var scopes = [ scope ];
def.forEach(function(sym) {
var scope = sym.scope;
do {
if (scopes.indexOf(scope) < 0) {
for (var name in names_in_use(scope, options)) {
names[name] = true;
}
scopes.push(scope);
} else break;
if (member(scope, scopes)) break;
names_in_use(scope, options).each(function(marker, name) {
names.set(name, marker);
});
scopes.push(scope);
} while (scope = scope.parent_scope);
});
var name;
for (var i = 0; i < holes.length; i++) {
name = base54(holes[i]);
if (names[name]) continue;
if (names.has(name)) continue;
holes.splice(i, 1);
in_use[name] = true;
in_use.set(name, true);
return name;
}
while (true) {
name = base54(++scope.cname);
if (in_use[name] || RESERVED_WORDS[name] || options.reserved.has[name]) continue;
if (!names[name]) break;
if (in_use.has(name) || RESERVED_WORDS[name] || options.reserved.has[name]) continue;
if (!names.has(name)) break;
holes.push(scope.cname);
}
in_use[name] = true;
in_use.set(name, true);
return name;
}
@@ -570,7 +580,7 @@ AST_Symbol.DEFMETHOD("definition", function() {
function _default_mangler_options(options) {
options = defaults(options, {
eval : false,
ie8 : false,
ie : false,
keep_fnames : false,
reserved : [],
toplevel : false,
@@ -596,7 +606,7 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
if (options.cache && options.cache.props) {
var mangled_names = names_in_use(this, options);
options.cache.props.each(function(mangled_name) {
mangled_names[mangled_name] = true;
mangled_names.set(mangled_name, true);
});
}
@@ -800,6 +810,7 @@ var base54 = (function() {
var leading = init("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_");
var chars, frequency;
function reset() {
chars = null;
frequency = Object.create(freq);
}
base54.consider = function(str, delta) {
@@ -811,19 +822,15 @@ var base54 = (function() {
return frequency[b] - frequency[a];
}
base54.sort = function() {
chars = leading.sort(compare).concat(digits.sort(compare));
chars = leading.sort(compare).concat(digits).sort(compare);
};
base54.reset = reset;
reset();
function base54(num) {
var ret = "", base = 54;
num++;
do {
num--;
ret += chars[num % base];
num = Math.floor(num / base);
base = 64;
} while (num > 0);
var ret = leading[num % 54];
for (num = Math.floor(num / 54); --num >= 0; num >>= 6) {
ret += chars[num & 0x3F];
}
return ret;
}
return base54;

View File

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

View File

@@ -96,15 +96,6 @@ function defaults(args, defs, croak) {
return defs;
}
function merge(obj, ext) {
var count = 0;
for (var i in ext) if (HOP(ext, i)) {
obj[i] = ext[i];
count++;
}
return count;
}
function noop() {}
function return_false() { return false; }
function return_true() { return true; }
@@ -143,7 +134,7 @@ function push_uniq(array, el) {
}
function string_template(text, props) {
return text.replace(/\{([^}]+)\}/g, function(str, p) {
return text.replace(/\{([^{}]+)\}/g, function(str, p) {
var value = props[p];
return value instanceof AST_Node ? value.print_to_string() : value;
});
@@ -171,63 +162,80 @@ function all(array, predicate) {
}
function Dictionary() {
this._values = Object.create(null);
this._size = 0;
this.values = Object.create(null);
}
Dictionary.prototype = {
set: function(key, val) {
if (!this.has(key)) ++this._size;
this._values["$" + key] = val;
if (key == "__proto__") {
this.proto_value = val;
} else {
this.values[key] = val;
}
return this;
},
add: function(key, val) {
if (this.has(key)) {
this.get(key).push(val);
var list = this.get(key);
if (list) {
list.push(val);
} else {
this.set(key, [ val ]);
}
return this;
},
get: function(key) { return this._values["$" + key] },
get: function(key) {
return key == "__proto__" ? this.proto_value : this.values[key];
},
del: function(key) {
if (this.has(key)) {
--this._size;
delete this._values["$" + key];
if (key == "__proto__") {
delete this.proto_value;
} else {
delete this.values[key];
}
return this;
},
has: function(key) { return ("$" + key) in this._values },
has: function(key) {
return key == "__proto__" ? "proto_value" in this : key in this.values;
},
all: function(predicate) {
for (var i in this._values)
if (!predicate(this._values[i], i.substr(1)))
return false;
for (var i in this.values)
if (!predicate(this.values[i], i)) return false;
if ("proto_value" in this && !predicate(this.proto_value, "__proto__")) return false;
return true;
},
each: function(f) {
for (var i in this._values)
f(this._values[i], i.substr(1));
for (var i in this.values)
f(this.values[i], i);
if ("proto_value" in this) f(this.proto_value, "__proto__");
},
size: function() {
return this._size;
return Object.keys(this.values).length + ("proto_value" in this);
},
map: function(f) {
var ret = [];
for (var i in this._values)
ret.push(f(this._values[i], i.substr(1)));
for (var i in this.values)
ret.push(f(this.values[i], i));
if ("proto_value" in this) ret.push(f(this.proto_value, "__proto__"));
return ret;
},
clone: function() {
var ret = new Dictionary();
for (var i in this._values)
ret._values[i] = this._values[i];
ret._size = this._size;
this.each(function(value, i) {
ret.set(i, value);
});
return ret;
},
toObject: function() { return this._values }
toObject: function() {
var obj = {};
this.each(function(value, i) {
obj["$" + i] = value;
});
return obj;
},
};
Dictionary.fromObject = function(obj) {
var dict = new Dictionary();
dict._size = merge(dict._values, obj);
for (var i in obj)
if (HOP(obj, i)) dict.set(i.slice(1), obj[i]);
return dict;
};
@@ -265,3 +273,21 @@ function first_in_statement(stack, arrow, export_default) {
return false;
}
}
function DEF_BITPROPS(ctor, props) {
if (props.length > 31) throw new Error("Too many properties: " + props.length + "\n" + props.join(", "));
props.forEach(function(name, pos) {
var mask = 1 << pos;
Object.defineProperty(ctor.prototype, name, {
get: function() {
return !!(this._bits & mask);
},
set: function(val) {
if (val)
this._bits |= mask;
else
this._bits &= ~mask;
},
});
});
}

View File

@@ -3,7 +3,7 @@
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
"license": "BSD-2-Clause",
"version": "3.13.6",
"version": "3.14.5",
"engines": {
"node": ">=0.8.0"
},

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

@@ -256,6 +256,7 @@ issue_3858: {
collapse_vars: true,
inline: true,
keep_fargs: false,
unsafe: true,
unused: true,
}
input: {
@@ -441,9 +442,9 @@ compress_annotations_disabled_output_annotations_enabled: {
}
expect_exact: [
"/*@__PURE__*/a(3),",
"/*#__PURE__*/b(5),",
"/*@__PURE__*/b(5),",
"c(side_effect),",
"/*#__PURE__*/d(effect());",
"/*@__PURE__*/d(effect());",
]
}

View File

@@ -254,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,

View File

@@ -363,6 +363,28 @@ negate: {
}
inline_this: {
options = {
inline: true,
}
input: {
var p = "PASS";
console.log({
p: "FAIL",
q: (() => this.p)(),
}.q);
}
expect: {
var p = "PASS";
console.log({
p: "FAIL",
q: this.p,
}.q);
}
expect_stdout: "PASS"
node_version: ">=4"
}
dont_inline_this: {
options = {
inline: true,
}
@@ -421,6 +443,7 @@ collapse_value: {
arrows: true,
collapse_vars: true,
keep_fargs: false,
unsafe: true,
unused: true,
}
input: {
@@ -555,6 +578,75 @@ reduce_iife_3: {
node_version: ">=4"
}
reduce_lambda_1: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var f = () => {
console.log(a, b);
};
var a = "foo", b = 42;
f();
b = "bar";
f();
}
expect: {
var f = () => {
console.log("foo", b);
};
var b = 42;
f();
b = "bar";
f();
}
expect_stdout: [
"foo 42",
"foo bar",
]
node_version: ">=4"
}
reduce_lambda_2: {
options = {
evaluate: true,
passes: 2,
reduce_vars: true,
side_effects: true,
unused: true,
}
input: {
(function(f, a, b) {
f = () => {
console.log(a, b);
};
a = "foo", b = 42;
f();
b = "bar";
f();
})();
}
expect: {
(function(f, a, b) {
f = () => {
console.log("foo", b);
};
b = 42;
f();
b = "bar";
f();
})();
}
expect_stdout: [
"foo 42",
"foo bar",
]
node_version: ">=4"
}
single_use_recursive: {
options = {
reduce_vars: true,

View File

@@ -550,6 +550,24 @@ logical_side_effects: {
node_version: ">=15"
}
evaluate_lazy_assignment: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = 42;
console.log(a &&= "PASS");
}
expect: {
console.log("PASS");
}
expect_stdout: "PASS"
node_version: ">=15"
}
issue_4815_1: {
options = {
evaluate: true,
@@ -701,3 +719,48 @@ issue_4876: {
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"
}

View File

@@ -227,9 +227,7 @@ inline_await_1_trim: {
console.log("PASS");
}
expect: {
(async function() {
await 0;
})();
0;
console.log("PASS");
}
expect_stdout: "PASS"
@@ -334,7 +332,7 @@ inline_await_3_trim: {
}
expect: {
(async function() {
return a = "PASS", b = console.log, await b(a);
return a = "PASS", b = console.log, b(a);
var a, b;
})();
}
@@ -342,6 +340,33 @@ inline_await_3_trim: {
node_version: ">=8"
}
inline_await_this: {
options = {
awaits: true,
inline: true,
}
input: {
var p = "FAIL";
({
p: "PASS",
async f() {
return await (async () => this.p)();
},
}).f().then(console.log);
}
expect: {
var p = "FAIL";
({
p: "PASS",
async f() {
return await this.p;
},
}).f().then(console.log);
}
expect_stdout: "PASS"
node_version: ">=8"
}
await_unary: {
options = {
awaits: true,
@@ -455,7 +480,7 @@ object_function: {
}).f();
}
expect: {
(async function() {
(async () => {
console.log("PASS");
})();
}
@@ -557,6 +582,51 @@ collapse_property_lambda: {
node_version: ">=8"
}
drop_async_1: {
options = {
awaits: true,
inline: true,
side_effects: true,
}
input: {
console.log(function(a) {
(async function() {
a *= 7;
})();
return a;
}(6));
}
expect: {
console.log(function(a) {
a *= 7;
return a;
}(6));
}
expect_stdout: "42"
node_version: ">=8"
}
drop_async_2: {
options = {
awaits: true,
collapse_vars: true,
evaluate: true,
inline: true,
side_effects: true,
}
input: {
console.log(function(a) {
(async b => await (a *= b))(7);
return a;
}(6));
}
expect: {
console.log(42);
}
expect_stdout: "42"
node_version: ">=8"
}
drop_return: {
options = {
side_effects: true,
@@ -1531,3 +1601,667 @@ issue_4764_3: {
expect_stdout: "PASS"
node_version: ">=8"
}
issue_4972_1: {
options = {
awaits: true,
side_effects: true,
}
input: {
console.log("foo");
(async function() {
try {
return await "bar";
} finally {
console.log("baz");
}
})().then(console.log);
console.log("moo");
}
expect: {
console.log("foo");
(async function() {
try {
return await "bar";
} finally {
console.log("baz");
}
})().then(console.log);
console.log("moo");
}
expect_stdout: [
"foo",
"moo",
"baz",
"bar",
]
node_version: ">=8"
}
issue_4972_2: {
options = {
awaits: true,
side_effects: true,
}
input: {
console.log("foo");
(async function() {
try {
console.log("bar");
} finally {
return await "baz";
}
})().then(console.log);
console.log("moo");
}
expect: {
console.log("foo");
(async function() {
try {
console.log("bar");
} finally {
return "baz";
}
})().then(console.log);
console.log("moo");
}
expect_stdout: [
"foo",
"bar",
"moo",
"baz",
]
node_version: ">=8"
}
issue_4972_3: {
options = {
awaits: true,
side_effects: true,
}
input: {
console.log("foo");
try {
(async function() {
return await "bar";
})().then(console.log);
} finally {
console.log("baz");
}
console.log("moo");
}
expect: {
console.log("foo");
try {
(async function() {
return "bar";
})().then(console.log);
} finally {
console.log("baz");
}
console.log("moo");
}
expect_stdout: [
"foo",
"baz",
"moo",
"bar",
]
node_version: ">=8"
}
issue_4974: {
options = {
awaits: true,
side_effects: true,
}
input: {
(async function f() {
return 42 in f();
})();
console.log("PASS");
}
expect: {
(async function f() {
return 42 in f();
})();
console.log("PASS");
}
expect_stdout: true
node_version: ">=8"
}
issue_4975: {
options = {
awaits: true,
side_effects: true,
}
input: {
(async function f(a) {
try {
if (a) console.log(typeof f());
} catch (e) {}
})(42);
}
expect: {
(async function f(a) {
try {
if (a) console.log(typeof f());
} catch (e) {}
})(42);
}
expect_stdout: "object"
node_version: ">=8"
}
issue_4987: {
options = {
awaits: true,
side_effects: true,
}
input: {
(async function() {
try {
await 42;
} finally {
console.log("foo");
}
})();
console.log("bar");
}
expect: {
(async function() {
try {
await 0;
} finally {
console.log("foo");
}
})();
console.log("bar");
}
expect_stdout: [
"bar",
"foo",
]
node_version: ">=8"
}
issue_5001: {
options = {
awaits: true,
inline: true,
side_effects: true,
}
input: {
var a = 0;
(async function() {
a++ | await 42;
})();
console.log(a ? "PASS" : "FAIL");
}
expect: {
var a = 0;
a++;
console.log(a ? "PASS" : "FAIL");
}
expect_stdout: "PASS"
node_version: ">=8"
}
issue_5019_1: {
options = {
dead_code: true,
}
input: {
(function(a) {
(async function() {
await 42;
console.log(a);
})();
a = "PASS";
})("FAIL");
}
expect: {
(function(a) {
(async function() {
await 42;
console.log(a);
})();
a = "PASS";
})("FAIL");
}
expect_stdout: "PASS"
node_version: ">=8"
}
issue_5019_2: {
options = {
dead_code: true,
}
input: {
console.log("sync", function(a) {
(async function() {
console.log(await "async", a);
})();
return a = "PASS";
}("FAIL"));
}
expect: {
console.log("sync", function(a) {
(async function() {
console.log(await "async", a);
})();
return a = "PASS";
}("FAIL"));
}
expect_stdout: [
"sync PASS",
"async PASS",
]
node_version: ">=8"
}
issue_5019_3: {
options = {
inline: true,
toplevel: true,
}
input: {
for (var i in "foo") {
(function(a) {
(async function() {
console.log(await "async", a);
})();
})(i);
console.log("sync", i);
}
}
expect: {
for (var i in "foo") {
(function(a) {
(async function() {
console.log(await "async", a);
})();
})(i);
console.log("sync", i);
}
}
expect_stdout: [
"sync 0",
"sync 1",
"sync 2",
"async 0",
"async 1",
"async 2",
]
node_version: ">=8"
}
issue_5023_1: {
options = {
awaits: true,
reduce_vars: true,
side_effects: true,
}
input: {
(async function() {
let a = a;
})();
console.log("PASS");
}
expect: {
(async function() {
let a = a;
})();
console.log("PASS");
}
expect_stdout: "PASS"
node_version: ">=8"
}
issue_5023_2: {
options = {
awaits: true,
reduce_vars: true,
side_effects: true,
}
input: {
(async function() {
let a;
a = a;
})();
console.log("PASS");
}
expect: {
(function() {
let a;
a = a;
})();
console.log("PASS");
}
expect_stdout: "PASS"
node_version: ">=8"
}
issue_5032_normal: {
options = {
merge_vars: true,
webkit: false,
}
input: {
function log(value) {
console.log(value);
return value;
}
async function f(a) {
var b = log(a), c = b;
log(b);
log(c);
}
f("PASS");
}
expect: {
function log(value) {
console.log(value);
return value;
}
async function f(c) {
var b = log(c), c = b;
log(b);
log(c);
}
f("PASS");
}
expect_stdout: [
"PASS",
"PASS",
"PASS",
]
node_version: ">=8"
}
issue_5032_webkit: {
options = {
merge_vars: true,
webkit: true,
}
input: {
function log(value) {
console.log(value);
return value;
}
async function f(a) {
var b = log(a), c = b;
log(b);
log(c);
}
f("PASS");
}
expect: {
function log(value) {
console.log(value);
return value;
}
async function f(a) {
var b = log(a), c = b;
log(b);
log(c);
}
f("PASS");
}
expect_stdout: [
"PASS",
"PASS",
"PASS",
]
node_version: ">=8"
}
issue_5034: {
options = {
functions: true,
reduce_vars: true,
unused: true,
}
input: {
(function() {
var await = function f() {
return async function() {
return f;
};
};
await()().then(function(value) {
console.log(value === await ? "PASS" : "FAIL");
});
})();
}
expect: {
(function() {
var await = function f() {
return async function() {
return f;
};
};
await()().then(function(value) {
console.log(value === await ? "PASS" : "FAIL");
});
})();
}
expect_stdout: "PASS"
node_version: ">=8"
}
issue_5070: {
options = {
awaits: true,
side_effects: true,
}
input: {
(async function() {
try {
for await (var a of console.log("PASS"));
} catch (e) {}
})();
}
expect: {
(async function() {
try {
for await (var a of console.log("PASS"));
} catch (e) {}
})();
}
expect_stdout: "PASS"
node_version: ">=10"
}
issue_5157_async_function: {
options = {
awaits: true,
side_effects: true,
}
input: {
async function f() {
throw "FAIL";
}
(async function() {
try {
return await f();
} catch (e) {
return "PASS";
}
})().then(console.log);
}
expect: {
async function f() {
throw "FAIL";
}
(async function() {
try {
return await f();
} catch (e) {
return "PASS";
}
})().then(console.log);
}
expect_stdout: "PASS"
node_version: ">=8"
}
issue_5157_async_iife: {
options = {
awaits: true,
side_effects: true,
}
input: {
(async function() {
try {
return await async function() {
throw "FAIL";
}();
} catch (e) {
return "PASS";
}
})().then(console.log);
}
expect: {
(async function() {
try {
return await async function() {
throw "FAIL";
}();
} catch (e) {
return "PASS";
}
})().then(console.log);
}
expect_stdout: "PASS"
node_version: ">=8"
}
issue_5157_promise: {
options = {
awaits: true,
side_effects: true,
}
input: {
var p = new Promise(function(resolve, reject) {
reject("FAIL");
});
(async function() {
try {
return await p;
} catch (e) {
return "PASS";
}
})().then(console.log);
}
expect: {
var p = new Promise(function(resolve, reject) {
reject("FAIL");
});
(async function() {
try {
return await p;
} catch (e) {
return "PASS";
}
})().then(console.log);
}
expect_stdout: "PASS"
node_version: ">=8"
}
issue_5159_1: {
options = {
awaits: true,
side_effects: true,
}
input: {
(async function() {
try {
throw "foo";
} catch (e) {
return await "bar";
} finally {
console.log("baz");
}
})().catch(console.log).then(console.log);
console.log("moo");
}
expect: {
(async function() {
try {
throw "foo";
} catch (e) {
return await "bar";
} finally {
console.log("baz");
}
})().catch(console.log).then(console.log);
console.log("moo");
}
expect_stdout: [
"moo",
"baz",
"bar",
]
node_version: ">=8"
}
issue_5159_2: {
options = {
awaits: true,
side_effects: true,
}
input: {
(async function() {
try {
throw "foo";
} catch (e) {
return await "bar";
}
})().catch(console.log).then(console.log);
console.log("baz");
}
expect: {
(async function() {
try {
throw "foo";
} catch (e) {
return "bar";
}
})().catch(console.log).then(console.log);
console.log("baz");
}
expect_stdout: [
"baz",
"bar",
]
node_version: ">=8"
}
issue_5177: {
options = {
properties: true,
}
input: {
(async function() {
return {
p(await) {},
}.p;
})().then(function(a) {
console.log(typeof a);
});
}
expect: {
(async function() {
return {
p(await) {},
}.p;
})().then(function(a) {
console.log(typeof a);
});
}
expect_stdout: "function"
node_version: ">=8"
}

View File

@@ -4,7 +4,7 @@ arithmetic: {
}
expect_exact: "console.log((1n+0x2n)*(0o3n- -4n)>>5n-6n);"
expect_stdout: "42n"
node_version: ">=10"
node_version: ">=10.4.0"
}
minus_dot: {
@@ -13,7 +13,7 @@ minus_dot: {
}
expect_exact: "console.log(typeof-42n.toString(),typeof(-42n).toString());"
expect_stdout: "number string"
node_version: ">=10"
node_version: ">=10.4.0"
}
evaluate: {
@@ -28,7 +28,7 @@ evaluate: {
console.log(0xdeadbeefn.toString(16));
}
expect_stdout: "deadbeef"
node_version: ">=10"
node_version: ">=10.4.0"
}
Number: {
@@ -42,7 +42,7 @@ Number: {
console.log(+("" + -0xfeed_dead_beef_badn));
}
expect_stdout: "-1148098955808013200"
node_version: ">=10"
node_version: ">=10.4.0"
}
issue_4590: {
@@ -58,7 +58,7 @@ issue_4590: {
0n || console.log("PASS");
}
expect_stdout: "PASS"
node_version: ">=10"
node_version: ">=10.4.0"
}
issue_4801: {
@@ -88,5 +88,5 @@ issue_4801: {
}
}
expect_stdout: "PASS"
node_version: ">=10"
node_version: ">=10.4.0"
}

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,
@@ -181,3 +579,121 @@ issue_4374: {
}
expect_stdout: "0"
}
issue_5028_1: {
options = {
booleans: true,
conditionals: true,
}
input: {
var a = 1;
console.log(function() {
return a-- ? a-- ? "FAIL 1" : "PASS" : "FAIL 2";
}());
}
expect: {
var a = 1;
console.log(function() {
return a-- ? a-- ? "FAIL 1" : "PASS" : "FAIL 2";
}());
}
expect_stdout: "PASS"
}
issue_5028_2: {
options = {
booleans: true,
conditionals: true,
dead_code: true,
if_return: true,
}
input: {
var a = 1;
(function() {
if (a--)
if (a--)
a = "FAIL";
else
return;
})();
console.log(a);
}
expect: {
var a = 1;
(function() {
a-- && a-- && (a = "FAIL");
})();
console.log(a);
}
expect_stdout: "-1"
}
issue_5028_3: {
options = {
booleans: true,
conditionals: true,
evaluate: true,
if_return: true,
}
input: {
var a = 1;
(function() {
if (a--)
if (a--)
a = "FAIL";
else
return;
})();
console.log(a);
}
expect: {
var a = 1;
(function() {
a-- && a-- && (a = "FAIL");
})();
console.log(a);
}
expect_stdout: "-1"
}
issue_5041_1: {
options = {
booleans: true,
conditionals: true,
}
input: {
var a = 42;
if (a)
if ([ a = null ])
if (a)
console.log("FAIL");
else
console.log("PASS");
}
expect: {
var a = 42;
a && [ a = null ] && (a ? console.log("FAIL") : console.log("PASS"));
}
expect_stdout: "PASS"
}
issue_5041_2: {
options = {
booleans: true,
conditionals: true,
}
input: {
var a;
if (!a)
if (a = 42)
if (a)
console.log("PASS");
else
console.log("FAIL");
}
expect: {
var a;
a || (a = 42) && (a ? console.log("PASS") : console.log("FAIL"));
}
expect_stdout: "PASS"
}

View File

@@ -72,7 +72,7 @@ fields: {
console.log(k, o[k]);
console.log(o.q);
}
expect_exact: 'var o=new class A{"#p";static #p="PASS";async;get q(){return A.#p}[6*7]=console?"foo":"bar"};for(var k in o)console.log(k,o[k]);console.log(o.q);'
expect_exact: 'var o=new class A{"#p";static#p="PASS";async;get q(){return A.#p}[6*7]=console?"foo":"bar"};for(var k in o)console.log(k,o[k]);console.log(o.q);'
expect_stdout: [
"42 foo",
"#p undefined",
@@ -136,7 +136,7 @@ private_methods: {
}
}().q.then(console.log);
}
expect_exact: "(new class A{static*#f(){yield 3*A.#p}async #g(){for(var a of A.#f())return a*await 2}static get #p(){return 7}get q(){return this.#g()}}).q.then(console.log);"
expect_exact: "(new class A{static*#f(){yield 3*A.#p}async#g(){for(var a of A.#f())return a*await 2}static get#p(){return 7}get q(){return this.#g()}}).q.then(console.log);"
expect_stdout: "42"
node_version: ">=14.6"
}
@@ -260,6 +260,9 @@ block_scoped: {
expect: {
"use strict";
0;
{
class A {}
}
if (console) {
class B {}
}
@@ -269,6 +272,38 @@ block_scoped: {
node_version: ">=4"
}
retain_declaration: {
options = {
dead_code: true,
}
input: {
"use strict";
var a = "FAIL";
try {
console.log(function() {
return a;
class a {}
}());
} catch (e) {
console.log("PASS");
}
}
expect: {
"use strict";
var a = "FAIL";
try {
console.log(function() {
return a;
class a {}
}());
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "PASS"
node_version: ">=4"
}
drop_extends: {
options = {
inline: true,
@@ -632,6 +667,7 @@ collapse_non_strict: {
collapse_rhs: {
options = {
collapse_vars: true,
unsafe: true,
}
input: {
"use strict";
@@ -937,9 +973,9 @@ issue_4681: {
}
expect: {
console.log(function(a) {
class A {
(class {
static p = a = this;
}
});
return typeof a;
}());
}
@@ -1121,7 +1157,7 @@ issue_4705: {
issue_4720: {
options = {
ie8: true,
ie: true,
reduce_vars: true,
toplevel: true,
unused: true,
@@ -1363,9 +1399,9 @@ issue_4821_1: {
}
expect: {
var a;
class A {
(class {
static p = void (a = this);
}
});
console.log(typeof a);
}
expect_stdout: "function"
@@ -1563,3 +1599,501 @@ drop_unused_self_reference: {
expect_stdout: "PASS"
node_version: ">=4"
}
issue_4951_1: {
input: {
class A {
static#p = console.log("PASS");
}
}
expect_exact: 'class A{static#p=console.log("PASS")}'
expect_stdout: "PASS"
node_version: ">=12"
}
issue_4951_2: {
input: {
new class {
constructor() {
this.#f().then(console.log);
}
async#f() {
return await "PASS";
}
}();
}
expect_exact: 'new class{constructor(){this.#f().then(console.log)}async#f(){return await"PASS"}};'
expect_stdout: "PASS"
node_version: ">=14.6"
}
issue_4962_1: {
options = {
ie: true,
inline: true,
reduce_vars: true,
unused: true,
}
input: {
(function() {
function f() {
while (console.log(typeof g));
}
class A {
static p = f();
}
})(function g() {});
}
expect: {
(function g() {}),
void function() {
while (console.log(typeof g));
}();
}
expect_stdout: "undefined"
node_version: ">=12"
}
issue_4962_2: {
options = {
ie: true,
inline: true,
reduce_vars: true,
unused: true,
}
input: {
console.log(function f() {}(function g() {
function h() {
f;
}
class A {
static p = h();
}
}, typeof g));
}
expect: {
console.log(function f() {}(function g() {
f;
}));
}
expect_stdout: "undefined"
node_version: ">=12"
}
issue_4982_1: {
options = {
dead_code: true,
}
input: {
"use strict";
try {} catch (e) {
class A extends 42 {}
}
console.log("PASS");
}
expect: {
"use strict";
{
class A {}
}
console.log("PASS");
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_4982_2: {
options = {
dead_code: true,
}
input: {
var a = "PASS";
try {} catch (e) {
class A {
static p = a = "FAIL";
}
}
console.log(a);
}
expect: {
var a = "PASS";
{
class A {}
}
console.log(a);
}
expect_stdout: "PASS"
node_version: ">=12"
}
issue_4992: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
class A {
static P = this;
get p() {}
}
console.log(typeof A.P);
}
expect: {
console.log(typeof class {
static P = this;
get p() {}
}.P);
}
expect_stdout: "function"
node_version: ">=12"
}
issue_4996_1: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
}
input: {
var a = 1;
console.log(new class A {
p = a-- && new A();
}().p.p);
}
expect: {
var a = 1;
console.log(new class A {
p = a-- && new A();
}().p.p);
}
expect_stdout: "0"
node_version: ">=12"
}
issue_4996_2: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = 1;
console.log(new class A {
p = a-- && new A();
}().p.p);
}
expect: {
var a = 1;
console.log(new class A {
p = a-- && new A();
}().p.p);
}
expect_stdout: "0"
node_version: ">=12"
}
issue_5015_1: {
options = {
side_effects: true,
}
input: {
"use strict";
var a;
try {
(class a {
[a]() {}
});
} catch (e) {
console.log("PASS");
}
}
expect: {
"use strict";
var a;
try {
(class a {
[a]() {}
});
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_5015_2: {
options = {
reduce_vars: true,
side_effects: true,
toplevel: true,
}
input: {
"use strict";
try {
new class A {
[(A, 42)]() {}
}();
} catch (e) {
console.log("PASS");
}
}
expect: {
"use strict";
try {
new class A {
[(A, 42)]() {}
}();
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_5015_3: {
options = {
reduce_vars: true,
side_effects: true,
toplevel: true,
}
input: {
"use strict";
(class A {
static f() {
return A;
}
});
console.log("PASS");
}
expect: {
"use strict";
console.log("PASS");
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_5053_1: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
}
input: {
"use strict";
try {
console.log(new class A {
constructor() {
A = 42;
}
}());
} catch (e) {
console.log("PASS");
}
}
expect: {
"use strict";
try {
console.log(new class A {
constructor() {
A = 42;
}
}());
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_5053_2: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
}
input: {
"use strict";
try {
console.log(new class A {
f() {
A = 42;
}
}().f());
} catch (e) {
console.log("PASS");
}
}
expect: {
"use strict";
try {
console.log(new class A {
f() {
A = 42;
}
}().f());
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_5053_3: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
}
input: {
try {
console.log(new class A {
p = A = 42;
}().p);
} catch (e) {
console.log("PASS");
}
}
expect: {
try {
console.log(new class A {
p = A = 42;
}().p);
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "PASS"
node_version: ">=12"
}
issue_5053_4: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
"use strict";
class A {
constructor() {
A = 42;
}
}
try {
console.log(new A());
} catch (e) {
console.log("PASS");
}
}
expect: {
"use strict";
class A {
constructor() {
A = 42;
}
}
try {
console.log(new A());
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_5082_1: {
options = {
inline: true,
reduce_vars: true,
unused: true,
}
input: {
(function() {
class A {
p = console.log("PASS");
q() {}
}
class B {
static P = new A();
}
})();
}
expect: {
(function() {
class A {
p = console.log("PASS");
q() {}
}
new A();
})();
}
expect_stdout: "PASS"
node_version: ">=12"
}
issue_5082_2: {
options = {
inline: true,
passes: 2,
reduce_vars: true,
unused: true,
}
input: {
(function() {
class A {
p = console.log("PASS");
q() {}
}
class B {
static P = new A();
}
})();
}
expect: {
void new class {
p = console.log("PASS");
q() {}
}();
}
expect_stdout: "PASS"
node_version: ">=12"
}
issue_5142: {
options = {
evaluate: true,
merge_vars: true,
reduce_vars: true,
toplevel: true,
}
input: {
var a = 0, b;
if (++a)
new class {
p = b = null;
constructor(c) {
console.log(c ? "FAIL" : "PASS");
}
}(b, a);
}
expect: {
var a = 0, b;
if (++a)
new class {
p = b = null;
constructor(c) {
console.log(c ? "FAIL" : "PASS");
}
}(b, 1);
}
expect_stdout: "PASS"
node_version: ">=12"
}

View File

@@ -2264,6 +2264,7 @@ var_defs: {
properties: true,
sequences: true,
side_effects: true,
unsafe: true,
unused: true,
}
input: {
@@ -2486,6 +2487,7 @@ issue_1858: {
options = {
collapse_vars: true,
pure_getters: true,
reduce_vars: true,
unused: true,
}
input: {
@@ -2907,6 +2909,7 @@ compound_assignment_2: {
issue_2187_1: {
options = {
collapse_vars: true,
reduce_vars: true,
unused: true,
}
input: {
@@ -4271,6 +4274,7 @@ issue_2436_14: {
options = {
collapse_vars: true,
reduce_vars: true,
unsafe: true,
unused: true,
}
input: {
@@ -4724,7 +4728,7 @@ cascade_statement: {
}
function f3(a, b) {
for (; a < b; a++)
if (c = a, a && b)
if ((c = a) && b)
var c = c = b(a);
}
}
@@ -4761,6 +4765,7 @@ unsafe_builtin: {
options = {
collapse_vars: true,
pure_getters: "strict",
reduce_vars: true,
unsafe: true,
unused: true,
}
@@ -6003,7 +6008,7 @@ issue_3215_1: {
options = {
collapse_vars: true,
evaluate: true,
ie8: false,
ie: false,
inline: true,
passes: 2,
side_effects: true,
@@ -6025,7 +6030,7 @@ issue_3215_2: {
options = {
collapse_vars: true,
evaluate: true,
ie8: true,
ie: true,
inline: true,
passes: 2,
side_effects: true,
@@ -6050,7 +6055,7 @@ issue_3215_3: {
options = {
collapse_vars: true,
evaluate: true,
ie8: false,
ie: false,
inline: true,
passes: 2,
side_effects: true,
@@ -6073,7 +6078,7 @@ issue_3215_4: {
options = {
collapse_vars: true,
evaluate: true,
ie8: true,
ie: true,
inline: true,
passes: 2,
side_effects: true,
@@ -6965,6 +6970,7 @@ sequence_in_iife_2: {
inline: true,
passes: 2,
side_effects: true,
unsafe: true,
unused: true,
}
input: {
@@ -6976,7 +6982,7 @@ sequence_in_iife_2: {
}
expect: {
var a = "foo", b = 42;
console.log(a, b = a);
console.log(b = a, b);
}
expect_stdout: "foo foo"
}
@@ -6988,6 +6994,7 @@ sequence_in_iife_3: {
passes: 2,
side_effects: true,
toplevel: true,
unsafe: true,
unused: true,
}
input: {
@@ -7092,6 +7099,7 @@ setter_side_effect: {
substitution_assign: {
options = {
collapse_vars: true,
unsafe: true,
}
input: {
function f1(a, b) {
@@ -7112,8 +7120,7 @@ substitution_assign: {
}
expect: {
function f1(a, b) {
f1 = a;
console.log(a, a);
console.log(f1 = a, a);
}
function f2(a, b) {
a = 1 + (b = a);
@@ -7917,6 +7924,7 @@ issue_3744: {
assign_value_def: {
options = {
collapse_vars: true,
reduce_vars: true,
unused: true,
}
input: {
@@ -7957,6 +7965,7 @@ join_vars_value_def: {
options = {
collapse_vars: true,
join_vars: true,
reduce_vars: true,
unused: true,
}
input: {
@@ -7996,6 +8005,7 @@ join_vars_value_def: {
var_value_def: {
options = {
collapse_vars: true,
reduce_vars: true,
unused: true,
}
input: {
@@ -8033,6 +8043,7 @@ var_value_def: {
mangleable_var: {
options = {
collapse_vars: true,
reduce_vars: true,
unused: true,
}
input: {
@@ -8067,6 +8078,7 @@ mangleable_var: {
mangleable_assignment_1: {
options = {
collapse_vars: true,
reduce_vars: true,
unused: true,
}
input: {
@@ -8098,6 +8110,7 @@ mangleable_assignment_1: {
mangleable_assignment_2: {
options = {
collapse_vars: true,
reduce_vars: true,
unused: true,
}
input: {
@@ -8850,7 +8863,7 @@ issue_4732_1: {
expect: {
var a = 0;
(function(b) {
(b = a++) && (b && console.log("PASS"));
(b = a++) && console.log("PASS");
})(a++);
}
expect_stdout: "PASS"
@@ -8939,6 +8952,8 @@ dot_non_local: {
issue_4806: {
options = {
collapse_vars: true,
reduce_vars: true,
toplevel: true,
}
input: {
var a, o = {
@@ -8962,6 +8977,7 @@ issue_4806: {
issue_4852: {
options = {
collapse_vars: true,
unsafe: true,
}
input: {
var a = "PASS";
@@ -9195,7 +9211,7 @@ issue_4918: {
expect_stdout: "PASS"
}
issue_4920: {
issue_4920_1: {
options = {
collapse_vars: true,
toplevel: true,
@@ -9220,3 +9236,333 @@ issue_4920: {
}
expect_stdout: "PASS"
}
issue_4920_2: {
options = {
collapse_vars: true,
toplevel: true,
}
input: {
var o = {
get PASS() {
a = "FAIL";
},
};
var a = "PASS", b;
o[b = a];
console.log(b);
}
expect: {
var o;
var a = "PASS", b;
({
get PASS() {
a = "FAIL";
},
})[b = a];
console.log(b);
}
expect_stdout: "PASS"
}
issue_4920_3: {
options = {
collapse_vars: true,
toplevel: true,
}
input: {
var log = console.log;
var o = {
get PASS() {
a = "FAIL";
},
};
var a = "PASS", b;
o[b = a];
log(b);
}
expect: {
var log = console.log;
var o;
var a = "PASS", b;
({
get PASS() {
a = "FAIL";
},
})[b = a];
log(b);
}
expect_stdout: "PASS"
}
issue_4920_4: {
options = {
collapse_vars: true,
toplevel: true,
}
input: {
var log = console.log;
var o = {
get [(a = "FAIL 1", "PASS")]() {
a = "FAIL 2";
},
};
var a = "PASS", b;
o[b = a];
log(b);
}
expect: {
var log = console.log;
var o = {
get [(a = "FAIL 1", "PASS")]() {
a = "FAIL 2";
},
};
var a = "PASS", b;
o[b = a];
log(b);
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_4935: {
options = {
collapse_vars: true,
reduce_vars: true,
toplevel: true,
}
input: {
var a = 1;
var b;
var c = b = a;
console || c(a++);
--b;
console.log(a, b);
}
expect: {
var a = 1;
var b;
var c = b = a;
console || a(a++);
--b;
console.log(a, b);
}
expect_stdout: "1 0"
}
inline_throw: {
options = {
collapse_vars: true,
inline: true,
keep_fargs: false,
unused: true,
}
input: {
try {
(function() {
return function(a) {
return function(b) {
throw b;
}(a);
};
})()("PASS");
} catch (e) {
console.log(e);
}
}
expect: {
try {
(function(a) {
return function() {
throw a;
}();
})("PASS");
} catch (e) {
console.log(e);
}
}
expect_stdout: "PASS"
}
issue_4977_1: {
options = {
collapse_vars: true,
unsafe: true,
}
input: {
var a = "FAIL";
var o = {
get p() {
return a;
}
};
a = "PASS";
console.log(o.p, a);
}
expect: {
var a = "FAIL";
var o = {
get p() {
return a;
}
};
a = "PASS";
console.log(o.p, a);
}
expect_stdout: "PASS PASS"
}
issue_4977_2: {
options = {
collapse_vars: true,
reduce_vars: true,
unsafe: true,
}
input: {
var a, o = {
get p() {
return a = "PASS";
},
};
if (console) {
var a = "FAIL";
console.log(o.p, a);
}
}
expect: {
var a, o = {
get p() {
return a = "PASS";
},
};
if (console) {
var a = "FAIL";
console.log(o.p, a);
}
}
expect_stdout: "PASS PASS"
}
issue_5112_1: {
options = {
collapse_vars: true,
}
input: {
console.log(function(a) {
try {
try {
if (console + (a = "PASS", ""))
return "FAIL 1";
a.p;
} catch (e) {}
} finally {
return a;
}
}("FAIL 2"));
}
expect: {
console.log(function(a) {
try {
try {
if (console + (a = "PASS", ""))
return "FAIL 1";
a.p;
} catch (e) {}
} finally {
return a;
}
}("FAIL 2"));
}
expect_stdout: "PASS"
}
issue_5112_2: {
options = {
collapse_vars: true,
}
input: {
console.log(function(a) {
try {
return function() {
try {
if (console + (a = "PASS", ""))
return "FAIL 1";
a.p;
} catch (e) {}
}();
} finally {
return a;
}
}("FAIL 2"));
}
expect: {
console.log(function(a) {
try {
return function() {
try {
if (console + (a = "PASS", ""))
return "FAIL 1";
a.p;
} catch (e) {}
}();
} finally {
return a;
}
}("FAIL 2"));
}
expect_stdout: "PASS"
}
issue_5182: {
options = {
arrows: true,
collapse_vars: true,
evaluate: true,
hoist_props: true,
inline: true,
merge_vars: true,
passes: 4,
reduce_vars: true,
sequences: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var con = console;
global.log = con.log;
var jump = function(x) {
console.log("JUMP:", x * 10);
return x + x;
};
var jump2 = jump;
var run = function(x) {
console.log("RUN:", x * -10);
return x * x;
};
var run2 = run;
var bar = (x, y) => {
console.log("BAR:", x + y);
return x - y;
};
var bar2 = bar;
var obj = {
foo: bar2,
go: run2,
not_used: jump2,
};
console.log(obj.foo(1, 2), global.log("PASS"));
}
expect: {
var con = console;
global.log = con.log,
console.log((console.log("BAR:", 3), -1), global.log("PASS"));
}
expect_stdout: [
"BAR: 3",
"PASS",
"-1 undefined",
]
node_version: ">=4"
}

View File

@@ -289,3 +289,18 @@ issue_3689: {
}
expect_stdout: "00"
}
issue_5145: {
options = {
strings: true,
}
input: {
var a = [];
console.log("" + a + ((a[0] = 4) + "2"));
}
expect: {
var a = [];
console.log("" + a + (a[0] = 4) + "2");
}
expect_stdout: "42"
}

View File

@@ -822,6 +822,33 @@ cond_13: {
}
}
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,

View File

@@ -486,7 +486,7 @@ do_continue: {
catch_ie8_1: {
options = {
ie8: true,
ie: true,
unused: true,
}
input: {
@@ -506,7 +506,7 @@ catch_ie8_1: {
catch_ie8_2: {
options = {
dead_code: true,
ie8: true,
ie: true,
passes: 2,
toplevel: true,
unused: true,
@@ -727,7 +727,7 @@ issue_4193: {
issue_4195: {
mangle = {
ie8: true,
ie: true,
}
input: {
console.log(function f(a) {
@@ -1131,7 +1131,7 @@ issue_4225: {
issue_4229: {
options = {
ie8: true,
ie: true,
side_effects: true,
}
input: {
@@ -1151,7 +1151,7 @@ issue_4229: {
issue_4231: {
options = {
ie8: true,
ie: true,
side_effects: true,
}
input: {
@@ -1535,3 +1535,160 @@ issue_4848: {
}
expect_stdout: "PASS"
}
issue_4954_1: {
rename = true
input: {
"use strict";
(function() {
{
const a = "foo";
console.log(a);
}
{
const a = "bar";
console.log(a);
}
})();
}
expect: {
"use strict";
(function() {
{
const a = "foo";
console.log(a);
}
{
const b = "bar";
console.log(b);
}
})();
}
expect_stdout: [
"foo",
"bar",
]
node_version: ">=4"
}
issue_4954_2: {
mangle = {}
input: {
"use strict";
const a = null;
(function(b) {
for (const a in null);
for (const a in b)
console.log("PASS");
})([ null ]);
}
expect: {
"use strict";
const a = null;
(function(o) {
for (const n in null);
for (const n in o)
console.log("PASS");
})([ null ]);
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_4960: {
mangle = {}
input: {
"use strict";
var a;
(function() {
{
const a = console.log("PASS");
}
try {} catch (e) {
const a = console.log("FAIL");
}
})();
}
expect: {
"use strict";
var a;
(function() {
{
const o = console.log("PASS");
}
try {} catch (o) {
const c = console.log("FAIL");
}
})();
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_4965_1: {
mangle = {}
input: {
"use strict";
try {
c;
} catch (a) {
{
const a = 1;
}
{
const a = console.log(typeof c);
}
}
}
expect: {
"use strict";
try {
c;
} catch (t) {
{
const c = 1;
}
{
const t = console.log(typeof c);
}
}
}
expect_stdout: "undefined"
node_version: ">=4"
}
issue_4965_2: {
mangle = {}
input: {
"use strict";
try {
throw 1;
} catch (e) {
try {
{
const e = 2;
}
} finally {
const e = 3;
console.log(typeof t);
}
}
}
expect: {
"use strict";
try {
throw 1;
} catch (o) {
try {
{
const t = 2;
}
} finally {
const o = 3;
console.log(typeof t);
}
}
}
expect_stdout: "undefined"
node_version: ">=4"
}

View File

@@ -939,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,
@@ -1420,3 +1599,73 @@ issue_4570: {
}
expect_stdout: "NaN"
}
issue_5030: {
options = {
dead_code: true,
}
input: {
(function(a, b) {
a = function f() {
if (a)
if (b--)
setImmediate(f);
else
console.log("FAIL");
else
console.log("PASS");
}();
})(42, 1);
}
expect: {
(function(a, b) {
a = function f() {
if (a)
if (b--)
setImmediate(f);
else
console.log("FAIL");
else
console.log("PASS");
}();
})(42, 1);
}
expect_stdout: "PASS"
node_version: ">=0.12"
}
issue_5106_1: {
options = {
dead_code: true,
}
input: {
console.log(typeof function(a) {
return a = arguments;
}("FAIL")[0]);
}
expect: {
console.log(typeof function(a) {
return a = arguments;
}("FAIL")[0]);
}
expect_stdout: "object"
}
issue_5106_2: {
options = {
dead_code: true,
}
input: {
"use strict";
console.log(function(a) {
return a = arguments;
}("PASS")[0]);
}
expect: {
"use strict";
console.log(function(a) {
return arguments;
}("PASS")[0]);
}
expect_stdout: "PASS"
}

View File

@@ -70,7 +70,7 @@ object_shorthand_assign: {
({ a = "PASS" } = 42);
console.log(a);
}
expect_exact: '({a:a="PASS"}=42);console.log(a);'
expect_exact: '({a="PASS"}=42);console.log(a);'
expect_stdout: "PASS"
node_version: ">=6"
}
@@ -80,7 +80,7 @@ object_shorthand_declaration: {
var { a = "PASS" } = 42;
console.log(a);
}
expect_exact: 'var{a:a="PASS"}=42;console.log(a);'
expect_exact: 'var{a="PASS"}=42;console.log(a);'
expect_stdout: "PASS"
node_version: ">=6"
}
@@ -91,7 +91,7 @@ object_shorthand_function: {
console.log(a);
})(42);
}
expect_exact: '(function({a:a="PASS"}){console.log(a)})(42);'
expect_exact: '(function({a="PASS"}){console.log(a)})(42);'
expect_stdout: "PASS"
node_version: ">=6"
}
@@ -149,7 +149,7 @@ process_boolean_returns: {
}
expect: {
console.log(function(a = console.log("FAIL 1")) {
return a() ? "PASS" : "FAIL 2";
return 42 ? "PASS" : "FAIL 2";
}(function() {
return 1;
}));
@@ -245,21 +245,64 @@ maintain_if: {
node_version: ">=6"
}
reduce_value: {
reduce_funarg: {
options = {
evaluate: true,
keep_fargs: false,
reduce_vars: true,
unused: true,
}
input: {
console.log(function(a = "PASS") {
return a;
}());
console.log(...function(a = "foo", b = "bar", c = "baz") {
return [ a, b, c ];
}(void 0, null));
}
expect: {
console.log("PASS");
console.log(...function() {
return [ "foo", null, "baz" ];
}());
}
expect_stdout: "PASS"
expect_stdout: "foo null baz"
node_version: ">=6"
}
reduce_array: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
unsafe: true,
unused: true,
}
input: {
var [ a = "foo", b = "bar", c = "baz" ] = [ void 0, null ];
console.log(a, b, c);
}
expect: {
var [ c = "baz" ] = [];
console.log("foo", null, c);
}
expect_stdout: "foo null baz"
node_version: ">=6"
}
reduce_object: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
unsafe: true,
unused: true,
}
input: {
var { a = "foo", b = "bar", c = "baz" } = { a: void 0, b: null };
console.log(a, b, c);
}
expect: {
var { c = "baz" } = {};
console.log("foo", null, c);
}
expect_stdout: "foo null baz"
node_version: ">=6"
}
@@ -422,7 +465,9 @@ inline_loop_1: {
inline_loop_2: {
options = {
inline: true,
sequences: true,
toplevel: true,
unused: true,
}
input: {
while (function(a = [ "PASS" ]) {
@@ -432,10 +477,11 @@ inline_loop_2: {
}());
}
expect: {
while (a = [ "PASS" ], a = function f(b) {
console.log(a[b]);
}(0), void 0) ;
var a;
while (a = [ "PASS" ],
b = void 0,
b = 0,
void (a = void console.log(a[b])));
var a, b;
}
expect_stdout: "PASS"
node_version: ">=6"
@@ -522,6 +568,20 @@ retain_empty_iife: {
node_version: ">=6"
}
drop_new_function: {
options = {
side_effects: true,
}
input: {
new function(a = console.log("PASS")) {}();
}
expect: {
void console.log("PASS");
}
expect_stdout: "PASS"
node_version: ">=6"
}
retain_fargs: {
options = {
unused: true,
@@ -598,6 +658,7 @@ unused_var_1: {
unused_var_2: {
options = {
pure_getters: "strict",
toplevel: true,
unused: true,
}
@@ -609,11 +670,7 @@ unused_var_2: {
};
}
expect: {
var {
p: [] = [ console.log("FAIL") ],
} = {
p: [ console.log("PASS") ],
};
console.log("PASS");
}
expect_stdout: "PASS"
node_version: ">=6"
@@ -676,7 +733,7 @@ unused_value_var_2: {
console.log(a);
}
expect: {
var [ a ] = [ "PASS" ];
var a = [ "PASS" ][0];
console.log(a);
}
expect_stdout: "PASS"
@@ -980,7 +1037,7 @@ mangle_arrow_1: {
});
}
expect_stdout: "PASS"
node_version: ">=6"
node_version: ">=6.9.3"
}
mangle_arrow_1_toplevel: {
@@ -1016,7 +1073,7 @@ mangle_arrow_1_toplevel: {
});
}
expect_stdout: "PASS"
node_version: ">=6"
node_version: ">=6.9.3"
}
mangle_arrow_2: {
@@ -1052,7 +1109,7 @@ mangle_arrow_2: {
});
}
expect_stdout: "PASS"
node_version: ">=6"
node_version: ">=6.9.3"
}
mangle_arrow_2_toplevel: {
@@ -1088,7 +1145,7 @@ mangle_arrow_2_toplevel: {
});
}
expect_stdout: "PASS"
node_version: ">=6"
node_version: ">=6.9.3"
}
issue_4444: {
@@ -1257,7 +1314,7 @@ issue_4468: {
expect: {
(function() {
var {
[console.log("PASS")]: b = 0,
[console.log("PASS")]: b,
} = 0;
})();
}
@@ -1416,6 +1473,7 @@ issue_4502_1: {
expect: {
(function() {
var a = "PASS";
void 0,
console.log(a),
a++,
void 0;
@@ -1439,6 +1497,7 @@ issue_4502_2: {
expect: {
(function() {
var a = "PASS";
void 0,
console.log(a),
a++,
void 0;
@@ -1528,7 +1587,7 @@ issue_4510_2: {
};
}
expect_stdout: "PASS"
node_version: ">=8"
node_version: ">=8.3.0"
}
issue_4523: {
@@ -1664,7 +1723,7 @@ issue_4588_2_evaluate: {
issue_4817: {
options = {
ie8: true,
ie: true,
inline: true,
unused: true,
}
@@ -1698,7 +1757,7 @@ issue_4854: {
}());
}
expect: {
console.log(void ([] = "foo"));
console.log(void 0);
}
expect_stdout: "undefined"
node_version: ">=6"
@@ -1729,3 +1788,172 @@ issue_4916: {
expect_stdout: "undefined"
node_version: ">=6"
}
issue_4994: {
options = {
loops: true,
unused: true,
}
input: {
var a = "FAIL";
(function(b = function() {
for (a in { PASS: 42 });
}()) {
var a;
})();
console.log(a);
}
expect: {
var a = "FAIL";
(function(b = function() {
for (a in { PASS: 42 });
}()) {})();
console.log(a);
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5057_1: {
options = {
collapse_vars: true,
inline: true,
sequences: true,
unused: true,
}
input: {
var a = 42;
(function() {
var b = function(c = (console.log("foo"), b = a)) {
a && console.log("bar");
}();
})();
}
expect: {
var a = 42;
console.log("foo"),
void (a && console.log("bar"));
}
expect_stdout: [
"foo",
"bar",
]
node_version: ">=6"
}
issue_5057_2: {
options = {
inline: true,
unused: true,
}
input: {
(function f(a) {
(function(b = console.log("FAIL")) {})(a);
})(42);
console.log(typeof b);
}
expect: {
(function(a) {
[ b = console.log("FAIL") ] = [ a ],
void 0;
var b;
})(42);
console.log(typeof b);
}
expect_stdout: "undefined"
node_version: ">=6"
}
issue_5057_3: {
options = {
inline: true,
unused: true,
}
input: {
(function(a) {
(function f(b) {
(function(a = console.log("FAIL 1")) {})(b);
console.log(a);
})("FAIL 2");
})("PASS");
}
expect: {
(function(a) {
(function(b) {
(function(a = console.log("FAIL 1")) {})(b);
console.log(a);
})("FAIL 2");
})("PASS");
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5065: {
options = {
pure_getters: "strict",
toplevel: true,
unused: true,
}
input: {
var [ a = console.log("PASS") ] = [ (A = 42).p ];
}
expect: {
var [ a = console.log("PASS") ] = [ (A = 42).p ];
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5138_1: {
options = {
evaluate: true,
}
input: {
console.log(function(a, b = a = "FAIL") {
return a;
}() && "PASS");
}
expect: {
console.log(function(a, b = a = "FAIL") {
return a;
}() && "PASS");
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5138_2: {
options = {
evaluate: true,
}
input: {
console.log(function(a, b = a = "FAIL 1") {
return a;
}(null, "FAIL 2") || "PASS");
}
expect: {
console.log((null, "PASS"));
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5192: {
options = {
dead_code: true,
ie: true,
}
input: {
(function a(a, [] = a = "PASS") {
console.log(a);
})("FAIL");
}
expect: {
(function a(a, [] = a = "PASS") {
console.log(a);
})("FAIL");
}
expect_stdout: "PASS"
node_version: ">=6"
}

View File

@@ -220,7 +220,7 @@ funarg_side_effects_2: {
}
}
expect_stdout: "PASS"
node_version: ">=6"
node_version: ">=6.9.2"
}
funarg_side_effects_3: {
@@ -254,7 +254,7 @@ funarg_side_effects_3: {
}
}
expect_stdout: "PASS"
node_version: ">=6"
node_version: ">=6.9.2"
}
funarg_unused_1: {
@@ -1010,6 +1010,42 @@ collapse_vars_8: {
node_version: ">=6"
}
collapse_vars_9: {
options = {
collapse_vars: true,
}
input: {
console.log(function(a) {
try {
var b = function([ c ]) {
if (c)
return "FAIL 1";
}();
a = "FAIL 2";
return b;
} catch (e) {
return a;
}
}("PASS"));
}
expect: {
console.log(function(a) {
try {
var b = function([ c ]) {
if (c)
return "FAIL 1";
}();
a = "FAIL 2";
return b;
} catch (e) {
return a;
}
}("PASS"));
}
expect_stdout: "PASS"
node_version: ">=6"
}
conditionals: {
options = {
conditionals: true,
@@ -1069,7 +1105,7 @@ drop_unused_1: {
try {
throw 42;
} catch (a) {
var [ a ] = [];
var a = [][0];
}
}
}
@@ -1102,6 +1138,175 @@ drop_unused_2: {
node_version: ">=6"
}
drop_hole: {
options = {
unused: true,
}
input: {
var [ a ] = [ , ];
console.log(a);
}
expect: {
var a = [][0];
console.log(a);
}
expect_stdout: "undefined"
node_version: ">=6"
}
keep_key_1: {
options = {
evaluate: true,
side_effects: true,
unused: true,
}
input: {
({} = {
[(console.log("PASS"), 42)]: null,
});
}
expect: {
({} = {
[(console.log("PASS"), 42)]: 0,
});
}
expect_stdout: "PASS"
node_version: ">=6"
}
keep_key_2: {
options = {
evaluate: true,
toplevel: true,
unused: true,
}
input: {
var { 42: a } = { [(console.log("PASS"), 42)](){} };
}
expect: {
var {} = { [(console.log("PASS"), 42)]: 0 };
}
expect_stdout: "PASS"
node_version: ">=6"
}
keep_key_2_pure_getters: {
options = {
evaluate: true,
pure_getters: "strict",
toplevel: true,
unused: true,
}
input: {
var { 42: a } = { [(console.log("PASS"), 42)](){} };
}
expect: {
console.log("PASS");
}
expect_stdout: "PASS"
node_version: ">=6"
}
keep_reference: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = [ {}, 42 ];
var [ b, c ] = a;
console.log(a[0] === b ? "PASS" : "FAIL");
}
expect: {
var a = [ {}, 42 ];
var [ b ] = a;
console.log(a[0] === b ? "PASS" : "FAIL");
}
expect_stdout: "PASS"
node_version: ">=6"
}
maintain_position_assign: {
options = {
unused: true,
}
input: {
console.log(([ , ] = [ , "PASS" ])[1]);
}
expect: {
console.log([ , "PASS" ][1]);
}
expect_stdout: "PASS"
node_version: ">=6"
}
maintain_position_var: {
options = {
toplevel: true,
unused: true,
}
input: {
A = "FAIL";
var [ a, b ] = [ A ];
console.log(b || "PASS");
}
expect: {
A = "FAIL";
var [ , b ] = [ A ];
console.log(b || "PASS");
}
expect_stdout: "PASS"
node_version: ">=6"
}
side_effects_array: {
options = {
unused: true,
}
input: {
try {
var [ a ] = 42;
} catch (e) {
console.log("PASS");
}
}
expect: {
try {
var [ a ] = 42;
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "PASS"
node_version: ">=6"
}
side_effects_object: {
options = {
toplevel: true,
unused: true,
}
input: {
var a = null, b = console, { c } = 42;
try {
c[a = "PASS"];
} catch (e) {
console.log(a);
}
}
expect: {
var a = null, c = (console, 42["c"]);
try {
c[a = "PASS"];
} catch (e) {
console.log(a);
}
}
expect_stdout: "PASS"
node_version: ">=6"
}
join_vars: {
options = {
conditionals: true,
@@ -1376,6 +1581,75 @@ hoist_vars: {
node_version: ">=6"
}
singleton_1: {
options = {
pure_getters: true,
side_effects: true,
unused: true,
}
input: {
var [ a ] = "P", b, o = {};
[ { 1: o.p } ] = [ "FAIL" ];
({ foo: [ o.q ] } = { foo: "S" });
[ b = "S" ] = [];
console.log(a + o.p + o.q + b);
}
expect: {
var b, a = "P"[0], o = {};
o.p = [ "FAIL"["1"] ][0];
o.q = { foo: "S"[0] }["foo"];
[ b = "S" ] = [];
console.log(a + o.p + o.q + b);
}
expect_stdout: "PASS"
node_version: ">=6"
}
singleton_2: {
options = {
evaluate: true,
passes: 2,
pure_getters: true,
side_effects: true,
unsafe: true,
unused: true,
}
input: {
var [ a ] = "P", b, o = {};
[ { 1: o.p } ] = [ "FAIL" ];
({ foo: [ o.q ] } = { foo: "S" });
[ b = "S" ] = [];
console.log(a + o.p + o.q + b);
}
expect: {
var b, a = "P", o = {};
o.p = "A";
o.q = "S";
[ b = "S" ] = [];
console.log(a + o.p + o.q + b);
}
expect_stdout: "PASS"
node_version: ">=6"
}
singleton_side_effects: {
options = {
side_effects: true,
unused: true,
}
input: {
[ 42[console.log("foo")] ] = [ console.log("bar") ];
}
expect: {
[ 42[console.log("foo")] ] = [ console.log("bar") ];
}
expect_stdout: [
"bar",
"foo",
]
node_version: ">=6"
}
issue_4280: {
options = {
evaluate: true,
@@ -1824,7 +2098,7 @@ issue_4321: {
issue_4323: {
options = {
ie8: true,
ie: true,
inline: true,
merge_vars: true,
reduce_vars: true,
@@ -1922,7 +2196,7 @@ issue_4372_2: {
}
expect: {
var a;
[ a ] = [ "PASS", "FAIL" ];
[ a ] = a = [ "PASS", "FAIL" ];
console.log(a);
}
expect_stdout: "PASS"
@@ -2556,3 +2830,539 @@ issue_4608_2: {
expect_stdout: "f"
node_version: ">=6"
}
issue_4994: {
options = {
loops: true,
unused: true,
}
input: {
var a = "FAIL";
(function([
{
[function() {
for (a in { PASS: null });
}()]: b,
},
]) {
var a;
})([ 42 ]);
console.log(a);
}
expect: {
var a = "FAIL";
(function([
{
[function() {
for (a in { PASS: null });
}()]: b,
},
]) {})([ 42 ]);
console.log(a);
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5017: {
options = {
collapse_vars: true,
reduce_vars: true,
toplevel: true,
}
input: {
var a = function() {};
var b = c = a;
var c = [ c ] = [ c ];
console.log(c[0] === a ? "PASS" : "FAIL");
}
expect: {
var a = function() {};
var b = a;
var c = [ c ] = [ c = a ];
console.log(c[0] === a ? "PASS" : "FAIL");
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5071_1: {
options = {
unused: true,
}
input: {
var a;
console.log(([ , a ] = [ "PA", , ]).join("SS"));
}
expect: {
var a;
console.log(([ , a ] = [ "PA", , ]).join("SS"));
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5071_2: {
options = {
pure_getters: "strict",
unused: true,
}
input: {
var a;
([ a ] = []).p = console.log("PASS");
}
expect: {
var a;
([ a ] = []).p = console.log("PASS");
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5074_getter: {
options = {
evaluate: true,
side_effects: true,
unused: true,
}
input: {
({} = { get [(console.log("PASS"), 42)]() {} });
}
expect: {
({} = { [(console.log("PASS"), 42)]: 0 });
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5074_getter_pure_getters: {
options = {
evaluate: true,
pure_getters: "strict",
side_effects: true,
unused: true,
}
input: {
({} = { get [(console.log("PASS"), 42)]() {} });
}
expect: {
console.log("PASS");
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5074_setter: {
options = {
evaluate: true,
side_effects: true,
unused: true,
}
input: {
({} = { set [(console.log("PASS"), 42)](v) {} });
}
expect: {
({} = { [(console.log("PASS"), 42)]: 0 });
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5074_setter_pure_getters: {
options = {
evaluate: true,
pure_getters: "strict",
side_effects: true,
unused: true,
}
input: {
({} = { set [(console.log("PASS"), 42)](v) {} });
}
expect: {
console.log("PASS");
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5074_method: {
options = {
evaluate: true,
side_effects: true,
unused: true,
}
input: {
({} = { [(console.log("PASS"), 42)]() {} });
}
expect: {
({} = { [(console.log("PASS"), 42)]: 0 });
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5074_method_pure_getters: {
options = {
evaluate: true,
pure_getters: "strict",
side_effects: true,
unused: true,
}
input: {
({} = { [(console.log("PASS"), 42)]() {} });
}
expect: {
console.log("PASS");
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5085_1: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
unsafe: true,
unused: true,
}
input: {
var a = "PASS";
var [ b ] = [ 42, a ], c = b ? 0 : a = "FAIL";
console.log(a);
}
expect: {
var a = "PASS";
var b = [ 42 ][0];
b;
console.log(a);
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5085_2: {
options = {
evaluate: true,
reduce_vars: true,
side_effects: true,
unsafe: true,
unused: true,
}
input: {
var a = "PASS";
(function(b) {
[ b ] = [ 42, a ];
var c = b ? 0 : a = "FAIL";
})();
console.log(a);
}
expect: {
var a = "PASS";
(function(b) {
b = [ 42 ][0];
})();
console.log(a);
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5087_1: {
options = {
collapse_vars: true,
inline: true,
properties: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
var a = "PASS";
(function() {
(function() {
(function([ b ]) {
b && console.log(b);
})([ a ]);
})();
})();
}
expect: {
var a = "PASS";
(function() {
var b;
(b = a) && console.log(b);
})();
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5087_2: {
options = {
collapse_vars: true,
inline: true,
passes: 2,
properties: true,
reduce_vars: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
var a = "PASS";
(function() {
(function() {
(function([ b ]) {
b && console.log(b);
})([ a ]);
})();
})();
}
expect: {
var a = "PASS";
a && console.log(a);
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5114_1: {
options = {
inline: true,
unused: true,
}
input: {
var a = "PASS";
(function({}, a) {})(42);
console.log(a);
}
expect: {
var a = "PASS";
[ {} ] = [ 42 ],
void 0;
console.log(a);
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5114_2: {
options = {
inline: true,
pure_getters: "strict",
reduce_vars: true,
side_effects: true,
unused: true,
}
input: {
var a = "PASS";
(function f([], a) {
f.length;
})([]);
console.log(a);
}
expect: {
var a = "PASS";
0;
console.log(a);
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5114_3: {
options = {
inline: true,
pure_getters: "strict",
reduce_vars: true,
side_effects: true,
unused: true,
}
input: {
var a = "PASS";
(function f(a, {}) {
f.length;
})(null, 42);
console.log(a);
}
expect: {
var a = "PASS";
0;
console.log(a);
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5153_array_assign: {
options = {
dead_code: true,
}
input: {
var a = function*() {
yield b;
}(), b;
[ b ] = b = a;
console.log(a === b ? "PASS" : "FAIL");
}
expect: {
var a = function*() {
yield b;
}(), b;
[ b ] = b = a;
console.log(a === b ? "PASS" : "FAIL");
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5153_array_var: {
options = {
dead_code: true,
}
input: {
var a = function*() {
yield b;
}(), [ b ] = b = a;
console.log(a === b ? "PASS" : "FAIL");
}
expect: {
var a = function*() {
yield b;
}(), [ b ] = b = a;
console.log(a === b ? "PASS" : "FAIL");
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5153_object_assign: {
options = {
dead_code: true,
}
input: {
var a = {
get p() {
return b;
},
}, b;
({
p: b
} = b = a);
console.log(a === b ? "PASS" : "FAIL");
}
expect: {
var a = {
get p() {
return b;
},
}, b;
({
p: b
} = b = a);
console.log(a === b ? "PASS" : "FAIL");
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5153_object_var: {
options = {
dead_code: true,
}
input: {
var a = {
get p() {
return b;
},
}, {
p: b
} = b = a;
console.log(a === b ? "PASS" : "FAIL");
}
expect: {
var a = {
get p() {
return b;
},
}, {
p: b
} = b = a;
console.log(a === b ? "PASS" : "FAIL");
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5168: {
options = {
collapse_vars: true,
}
input: {
(function a({
[console.log(typeof function() {
++a;
return a;
}())]: b,
}) {
var a;
})({});
}
expect: {
(function a({
[console.log(typeof function() {
++a;
return a;
}())]: b,
}) {
var a;
})({});
}
expect_stdout: "function"
node_version: ">=6"
}
issue_5189_1: {
options = {
pure_getters: "strict",
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var a = 42;
[ a.p ] = a = "PASS";
console.log(a);
}
expect: {
var a;
[ a.p ] = a = "PASS";
console.log(a);
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5189_2: {
options = {
pure_getters: "strict",
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var a = 42;
({ p: a.q } = a = "PASS");
console.log(a);
}
expect: {
var a;
({ p: a.q } = a = "PASS");
console.log(a);
}
expect_stdout: "PASS"
node_version: ">=6"
}

View File

@@ -795,9 +795,9 @@ issue_1656: {
beautify: true,
}
input: {
for(var a=0;;);
for (var a=0;;);
}
expect_exact: "for (;;) ;"
expect_exact: "for (;;);"
}
issue_1709: {
@@ -1110,7 +1110,7 @@ issue_1838: {
}
expect_exact: [
"function f() {",
" for (a; c; ) ;",
" for (a; c; );",
"}",
]
}
@@ -1557,9 +1557,9 @@ issue_2665: {
}
expect: {
var a = 1;
!function g() {
(function g() {
a-- && g();
}();
})();
console.log(a);
}
expect_stdout: "-1"
@@ -2345,7 +2345,7 @@ function_argument_reference: {
function_parameter_ie8: {
options = {
ie8: true,
ie: true,
reduce_vars: true,
unused: true,
}
@@ -2916,7 +2916,7 @@ issue_4133: {
console.log(a);
}
expect: {
var b = 1;
var a = 1;
console.log(0);
}
expect_stdout: "0"
@@ -3062,7 +3062,7 @@ issue_4184: {
expect_stdout: "42"
}
issue_4235: {
issue_4235_1: {
options = {
inline: true,
reduce_vars: true,
@@ -3080,12 +3080,35 @@ issue_4235: {
})();
}
expect: {
void function() {
var f = console.log(f);
}();
}
expect_stdout: "undefined"
}
issue_4235_2: {
options = {
inline: true,
passes: 2,
reduce_vars: true,
side_effects: true,
unused: true,
varify: true,
}
input: {
(function() {
f = console.log(f),
void 0;
var f;
{
const f = 0;
}
(function f() {
var f = console.log(f);
})();
})();
}
expect: {
console.log(void 0);
}
expect_stdout: "undefined"
}
@@ -3231,7 +3254,7 @@ issue_4558_1: {
issue_4558_2: {
options = {
evaluate: true,
ie8: true,
ie: true,
reduce_vars: true,
unused: true,
}
@@ -3380,7 +3403,7 @@ issue_4834: {
}
expect: {
try {
void b.p;
b.p;
} catch (e) {
console.log("PASS");
}
@@ -3436,7 +3459,7 @@ issue_4912_2: {
console.log(function() {
var g, f = function() {};
f.p = {};
(g = f.p.q = function() {}).r = "PASS";
(f.p.q = function() {}).r = "PASS";
return f;
}().p.q.r);
}
@@ -3470,3 +3493,26 @@ issue_4912_3: {
}
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

@@ -684,26 +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: true
expect_stdout: [
"false",
"PASS",
"S",
"PASS",
"false",
"PASS",
"S",
"PASS",
]
}
call_args: {
@@ -3182,7 +3203,7 @@ issue_4552: {
expect_stdout: "NaN"
}
issue_4886: {
issue_4886_1: {
options = {
evaluate: true,
unsafe: true,
@@ -3201,3 +3222,23 @@ issue_4886: {
}
expect_stdout: "true"
}
issue_4886_2: {
options = {
evaluate: true,
unsafe: true,
}
input: {
console.log("foo" in {
"foo": null,
__proto__: 42,
});
}
expect: {
console.log("foo" in {
"foo": null,
__proto__: 42,
});
}
expect_stdout: "true"
}

View File

@@ -62,7 +62,7 @@ assignment_2: {
}
expect_exact: "var a=8n;a**=a;console.log(a);"
expect_stdout: "16777216n"
node_version: ">=10"
node_version: ">=10.4.0"
}
evaluate: {
@@ -99,8 +99,8 @@ issue_4664: {
expect: {
(function f() {
new function(a) {
console.log(typeof f, 1073741824, typeof this);
}(A = 0);
console.log(typeof f, a, typeof this);
}((A = 0, 2 ** 30));
})();
}
expect_stdout: "function 1073741824 object"

View File

@@ -249,7 +249,7 @@ hoist_exports_2: {
}
}
expect: {
let e, { foo: a } = 42;
let e, a = 42["foo"];
function f(t, { [e]: o }) {
t(o, f);
}

View File

@@ -1171,11 +1171,11 @@ issue_2620_4: {
}
expect: {
var c = "FAIL";
!function() {
(function() {
switch (NaN) {
case void (c = "PASS"):
}
}();
})();
console.log(c);
}
expect_stdout: "PASS"
@@ -2123,7 +2123,7 @@ issue_3016_2: {
issue_3016_2_ie8: {
options = {
dead_code: true,
ie8: true,
ie: true,
inline: true,
toplevel: true,
}
@@ -2188,7 +2188,7 @@ issue_3016_3: {
issue_3016_3_ie8: {
options = {
dead_code: true,
ie8: true,
ie: true,
inline: true,
toplevel: true,
}
@@ -2826,6 +2826,36 @@ functions_use_strict: {
expect_stdout: "a true 42 function function function"
}
functions_cross_scope_reference: {
options = {
functions: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
log = function(fn) {
console.log(typeof fn());
};
var a = function() {};
function f() {
return a;
}
while (log(f));
}
expect: {
log = function(fn) {
console.log(typeof fn());
};
function a() {}
function f() {
return a;
}
while (log(f));
}
expect_stdout: "function"
}
functions_inner_var: {
options = {
functions: true,
@@ -2905,6 +2935,7 @@ issue_2437: {
issue_2485_1: {
options = {
functions: true,
passes: 2,
reduce_funcs: true,
reduce_vars: true,
unused: true,
@@ -2955,6 +2986,7 @@ issue_2485_2: {
options = {
functions: true,
inline: true,
passes: 2,
reduce_funcs: true,
reduce_vars: true,
unused: true,
@@ -4825,8 +4857,9 @@ issue_4155: {
}
expect: {
(function() {
void console.log(b);
var b = function() {};
var a;
void console.log(a);
function b() {}
b && console.log(typeof b);
})();
}
@@ -5236,7 +5269,7 @@ issue_4265: {
expect: {
function f() {
return console, function() {
return console.log(a);
console.log(a);
var a;
}(), 0;
}
@@ -6208,3 +6241,464 @@ reduce_cross_reference_4_toplevel: {
expect: {}
expect_stdout: true
}
recursive_collapse: {
options = {
collapse_vars: true,
reduce_vars: true,
}
input: {
console.log(function f(a) {
var b = a && f();
return b;
}("FAIL") || "PASS");
}
expect: {
console.log(function f(a) {
var b;
return a && f();
}("FAIL") || "PASS");
}
expect_stdout: "PASS"
}
issue_5025: {
options = {
collapse_vars: true,
inline: true,
reduce_vars: true,
unused: true,
}
input: {
function f(a) {
function g() {
b = 42;
}
g(b = a);
var b = this;
console.log(typeof b);
}
f();
}
expect: {
function f(a) {
b = a,
void (b = 42);
var b = this;
console.log(typeof b);
}
f();
}
expect_stdout: "object"
}
issue_5036: {
options = {
functions: true,
reduce_vars: true,
unused: true,
}
input: {
console.log(typeof function() {
var await = function f() {
return f;
};
return await() === await;
}() ? "PASS" : "FAIL");
}
expect: {
console.log(typeof function() {
function await() {
return await;
}
return await() === await;
}() ? "PASS" : "FAIL");
}
expect_stdout: "PASS"
}
issue_5046: {
options = {
conditionals: true,
evaluate: true,
keep_fnames: true,
passes: 2,
reduce_vars: true,
side_effects: true,
toplevel: true,
}
input: {
var a = 0;
if (a)
0();
else
(function f() {
f;
return a = "PASS";
})();
console.log(a);
}
expect: {
var a = 0;
(a ? 0 : function f() {
return a = "PASS";
})();
console.log(a);
}
expect_stdout: "PASS"
}
issue_5061_1: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
}
input: {
var f, a = 1;
(f = function() {
console.log(a ? "foo" : "bar");
})();
f(a = 0);
}
expect: {
var f, a = 1;
(f = function() {
console.log(a ? "foo" : "bar");
})();
f(a = 0);
}
expect_stdout: [
"foo",
"bar",
]
}
issue_5061_2: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var f, a = 1;
(f = function() {
console.log(a ? "foo" : "bar");
})();
f(a = 0);
}
expect: {
var f, a = 1;
(f = function() {
console.log(a ? "foo" : "bar");
})();
f(a = 0);
}
expect_stdout: [
"foo",
"bar",
]
}
issue_5067: {
options = {
inline: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var f = function() {
f();
};
}
expect: {}
}
issue_5096_1: {
options = {
evaluate: true,
passes: 2,
reduce_vars: true,
side_effects: true,
toplevel: true,
}
input: {
var a, b = "FAIL", c = 1;
do {
a && a();
a = function() {
b = "PASS";
};
} while (c--);
console.log(b);
}
expect: {
var a, b = "FAIL", c = 1;
do {
a && a();
a = function() {
b = "PASS";
};
} while (c--);
console.log(b);
}
expect_stdout: "PASS"
}
issue_5096_2: {
options = {
passes: 2,
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var a, b = "FAIL", c = 1;
do {
a && a();
a = function() {
b = "PASS";
};
} while (c--);
console.log(b);
}
expect: {
var a, b = "FAIL", c = 1;
do {
a && a();
a = function() {
b = "PASS";
};
} while (c--);
console.log(b);
}
expect_stdout: "PASS"
}
issue_5096_3: {
options = {
evaluate: true,
reduce_vars: true,
side_effects: true,
toplevel: true,
}
input: {
var b = "FAIL", c = 1;
do {
a && a();
var a = function() {
b = "PASS";
};
} while (c--);
console.log(b);
}
expect: {
var b = "FAIL", c = 1;
do {
a && a();
var a = function() {
b = "PASS";
};
} while (c--);
console.log(b);
}
expect_stdout: "PASS"
}
issue_5096_4: {
options = {
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var b = "FAIL", c = 1;
do {
a && a();
var a = function() {
b = "PASS";
};
} while (c--);
console.log(b);
}
expect: {
var b = "FAIL", c = 1;
do {
a && a();
var a = function() {
b = "PASS";
};
} while (c--);
console.log(b);
}
expect_stdout: "PASS"
}
issue_5098: {
options = {
reduce_vars: true,
unused: true,
}
input: {
(function(o) {
function f() {
f = console.log;
if (o.p++)
throw "FAIL";
f("PASS");
}
return f;
})({ p: 0 })();
}
expect: {
(function(o) {
function f() {
f = console.log;
if (o.p++)
throw "FAIL";
f("PASS");
}
return f;
})({ p: 0 })();
}
expect_stdout: "PASS"
}
shorter_without_void: {
options = {
inline: true,
passes: 2,
reduce_vars: true,
side_effects: true,
toplevel: true,
}
input: {
var a;
function f(b) {
a = b;
}
f("foo");
console.log(a) || f("bar");
console.log(a, f("baz"));
console.log(a);
}
expect: {
var a;
function f(b) {
a = b;
}
a = "foo";
console.log(a) || (a = "bar");
console.log(a, f("baz"));
console.log(a);
}
expect_stdout: [
"foo",
"bar undefined",
"baz",
]
}
issue_5120: {
options = {
functions: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = function f() {
function g() {
f || g();
}
g();
return f.valueOf();
};
console.log(a() === a ? "PASS" : "FAIL");
}
expect: {
function a() {
(function g() {
a || g();
})();
return a.valueOf();
}
console.log(a() === a ? "PASS" : "FAIL");
}
expect_stdout: "PASS"
}
issue_5140: {
options = {
collapse_vars: true,
inline: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
A = 42;
function f(b) {
return b >> 0;
}
var a = f(42 in []);
console.log(f(A));
}
expect: {
function f(b) {
return b >> 0;
}
A = 42;
console.log(A >> 0);
}
expect_stdout: "42"
}
issue_5173_1: {
options = {
conditionals: true,
inline: true,
reduce_vars: true,
side_effects: true,
toplevel: true,
}
input: {
function f(a, b) {
console.log(b);
}
f([ A = 42, [] + "" || (A = f) ]);
}
expect: {
function f(a, b) {
console.log(b);
}
f([ A = 42, [] + "" || (A = f) ]);
}
expect_stdout: "undefined"
}
issue_5173_2: {
options = {
conditionals: true,
inline: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
function f(a, b) {
console.log(b);
}
f([ A = 42, [] + "" || (A = f) ]);
}
expect: {
function f(a, b) {
console.log(b);
}
f(A = [] + "" ? 42 : f);
}
expect_stdout: "undefined"
}

View File

@@ -217,7 +217,8 @@ name_collision_1: {
var obj_foo = 1;
var obj_bar = 2;
function f() {
var obj_foo$0 = 3,
var obj,
obj_foo$0 = 3,
obj_bar = 4,
obj_b_r = 5,
obj_b_r$0 = 6,
@@ -249,7 +250,8 @@ name_collision_2: {
console.log(o.p === o.p, o["+"](4), o["-"](5), o__$0, o__$1);
}
expect: {
var o_p = 1,
var o,
o_p = 1,
o__ = function(x) {
return x;
},
@@ -283,7 +285,8 @@ name_collision_3: {
console.log(o.p === o.p, o["+"](4), o["-"](5));
}
expect: {
var o_p = 1,
var o,
o_p = 1,
o__ = function(x) {
return x;
},
@@ -315,7 +318,7 @@ name_collision_4: {
}
expect: {
console.log(function() {
var o_p$0 = 0, o_q = "PASS";
var o, o_p$0 = 0, o_q = "PASS";
return function(o_p) {
if (!o_p$0) return o_p;
}(o_q);
@@ -768,7 +771,7 @@ issue_3046: {
expect: {
console.log(function(a) {
do {
var b_c = a++;
var b, b_c = a++;
} while (b_c && a);
return a;
}(0));
@@ -777,6 +780,32 @@ issue_3046: {
}
issue_3071_1: {
options = {
evaluate: true,
hoist_props: true,
inline: true,
join_vars: true,
passes: 3,
reduce_vars: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
(function() {
var obj = {};
obj.one = 1;
obj.two = 2;
console.log(obj.one, obj.two);
})();
}
expect: {
console.log(1, 2);
}
expect_stdout: "1 2"
}
issue_3071_1_toplevel: {
options = {
evaluate: true,
hoist_props: true,
@@ -905,7 +934,7 @@ issue_3411: {
expect: {
var c = 1;
!function f() {
var o_p = --c && f();
var o, o_p = --c && f();
+{} || console.log("PASS");
}();
}
@@ -1016,9 +1045,7 @@ issue_3945_1: {
expect: {
function f() {
o.p;
var o = {
q: 0,
};
var o, o_q = 0;
}
}
}
@@ -1037,9 +1064,7 @@ issue_3945_2: {
}
expect: {
console.log(typeof o);
var o = {
p: 0,
};
var o, o_p = 0;
}
expect_stdout: "undefined"
}
@@ -1094,3 +1119,60 @@ object_super: {
expect_stdout: "PASS"
node_version: ">=4"
}
issue_4985: {
options = {
hoist_props: true,
reduce_vars: true,
toplevel: true,
}
input: {
var a = { p: 42 };
console.log(function() {
a;
}());
}
expect: {
var a, a_p = 42;
console.log(function() {
({});
}());
}
expect_stdout: "undefined"
}
issue_5182: {
options = {
hoist_props: true,
merge_vars: true,
passes: 2,
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var o = console;
log = o.log;
o = {
p: function(a) {
console.log(a ? "PASS" : "FAIL");
return a;
},
};
log(o.p(42));
}
expect: {
var o_p = console;
log = o_p.log;
o_p = function(a) {
console.log(a ? "PASS" : "FAIL");
return a;
};
log(o_p(42));
}
expect_stdout: [
"PASS",
"42",
]
}

View File

@@ -135,7 +135,7 @@ issue_2295: {
}
}
issue_4487: {
issue_4487_1: {
options = {
functions: true,
hoist_vars: true,
@@ -150,6 +150,31 @@ issue_4487: {
};
var b = a();
}
expect: {
var a = function f() {
var f = console.log(typeof f);
};
a();
}
expect_stdout: "undefined"
}
issue_4487_2: {
options = {
functions: true,
hoist_vars: true,
keep_fnames: true,
passes: 2,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = function f() {
var f = console.log(typeof f);
};
var b = a();
}
expect: {
function a() {
var f = console.log(typeof f);
@@ -159,6 +184,30 @@ issue_4487: {
expect_stdout: "undefined"
}
issue_4487_3: {
options = {
functions: true,
hoist_vars: true,
keep_fnames: true,
passes: 3,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = function f() {
var f = console.log(typeof f);
};
var b = a();
}
expect: {
(function a() {
console.log(typeof void 0);
})();
}
expect_stdout: "undefined"
}
issue_4489: {
options = {
collapse_vars: true,
@@ -250,18 +299,18 @@ issue_4839: {
unused: true,
}
input: {
var o = function(a, b) {
var log = console.log, o = function(a, b) {
return b && b;
}("foo");
for (var k in o)
throw "FAIL";
console.log("PASS");
log("PASS");
}
expect: {
var k, o = void 0;
for (k in o)
var k, log = console.log;
for (k in void 0)
throw "FAIL";
console.log("PASS");
log("PASS");
}
expect_stdout: "PASS"
}
@@ -287,8 +336,7 @@ issue_4859: {
}
expect: {
(function f(a) {
var d = 1 / 0, d = Infinity;
console.log(d);
console.log(Infinity);
return f;
})();
}
@@ -322,9 +370,7 @@ issue_4893_1: {
expect: {
try{
(function f() {
var b;
b = null;
b.p += 42;
null.p += 42;
f;
})();
} catch (e) {
@@ -396,3 +442,61 @@ issue_4898: {
}
expect_stdout: "PASS"
}
issue_5187: {
options = {
hoist_props: true,
hoist_vars: true,
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
function f() {
var a = 42;
do {
var b = { 0: a++ };
} while (console.log(b[b ^= 0]));
}
f();
}
expect: {
(function() {
var b, a = 42;
do {
b = { 0: a++ };
} while (console.log(b[b ^= 0]));
})();
}
expect_stdout: "42"
}
issue_5195: {
options = {
hoist_props: true,
hoist_vars: true,
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
function f() {
var a;
do {
var b = { p: a };
} while (console.log(b += ""));
}
f();
}
expect: {
(function() {
var a, b;
do {
b = { p: a };
} while (console.log(b += ""));
})();
}
expect_stdout: "[object Object]"
}

File diff suppressed because it is too large Load Diff

View File

@@ -94,13 +94,15 @@ drop_unused: {
}
input: {
import a, * as b from "foo";
import { c, bar as d } from "baz";
console.log(c);
import { c } from "bar";
import { d, _ as e } from "baz";
console.log(d);
}
expect: {
import "foo";
import { c as c } from "baz";
console.log(c);
import "bar";
import { d as d } from "baz";
console.log(d);
}
}

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

@@ -489,6 +489,116 @@ join_object_assignments_regex: {
expect_stdout: "1"
}
chained_assignments: {
options = {
join_vars: true,
}
input: {
var a, b = a = {};
b.p = "PASS";
console.log(a.p);
}
expect: {
var a, b = a = {
p: "PASS",
};
console.log(a.p);
}
expect_stdout: "PASS"
}
folded_assignments_1: {
options = {
evaluate: true,
join_vars: true,
}
input: {
var a = {};
a[a.PASS = 42] = "PASS";
console.log(a[42], a.PASS);
}
expect: {
var a = {
PASS: 42,
42: "PASS",
};
console.log(a[42], a.PASS);
}
expect_stdout: "PASS 42"
}
folded_assignments_2: {
options = {
evaluate: true,
join_vars: true,
}
input: {
"use strict";
var a = {};
a[42] = "FAIL";
a[a.PASS = 42] = "PASS";
console.log(a[42], a.PASS);
}
expect: {
"use strict";
var a = {
42: "FAIL",
PASS: 42,
};
a[42] = "PASS";
console.log(a[42], a.PASS);
}
expect_stdout: "PASS 42"
}
inlined_assignments: {
options = {
join_vars: true,
unused: true,
}
input: {
var a;
(a = {}).p = "PASS";
console.log(a.p);
}
expect: {
var a = {
p: "PASS",
};
console.log(a.p);
}
expect_stdout: "PASS"
}
typescript_enum: {
rename = true
options = {
assignments: true,
collapse_vars: true,
evaluate: true,
hoist_props: true,
inline: true,
join_vars: true,
passes: 4,
reduce_vars: true,
sequences: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var Enum;
(function (Enum) {
Enum[Enum.PASS = 42] = "PASS";
})(Enum || (Enum = {}));
console.log(Enum[42], Enum.PASS);
}
expect: {
console.log("PASS", 42);
}
expect_stdout: "PASS 42"
}
issue_2816: {
options = {
join_vars: true,
@@ -1015,7 +1125,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;
})();
@@ -1183,3 +1293,26 @@ assign_sequence_var: {
"1 2 3",
]
}
issue_5175: {
options = {
join_vars: true,
}
input: {
function log(f) {
console.log(f(), A.p);
}
log(function() {
return (A = {}).p = "PASS";
});
}
expect: {
function log(f) {
console.log(f(), A.p);
}
log(function() {
return (A = {}).p = "PASS";
});
}
expect_stdout: "PASS PASS"
}

View File

@@ -117,6 +117,7 @@ issue_1858: {
collapse_vars: true,
keep_fargs: false,
pure_getters: true,
reduce_vars: true,
unused: true,
}
input: {
@@ -950,7 +951,7 @@ function_name_mangle_ie8: {
unused: true,
}
mangle = {
ie8: true,
ie: true,
toplevel: true,
}
input: {
@@ -1157,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);
@@ -1167,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);

View File

@@ -83,8 +83,9 @@ labels_5: {
conditionals: true,
dead_code: true,
if_return: true,
unused: true,
}
// should keep the break-s in the following
// should keep `break`s below
input: {
while (foo) {
if (bar) break;
@@ -100,8 +101,8 @@ labels_5: {
if (bar) break;
console.log("foo");
}
out: while (foo) {
if (bar) break out;
while (foo) {
if (bar) break;
console.log("foo");
}
}
@@ -189,23 +190,22 @@ labels_10: {
conditionals: true,
dead_code: true,
if_return: true,
unused: true,
}
input: {
out: while (foo) {
x();
y();
out: while (42) {
console.log("PASS");
break out;
z();
k();
console.log("FAIL");
}
};
expect: {
out: while (foo) {
x();
y();
break out;
while (42) {
console.log("PASS");
break;
}
}
expect_stdout: "PASS"
}
issue_4466_1: {

View File

@@ -20,6 +20,39 @@ retain_block: {
node_version: ">=4"
}
retain_assignment: {
options = {
dead_code: true,
reduce_vars: true,
}
input: {
"use strict";
function f() {
return a = 0;
let a;
}
try {
f();
} catch (e) {
console.log("PASS");
}
}
expect: {
"use strict";
function f() {
return a = 0;
let a;
}
try {
f();
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "PASS"
node_version: ">=4"
}
retain_catch: {
options = {
dead_code: true,
@@ -461,6 +494,41 @@ reduce_vars_3: {
node_version: ">=4"
}
reduce_lambda: {
options = {
evaluate: true,
functions: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
"use strict";
let f = function() {
console.log(a, b);
};
let a = "foo", b = 42;
f();
b = "bar";
f();
}
expect: {
"use strict";
function f() {
console.log("foo", b);
}
let b = 42;
f();
b = "bar";
f();
}
expect_stdout: [
"foo 42",
"foo bar",
]
node_version: ">=4"
}
hoist_props: {
options = {
hoist_props: true,
@@ -536,6 +604,38 @@ loop_block_2: {
node_version: ">=4"
}
do_break: {
options = {
loops: true,
}
input: {
"use strict";
try {
do {
if (a)
break;
let a;
} while (!console);
} catch (e) {
console.log("PASS");
}
}
expect: {
"use strict";
try {
do {
if (a)
break;
let a;
} while (!console);
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "PASS"
node_version: ">=4"
}
do_continue: {
options = {
loops: true,
@@ -596,6 +696,82 @@ dead_block_after_return: {
node_version: ">=4"
}
if_return_1: {
options = {
if_return: true,
}
input: {
"use strict";
function f(a) {
function g() {
return b = "PASS";
}
if (a)
return g();
let b;
return g();
};
console.log(f());
}
expect: {
"use strict";
function f(a) {
function g() {
return b = "PASS";
}
if (a)
return g();
let b;
return g();
};
console.log(f());
}
expect_stdout: "PASS"
node_version: ">=4"
}
if_return_2: {
options = {
if_return: true,
}
input: {
"use strict";
function f(a) {
function g() {
return b = "FAIL";
}
if (a)
return g();
let b;
return g();
};
try {
console.log(f(42));
} catch (e) {
console.log("PASS");
}
}
expect: {
"use strict";
function f(a) {
function g() {
return b = "FAIL";
}
if (a)
return g();
let b;
return g();
};
try {
console.log(f(42));
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "PASS"
node_version: ">=4"
}
do_if_continue_1: {
options = {
if_return: true,
@@ -897,6 +1073,7 @@ issue_4210: {
issue_4212_1: {
options = {
dead_code: true,
reduce_vars: true,
}
input: {
"use strict";
@@ -987,7 +1164,7 @@ issue_4225: {
issue_4229: {
options = {
ie8: true,
ie: true,
side_effects: true,
}
input: {
@@ -1018,7 +1195,7 @@ issue_4229: {
issue_4231: {
options = {
ie8: true,
ie: true,
side_effects: true,
}
input: {
@@ -1387,7 +1564,7 @@ issue_4438: {
issue_4531_1: {
mangle = {
ie8: true,
ie: true,
toplevel: true,
}
input: {
@@ -1413,11 +1590,11 @@ issue_4531_1: {
issue_4531_2: {
options = {
evaluate: true,
ie8: true,
ie: true,
toplevel: true,
}
mangle = {
ie8: true,
ie: true,
toplevel: true,
}
input: {
@@ -1546,3 +1723,27 @@ issue_4848: {
expect_stdout: "PASS"
node_version: ">=4"
}
issue_4985: {
options = {
hoist_props: true,
reduce_vars: true,
toplevel: true,
}
input: {
"use strict";
let a = { p: 42 };
console.log(function() {
a;
}());
}
expect: {
"use strict";
let a = { p: 42 };
console.log(function() {
a;
}());
}
expect_stdout: "undefined"
node_version: ">=4"
}

View File

@@ -193,9 +193,9 @@ evaluate: {
} while (false);
}
expect: {
for(;;)
for (;;)
a();
for(;;)
for (;;)
c();
d();
}
@@ -265,7 +265,7 @@ issue_1532_2: {
issue_186: {
beautify = {
beautify: false,
ie8: false,
ie: false,
}
input: {
var x = 3;
@@ -284,7 +284,7 @@ issue_186: {
issue_186_ie8: {
beautify = {
beautify: false,
ie8: true,
ie: true,
}
input: {
var x = 3;
@@ -303,7 +303,7 @@ issue_186_ie8: {
issue_186_beautify: {
beautify = {
beautify: true,
ie8: false,
ie: false,
}
input: {
var x = 3;
@@ -330,7 +330,7 @@ issue_186_beautify: {
issue_186_beautify_ie8: {
beautify = {
beautify: true,
ie8: true,
ie: true,
}
input: {
var x = 3;
@@ -360,7 +360,7 @@ issue_186_braces: {
beautify = {
beautify: false,
braces: true,
ie8: false,
ie: false,
}
input: {
var x = 3;
@@ -380,7 +380,7 @@ issue_186_braces_ie8: {
beautify = {
beautify: false,
braces: true,
ie8: true,
ie: true,
}
input: {
var x = 3;
@@ -400,7 +400,7 @@ issue_186_beautify_braces: {
beautify = {
beautify: true,
braces: true,
ie8: false,
ie: false,
}
input: {
var x = 3;
@@ -432,7 +432,7 @@ issue_186_beautify_braces_ie8: {
beautify = {
beautify: true,
braces: true,
ie8: true,
ie: true,
}
input: {
var x = 3;

View File

@@ -359,7 +359,7 @@ issue_4107: {
issue_4109: {
options = {
ie8: true,
ie: true,
merge_vars: true,
toplevel: true,
}
@@ -476,9 +476,9 @@ issue_4112: {
try {
throw 42;
} catch (e) {
var a = e;
for (e in a);
a = function() {};
var o = e;
for (e in o);
function a() {}
console.log(typeof a);
return a;
}
@@ -2735,8 +2735,7 @@ issue_4135: {
0;
a++;
if (!a)
c = (a++, c = 0, void (c && c.p));
var c;
var c = void a++;
console.log(a, -1, c);
}
expect_stdout: "1 -1 undefined"
@@ -3075,7 +3074,7 @@ issue_4237_2: {
console.log(function(a) {
do {
switch (0) {
case 0:
default:
var b = a++;
if (b)
return "FAIL";
@@ -3301,3 +3300,137 @@ issue_4761: {
}
expect_stdout: "undefined"
}
issue_4956_1: {
options = {
merge_vars: true,
toplevel: true,
}
input: {
var a, b;
function f(c) {
switch (c) {
case 0:
a = { p: 42 };
case 1:
b = a.p;
console.log(b);
}
}
f(0);
f(1);
}
expect: {
var a, b;
function f(c) {
switch (c) {
case 0:
a = { p: 42 };
case 1:
b = a.p;
console.log(b);
}
}
f(0);
f(1);
}
expect_stdout: [
"42",
"42",
]
}
issue_4956_2: {
options = {
merge_vars: true,
toplevel: true,
}
input: {
var a, b;
function f(c) {
if (0 == c) {
console;
a = { p: 42 };
}
b = a.p;
if (1 == c)
console.log(b);
}
f(0);
f(1);
}
expect: {
var a, b;
function f(c) {
if (0 == c) {
console;
a = { p: 42 };
}
b = a.p;
if (1 == c)
console.log(b);
}
f(0);
f(1);
}
expect_stdout: "42"
}
issue_5182: {
options = {
arrows: true,
collapse_vars: true,
evaluate: true,
hoist_props: true,
inline: true,
merge_vars: true,
passes: 4,
reduce_vars: true,
sequences: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
try {
var con = console;
} catch (x) {}
global.log = con.log;
var jump = function(x) {
console.log("JUMP:", x * 10);
return x + x;
};
var jump2 = jump;
var run = function(x) {
console.log("RUN:", x * -10);
return x * x;
};
var run2 = run;
var bar = (x, y) => {
console.log("BAR:", x + y);
return x - y;
};
var bar2 = bar;
var obj = {
foo: bar2,
go: run2,
not_used: jump2,
};
console.log(obj.foo(1, 2), global.log("PASS"));
}
expect: {
try {
var con = console;
} catch (x) {}
global.log = con.log,
console.log((console.log("BAR:", 3), -1), global.log("PASS"));
}
expect_stdout: [
"BAR: 3",
"PASS",
"-1 undefined",
]
node_version: ">=4"
}

View File

@@ -110,10 +110,162 @@ conditional_assignment_4: {
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,
ie8: true,
ie: true,
}
input: {
var a;

View File

@@ -521,3 +521,25 @@ issue_4415: {
expect_stdout: "PASS"
node_version: ">=4"
}
issue_5213: {
options = {
objects: true,
}
input: {
var a = "FAIL";
console.log({
p: a = "PASS",
0: a,
p: null,
}[0]);
}
expect: {
var a = "FAIL";
console.log({
p: (a = "PASS", null),
0: a,
}[0]);
}
expect_stdout: "PASS"
}

View File

@@ -43,6 +43,68 @@ ternary_decimal: {
expect_stdout: "PASS"
}
assign_parentheses_call: {
input: {
var o = {};
((() => o)?.()).p = "PASS";
console.log(o.p);
}
expect_exact: 'var o={};((()=>o)?.()).p="PASS";console.log(o.p);'
expect_stdout: "PASS"
node_version: ">=14"
}
assign_parentheses_dot: {
input: {
(console?.log).name.p = console.log("PASS");
}
expect_exact: '(console?.log).name.p=console.log("PASS");'
expect_stdout: "PASS"
node_version: ">=14"
}
assign_no_parentheses: {
input: {
console[console.log?.("PASS")] = 42;
}
expect_exact: 'console[console.log?.("PASS")]=42;'
expect_stdout: "PASS"
node_version: ">=14"
}
call_parentheses: {
input: {
(function(o) {
console.log(o.f("FAIL"), (o.f)("FAIL"), (0, o.f)(42));
console.log(o?.f("FAIL"), (o?.f)("FAIL"), (0, o?.f)(42));
})({
a: "PASS",
f(b) {
return this.a || b;
},
});
}
expect_exact: '(function(o){console.log(o.f("FAIL"),o.f("FAIL"),(0,o.f)(42));console.log(o?.f("FAIL"),(o?.f)("FAIL"),(0,o?.f)(42))})({a:"PASS",f(b){return this.a||b}});'
expect_stdout: [
"PASS PASS 42",
"PASS PASS 42",
]
node_version: ">=14"
}
unary_parentheses: {
input: {
var o = { p: 41 };
(function() {
return o;
}?.()).p++;
console.log(o.p);
}
expect_exact: "var o={p:41};(function(){return o}?.()).p++;console.log(o.p);"
expect_stdout: "42"
node_version: ">=14"
}
collapse_vars_1: {
options = {
collapse_vars: true,
@@ -195,6 +257,99 @@ trim_2: {
node_version: ">=14"
}
trim_dot_call_1: {
options = {
evaluate: true,
optional_chains: true,
}
input: {
console.log(null?.f());
}
expect: {
console.log(void 0);
}
expect_stdout: "undefined"
node_version: ">=14"
}
trim_dot_call_2: {
options = {
evaluate: true,
optional_chains: true,
unsafe: true,
}
input: {
try {
(null?.p)();
} catch (e) {
console.log("PASS");
}
}
expect: {
try {
(void 0)();
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "PASS"
node_version: ">=14"
}
trim_dot_call_3: {
options = {
evaluate: true,
optional_chains: true,
unsafe: true,
}
input: {
try {
({ p: null })?.p();
} catch (e) {
console.log("PASS");
}
}
expect: {
try {
null();
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "PASS"
node_version: ">=14"
}
trim_dot_sub: {
options = {
evaluate: true,
optional_chains: true,
}
input: {
console.log(null?.p[42]);
}
expect: {
console.log(void 0);
}
expect_stdout: "undefined"
node_version: ">=14"
}
trim_sub_call_call: {
options = {
evaluate: true,
optional_chains: true,
}
input: {
console.log(null?.[42]()());
}
expect: {
console.log(void 0);
}
expect_stdout: "undefined"
node_version: ">=14"
}
issue_4906: {
options = {
toplevel: true,
@@ -211,3 +366,103 @@ issue_4906: {
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";
@@ -1463,3 +1463,118 @@ issue_4888: {
}
expect_stdout: "object"
}
issue_5093: {
beautify = {
keep_quoted_props: true,
}
input: {
console.log({
a: true,
'42': "PASS",
"null": [],
}[6 * 7]);
}
expect_exact: 'console.log({a:true,"42":"PASS","null":[]}[6*7]);'
expect_stdout: "PASS"
}
issue_5093_quote_keys: {
beautify = {
keep_quoted_props: true,
quote_keys: true,
}
input: {
console.log({
a: true,
'42': "PASS",
"null": [],
}[6 * 7]);
}
expect_exact: 'console.log({"a":true,"42":"PASS","null":[]}[6*7]);'
expect_stdout: "PASS"
}
issue_5093_quote_style: {
beautify = {
keep_quoted_props: true,
quote_style: 3,
}
input: {
console.log({
a: true,
'42': "PASS",
"null": [],
}[6 * 7]);
}
expect_exact: 'console.log({a:true,\'42\':"PASS","null":[]}[6*7]);'
expect_stdout: "PASS"
}
object_methods: {
options = {
properties: true,
}
input: {
({
p() {
console.log("FAIL 1");
},
*q() {
console.log("FAIL 2");
},
async r() {
console.log("FAIL 3");
},
async *s() {
console.log("PASS");
},
}).s().next();
}
expect: {
[
() => {
console.log("FAIL 1");
},
function*() {
console.log("FAIL 2");
},
async () => {
console.log("FAIL 3");
},
async function*() {
console.log("PASS");
},
][3]().next();
}
expect_stdout: "PASS"
node_version: ">=10"
}
issue_5177: {
options = {
properties: true,
}
input: {
var a = "FAIL";
var o = { a: "PASS" };
o.p = {
q() {
return this.a;
},
}.q;
console.log(o.p());
}
expect: {
var a = "FAIL";
var o = { a: "PASS" };
o.p = {
q() {
return this.a;
},
}.q;
console.log(o.p());
}
expect_stdout: "PASS"
node_version: ">=4"
}

View File

@@ -1320,6 +1320,7 @@ issue_2878: {
issue_3427: {
options = {
assignments: true,
evaluate: true,
inline: true,
pure_getters: "strict",
@@ -1638,3 +1639,49 @@ nested_property_assignments_3: {
}
expect_stdout: "PASS"
}
nested_property_assignments_4: {
options = {
pure_getters: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var n, o = { p: { q: { r: "PASS" } } };
(n = o.p).r = n.q.r;
console.log(o.p.r);
}
expect: {
var n, o = { p: { q: { r: "PASS" } } };
(n = o.p).r = n.q.r;
console.log(o.p.r);
}
expect_stdout: "PASS"
}
issue_4939: {
options = {
pure_getters: "strict",
side_effects: true,
}
input: {
({
__proto__: {
get p() {
console.log("PASS");
},
},
}).p;
}
expect: {
({
__proto__: {
get p() {
console.log("PASS");
},
},
}).p;
}
expect_stdout: "PASS"
}

View File

@@ -1292,6 +1292,7 @@ toplevel_on_loops_3: {
loops: true,
reduce_funcs: true,
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
@@ -2071,72 +2072,6 @@ 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 = {
conditionals: true,
dead_code: true,
@@ -2168,7 +2103,7 @@ issue_1670_5: {
expect_stdout: "1"
}
issue_1670_6: {
issue_1670_4: {
options = {
conditionals: true,
dead_code: true,
@@ -3158,7 +3093,7 @@ accessor_1: {
a = 2;
return a;
},
b: 1
b: 1,
}.b, a);
}
expect: {
@@ -3168,7 +3103,7 @@ accessor_1: {
a = 2;
return a;
},
b: 1
b: 1,
}.b, a);
}
expect_stdout: "1 1"
@@ -3188,7 +3123,7 @@ accessor_2: {
var B = {
get c() {
console.log(A);
}
},
};
B.c;
}
@@ -3196,7 +3131,7 @@ accessor_2: {
({
get c() {
console.log(1);
}
},
}).c;
}
expect_stdout: "1"
@@ -3242,7 +3177,7 @@ obj_var_1: {
var obj = {
bar: function() {
return C + C;
}
},
};
console.log(obj.bar());
}
@@ -3250,7 +3185,7 @@ obj_var_1: {
console.log({
bar: function() {
return 2;
}
},
}.bar());
}
expect_stdout: "2"
@@ -3274,7 +3209,7 @@ obj_var_2: {
var obj = {
bar: function() {
return C + C;
}
},
};
console.log(obj.bar());
}
@@ -4488,6 +4423,7 @@ perf_2: {
perf_3: {
options = {
passes: 2,
reduce_funcs: true,
reduce_vars: true,
toplevel: true,
@@ -4496,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);
@@ -4528,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);
@@ -4540,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);
@@ -4632,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);
@@ -4664,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);
@@ -4677,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);
@@ -7384,6 +7320,64 @@ local_assignment_loop: {
expect_stdout: "PASS"
}
local_assignment_modified: {
options = {
evaluate: true,
reduce_vars: true,
side_effects: true,
toplevel: true,
}
input: {
var a;
(a = a || {}).p = 42;
console.log(a.p);
}
expect: {
var a;
(a = {}).p = 42;
console.log(a.p);
}
expect_stdout: "42"
}
local_declaration: {
options = {
evaluate: true,
reduce_vars: true,
side_effects: true,
toplevel: true,
}
input: {
var a;
a || console.log(a = "PASS");
}
expect: {
var a;
console.log("PASS");
}
expect_stdout: "PASS"
}
local_definition_modified: {
options = {
evaluate: true,
reduce_vars: true,
side_effects: true,
toplevel: true,
}
input: {
var a = a || {};
a.p = 42;
console.log(a.p);
}
expect: {
var a = {};
a.p = 42;
console.log(a.p);
}
expect_stdout: "42"
}
issue_3957_1: {
options = {
evaluate: true,
@@ -7499,6 +7493,7 @@ issue_4030: {
collapse_vars: true,
evaluate: true,
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
@@ -7631,3 +7626,208 @@ issue_4568: {
}
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: {

View File

@@ -51,7 +51,7 @@ arrow_destructured_object_1: {
}
expect_exact: "var f=({...a})=>a,o=f({PASS:42});for(var k in o)console.log(k,o[k]);"
expect_stdout: "PASS 42"
node_version: ">=8"
node_version: ">=8.3.0"
}
arrow_destructured_object_2: {
@@ -62,7 +62,7 @@ arrow_destructured_object_2: {
}
expect_exact: "var f=({FAIL:a,...b})=>b,o=f({PASS:42,FAIL:null});for(var k in o)console.log(k,o[k]);"
expect_stdout: "PASS 42"
node_version: ">=8"
node_version: ">=8.3.0"
}
arrow_destructured_object_3: {
@@ -79,7 +79,7 @@ arrow_destructured_object_3: {
"2 S",
"3 S",
]
node_version: ">=8"
node_version: ">=8.3.0"
}
funarg_1: {
@@ -131,7 +131,7 @@ destructured_object_1: {
}
expect_exact: 'var{...a}=["FAIL","PASS",42];console.log(a[1],a[2]);'
expect_stdout: "PASS 42"
node_version: ">=8"
node_version: ">=8.3.0"
}
destructured_object_2: {
@@ -141,7 +141,7 @@ destructured_object_2: {
}
expect_exact: 'var{0:a,...b}=["FAIL","PASS",42];console.log(b[1],b[2]);'
expect_stdout: "PASS 42"
node_version: ">=8"
node_version: ">=8.3.0"
}
drop_fargs: {
@@ -231,7 +231,7 @@ reduce_destructured_object: {
console.log(a[0]);
}
expect_stdout: "PASS"
node_version: ">=8"
node_version: ">=8.3.0"
}
retain_destructured_array: {
@@ -244,7 +244,7 @@ retain_destructured_array: {
console.log.apply(console, b);
}
expect: {
var [ , ...b ] = [ "FAIL", "PASS", 42 ];
var [ ...b ] = [ "PASS", 42 ];
console.log.apply(console, b);
}
expect_stdout: "PASS 42"
@@ -270,7 +270,7 @@ retain_destructured_object_1: {
"1 PASS",
"2 42",
]
node_version: ">=8"
node_version: ">=8.3.0"
}
retain_destructured_object_2: {
@@ -284,7 +284,7 @@ retain_destructured_object_2: {
console.log(k, b[k]);
}
expect: {
var { foo: [], ...b } = { foo: [ "FAIL" ], bar: "PASS", baz: 42 };
var { foo: {}, ...b } = { foo: 0, bar: "PASS", baz: 42 };
for (var k in b)
console.log(k, b[k]);
}
@@ -292,7 +292,7 @@ retain_destructured_object_2: {
"bar PASS",
"baz 42",
]
node_version: ">=8"
node_version: ">=8.3.0"
}
retain_funarg_destructured_array_1: {
@@ -344,7 +344,7 @@ retain_funarg_destructured_object_1: {
console.log((({ ...a }) => a)([ "PASS" ])[0]);
}
expect_stdout: "PASS"
node_version: ">=8"
node_version: ">=8.3.0"
}
retain_funarg_destructured_object_2: {
@@ -362,7 +362,7 @@ retain_funarg_destructured_object_2: {
}({ p: "FAIL" }).p || "PASS");
}
expect_stdout: "PASS"
node_version: ">=8"
node_version: ">=8.3.0"
}
drop_unused_call_args_1: {
@@ -407,6 +407,24 @@ drop_unused_call_args_2: {
node_version: ">=6"
}
maintain_position: {
options = {
unused: true,
}
input: {
A = "FAIL";
var [ , ...a ] = [ A, "PASS" ];
console.log(a[0]);
}
expect: {
A = "FAIL";
var [ , ...a ] = [ A, "PASS" ];
console.log(a[0]);
}
expect_stdout: "PASS"
node_version: ">=6"
}
merge_funarg: {
options = {
merge_vars: true,
@@ -464,7 +482,7 @@ merge_funarg_destructured_object: {
})([ "PASS" ]);
}
expect_stdout: "PASS"
node_version: ">=8"
node_version: ">=8.3.0"
}
keep_arguments: {
@@ -491,7 +509,7 @@ drop_rest_array: {
rests: true,
}
input: {
var [ ...[ a ]] = [ "PASS" ];
var [ ...[ a ] ] = [ "PASS" ];
console.log(a);
}
expect: {
@@ -542,6 +560,100 @@ drop_rest_lambda: {
node_version: ">=6"
}
keep_rest_array: {
options = {
rests: true,
}
input: {
var [ ...[ ...a ] ] = "PASS";
console.log(a.join(""));
}
expect: {
var [ ...a ] = "PASS";
console.log(a.join(""));
}
expect_stdout: "PASS"
node_version: ">=6"
}
keep_rest_arrow: {
options = {
arrows: true,
keep_fargs: false,
reduce_vars: true,
rests: true,
}
input: {
console.log(((...[ ...a ]) => a.join(""))("PASS"));
}
expect: {
console.log(((...a) => a.join(""))("PASS"));
}
expect_stdout: "PASS"
node_version: ">=6"
}
keep_rest_lambda_1: {
options = {
keep_fargs: false,
reduce_vars: true,
rests: true,
toplevel: true,
}
input: {
function f(...[ ...a ]) {
return a.join("");
}
console.log(f("PASS"), f([ 42 ]));
}
expect: {
function f(...a) {
return a.join("");
}
console.log(f("PASS"), f([ 42 ]));
}
expect_stdout: "PASS 42"
node_version: ">=6"
}
keep_rest_lambda_2: {
options = {
unused: true,
}
input: {
function f(...[ ...a ]) {
return a.join("");
}
console.log(f("PASS"), f([ 42 ]));
}
expect: {
function f(...[ ...a ]) {
return a.join("");
}
console.log(f("PASS"), f([ 42 ]));
}
expect_stdout: "PASS 42"
node_version: ">=6"
}
drop_new_function: {
options = {
side_effects: true,
}
input: {
new function(...{
[console.log("PASS")]: a,
}) {}();
}
expect: {
void ([ ... {
[console.log("PASS")]: [].e,
}] = []);
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_4525_1: {
options = {
arguments: true,
@@ -647,6 +759,78 @@ issue_4544_2: {
node_version: ">=6"
}
issue_4560_1: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
}
input: {
var a = 0;
(function(...{
[a++]: {},
}) {})(2);
console.log(a);
}
expect: {
var a = 0;
(function(...{
[a++]: {},
}) {})(2);
console.log(a);
}
expect_stdout: "1"
node_version: ">=6"
}
issue_4560_2: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = 0;
(function(...{
[a++]: {},
}) {})(2);
console.log(a);
}
expect: {
var a = 0;
(function(...{
[a++]: {},
}) {})(2);
console.log(a);
}
expect_stdout: "1"
node_version: ">=6"
}
issue_4560_3: {
options = {
collapse_vars: true,
reduce_vars: true,
toplevel: true,
}
input: {
var a = 0, b;
[ ...{
[a++]: b,
} ] = [ "PASS" ];
console.log(b);
}
expect: {
var a = 0, b;
[ ...{
[a++]: b,
} ] = [ "PASS" ];
console.log(b);
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_4562: {
options = {
evaluate: true,
@@ -667,7 +851,7 @@ issue_4562: {
issue_4575: {
options = {
collapse_vars: true,
ie8: true,
ie: true,
reduce_vars: true,
rests: true,
unused: true,
@@ -777,10 +961,247 @@ issue_4666: {
expect: {
var a = 0, b = 0;
var o = (c => +a + c)([ b ]);
for(var k in o)
for (var k in o)
b++;
console.log(1, b);
}
expect_stdout: "1 2"
node_version: ">=6"
}
issue_5089_1: {
options = {
unused: true,
}
input: {
var {
p: [] = 42,
...o
} = {
p: [],
};
console.log(o.p);
}
expect: {
var {
p: {},
...o
} = {
p: 0,
};
console.log(o.p);
}
expect_stdout: "undefined"
node_version: ">=8.3.0"
}
issue_5089_2: {
options = {
pure_getters: "strict",
unused: true,
}
input: {
var {
p: {} = null,
...o
} = {
p: {},
};
console.log(o.p);
}
expect: {
var {
p: {},
...o
} = {
p: 0,
};
console.log(o.p);
}
expect_stdout: "undefined"
node_version: ">=8.3.0"
}
issue_5100_1: {
options = {
passes: 2,
pure_getters: "strict",
side_effects: true,
unused: true,
}
input: {
var a;
[ {
p: {},
...a
} ] = [ {
p: {
q: a,
} = 42,
r: "PASS",
} ];
console.log(a.r);
}
expect: {
var a;
({
p: {},
...a
} = [ {
p: [ a = 42["q"] ],
r: "PASS",
} ][0]);
console.log(a.r);
}
expect_stdout: "PASS"
node_version: ">=8.3.0"
}
issue_5100_2: {
options = {
passes: 2,
pure_getters: "strict",
side_effects: true,
unused: true,
}
input: {
var a;
[ {
p: {},
...a
} ] = [ {
p: (console.log("PASS"), {
q: a,
} = 42),
} ];
}
expect: {
var a;
({
p: {},
...a
} = [ {
p: [ console.log("PASS"), a = 42["q"] ],
} ][0]);
}
expect_stdout: "PASS"
node_version: ">=10.22.0"
}
issue_5108: {
options = {
evaluate: true,
reduce_vars: true,
rests: true,
unsafe: true,
unused: true,
}
input: {
console.log(function([ ...[ a ] ]) {
return a;
}([ "PASS", "FAIL" ]));
}
expect: {
console.log(function([]) {
return "PASS";
}([ "PASS", "FAIL" ]));
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5128_1: {
options = {
inline: true,
}
input: {
console.log(function() {
return function f(...[ a ]) {
return a;
}("PASS");
}());
}
expect: {
console.log(function f(...[ a ]) {
return a;
}("PASS"));
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5128_2: {
options = {
inline: true,
keep_fnames: true,
unused: true,
}
input: {
console.log(function() {
return function f(...[ a ]) {
return a;
}("PASS");
}());
}
expect: {
console.log(function f(...[ a ]) {
return a;
}("PASS"));
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5165_1: {
options = {
conditionals: true,
dead_code: true,
evaluate: true,
reduce_vars: true,
rests: true,
side_effects: true,
switches: true,
unsafe: true,
}
input: {
console.log(function([ ...a ]) {
switch (a) {
case a:
return "PASS";
}
}([]));
}
expect: {
console.log(function([ ...a ]) {
return "PASS";
}([]));
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5165_2: {
options = {
conditionals: true,
dead_code: true,
evaluate: true,
reduce_vars: true,
rests: true,
side_effects: true,
switches: true,
unsafe: true,
}
input: {
console.log(function(...a) {
switch (a) {
case a:
return "PASS";
}
}());
}
expect: {
console.log("PASS");
}
expect_stdout: "PASS"
node_version: ">=6"
}

View File

@@ -201,3 +201,20 @@ issue_4811_2: {
expect_stdout: "PASS [object global] true"
node_version: ">=8"
}
issue_5197: {
rename = true
input: {
function f(async) {
async(")=>{}");
}
console.log("" + this.__proto__);
}
expect: {
function f(a) {
a(")=>{}");
}
console.log("" + this.__proto__);
}
expect_stdout: "[object global]"
}

View File

@@ -341,7 +341,7 @@ convert_setter: {
console.log(k, o[k]);
}
expect_stdout: "PASS undefined"
node_version: ">=8"
node_version: ">=8.3.0"
}
keep_getter_1: {
@@ -370,7 +370,7 @@ keep_getter_1: {
});
}
expect_stdout: "PASS"
node_version: ">=8"
node_version: ">=8.3.0"
}
keep_getter_2: {
@@ -399,7 +399,7 @@ keep_getter_2: {
"foo",
"bar",
]
node_version: ">=8"
node_version: ">=8.3.0"
}
keep_getter_3: {
@@ -429,7 +429,7 @@ keep_getter_3: {
});
}
expect_stdout: "PASS"
node_version: ">=8"
node_version: ">=8.3.0"
}
keep_getter_4: {
@@ -460,7 +460,7 @@ keep_getter_4: {
});
}
expect_stdout: "PASS"
node_version: ">=8"
node_version: ">=8.3.0"
}
keep_accessor: {
@@ -508,7 +508,7 @@ keep_accessor: {
"q undefined",
"r null",
]
node_version: ">=8"
node_version: ">=8.3.0"
}
object_key_order_1: {
@@ -538,7 +538,7 @@ object_key_order_1: {
"a 3",
"b 2",
]
node_version: ">=8 <=10"
node_version: ">=8.3.0 <=10"
}
object_key_order_2: {
@@ -568,7 +568,7 @@ object_key_order_2: {
"a 3",
"b 2",
]
node_version: ">=8"
node_version: ">=8.3.0"
}
object_key_order_3: {
@@ -598,7 +598,7 @@ object_key_order_3: {
"a 3",
"b 2",
]
node_version: ">=8"
node_version: ">=8.3.0"
}
object_key_order_4: {
@@ -628,7 +628,7 @@ object_key_order_4: {
"a 3",
"b 2",
]
node_version: ">=8"
node_version: ">=8.3.0"
}
object_spread_array: {
@@ -654,7 +654,7 @@ object_spread_array: {
"0 foo",
"1 bar",
]
node_version: ">=8"
node_version: ">=8.3.0"
}
object_spread_string: {
@@ -681,7 +681,7 @@ object_spread_string: {
"1 o",
"2 o",
]
node_version: ">=8"
node_version: ">=8.3.0"
}
unused_var_side_effects: {
@@ -711,7 +711,7 @@ unused_var_side_effects: {
});
}
expect_stdout: "PASS"
node_version: ">=8"
node_version: ">=8.3.0"
}
unsafe_join_1: {
@@ -793,7 +793,7 @@ issue_4329: {
}[0]);
}
expect_stdout: "PASS"
node_version: ">=8"
node_version: ">=8.3.0"
}
issue_4331: {
@@ -871,7 +871,7 @@ issue_4345: {
}[42]);
}
expect_stdout: "PASS"
node_version: ">=8"
node_version: ">=8.3.0"
}
issue_4361: {
@@ -901,7 +901,7 @@ issue_4361: {
"foo",
"undefined",
]
node_version: ">=8"
node_version: ">=8.3.0"
}
issue_4363: {
@@ -922,7 +922,7 @@ issue_4363: {
});
}
expect_stdout: "PASS"
node_version: ">=8"
node_version: ">=8.3.0"
}
issue_4556: {
@@ -945,78 +945,6 @@ issue_4556: {
node_version: ">=6"
}
issue_4560_1: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
}
input: {
var a = 0;
(function(...{
[a++]: {},
}) {})(2);
console.log(a);
}
expect: {
var a = 0;
(function(...{
[a++]: {},
}) {})(2);
console.log(a);
}
expect_stdout: "1"
node_version: ">=6"
}
issue_4560_2: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = 0;
(function(...{
[a++]: {},
}) {})(2);
console.log(a);
}
expect: {
var a = 0;
(function(...{
[a++]: {},
}) {})(2);
console.log(a);
}
expect_stdout: "1"
node_version: ">=6"
}
issue_4560_3: {
options = {
collapse_vars: true,
reduce_vars: true,
toplevel: true,
}
input: {
var a = 0, b;
[ ...{
[a++]: b,
} ] = [ "PASS" ];
console.log(b);
}
expect: {
var a = 0, b;
[ ...{
[a++]: b,
} ] = [ "PASS" ];
console.log(b);
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_4614: {
options = {
pure_getters: "strict",
@@ -1066,7 +994,7 @@ issue_4849: {
}()));
}
expect_stdout: "object"
node_version: ">=8"
node_version: ">=8.3.0"
}
issue_4882_1: {
@@ -1098,7 +1026,7 @@ issue_4882_1: {
"PASS",
"undefined",
]
node_version: ">=8"
node_version: ">=8.3.0"
}
issue_4882_2: {
@@ -1124,7 +1052,7 @@ issue_4882_2: {
"42",
"PASS",
]
node_version: ">=8"
node_version: ">=8.3.0"
}
issue_4882_3: {
@@ -1154,5 +1082,25 @@ issue_4882_3: {
"PASS",
"42",
]
node_version: ">=8"
node_version: ">=8.3.0"
}
issue_5006: {
options = {
arguments: true,
}
input: {
console.log(function(b, c) {
c = "FAIL 2";
return arguments[1];
}(...[], "FAIL 1") || "PASS");
}
expect: {
console.log(function(b, c) {
c = "FAIL 2";
return arguments[1];
}(...[], "FAIL 1") || "PASS");
}
expect_stdout: "PASS"
node_version: ">=6"
}

View File

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

View File

@@ -131,6 +131,105 @@ malformed_escape: {
node_version: ">=4"
}
booleans: {
options = {
booleans: true,
evaluate: true,
templates: true,
}
input: {
var a;
console.log(`$${a}${a}` ? "PASS" : "FAIL");
}
expect: {
var a;
console.log("$" + a + a ? "PASS" : "FAIL");
}
expect_stdout: "PASS"
node_version: ">=4"
}
escape_placeholder_1: {
options = {
templates: true,
}
input: {
console.log(`\${\n`);
}
expect: {
console.log(`\${
`);
}
expect_stdout: [
"${",
"",
]
node_version: ">=4"
}
escape_placeholder_2: {
options = {
evaluate: true,
templates: true,
}
input: {
console.log(`\n${"${"}\n`);
}
expect: {
console.log(`
\${
`);
}
expect_stdout: [
"",
"${",
"",
]
node_version: ">=4"
}
escape_placeholder_3: {
options = {
evaluate: true,
templates: true,
}
input: {
console.log(`\n$${"{"}\n`);
}
expect: {
console.log(`
\${
`);
}
expect_stdout: [
"",
"${",
"",
]
node_version: ">=4"
}
escape_placeholder_4: {
options = {
evaluate: true,
templates: true,
}
input: {
console.log(`\n${"$"}${"{"}\n`);
}
expect: {
console.log(`
\${
`);
}
expect_stdout: [
"",
"${",
"",
]
node_version: ">=4"
}
evaluate: {
options = {
evaluate: true,
@@ -174,7 +273,7 @@ partial_evaluate: {
console.log(`${6 * 7} foo ${console ? `PA` + "SS" : `FA` + `IL`}`);
}
expect: {
console.log(`42 foo ${console ? "PASS" : "FAIL"}`);
console.log("42 foo " + (console ? "PASS" : "FAIL"));
}
expect_stdout: "42 foo PASS"
node_version: ">=4"
@@ -204,7 +303,7 @@ malformed_evaluate_2: {
console.log(`\u0${0}b${5}`);
}
expect: {
console.log(`\u0${0}b5`);
console.log(`\u00b` + 5);
}
expect_stdout: true
node_version: ">=4"
@@ -238,7 +337,7 @@ malformed_evaluate_4: {
console.log("\\u00b5");
}
expect_stdout: "\\u00b5"
node_version: ">=8"
node_version: ">=8.10.0"
}
unsafe_evaluate: {
@@ -254,7 +353,7 @@ unsafe_evaluate: {
console.log("\\uFo");
}
expect_stdout: "\\uFo"
node_version: ">=8"
node_version: ">=8.10.0"
}
side_effects_1: {
@@ -315,6 +414,21 @@ unsafe_side_effects: {
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,
@@ -342,13 +456,14 @@ issue_4604: {
issue_4606: {
options = {
evaluate: true,
strings: true,
templates: true,
}
input: {
console.log(`${typeof A} ${"\r"} ${"\\"} ${"`"}`);
}
expect: {
console.log(`${typeof A} \r \\ \``);
console.log(typeof A + " \r \\ `");
}
expect_stdout: "undefined \r \\ `"
node_version: ">=4"
@@ -398,3 +513,259 @@ issue_4676: {
expect_stdout: "PASS"
node_version: ">=4"
}
issue_4931: {
options = {
evaluate: true,
templates: true,
unsafe: true,
}
input: {
console.log(String.raw`${typeof A} ${"\r"}`);
console.log(String.raw`${"\\"} ${"`"}`);
}
expect: {
console.log(String.raw`${typeof A} ${"\r"}`);
console.log("\\ `");
}
expect_stdout: [
"undefined \r",
"\\ `",
]
node_version: ">=4"
}
issue_5125_1: {
options = {
evaluate: true,
strings: true,
templates: true,
}
input: {
console.log(`PASS ${typeof A}`);
}
expect: {
console.log("PASS " + typeof A);
}
expect_stdout: "PASS undefined"
node_version: ">=4"
}
issue_5125_2: {
options = {
evaluate: true,
strings: true,
templates: true,
}
input: {
console.log(`PASS
${typeof A}`);
}
expect: {
console.log(`PASS
` + typeof A);
}
expect_stdout: [
"PASS",
"undefined",
]
node_version: ">=4"
}
issue_5125_3: {
options = {
evaluate: true,
strings: true,
templates: true,
}
input: {
console.log(`PASS\n${typeof A}`);
}
expect: {
console.log(`PASS
` + typeof A);
}
expect_stdout: [
"PASS",
"undefined",
]
node_version: ">=4"
}
issue_5125_4: {
options = {
evaluate: true,
strings: true,
templates: true,
}
input: {
console.log(`PASS
${typeof A}`);
}
expect: {
console.log(`PASS
` + typeof A);
}
expect_stdout: [
"PASS",
"",
"undefined",
]
node_version: ">=4"
}
issue_5125_5: {
options = {
evaluate: true,
strings: true,
templates: true,
}
input: {
console.log(`PASS\n\n${typeof A}`);
}
expect: {
console.log(`PASS
` + typeof A);
}
expect_stdout: [
"PASS",
"",
"undefined",
]
node_version: ">=4"
}
issue_5125_6: {
options = {
evaluate: true,
strings: true,
templates: true,
}
input: {
console.log(`${typeof A} ${typeof B} PASS`);
}
expect: {
console.log(typeof A + ` ${typeof B} PASS`);
}
expect_stdout: "undefined undefined PASS"
node_version: ">=4"
}
issue_5125_7: {
options = {
evaluate: true,
strings: true,
templates: true,
}
input: {
console.log(`${typeof A} ${typeof B} ${typeof C} PASS`);
}
expect: {
console.log(typeof A + ` ${typeof B} ${typeof C} PASS`);
}
expect_stdout: "undefined undefined undefined PASS"
node_version: ">=4"
}
issue_5125_8: {
options = {
evaluate: true,
strings: true,
templates: true,
}
input: {
console.log(`${typeof A}${typeof B}${typeof C} PASS`);
}
expect: {
console.log(typeof A + typeof B + typeof C + " PASS");
}
expect_stdout: "undefinedundefinedundefined PASS"
node_version: ">=4"
}
issue_5136: {
options = {
templates: true,
}
input: {
console.log(`${A = []}${A[0] = 42}`);
}
expect: {
console.log(`` + (A = []) + (A[0] = 42));
}
expect_stdout: "42"
node_version: ">=4"
}
issue_5145_1: {
options = {
strings: true,
templates: true,
}
input: {
var a = [];
console.log(`${a}${a[0] = 42}
`);
}
expect: {
var a = [];
console.log(`${a}${a[0] = 42}
`);
}
expect_stdout: [
"42",
"",
]
node_version: ">=4"
}
issue_5145_2: {
options = {
strings: true,
templates: true,
}
input: {
var a = [];
console.log(`${a}${a}${a[0] = 42}
`);
}
expect: {
var a = [];
console.log("" + a + a + (a[0] = 42) + `
`);
}
expect_stdout: [
"42",
"",
]
node_version: ">=4"
}
issue_5199: {
options = {
collapse_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = function() {
console.log(typeof b);
}``;
{
const b = a;
}
}
expect: {
var a = function() {
console.log(typeof b);
}``;
{
const b = a;
}
}
expect_stdout: "undefined"
node_version: ">=4"
}

View File

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

View File

@@ -67,7 +67,8 @@ unicode_escaped_identifier_2: {
}
expect_exact: 'var a="foo";var \u{10000}="bar";console.log(a,\u{10000});'
expect_stdout: "foo bar"
node_version: ">=4"
// non-BMP support is platform-dependent on Node.js v4
node_version: ">=6"
}
unicode_identifier_ascii_only: {
@@ -200,7 +201,8 @@ surrogate_pair: {
}
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"
// non-BMP support is platform-dependent on Node.js v4
node_version: ">=6"
}
surrogate_pair_ascii: {
@@ -216,5 +218,6 @@ surrogate_pair_ascii: {
}
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"
// non-BMP support is platform-dependent on Node.js v4
node_version: ">=6"
}

View File

@@ -111,7 +111,7 @@ hoist_props_const: {
}
}
expect: {
var o_p = "PASS";
var o = 0, o_p = "PASS";
console.log(o_p);
}
expect_stdout: "PASS"
@@ -136,7 +136,7 @@ hoist_props_let: {
}
expect: {
"use strict";
var o_p = "PASS";
var o, o_p = "PASS";
console.log(o_p);
}
expect_stdout: "PASS"
@@ -523,3 +523,93 @@ default_init: {
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: {

View File

@@ -96,7 +96,7 @@ pause_resume: {
node_version: ">=4"
}
arrow_yield: {
arrow_yield_1: {
input: {
yield = "PASS";
console.log(function*() {
@@ -108,6 +108,18 @@ arrow_yield: {
node_version: ">=4"
}
arrow_yield_2: {
input: {
console.log(typeof function *() {
// Syntax error on Node.js v6+
return (yield) => {};
}().next().value);
}
expect_exact: "console.log(typeof function*(){return(yield)=>{}}().next().value);"
expect_stdout: "function"
node_version: "4"
}
for_of: {
input: {
function* f() {
@@ -958,7 +970,7 @@ issue_4639_1: {
}().next().value());
}
expect_stdout: "PASS"
node_version: ">=4"
node_version: ">=4 <7 || >=8.7.0"
}
issue_4639_2: {
@@ -1083,3 +1095,217 @@ issue_4769_2: {
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5019_1: {
options = {
dead_code: true,
}
input: {
(function(a) {
return a = function*() {
console.log(typeof a);
}();
})().next();
}
expect: {
(function(a) {
return a = function*() {
console.log(typeof a);
}();
})().next();
}
expect_stdout: "object"
node_version: ">=4"
}
issue_5019_2: {
options = {
inline: true,
toplevel: true,
}
input: {
var a = [];
for (var b in "foo")
a.push(function(c) {
return function*() {
console.log(c);
}();
}(b));
a.map(function(d) {
return d.next();
});
}
expect: {
var a = [];
for (var b in "foo")
a.push(function(c) {
return function*() {
console.log(c);
}();
}(b));
a.map(function(d) {
return d.next();
});
}
expect_stdout: [
"0",
"1",
"2",
]
node_version: ">=4"
}
issue_5032_normal: {
options = {
merge_vars: true,
webkit: false,
}
input: {
function log(value) {
console.log(value);
return value;
}
function *f(a) {
var b = log(a), c = b;
log(b);
log(c);
}
f("PASS").next();
}
expect: {
function log(value) {
console.log(value);
return value;
}
function *f(c) {
var b = log(c), c = b;
log(b);
log(c);
}
f("PASS").next();
}
expect_stdout: [
"PASS",
"PASS",
"PASS",
]
node_version: ">=4"
}
issue_5032_webkit: {
options = {
merge_vars: true,
webkit: true,
}
input: {
function log(value) {
console.log(value);
return value;
}
function *f(a) {
var b = log(a), c = b;
log(b);
log(c);
}
f("PASS").next();
}
expect: {
function log(value) {
console.log(value);
return value;
}
function *f(a) {
var b = log(a), c = b;
log(b);
log(c);
}
f("PASS").next();
}
expect_stdout: [
"PASS",
"PASS",
"PASS",
]
node_version: ">=4"
}
issue_5034: {
options = {
functions: true,
reduce_vars: true,
unused: true,
}
input: {
console.log(function() {
var yield = function f() {
return function*() {
return f;
};
};
return yield()().next().value === yield;
}() ? "PASS" : "FAIL");
}
expect: {
console.log(function() {
var yield = function f() {
return function*() {
return f;
};
};
return yield()().next().value === yield;
}() ? "PASS" : "FAIL");
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_5076: {
options = {
evaluate: true,
hoist_vars: true,
passes: 2,
pure_getters: "strict",
side_effects: true,
toplevel: true,
unused: true,
yields: true,
}
input: {
var a;
console.log("PASS");
var b = function*({
p: {},
}) {}({
p: { a } = 42,
});
}
expect: {
var a;
console.log("PASS");
a = 42["a"];
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5177: {
options = {
properties: true,
}
input: {
console.log(typeof function*() {
return {
p(yield) {},
}.p;
}().next().value);
}
expect: {
console.log(typeof function*() {
return {
p(yield) {},
}.p;
}().next().value);
}
expect_stdout: "function"
node_version: ">=4"
}

View File

@@ -0,0 +1 @@
console?.log``;

View File

@@ -1,7 +1,5 @@
// (beautified)
console.log(function() {
return 1 + .1 + .1;
}());
console.log(1 + .1 + .1);
// output: 1.2000000000000002
//
// minify: 1.2

View File

@@ -58,22 +58,31 @@ if (typeof phantom == "undefined") {
}).listen();
server.on("listening", function() {
var port = server.address().port;
if (debug) {
console.log("http://localhost:" + port + "/");
} else (function install() {
child_process.spawn(process.platform == "win32" ? "npm.cmd" : "npm", [
if (debug) return console.log("http://localhost:" + port + "/");
var cmd = process.platform == "win32" ? "npm.cmd" : "npm";
function npm(args, done) {
child_process.spawn(cmd, args, { stdio: [ "ignore", 1, 2 ] }).on("exit", done);
}
(function install() {
npm([
"install",
"graceful-fs@4.2.6",
"is-my-json-valid@2.20.5",
"phantomjs-prebuilt@2.1.14",
"--no-audit",
"--no-optional",
"--no-save",
"--no-update-notifier",
], {
stdio: [ "ignore", 1, 2 ]
}).on("exit", function(code) {
], function(code) {
if (code) {
console.log("npm install failed with code", code);
return install();
return npm([
"cache",
"clean",
"--force",
], install);
}
var program = require("phantomjs-prebuilt").exec(process.argv[1], port);
program.stdout.pipe(process.stdout);

View File

@@ -721,6 +721,20 @@ describe("bin/uglifyjs", function() {
done();
});
});
it("Should throw syntax error (console?.log``)", function(done) {
var command = uglifyjscmd + " test/input/invalid/optional-template.js";
exec(command, function(err, stdout, stderr) {
assert.ok(err);
assert.strictEqual(stdout, "");
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
"Parse error at test/input/invalid/optional-template.js:1,12",
"console?.log``;",
" ^",
"ERROR: Invalid template on optional chain",
].join("\n"));
done();
});
});
it("Should handle literal string as source map input", function(done) {
var command = [
uglifyjscmd,

View File

@@ -191,7 +191,7 @@ describe("comments", function() {
});
it("Should correctly preserve new lines around comments", function() {
var tests = [
[
[
"// foo",
"// bar",

View File

@@ -1,7 +1,6 @@
var assert = require("assert");
var exec = require("child_process").exec;
var path = require("path");
var readFileSync = require("fs").readFileSync;
describe("bin/uglifyjs with input file globs", function() {
var uglifyjscmd = '"' + process.argv[0] + '" bin/uglifyjs';

View File

@@ -1,21 +0,0 @@
var assert = require("assert");
var UglifyJS = require("../..");
describe("ie8", function() {
it("Should be able to minify() with undefined as catch parameter in a try...catch statement", function() {
assert.strictEqual(
UglifyJS.minify([
"function a(b){",
" try {",
" throw 'Stuff';",
" } catch (undefined) {",
" console.log('caught: ' + undefined);",
" }",
" console.log('undefined is ' + undefined);",
" return b === undefined;",
"};",
].join("\n")).code,
'function a(o){try{throw"Stuff"}catch(o){console.log("caught: "+o)}return console.log("undefined is "+void 0),void 0===o}'
);
});
});

View File

@@ -1,5 +1,5 @@
var assert = require("assert");
var UglifyJS = require("../..");
var UglifyJS = require("../node");
describe("let", function() {
this.timeout(30000);
@@ -7,11 +7,11 @@ describe("let", function() {
// Produce a lot of variables in a function and run it through mangle.
var s = '"dddddeeeeelllllooooottttt"; function foo() {';
for (var i = 0; i < 18000; i++) {
s += "var v" + i + "=0;";
s += "var v" + i + "=[];";
}
s += '}';
var result = UglifyJS.minify(s, {
compress: false
compress: false,
}).code;
// Verify that select keywords and reserved keywords not produced
@@ -41,7 +41,7 @@ describe("let", function() {
}
var result = UglifyJS.minify(s, {
compress: false,
ie8: true,
ie: true,
mangle: {
properties: true,
}
@@ -54,4 +54,43 @@ describe("let", function() {
assert.notStrictEqual(result.indexOf('v["' + name + '"]'), -1);
});
});
it("Should parse `let` as name correctly", function() {
[
"for(var let;let;let)let;",
"function let(let){let}",
].forEach(function(code) {
var ast = UglifyJS.parse(code);
assert.strictEqual(ast.print_to_string(), code);
assert.throws(function() {
UglifyJS.parse('"use strict";' + code);
}, function(e) {
return e instanceof UglifyJS.JS_Parse_Error && e.message == "Unexpected let in strict mode";
}, code);
});
});
it("Should throw on ambiguous use of `let`", function() {
[
"export let",
[
"let",
"console.log(42)",
].join("\n"),
[
"let",
"[ console.log(42) ]",
].join("\n"),
[
"let",
"{",
" console.log(42)",
"}",
].join("\n"),
].forEach(function(code) {
assert.throws(function() {
UglifyJS.parse(code);
}, function(e) {
return e instanceof UglifyJS.JS_Parse_Error;
}, code);
});
});
});

View File

@@ -25,7 +25,7 @@ describe("minify", function() {
if (result.error) throw result.error;
assert.strictEqual(result.code, "print(42);");
assert.strictEqual(JSON.stringify(options), value);
})
});
it("Should skip inherited keys from `files`", function() {
var files = Object.create({ skip: this });
files[0] = "alert(1 + 1)";

View File

@@ -1,5 +1,4 @@
var assert = require("assert");
var exec = require("child_process").exec;
var fs = require("fs");
var reduce_test = require("../reduce");
var semver = require("semver");
@@ -282,35 +281,40 @@ describe("test/reduce.js", function() {
});
if (result.error) throw result.error;
assert.deepEqual(result.warnings, []);
assert.strictEqual(result.code.replace(/function \(/g, "function("), (semver.satisfies(process.version, "<=0.10") ? [
"// Can't reproduce test failure",
"// minify options: {",
'// "compress": false,',
'// "mangle": false,',
'// "output": {',
'// "beautify": true',
"// }",
"// }",
] : [
[
"try{",
"null[function(){}]",
"}catch(e){",
"console.log(e)",
"}",
].join(""),
"// output: TypeError: Cannot read property 'function(){}' of null",
"// ",
"// minify: TypeError: Cannot read property 'function() {}' of null",
"// ",
"// options: {",
'// "compress": false,',
'// "mangle": false,',
'// "output": {',
'// "beautify": true',
"// }",
"// }",
]).join("\n"));
if (semver.satisfies(process.version, "<=0.10")) {
assert.strictEqual(result.code, [
"// Can't reproduce test failure",
"// minify options: {",
'// "compress": false,',
'// "mangle": false,',
'// "output": {',
'// "beautify": true',
"// }",
"// }",
].join("\n"));
} else {
var message = result.code.split(/\n/, 3)[1].slice("// output: ".length);
assert.strictEqual(result.code, [
[
"try{",
"null[function(){}]",
"}catch(e){",
"console.log(e)",
"}",
].join(""),
"// output: " + message,
"// ",
"// minify: " + message.replace("(){}", "() {}"),
"// ",
"// options: {",
'// "compress": false,',
'// "mangle": false,',
'// "output": {',
'// "beautify": true',
"// }",
"// }",
].join("\n"));
}
});
it("Should maintain block-scope for const/let", function() {
if (semver.satisfies(process.version, "<4")) return;

View File

@@ -101,6 +101,19 @@ describe("sourcemaps", function() {
var map = JSON.parse(result.map);
assert.deepEqual(map.names, []);
});
it("Should mark class properties", function() {
var result = UglifyJS.minify([
"class A {",
" static P = 42",
" set #q(v) {}",
"}",
].join("\n"), {
sourceMap: true,
});
if (result.error) throw result.error;
assert.strictEqual(result.code, "class A{static P=42;set#q(s){}}");
assert.strictEqual(result.map, '{"version":3,"sources":["0"],"names":["A","P","#q","v"],"mappings":"MAAMA,EACFC,SAAW,GACXC,MAAOC"}');
});
it("Should mark array/object literals", function() {
var result = UglifyJS.minify([
"var obj = {};",
@@ -349,7 +362,7 @@ describe("sourcemaps", function() {
it("Should not modify input source map", function() {
var orig = get_map();
var original = JSON.stringify(orig);
var map = prepare_map(orig);
prepare_map(orig);
assert.strictEqual(JSON.stringify(orig), original);
});
it("Should copy over original sourcesContent", function() {

View File

@@ -4,34 +4,27 @@ var UglifyJS = require("../..");
describe("spidermonkey export/import sanity test", function() {
it("Should produce a functional build when using --self with spidermonkey", function(done) {
this.timeout(60000);
this.timeout(120000);
var uglifyjs = '"' + process.argv[0] + '" bin/uglifyjs';
var command = uglifyjs + " --self -cm --wrap SpiderUglify -o spidermonkey | " +
uglifyjs + " -p spidermonkey -cm";
exec(command, {
maxBuffer: 1048576
}, function(err, stdout) {
var command = [
uglifyjs + " --self -cm --wrap SpiderUglify -o spidermonkey",
uglifyjs + " -p spidermonkey -cm",
].join(" | ");
exec(command, { maxBuffer: 1048576 }, function(err, stdout) {
if (err) throw err;
eval(stdout);
assert.strictEqual(typeof SpiderUglify, "object");
var result = SpiderUglify.minify("foo([true,,2+3]);");
assert.strictEqual(result.error, undefined);
assert.strictEqual(result.code, "foo([!0,,5]);");
done();
});
});
it("Should not add unnecessary escape slashes to regexps", function() {
it("Should not add unnecessary escape slashes to RegExp", function() {
var input = "/[\\\\/]/;";
var ast = UglifyJS.parse(input).to_mozilla_ast();
assert.equal(
UglifyJS.AST_Node.from_mozilla_ast(ast).print_to_string(),
input
);
assert.strictEqual(UglifyJS.AST_Node.from_mozilla_ast(ast).print_to_string(), input);
});
it("Should judge between directives and strings correctly on import", function() {

View File

@@ -12,7 +12,7 @@ describe("String literals", function() {
'"\u2029"',
].forEach(function(input) {
assert.throws(function() {
var ast = UglifyJS.parse(input);
UglifyJS.parse(input);
}, function(e) {
return e instanceof UglifyJS.JS_Parse_Error
&& e.message === "Unterminated string constant";
@@ -44,7 +44,7 @@ describe("String literals", function() {
'"use strict";\n"\\011"',
].forEach(function(input) {
assert.throws(function() {
var output = UglifyJS.parse(input);
UglifyJS.parse(input);
}, function(e) {
return e instanceof UglifyJS.JS_Parse_Error
&& e.message === "Legacy octal escape sequences are not allowed in strict mode";

View File

@@ -34,20 +34,20 @@ describe("Template literals", function() {
[
// native line breaks
[ "`foo\nbar`", "`foo\nbar`" ],
[ "`foo\rbar`", "`foo\rbar`" ],
[ "`foo\rbar`", "`foo\nbar`" ],
[ "`foo\r\nbar`", "`foo\nbar`" ],
[ "`foo\r\n\rbar`", "`foo\n\rbar`" ],
[ "`foo\r\n\rbar`", "`foo\n\nbar`" ],
// escaped line breaks
[ "`foo\\nbar`", "`foo\\nbar`" ],
[ "`foo\\rbar`", "`foo\\rbar`" ],
[ "`foo\r\\nbar`", "`foo\r\\nbar`" ],
[ "`foo\r\\nbar`", "`foo\n\\nbar`" ],
[ "`foo\\r\nbar`", "`foo\\r\nbar`" ],
[ "`foo\\r\\nbar`", "`foo\\r\\nbar`" ],
// continuation
[ "`foo\\\nbar`", "`foo\\\nbar`" ],
[ "`foo\\\rbar`", "`foo\\\rbar`" ],
[ "`foo\\\rbar`", "`foo\\\nbar`" ],
[ "`foo\\\r\nbar`", "`foo\\\nbar`" ],
[ "`foo\\\r\n\rbar`", "`foo\\\n\rbar`" ],
[ "`foo\\\r\n\rbar`", "`foo\\\n\nbar`" ],
[ "`foo\\\\nbar`", "`foo\\\\nbar`" ],
[ "`foo\\\\rbar`", "`foo\\\\rbar`" ],
[ "`foo\\\\r\nbar`", "`foo\\\\r\nbar`" ],

View File

@@ -22,7 +22,7 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
reduce_options = reduce_options || {};
var print_options = {};
[
"ie8",
"ie",
"v8",
"webkit",
].forEach(function(name) {
@@ -46,7 +46,7 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
if (verbose) {
log("// Node.js " + process.version + " on " + os.platform() + " " + os.arch());
}
if (differs.error && [ "DefaultsError", "SyntaxError" ].indexOf(differs.error.name) < 0) {
if (differs && differs.error && [ "DefaultsError", "SyntaxError" ].indexOf(differs.error.name) < 0) {
test_for_diff = test_minify;
differs = test_for_diff(testcase, minify_options, result_cache, max_timeout);
}
@@ -132,6 +132,8 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
return;
}
if (parent instanceof U.AST_VarDef && parent.name === node) return;
// preserve class methods
if (parent instanceof U.AST_ClassMethod && parent.value === node) return;
// preserve exports
if (parent instanceof U.AST_ExportDeclaration) return;
if (parent instanceof U.AST_ExportDefault) return;
@@ -147,6 +149,9 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
if (parent instanceof U.AST_For && parent.init === node && node instanceof U.AST_Definitions) return node;
// preserve for (xxx in/of ...)
if (parent instanceof U.AST_ForEnumeration && parent.init === node) return node;
// preserve super(...)
if (node.TYPE == "Call" && node.expression instanceof U.AST_Super) return;
if (node instanceof U.AST_Super && parent.TYPE == "Call" && parent.expression === node) return node;
// node specific permutations with no parent logic
@@ -210,9 +215,9 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
// hoist and return expressions from the IIFE function expression
var seq = [];
node.expression.body.forEach(function(node) {
var expr = expr instanceof U.AST_Exit ? node.value : node.body;
var expr = node instanceof U.AST_Exit ? node.value : node.body;
if (expr instanceof U.AST_Node && !U.is_statement(expr) && can_hoist(expr)) {
// collect expressions from each statements' body
// collect expressions from each statement's body
seq.push(expr);
}
});
@@ -390,7 +395,7 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
var expr = [
node.expression, // switch expression
node.body[0] && node.body[0].expression, // first case expression or undefined
node.body[0] && node.body[0], // first case body or undefined
node.body[0], // first case body or undefined
][ (node.start._permute * steps | 0) % 4 ];
node.start._permute += step;
if (expr && (!(expr instanceof U.AST_Statement) || !has_loopcontrol(expr, node, parent))) {
@@ -721,7 +726,7 @@ function to_statement_init(node) {
return node instanceof U.AST_Const || node instanceof U.AST_Let ? new U.AST_BlockStatement({
body: [ node ],
start: {},
}) : to_statement(node);;
}) : to_statement(node);
}
function wrap_with_console_log(node) {

View File

@@ -14,6 +14,13 @@ minify_in_situ() {
uglify-js $ARGS
}
npm_install() {
PKG="$1"
while !(npm install $PKG); do
while !(npm cache clean --force); do echo "'npm cache clean' failed - retrying..."; done
done
}
rm -rf tmp/acorn \
&& git clone https://github.com/acornjs/acorn.git tmp/acorn \
&& cd tmp/acorn \
@@ -89,7 +96,7 @@ minify_in_situ "acorn/src" \
&& minify_in_situ "acorn-loose/src" \
&& minify_in_situ "acorn-walk/src" \
&& rm -rf node_modules \
&& npm install \
&& npm_install \
&& rm -rf acorn/dist acorn-loose/dist acorn-walk/dist \
&& npm run build \
&& minify_in_situ "acorn/dist" \

View File

@@ -14,6 +14,13 @@ minify_in_situ() {
uglify-js $ARGS
}
npm_install() {
PKG="$1"
while !(npm install $PKG); do
while !(npm cache clean --force); do echo "'npm cache clean' failed - retrying..."; done
done
}
rm -rf tmp/bootstrap \
&& git clone --depth 1 --branch v5.0.0-beta2 https://github.com/twbs/bootstrap.git tmp/bootstrap \
&& cd tmp/bootstrap \
@@ -171,7 +178,7 @@ rm -rf tmp/bootstrap \
EOF
ERR=$?; if [ "$ERR" != "0" ]; then echo "Error: $ERR"; exit $ERR; fi
rm -rf node_modules \
&& npm ci \
&& npm_install \
&& minify_in_situ "node_modules/@popperjs/core" \
&& rm -rf dist/js/* \
&& minify_in_situ "build" \

View File

@@ -14,6 +14,13 @@ minify_in_situ() {
uglify-js $ARGS
}
npm_install() {
PKG="$1"
while !(npm install $PKG); do
while !(npm cache clean --force); do echo "'npm cache clean' failed - retrying..."; done
done
}
rm -rf tmp/buble \
&& git clone https://github.com/bublejs/buble.git tmp/buble \
&& cd tmp/buble \
@@ -38,7 +45,7 @@ EOF
ERR=$?; if [ "$ERR" != "0" ]; then echo "Error: $ERR"; exit $ERR; fi
minify_in_situ "src" \
&& rm -rf node_modules \
&& npm ci \
&& npm_install \
&& rm -rf dist \
&& npm run build \
&& minify_in_situ "dist" \

View File

@@ -14,6 +14,13 @@ minify_in_situ() {
uglify-js $ARGS
}
npm_install() {
PKG="$1"
while !(npm install $PKG); do
while !(npm cache clean --force); do echo "'npm cache clean' failed - retrying..."; done
done
}
rm -rf tmp/butternut \
&& git clone https://github.com/Rich-Harris/butternut.git tmp/butternut \
&& cd tmp/butternut \
@@ -38,7 +45,7 @@ EOF
ERR=$?; if [ "$ERR" != "0" ]; then echo "Error: $ERR"; exit $ERR; fi
minify_in_situ "src" \
&& rm -rf node_modules \
&& npm install \
&& npm_install \
&& rm -rf dist \
&& npm run build \
&& minify_in_situ "dist" \

View File

@@ -36,7 +36,9 @@ EOF
}
if [ $NATIVE ]; then unset -f timeout; fi
git clone --branch v1.6.0 --depth 1 https://github.com/jasongin/nvs.git ~/.nvs
while !(git clone --branch v1.6.0 --depth 1 https://github.com/jasongin/nvs.git ~/.nvs); do
rm -rf ~/.nvs
done
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
@@ -51,4 +53,6 @@ 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
while !(npm install); do
while !(npm cache clean --force); do echo "'npm cache clean' failed - retrying..."; done
done

View File

@@ -18,6 +18,13 @@ minify_in_situ() {
uglify-js $ARGS
}
npm_install() {
PKG="$1"
while !(npm install $PKG); do
while !(npm cache clean --force); do echo "'npm cache clean' failed - retrying..."; done
done
}
rm -rf tmp/mathjs \
&& git clone --depth 1 --branch v9.2.0 https://github.com/josdejong/mathjs.git tmp/mathjs \
&& cd tmp/mathjs \
@@ -191,7 +198,7 @@ minify_in_situ "bin" \
&& minify_in_situ "test" \
&& minify_in_situ "tools" \
&& rm -rf node_modules \
&& npm ci \
&& npm_install \
&& rm -rf lib \
&& npm run build \
&& minify_in_situ "lib" \

View File

@@ -14,6 +14,13 @@ minify_in_situ() {
uglify-js $ARGS
}
npm_install() {
PKG="$1"
while !(npm install $PKG); do
while !(npm cache clean --force); do echo "'npm cache clean' failed - retrying..."; done
done
}
rm -rf tmp/rollup \
&& git clone https://github.com/rollup/rollup.git tmp/rollup \
&& cd tmp/rollup \
@@ -77,7 +84,7 @@ minify_in_situ "bin" \
&& minify_in_situ "browser" \
&& minify_in_situ "src" \
&& rm -rf node_modules \
&& npm ci \
&& npm_install \
&& rm -rf dist \
&& npm run build \
&& minify_in_situ "dist" \

View File

@@ -24,6 +24,13 @@ EOF
uglify-js $ARGS
}
npm_install() {
PKG="$1"
while !(npm install $PKG); do
while !(npm cache clean --force); do echo "'npm cache clean' failed - retrying..."; done
done
}
rm -rf tmp/rollup \
&& git clone --depth 1 --branch v2.39.1 https://github.com/rollup/rollup.git tmp/rollup \
&& cd tmp/rollup \
@@ -36,6 +43,9 @@ rm -rf tmp/rollup \
- "postpublish": "pinst --enable",
- "prepare": "npm run build",
- "prepublishOnly": "pinst --disable && npm ci && npm run lint:nofix && npm run security && npm run build:bootstrap && npm run test:all",
@@ -93 +89 @@
- "is-reference": "lukastaegert/is-reference#update-class-features",
+ "is-reference": "3.0.0",
--- a/test/cli/index.js
+++ b/test/cli/index.js
@@ -13,0 +14,3 @@ sander.rimrafSync(__dirname, 'node_modules');
@@ -44,11 +54,11 @@ rm -rf tmp/rollup \
+sander.rimrafSync(__dirname, 'samples', 'watch', 'watch-config-initial-error');
EOF
ERR=$?; if [ "$ERR" != "0" ]; then echo "Error: $ERR"; exit $ERR; fi
npm install esbuild-wasm@0.8.56 \
npm_install esbuild-wasm@0.8.56 \
&& minify_in_situ "cli" \
&& minify_in_situ "src" \
&& rm -rf node_modules \
&& npm ci \
&& npm_install \
&& rm -rf dist \
&& npm run build \
&& minify_in_situ "dist" \

View File

@@ -28,6 +28,13 @@ EOF
uglify-js $ARGS
}
npm_install() {
PKG="$1"
while !(npm install $PKG); do
while !(npm cache clean --force); do echo "'npm cache clean' failed - retrying..."; done
done
}
rm -rf tmp/sucrase \
&& git clone https://github.com/alangpierce/sucrase.git tmp/sucrase \
&& cd tmp/sucrase \
@@ -83,10 +90,10 @@ rm -rf tmp/sucrase \
+export { getJSXPragmaInfo as HACK };
EOF
ERR=$?; if [ "$ERR" != "0" ]; then echo "Error: $ERR"; exit $ERR; fi
npm install esbuild-wasm@0.8.56 \
npm_install esbuild-wasm@0.8.56 \
&& minify_in_situ "src" \
&& rm -rf node_modules \
&& npm install \
&& npm_install \
&& npm run clean \
&& npm run build \
&& minify_in_situ "dist" \

View File

@@ -14,6 +14,13 @@ minify_in_situ() {
uglify-js $ARGS
}
npm_install() {
PKG="$1"
while !(npm install $PKG); do
while !(npm cache clean --force); do echo "'npm cache clean' failed - retrying..."; done
done
}
rm -rf tmp/web-tooling-benchmark \
&& git clone --depth 1 --branch v0.5.3 https://github.com/v8/web-tooling-benchmark.git tmp/web-tooling-benchmark \
&& cd tmp/web-tooling-benchmark \
@@ -47,7 +54,7 @@ ERR=$?; if [ "$ERR" != "0" ]; then echo "Error: $ERR"; exit $ERR; fi
minify_in_situ "src" \
&& minify_in_situ "third_party" \
&& rm -rf node_modules \
&& npm ci \
&& npm_install \
&& rm -rf build/* \
&& npm run build:terser-bundled \
&& npm run build:uglify-js-bundled \

View File

@@ -27,8 +27,8 @@ exports.run_code = semver.satisfies(process.version, "0.8") ? function(code, top
} : semver.satisfies(process.version, "<0.12") ? run_code_vm : function(code, toplevel, timeout) {
if ([
/\basync[ \t]*\([\s\S]*?\)[ \t]*=>/,
/\b(async[ \t]+function|setImmediate|setInterval|setTimeout)\b/,
/\basync([ \t]+|[ \t]*\*[ \t]*)[^\s()[\]{},.&|!~=*%/+-]+(\s*\(|[ \t]*=>)/,
/\b(async[ \t]+function|Promise|setImmediate|setInterval|setTimeout)\b/,
/\basync([ \t]+|[ \t]*#|[ \t]*\*[ \t]*)[^\s()[\]{}#:;,.&|!~=*%/+-]+(\s*\(|[ \t]*=>)/,
].some(function(pattern) {
return pattern.test(code);
})) {
@@ -51,13 +51,13 @@ exports.same_stdout = semver.satisfies(process.version, "0.12") ? function(expec
};
exports.patch_module_statements = function(code) {
var count = 0, imports = [];
code = code.replace(/\bexport(?:\s*\{[^}]*}\s*?(?:$|\n|;)|\s+default\b(?:\s*(\(|\{|class\s*\{|class\s+(?=extends\b)|(?:async\s+)?function\s*(?:\*\s*)?\())?|\b)/g, function(match, header) {
code = code.replace(/\bexport(?:\s*\{[^{}]*}\s*?(?:$|\n|;)|\s+default\b(?:\s*(\(|\{|class\s*\{|class\s+(?=extends\b)|(?:async\s+)?function\s*(?:\*\s*)?\())?|\b)/g, function(match, header) {
if (!header) return "";
if (header.length == 1) return "0, " + header;
return header.slice(0, -1) + " _" + ++count + header.slice(-1);
}).replace(/\bimport\.meta\b/g, function() {
return '({ url: "https://example.com/path/index.html" })';
}).replace(/\bimport\b(?:\s*([^('"]+)\bfrom\b)?\s*(['"]).*?\2(?:$|\n|;)/g, function(match, symbols) {
}).replace(/\bimport\b(?:\s*([^\s('"][^('"]*)\bfrom\b)?\s*(['"]).*?\2(?:$|\n|;)/g, function(match, symbols) {
if (symbols) {
if (!/^[{*]/.test(symbols)) symbols = "default:" + symbols;
symbols = symbols.replace(/[{}]/g, "").trim().replace(/\s*,\s*/g, ",");
@@ -202,13 +202,11 @@ function setup(global, builtins, setup_log, setup_tty) {
});
Object.defineProperties(global, props);
// for Node.js v8+
if (global.toString !== Object.prototype.toString) {
global.__proto__ = Object.defineProperty(Object.create(global.__proto__), "toString", {
value: function() {
return "[object global]";
},
});
}
global.__proto__ = Object.defineProperty(Object.create(global.__proto__), "toString", {
value: function() {
return "[object global]";
},
});
function self() {
return this;
@@ -254,8 +252,11 @@ function run_code_vm(code, toplevel, timeout) {
var ctx = vm.createContext({ console: console });
// for Node.js v6
vm.runInContext(setup_code, ctx);
vm.runInContext(toplevel ? "(function(){" + code + "})();" : code, ctx, { timeout: timeout });
return strip_color_codes(stdout);
vm.runInContext(toplevel ? "(function(){\n" + code + "\n})();" : code, ctx, { timeout: timeout });
// for Node.js v4
return strip_color_codes(stdout.replace(/\b(Array \[|Object {)/g, function(match) {
return match.slice(-1);
}));
} catch (ex) {
return ex;
} finally {
@@ -265,7 +266,7 @@ function run_code_vm(code, toplevel, timeout) {
function run_code_exec(code, toplevel, timeout) {
if (toplevel) {
code = setup_code + "(function(){" + code + "})();";
code = setup_code + "(function(){\n" + code + "\n})();";
} else {
code = code.replace(/^((["'])[^"']*\2(;|$))?/, function(directive) {
return directive + setup_code;
@@ -278,11 +279,11 @@ function run_code_exec(code, toplevel, timeout) {
timeout: timeout || 5000,
});
if (result.status === 0) return result.stdout;
var msg = ("" + result.stderr).replace(/\r\n/g, "\n");
if (result.error && result.error.code == "ETIMEDOUT" || /FATAL ERROR:/.test(msg)) {
return new Error("Script execution timed out.");
}
if (result.error) return result.error;
var msg = result.stderr.replace(/\r\n/g, "\n");
var end = msg.indexOf("\n\n-----===== UNCAUGHT EXCEPTION =====-----\n\n");
var details;
if (end >= 0) {
@@ -294,7 +295,7 @@ function run_code_exec(code, toplevel, timeout) {
} catch (e) {}
}
var match = /\n([^:\s]*Error)(?:: ([\s\S]+?))?\n( at [\s\S]+)\n$/.exec(msg);
if (!match) return details;
if (!match) return details || new Error("Script execution aborted.");
var ex = new global[match[1]](match[2]);
ex.stack = ex.stack.slice(0, ex.stack.indexOf(" at ")) + match[3];
if (typeof details == "object") {

View File

@@ -1,7 +1,7 @@
var get = require("https").get;
var parse = require("url").parse;
var base, token, run_number, eldest = true;
var base, token, run_number;
exports.init = function(url, auth, num) {
base = url;
token = auth;
@@ -19,14 +19,14 @@ exports.should_stop = function(callback) {
do {
workflow = runs.pop();
if (!workflow) return;
if (workflow.event == "schedule" && workflow.run_number == run_number) found = true;
if (is_cron(workflow) && workflow.run_number == run_number) found = true;
} while (!found && workflow.status == "completed");
read(workflow.jobs_url, function(reply) {
if (!reply || !Array.isArray(reply.jobs)) return;
if (!reply.jobs.every(function(job) {
if (job.status == "completed") return true;
remaining--;
return found || workflow.event != "schedule";
return found || !is_cron(workflow);
})) return;
if (remaining >= 0) {
next();
@@ -38,6 +38,10 @@ exports.should_stop = function(callback) {
});
};
function is_cron(workflow) {
return /^(schedule|workflow_dispatch|workflow_run)$/.test(workflow.event);
}
function read(url, callback) {
var done = function(reply) {
done = function() {};
@@ -56,7 +60,7 @@ function read(url, callback) {
}).on("end", function() {
var reply;
try {
reply = JSON.parse(chunks.join(""))
reply = JSON.parse(chunks.join(""));
} catch (e) {}
done(reply);
}).on("error", function() {

View File

@@ -334,6 +334,7 @@ var VAR_NAMES = [
"arguments",
"async",
"await",
"let",
"yield",
];
var INITIAL_NAMES_LEN = VAR_NAMES.length;
@@ -352,10 +353,11 @@ var TYPEOF_OUTCOMES = [
];
var avoid_vars = [];
var block_vars = [];
var block_vars = [ "let" ];
var lambda_vars = [];
var unique_vars = [];
var classes = [];
var allow_this = true;
var async = false;
var has_await = false;
var export_default = false;
@@ -398,10 +400,11 @@ function mayDefer(code) {
function createTopLevelCode() {
VAR_NAMES.length = INITIAL_NAMES_LEN; // prune any previous names still in the list
block_vars.length = 0;
block_vars.length = 1;
lambda_vars.length = 0;
unique_vars.length = 0;
classes.length = 0;
allow_this = true;
async = false;
has_await = false;
export_default = false;
@@ -1731,6 +1734,8 @@ function createObjectFunction(recurmax, stmtDepth, canThrow, internal, isClazz)
fn = function(defns) {
if (generator) name = "*" + name;
if (async) name = "async "+ name;
var save_allow = allow_this;
if (internal == "super") allow_this = false;
s = [
name + "(" + createParams(save_async, save_generator, NO_DUPLICATE) + "){",
strictMode(),
@@ -1738,6 +1743,7 @@ function createObjectFunction(recurmax, stmtDepth, canThrow, internal, isClazz)
];
s.push(_createStatements(2, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CANNOT_RETURN, stmtDepth));
if (internal == "super") s.push("super" + createArgs(recurmax, stmtDepth, canThrow, NO_TEMPLATE) + ";");
allow_this = save_allow;
if (/^(constructor|super)$/.test(internal) || rng(10) == 0) for (var i = rng(4); --i >= 0;) {
s.push(rng(2) ? createSuperAssignment(recurmax, stmtDepth, canThrow) : createThisAssignment(recurmax, stmtDepth, canThrow));
}
@@ -1974,7 +1980,7 @@ function createValue() {
var v;
do {
v = VALUES[rng(VALUES.length)];
} while (v == "new.target" && rng(200));
} while (v == "new.target" && rng(200) || !allow_this && v == "this");
return v;
}
@@ -2022,6 +2028,7 @@ function removeAvoidVar(name) {
function isBannedKeyword(name) {
switch (name) {
case "arguments":
case "let":
return in_class;
case "await":
return async !== false;
@@ -2073,8 +2080,8 @@ if (require.main !== module) {
return;
}
function run_code(code, toplevel) {
return sandbox.run_code(sandbox.patch_module_statements(code), toplevel);
function run_code(code, toplevel, timeout) {
return sandbox.run_code(sandbox.patch_module_statements(code), toplevel, timeout);
}
function writeln(stream, msg) {
@@ -2251,7 +2258,7 @@ function sort_globals(code) {
return (typeof global[n] == "function") - (typeof global[m] == "function")
|| (m < n ? -1 : m > n ? 1 : 0);
};
} + "(this));" + code);
} + "(this));\n" + code);
if (!Array.isArray(globals)) {
errorln();
errorln();
@@ -2289,6 +2296,20 @@ function fuzzy_match(original, uglified) {
}
}
function patch_proto() {
[ Array, Boolean, Error, Function, Number, Object, RegExp, String ].forEach(function(type) {
[ "toString", "valueOf" ].forEach(function(prop) {
type.prototype[prop] = function(fn) {
return function() {
try {
return fn.apply(this, arguments);
} catch (e) {}
};
}(type.prototype[prop]);
});
});
}
function is_error_timeout(ex) {
return /timed out/.test(ex.message);
}
@@ -2298,7 +2319,7 @@ function is_error_in(ex) {
}
function is_error_spread(ex) {
return ex.name == "TypeError" && /Found non-callable @@iterator| is not iterable| is not a function/.test(ex.message);
return ex.name == "TypeError" && /Found non-callable @@iterator| is not iterable| not a function/.test(ex.message);
}
function is_error_recursion(ex) {
@@ -2331,7 +2352,7 @@ function patch_try_catch(orig, toplevel) {
tries: [],
} ];
var tail_throw = '\nif (typeof UFUZZ_ERROR == "object") throw UFUZZ_ERROR;\n';
var re = /(?:(?:^|[\s{}):;])try|}\s*catch\s*\(([^)[{]+)\)|}\s*finally)\s*(?={)/g;
var re = /(?:(?:^|[\s{}):;])try|}\s*catch\s*\(([^()[{]+)\)|}\s*finally)\s*(?={)/g;
while (stack.length) {
var code = stack[0].code;
var offset = stack[0].offset;
@@ -2448,8 +2469,10 @@ for (var round = 1; round <= num_iterations; round++) {
println("original result:");
println(result);
println();
// ignore v8 parser bug
return bug_async_arrow_rest(result);
// ignore v8 parser bug
return bug_async_arrow_rest(result)
// ignore runtime platform bugs
|| result.message == "Script execution aborted.";
})) continue;
minify_options.forEach(function(options) {
var o = JSON.parse(options);
@@ -2464,6 +2487,8 @@ for (var round = 1; round <= num_iterations; round++) {
ok = sandbox.same_stdout(original_result, uglify_result);
// ignore v8 parser bug
if (!ok && bug_async_arrow_rest(uglify_result)) ok = true;
// ignore runtime platform bugs
if (!ok && uglify_result.message == "Script execution aborted.") ok = true;
// handle difference caused by time-outs
if (!ok && errored && is_error_timeout(original_result)) {
if (is_error_timeout(uglify_result)) {
@@ -2495,8 +2520,8 @@ for (var round = 1; round <= num_iterations; round++) {
if (!ok && errored && uglify_result.name == "ReferenceError" && original_result.name == "ReferenceError") ok = true;
// ignore difference due to implicit strict-mode in `class`
if (!ok && /\bclass\b/.test(original_code)) {
var original_strict = run_code('"use strict";' + original_code, toplevel);
var uglify_strict = run_code('"use strict";' + uglify_code, toplevel);
var original_strict = run_code('"use strict";\n' + original_code, toplevel);
var uglify_strict = run_code('"use strict";\n' + uglify_code, toplevel);
if (typeof original_strict != "string") {
ok = typeof uglify_strict != "string";
} else {
@@ -2507,6 +2532,12 @@ for (var round = 1; round <= num_iterations; round++) {
if (!ok && errored && /\bimport\b/.test(original_code)) {
if (is_error_redeclaration(uglify_result) && is_error_redeclaration(original_result)) ok = true;
}
// ignore difference due to `__proto__` assignment
if (!ok && /\b__proto__\b/.test(original_code)) {
var original_proto = run_code("(" + patch_proto + ")();\n" + original_code, toplevel);
var uglify_proto = run_code("(" + patch_proto + ")();\n" + uglify_code, toplevel);
ok = sandbox.same_stdout(original_proto, uglify_proto);
}
// ignore difference in error message caused by `in`
if (!ok && errored && is_error_in(uglify_result) && is_error_in(original_result)) ok = true;
// ignore difference in error message caused by spread syntax

View File

@@ -16,7 +16,7 @@
},
{},
{
"ie8": true,
"ie": true,
"toplevel": true
},
{