Compare commits

...

180 Commits

Author SHA1 Message Date
Alex Lam S.L
6de708af37 v3.15.0 2022-01-26 01:33:13 +08:00
Alex Lam S.L
b9b2a4f7f8 fix corner case in inline (#5311)
fixes #5222
2022-01-26 00:47:24 +08:00
Alex Lam S.L
b46c7944c6 fix corner case in collapse_vars (#5310)
fixes #5309
2022-01-23 00:45:11 +08:00
Alex Lam S.L
866cd4a975 enhance merge_vars (#5308) 2022-01-21 09:40:33 +08:00
Alex Lam S.L
e24b255350 implement keep_fargs for mangle (#5307)
closes #4657
2022-01-21 05:13:26 +08:00
Alex Lam S.L
efed55f42d fix corner case in inline (#5306)
fixes #5305
2022-01-19 08:14:19 +08:00
Alex Lam S.L
8c2b76eff9 enhance side_effects (#5304) 2022-01-17 23:18:42 +08:00
Alex Lam S.L
b636e97e3b fix corner cases in awaits (#5303) 2022-01-17 16:22:26 +08:00
Alex Lam S.L
35d7f316ef fix corner cases in typeofs (#5301) 2022-01-17 14:03:41 +08:00
Alex Lam S.L
43807c26fb fix performance regression (#5302)
fixes #5297
2022-01-17 11:49:47 +08:00
Alex Lam S.L
774feeadb8 minor clean-ups (#5300) 2022-01-17 01:14:52 +08:00
Alex Lam S.L
d96c59f9e6 fix corner case in side_effects (#5299)
fixes #5298
2022-01-16 02:33:14 +08:00
Alex Lam S.L
dfd6418878 fix corner case in inline (#5297)
fixes #5296
2022-01-15 04:18:35 +08:00
Alex Lam S.L
87e8aca245 fix corner cases in reduce_vars, side_effects & unused (#5295)
fixes #5294
2022-01-15 01:44:36 +08:00
Alex Lam S.L
14e1311bdf fix corner cases in side_effects (#5293)
fixes #5292
2022-01-14 09:14:04 +08:00
Alex Lam S.L
ff3c2ed7a2 fix corner case in inline (#5291)
fixes #5290
2022-01-12 20:17:34 +08:00
Alex Lam S.L
f8602aca96 fix corner case in inline (#5289)
fixes #5288
2022-01-12 16:24:50 +08:00
Alex Lam S.L
9a58270b70 enhance imports (#5287) 2022-01-12 16:24:04 +08:00
Alex Lam S.L
f639a30bd2 fix corner cases in typeofs (#5286) 2022-01-11 13:13:46 +08:00
Alex Lam S.L
082013c20f report runtime process aborts correctly (#5285) 2022-01-11 09:12:01 +08:00
Alex Lam S.L
c7d2837184 fix corner case in inline (#5284)
fixes #5283
2022-01-10 15:43:26 +08:00
Alex Lam S.L
caaa753861 minor clean-ups (#5282) 2022-01-10 13:02:26 +08:00
Alex Lam S.L
4b949f6686 suppress false positives in ufuzz (#5281) 2022-01-10 05:05:35 +08:00
Alex Lam S.L
e9d9d5a9d2 improve class compatibility in side_effects (#5279) 2022-01-09 21:15:42 +08:00
Alex Lam S.L
f473b4db38 fix corner case in collapse_vars (#5278)
fixes #5277
2022-01-08 09:46:21 +08:00
Alex Lam S.L
b0df5d7b55 enhance collapse_vars & reduce_vars (#5275)
fixes #5276
2022-01-08 05:26:49 +08:00
Alex Lam S.L
be8c75bae1 fix corner case in collapse_vars (#5274)
fixes #5273
2022-01-07 15:00:23 +08:00
Alex Lam S.L
58bea676ac fix corner case in unused (#5272)
fixes #5271
2022-01-07 14:33:42 +08:00
Alex Lam S.L
9aab1f3661 fix corner case in inline (#5270)
fixes #5269
2022-01-07 13:22:16 +08:00
Alex Lam S.L
10a1523ee6 enhance collapse_vars (#5268) 2022-01-07 05:13:37 +08:00
Alex Lam S.L
d46eb69320 fix corner case in inline (#5267)
fixes #5266
2022-01-05 04:25:48 +08:00
Alex Lam S.L
3a3666a94e fix corner cases in inline (#5265)
fixes #5263
fixes #5264
2022-01-04 22:05:03 +08:00
Alex Lam S.L
2f568b9357 enhance mangle (#5262) 2022-01-04 10:06:00 +08:00
Alex Lam S.L
c94624f36c fix corner case in collapse_vars (#5261)
fixes #5260
2022-01-04 04:18:41 +08:00
Alex Lam S.L
dec359ce58 fix corner case in awaits & inline (#5259)
fixes #5258
2022-01-03 20:57:24 +08:00
Alex Lam S.L
1a054e869e fix corner case in inline (#5257)
fixes #5256
2022-01-03 10:13:29 +08:00
Alex Lam S.L
7889192cae fix corner cases in inline (#5255)
fixes #5254
2022-01-02 21:24:41 +08:00
Alex Lam S.L
f7841bc8b8 fix corner case in inline (#5253)
fixes #5251
2022-01-02 16:10:39 +08:00
Alex Lam S.L
aa6eb0d5be fix corner cases in inline (#5252)
fixes #5249
fixes #5250
2022-01-02 14:59:32 +08:00
Alex Lam S.L
87a7426598 enhance inline & unused (#5245) 2022-01-02 05:40:43 +08:00
Alex Lam S.L
8d0422b6f3 enhance reduce_vars (#5248) 2022-01-01 07:53:47 +08:00
Alex Lam S.L
e7ce1051fe fix corner cases in reduce_vars & unused (#5247)
fixes #5246
2021-12-31 04:47:13 +08:00
Alex Lam S.L
80d5f23fee fix corner case with lexical variables (#5244) 2021-12-30 05:15:53 +08:00
Alex Lam S.L
d51caaf358 enhance inline (#5243) 2021-12-28 00:53:12 +08:00
Alex Lam S.L
835d130ccf fix corner cases in inline (#5241)
fixes #5239
fixes #5240
2021-12-26 08:39:06 +08:00
Alex Lam S.L
e1013bd56d fix corner case in inline (#5238)
fixes #5237
2021-12-25 19:30:49 +08:00
Alex Lam S.L
13d41778b3 suppress false positives in test/reduce (#5235) 2021-12-25 03:13:37 +08:00
Alex Lam S.L
bab416465f fix corner case in conditionals (#5233)
fixes #5232
2021-12-23 22:25:02 +08:00
Alex Lam S.L
29a1e71705 fix corner case in inline (#5231)
fixes #5230
2021-12-23 14:26:07 +08:00
Alex Lam S.L
7b2eb4b5ff improve handling of non-trivial assignment values (#5227) 2021-12-23 07:55:06 +08:00
Alex Lam S.L
343bf6d7a5 fix corner case in booleans & inline (#5229)
fixes #5228
2021-12-21 23:46:20 +08:00
Alex Lam S.L
ba42cbad3f enhance inline (#5226) 2021-12-21 13:03:11 +08:00
Alex Lam S.L
86406e71ec fix corner case in unused (#5225)
fixes #5224
2021-12-20 02:25:38 +08:00
Alex Lam S.L
9e927ecc9a fix corner case in hoist_props (#5223)
fixes #5222
2021-12-16 02:57:34 +08:00
Alex Lam S.L
509896a410 improve compress efficiency (#5220) 2021-12-15 08:08:24 +08:00
Alex Lam S.L
7fe7c39a01 speed up compress (#5219) 2021-12-14 07:42:47 +08:00
Alex Lam S.L
2c5e23506b v3.14.5 2021-12-13 08:11:48 +08:00
Alex Lam S.L
07f35ea2c9 suppress false positives in ufuzz (#5216)
closes #5212
closes #5215
2021-12-12 06:19:06 +08:00
Alex Lam S.L
57a9519c3d fix corner case in objects (#5214)
fixes #5213
2021-12-10 06:02:22 +08:00
Alex Lam S.L
9e4c4c995c minor clean-up (#5210) 2021-12-10 04:48:06 +08:00
Alex Lam S.L
d11c82f8ca minor clean-up (#5209) 2021-12-09 05:14:57 +08:00
Alex Lam S.L
bc27966a19 workaround v8 performance quirks (#5207) 2021-12-08 13:40:47 +08:00
Alex Lam S.L
8f39491e96 workaround Unicode compatibility in testing (#5206) 2021-12-07 18:56:57 +08:00
Alex Lam S.L
065c50ebde improve sandbox resilience against process aborts (#5205) 2021-12-07 04:54:58 +08:00
Alex Lam S.L
d2e7c4af20 improve testing compatibility with Node.js (#5204) 2021-12-06 22:42:45 +08:00
Alex Lam S.L
033d8d9405 reduce memory pressure via bit fields (#5203) 2021-12-06 11:30:05 +08:00
Alex Lam S.L
b0799105c2 improve Dictionary performance (#5202)
- workaround `__proto__` quirks on v8
2021-12-05 14:58:52 +08:00
Alex Lam S.L
860aa9531b v3.14.4 2021-12-01 02:34:20 +08:00
Alex Lam S.L
2547542873 workaround sporadic slowdown in GitHub Actions (#5201) 2021-11-28 08:45:29 +08:00
Alex Lam S.L
3f8f0e246e fix corner case in collapse_vars (#5200)
fixes #5199
2021-11-28 01:43:43 +08:00
Alex Lam S.L
12227ebbb0 workaround toString() quirks on global context (#5198)
closes #5197
2021-11-27 23:17:51 +08:00
Alex Lam S.L
1b4bd7082b fix corner case in hoist_vars (#5196)
fixes #5195
2021-11-25 04:49:38 +08:00
Alex Lam S.L
0b6c185818 enhance merge_vars (#5194)
closes #5182
2021-11-24 19:08:40 +08:00
Alex Lam S.L
bfd0ac7f4b fix corner case in ie (#5193)
fixes #5192
2021-11-24 17:29:26 +08:00
Alex Lam S.L
1a8f2ecc65 enhance collapse_vars (#5186)
closes #5182
2021-11-24 17:28:36 +08:00
Alex Lam S.L
dc9e1ff0b1 fix corner case in unused (#5190)
fixes #5189
2021-11-23 20:10:05 +08:00
Alex Lam S.L
ea10498902 fix corner case in hoist_vars (#5188)
fixes #5187
2021-11-23 18:00:47 +08:00
Alex Lam S.L
69636dad69 improve sandbox async detection (#5185)
closes #5184
2021-11-23 02:29:54 +08:00
Alex Lam S.L
3ee1b0d00d enhance hoist_props & reduce_vars (#5183)
closes #5182
2021-11-23 00:31:10 +08:00
Alex Lam S.L
1e3ca4c6f7 enhance side_effects & unused (#5181) 2021-11-22 11:14:28 +08:00
Alex Lam S.L
839f4361f4 minor clean-up (#5180) 2021-11-19 16:34:11 +08:00
Alex Lam S.L
ae5c3ee8a1 fix corner cases in properties (#5178)
fixes #5177
2021-11-17 04:21:44 +08:00
Alex Lam S.L
77f7ae5ba2 fix corner case in join_vars (#5176)
fixes #5175
2021-11-15 21:35:54 +08:00
Alex Lam S.L
2d0f8bcff5 fix corner case in inline (#5174)
fixes #5173
2021-11-15 07:14:08 +08:00
Alex Lam S.L
f97e107c09 enhance reduce_vars (#5171) 2021-11-13 22:18:56 +08:00
Alex Lam S.L
e9932e1314 fix corner case in collapse_vars (#5169)
fixes #5168
2021-11-13 22:18:18 +08:00
Alex Lam S.L
eaa84d32df include Node.js v16 in CI tests (#5170)
- fix compatibility issues on v0.10 & v0.12
2021-11-13 18:34:18 +08:00
Alex Lam S.L
6e4aa0326f enhance reduce_vars (#5164)
- fix corner case in `join_vars`
2021-11-04 18:36:39 +08:00
Alex Lam S.L
f9a4b36dd1 fix corner cases in reduce_vars & rests (#5166)
fixes #5165
2021-11-03 21:29:01 +08:00
Alex Lam S.L
3acb5a329e enhance join_vars (#5162) 2021-11-02 11:33:24 +08:00
Alex Lam S.L
6d94242318 enhance reduce_vars (#5163) 2021-11-02 11:32:26 +08:00
Alex Lam S.L
bca83cb9df v3.14.3 2021-11-02 05:03:46 +08:00
Alex Lam S.L
a841d45bc3 fix corner case in awaits (#5160)
fixes #5159
2021-10-31 23:46:55 +08:00
Alex Lam S.L
eb93d92357 fix corner case in awaits (#5158)
fixes #5157
2021-10-29 23:33:10 +08:00
Alex Lam S.L
a0250ec923 fix corner case in dead_code (#5154)
fixes #5153
2021-10-25 06:18:16 +08:00
Alex Lam S.L
25801627be parse let as symbol names correctly (#5151)
fixes #5149
2021-10-21 02:14:29 +08:00
Alex Lam S.L
32ae994f88 fix issues in tests flagged by LGTM (#5150) 2021-10-21 02:07:23 +08:00
Alex Lam S.L
03aec89f60 fix corner cases in strings & templates (#5147)
fixes #5145
2021-10-16 18:02:23 +08:00
Alex Lam S.L
faf0190546 document ECMAScript quirks (#5148)
- exclude Node.js v0.8 from CI as npm registry no longer works

closes #5146
2021-10-16 13:28:13 +08:00
Alex Lam S.L
c8b0f685ee fix corner case in merge_vars (#5143)
fixes #5142
2021-10-05 00:42:46 +08:00
Alex Lam S.L
87b99162fb fix corner case in inline (#5141)
fixes #5140
2021-10-02 06:54:42 +08:00
Alex Lam S.L
940887f20f fix corner case in evaluate (#5139)
fixes #5138
2021-10-01 02:52:21 +08:00
Alex Lam S.L
0b2573c3fa fix corner case in templates (#5137)
fixes #5136
2021-09-30 21:43:34 +08:00
Alex Lam S.L
157521066f avoid potential RegExp denial-of-service (#5135)
closes #5133
closes #5134
2021-09-30 01:49:46 +08:00
Alex Lam S.L
f766babf5e enhance templates (#5131)
closes #5125
2021-09-23 18:26:26 +08:00
Alex Lam S.L
436a29367c enhance dead_code (#5130) 2021-09-22 03:11:45 +08:00
Alex Lam S.L
55418fd460 fix corner case in rests (#5129)
fixes #5128
2021-09-20 05:02:35 +08:00
Alex Lam S.L
85786889bd v3.14.2 2021-09-07 21:52:59 +08:00
Alex Lam S.L
4b88dfb8d9 tweak test & warnings (#5123)
closes #5116
closes #5117
closes #5122
2021-09-07 01:33:23 +08:00
Alex Lam S.L
c3aef23614 fix corner case in reduce_vars (#5121)
fixes #5120
2021-08-25 10:39:35 +08:00
Alex Lam S.L
db94d21980 fix corner case in side_effects (#5118) 2021-08-23 08:51:59 +08:00
Alex Lam S.L
9634a9d1fd fix corner cases in optional_chains (#5110) 2021-08-20 10:10:10 +08:00
Alex Lam S.L
befb99bd71 fix corner case in inline (#5115)
fixes #5114
2021-08-18 15:57:08 +08:00
Alex Lam S.L
02eb8baa1c fix corner case in collapse_vars (#5113)
fixes #5112
2021-08-18 10:54:24 +08:00
Alex Lam S.L
c09f63aefb fix corner case in rests (#5109)
fixes #5108
2021-08-09 08:59:33 +08:00
Alex Lam S.L
fdcc6d3a9c fix corner case in dead_code (#5107)
fixes #5106
2021-08-06 08:35:11 +08:00
Alex Lam S.L
4fe2cac35e enhance inline (#5105) 2021-07-27 21:47:01 +08:00
Alex Lam S.L
e219a9a78a v3.14.1 2021-07-27 16:53:57 +08:00
Alex Lam S.L
c80eabd61e fix ie8 option alias (#5103)
fixes #5102
2021-07-26 16:45:43 +08:00
Alex Lam S.L
9b82f9be91 fix corner case in unused (#5101)
fixes #5100
2021-07-26 16:44:34 +08:00
Alex Lam S.L
657d525c80 fix corner case in reduce_vars (#5099)
fixes #5098
2021-07-24 07:10:14 +08:00
Alex Lam S.L
6a3fe9d1df fix corner cases in reduce_vars (#5097)
fixes #5096
2021-07-23 17:17:20 +08:00
Alex Lam S.L
ec7fadcb5b v3.14.0 2021-07-22 21:13:43 +08:00
Alex Lam S.L
65adeba55d extend keep_quoted_props over numeric keys (#5094)
fixes #5093
2021-07-22 06:12:57 +08:00
Alex Lam S.L
7fac839c62 fix corner case in merge_vars (#5092)
fixes #5091
2021-07-21 02:47:53 +08:00
Alex Lam S.L
8926a2f327 fix corner case in unused (#5090)
fixes #5089
2021-07-21 01:10:58 +08:00
Alex Lam S.L
85968dee54 fix corner case in inline (#5088)
fixes #5087
2021-07-19 22:35:45 +08:00
Alex Lam S.L
a7e7865e6b fix corner case in unused (#5086)
fixes #5085
2021-07-18 19:38:09 +08:00
Alex Lam S.L
ef5f7fc25e workaround various IE quirks (#5084)
fixes #5081
2021-07-17 20:20:56 +08:00
Alex Lam S.L
902997b73d fix corner case in inline (#5083)
fixes #5082
2021-07-16 22:13:33 +08:00
Alex Lam S.L
f18804fa06 fix corner case in unused (#5080)
fixes #5079
2021-07-14 23:02:45 +08:00
Alex Lam S.L
8e2dff632e suppress false positives in ufuzz (#5078) 2021-07-13 04:10:59 +08:00
Alex Lam S.L
92c3fddd7a fix corner case in unused & yields (#5077)
fixes #5076
2021-07-12 23:16:12 +08:00
Alex Lam S.L
0d350b78bf fix corner cases in unused (#5075)
fixes #5074
2021-07-12 07:43:13 +08:00
Alex Lam S.L
1ad830facb fix corner cases in unused (#5073)
fixes #5071
2021-07-11 14:52:38 +08:00
Alex Lam S.L
64ebf6efe9 fix corner case in awaits & side_effects (#5072)
fixes #5070
2021-07-11 13:43:08 +08:00
Alex Lam S.L
08391b8e1c fix corner case in hoist_props (#5069) 2021-07-11 10:59:57 +08:00
Alex Lam S.L
d147d5d7f0 fix corner case in inline (#5068)
fixes #5067
2021-07-11 04:11:10 +08:00
Alex Lam S.L
aae1fcd12d fix corner case in unused (#5066)
fixes #5065
2021-07-11 00:43:01 +08:00
Alex Lam S.L
f67dd31cbb enhance unused (#5064) 2021-07-10 19:58:57 +08:00
Alex Lam S.L
450aabaaa0 fix corner cases in rests & unused (#5063) 2021-07-10 00:28:23 +08:00
Alex Lam S.L
ea7829daf5 fix corner case in reduce_vars (#5062)
fixes #5061
2021-07-08 16:31:04 +08:00
Alex Lam S.L
6577d641ac enhance evaluate & reduce_vars (#5060) 2021-07-08 00:29:23 +08:00
Alex Lam S.L
2340feff87 support destructured shorthand for default parameters (#5059)
closes #4990
2021-07-07 22:45:24 +08:00
Alex Lam S.L
0c48b84540 fix corner cases in inline & unused (#5058)
fixes #5057
2021-07-07 10:29:16 +08:00
Alex Lam S.L
1fefe3f1d1 fix corner case in reduce_vars (#5056)
fixes #5055
2021-07-07 02:23:09 +08:00
Alex Lam S.L
0668fad5e9 fix corner case with class (#5054)
fixes #5053
2021-07-06 16:04:11 +08:00
Alex Lam S.L
d0e3f6955d enhance functions (#5052) 2021-07-06 02:43:09 +08:00
Alex Lam S.L
6961c57d1e fix corner case in reduce_vars (#5051)
fixes #5050
2021-07-05 11:57:58 +08:00
Alex Lam S.L
f5dbb672b9 fix corner case in reduce_funcs (#5049)
fixes #5048
2021-07-04 15:09:05 +08:00
Alex Lam S.L
f4ae267920 fix corner case in reduce_vars (#5047)
fixes #5046
2021-07-04 13:45:09 +08:00
Alex Lam S.L
972b9f0bef enhance functions & reduce_vars (#5045) 2021-07-04 06:19:08 +08:00
Alex Lam S.L
668f96623c tweak beautify output (#5044) 2021-07-03 23:10:39 +08:00
Alex Lam S.L
1b745494ce enhance booleans (#5043) 2021-07-01 03:05:52 +08:00
Alex Lam S.L
611abff49f fix corner case in booleans (#5042)
fixes #5041
2021-07-01 00:52:54 +08:00
Alex Lam S.L
4ba8b66c5a fix corner case in ie8 (#5040)
fixes #5039
2021-06-30 02:14:07 +08:00
Alex Lam S.L
798121c9f3 enhance reduce_vars (#5038) 2021-06-29 03:51:44 +08:00
Alex Lam S.L
b23b333d9d v3.13.10 2021-06-27 22:59:34 +08:00
Alex Lam S.L
7621527a5f fix corner case in functions (#5037)
fixes #5036
2021-06-25 03:43:52 +08:00
Alex Lam S.L
1a064b6e74 fix corner case in functions (#5035)
fixes #5034
2021-06-24 19:43:46 +08:00
Alex Lam S.L
82772ccb12 workaround Safari quirks (#5033)
closes #5032
2021-06-24 17:09:19 +08:00
Alex Lam S.L
7cbcd11440 fix corner case in dead_code (#5031)
fixes #5030
2021-06-23 22:56:28 +08:00
Alex Lam S.L
980dbde171 fix corner cases in booleans (#5029)
fixes #5028
2021-06-23 07:42:57 +08:00
Alex Lam S.L
8b05677c15 fix corner case in collapse_vars (#5026)
fixes #5025
2021-06-23 05:03:11 +08:00
Alex Lam S.L
95090dbf24 fix corner case in side_effects (#5024)
fixes #5023
2021-06-23 00:36:07 +08:00
Alex Lam S.L
7c5b6f349e enhance booleans (#5022)
closes #5021
2021-06-23 00:35:50 +08:00
Alex Lam S.L
e9c902b044 fix corner cases in dead_code & inline (#5020)
fixes #5019
2021-06-21 22:28:54 +08:00
Alex Lam S.L
111366fca0 fix corner case in collapse_vars (#5018)
fixes #5017
2021-06-21 11:12:45 +08:00
Alex Lam S.L
e368d39715 fix corner cases in reduce_vars & side_effects (#5016)
fixes #5015
2021-06-21 03:13:05 +08:00
Alex Lam S.L
fd8dec61ad enhance dead_code (#5014) 2021-06-20 15:30:04 +08:00
Alex Lam S.L
7880568d15 fix corner case in switches (#5013)
fixes #5012
2021-06-15 23:51:53 +08:00
Alex Lam S.L
21fc8f4630 fix corner case in switches (#5011)
fixes #5010
2021-06-15 20:59:53 +08:00
Alex Lam S.L
bf76e35772 fix corner case in switches (#5009)
fixes #5008
2021-06-15 18:27:55 +08:00
Alex Lam S.L
ac1262dc97 fix corner case in arguments (#5007)
fixes #5006
2021-06-15 12:53:22 +08:00
Alex Lam S.L
498ac83541 enhance switches (#5005)
closes #5004
2021-06-15 10:32:39 +08:00
Alex Lam S.L
6fc7a2ab6a fix corner case in side_effects (#5002)
fixes #5001
2021-06-13 20:29:14 +08:00
Alex Lam S.L
f8b2215145 fix corner cases in parse & unused (#5000) 2021-06-13 00:10:01 +08:00
Alex Lam S.L
70ceda5398 minor clean-up (#4998) 2021-06-12 09:20:06 +08:00
Alex Lam S.L
ce75477670 fix corner case in reduce_vars (#4997)
fixes #4996
2021-06-10 08:03:17 +08:00
Alex Lam S.L
e70b84895c fix corner cases in loops & unused (#4995)
fixes #4994
2021-06-10 07:58:33 +08:00
90 changed files with 15387 additions and 3012 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

@@ -111,10 +111,11 @@ 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-fargs Do not mangle/drop function arguments.
--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.
@@ -502,7 +503,10 @@ 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_fargs` (default: `false`) — pass `true` to prevent discarding or mangling
of function arguments.
- `keep_fnames` (default: `false`) — pass `true` to prevent discarding or mangling
of function names. Useful for code relying on `Function.prototype.name`.
@@ -566,7 +570,6 @@ if (result.error) throw result.error;
},
nameCache: null, // or specify a name cache object
toplevel: false,
ie8: false,
warnings: false,
}
```
@@ -708,7 +711,8 @@ to be `false` and all symbol names will be omitted.
- `1` — inline simple functions
- `2` — inline functions with arguments
- `3` — inline functions with arguments and variables
- `true`same as `3`
- `4`inline functions with arguments, variables and statements
- `true` — same as `4`
- `join_vars` (default: `true`) — join consecutive `var` statements
@@ -795,9 +799,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)
@@ -869,6 +872,9 @@ UglifyJS.minify(code, { mangle: { toplevel: true } }).code;
- `debug` (default: `false`) — Mangle names with the original name still present.
Pass an empty string `""` to enable, or a non-empty string to set the debug suffix.
- `keep_fargs` (default: `false`) — Use `true` to prevent mangling of function
arguments.
- `keep_quoted` (default: `false`) — Only mangle unquoted property names.
- `regex` (default: `null`) — Pass a RegExp literal to only mangle property
@@ -1201,6 +1207,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
({

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 = {
@@ -70,6 +72,7 @@ function process_option(name, no_value) {
} else {
if (padding.length < name.length) padding = Array(name.length + 1).join(" ");
toplevels.push([ {
keep_fargs: "keep-fargs",
keep_fnames: "keep-fnames",
nameCache: "name-cache",
}[name] || name, option ]);
@@ -101,7 +104,8 @@ 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-fargs Do not mangle/drop function arguments.",
" --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 +114,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 +150,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;
@@ -155,6 +162,9 @@ function process_option(name, no_value) {
case "no-annotations":
options.annotations = false;
break;
case "keep-fargs":
options.keep_fargs = true;
break;
case "keep-fnames":
options.keep_fnames = true;
break;
@@ -344,9 +354,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 +437,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 +526,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 +566,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.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];
}
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,53 @@ var AST_Node = DEFNODE("Node", "start end", {
},
}, null);
DEF_BITPROPS(AST_Node, [
"_optimized",
"_squeezed",
// AST_Call
"call_only",
// AST_Lambda
"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 +302,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 +533,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 +592,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 +1338,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 +1366,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 +1389,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() {
@@ -1491,6 +1538,12 @@ var AST_Assign = DEFNODE("Assign", null, {
throw new Error("left must be assignable: " + node.TYPE);
}
});
} else if (!(this.left instanceof AST_Infinity
|| this.left instanceof AST_NaN
|| this.left instanceof AST_PropAccess && !this.left.optional
|| this.left instanceof AST_SymbolRef
|| this.left instanceof AST_Undefined)) {
throw new Error("left must be assignable");
}
},
}, AST_Binary);
@@ -1749,7 +1802,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 +1816,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",
@@ -1925,27 +1978,27 @@ var AST_Atom = DEFNODE("Atom", null, {
var AST_Null = DEFNODE("Null", null, {
$documentation: "The `null` atom",
value: null
value: null,
}, AST_Atom);
var AST_NaN = DEFNODE("NaN", null, {
$documentation: "The impossible value",
value: 0/0
value: 0/0,
}, AST_Atom);
var AST_Undefined = DEFNODE("Undefined", null, {
$documentation: "The `undefined` value",
value: function(){}()
value: function(){}(),
}, AST_Atom);
var AST_Hole = DEFNODE("Hole", null, {
$documentation: "A hole in an array",
value: function(){}()
value: function(){}(),
}, AST_Atom);
var AST_Infinity = DEFNODE("Infinity", null, {
$documentation: "The `Infinity` value",
value: 1/0
value: 1/0,
}, AST_Atom);
var AST_Boolean = DEFNODE("Boolean", null, {
@@ -1957,12 +2010,12 @@ var AST_Boolean = DEFNODE("Boolean", null, {
var AST_False = DEFNODE("False", null, {
$documentation: "The `false` atom",
value: false
value: false,
}, AST_Boolean);
var AST_True = DEFNODE("True", null, {
$documentation: "The `true` atom",
value: true
value: true,
}, AST_Boolean);
/* -----[ TreeWalker ]----- */
@@ -2001,7 +2054,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

@@ -28,7 +28,7 @@ function read_source_map(name, toplevel) {
var match = /^# ([^\s=]+)=(\S+)\s*$/.exec(comment.value);
if (!match) break;
if (match[1] == "sourceMappingURL") {
match = /^data:application\/json(;.*?)?;base64,(\S+)$/.exec(match[2]);
match = /^data:application\/json(;.*?)?;base64,([^,]+)$/.exec(match[2]);
if (!match) break;
return to_ascii(match[2]);
}
@@ -76,7 +76,9 @@ function minify(files, options) {
annotations: undefined,
compress: {},
enclose: false,
ie: false,
ie8: false,
keep_fargs: false,
keep_fnames: false,
mangle: {},
nameCache: null,
@@ -96,17 +98,20 @@ 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_fargs) set_shorthand("keep_fargs", options, [ "compress", "mangle" ]);
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_fargs: 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) {
@@ -999,7 +1005,7 @@
});
def_to_moz(AST_RegExp, function To_Moz_RegExpLiteral(M) {
var flags = M.value.toString().match(/[gimuy]*$/)[0];
var flags = M.value.toString().match(/\/([gimuy]*)$/)[1];
var value = "/" + M.value.raw_source + "/" + flags;
return {
type: "Literal",
@@ -1007,8 +1013,8 @@
raw: value,
regex: {
pattern: M.value.raw_source,
flags: flags
}
flags: flags,
},
};
});
@@ -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";
@@ -521,9 +521,7 @@ function OutputStream(options) {
indent();
}
var preamble = options.preamble;
if (preamble) {
print(preamble.replace(/\r\n?|[\n\u2028\u2029]|\s*$/g, "\n"));
}
if (preamble) print(preamble.replace(/\r\n?|\u2028|\u2029|(^|\S)\s*$/g, "$1\n"));
}
comments = comments.filter(comment_filter, node);
@@ -790,35 +788,26 @@ function OutputStream(options) {
if (p instanceof AST_Unary) return true;
});
function lhs_has_optional(node, output) {
var p = output.parent();
if (p instanceof AST_PropAccess && p.expression === node && is_lhs(p, output.parent(1))) {
// ++(foo?.bar).baz
// (foo?.()).bar = baz
do {
if (node.optional) return true;
node = node.expression;
} while (node.TYPE == "Call" || node instanceof AST_PropAccess);
}
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) {
if (p.expression !== node) return false;
// 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";
}
return lhs_has_optional(node, output);
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) {
@@ -833,7 +822,10 @@ function OutputStream(options) {
var g = output.parent(1);
if (g instanceof AST_Assign && g.left === p) return true;
}
return lhs_has_optional(node, output);
// (foo?.())()
// (foo?.()).bar
// new (foo?.())()
return need_chain_parens(node, p);
});
PARENS(AST_New, function(output) {
@@ -980,7 +972,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");
@@ -997,7 +988,6 @@ function OutputStream(options) {
output.with_parens(function() {
self.condition.print(output);
});
output.space();
force_statement(self.body, output);
});
DEFPRINT(AST_For, function(output) {
@@ -1027,7 +1017,6 @@ function OutputStream(options) {
self.step.print(output);
}
});
output.space();
force_statement(self.body, output);
});
function print_for_enum(prefix, infix) {
@@ -1042,7 +1031,6 @@ function OutputStream(options) {
output.space();
self.object.print(output);
});
output.space();
force_statement(self.body, output);
};
}
@@ -1056,7 +1044,6 @@ function OutputStream(options) {
output.with_parens(function() {
self.expression.print(output);
});
output.space();
force_statement(self.body, output);
});
DEFPRINT(AST_ExportDeclaration, function(output) {
@@ -1163,8 +1150,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);
}
@@ -1295,7 +1283,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
@@ -1325,16 +1313,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");
if (self.alternative instanceof AST_If) {
output.space();
if (self.alternative instanceof AST_If)
self.alternative.print(output);
else
} else {
force_statement(self.alternative, output);
}
} else {
force_statement(self.body, output);
}
@@ -1475,7 +1463,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) {
@@ -1520,7 +1508,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);
@@ -1634,7 +1622,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);
});
@@ -1683,30 +1683,23 @@ function OutputStream(options) {
function print_property_key(self, output) {
var key = self.key;
if (key instanceof AST_Node) {
output.with_square(function() {
if (key instanceof AST_Node) return output.with_square(function() {
key.print(output);
});
} else if (output.option("quote_keys")) {
output.print_string(key);
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 {
var quote = self.start && self.start.quote;
if (self.private) {
} else 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 {
} else if (RESERVED_WORDS[key] ? !output.option("ie") : is_identifier_string(key)) {
output.print_name(key);
return key;
}
} else {
output.print_string(key, quote);
}
}
}
DEFPRINT(AST_ObjectKeyVal, function(output) {
var self = this;
print_property_key(self, output);
@@ -1836,6 +1829,7 @@ function OutputStream(options) {
} else if (stat instanceof AST_EmptyStatement) {
output.force_semicolon();
} else {
output.space();
stat.print(output);
}
}
@@ -1874,8 +1868,8 @@ function OutputStream(options) {
len = match[0].length;
digits = str.slice(len);
candidates.push(digits + "e-" + (digits.length + len - 1));
} else if (match = /0+$/.exec(str)) {
len = match[0].length;
} else if (match = /[^0]0+$/.exec(str)) {
len = match[0].length - 1;
candidates.push(str.slice(0, -len) + "e" + len);
} else if (match = /^(\d)\.(\d+)e(-?\d+)$/.exec(str)) {
candidates.push(match[1] + match[2] + "e" + (match[3] - match[2].length));
@@ -1884,6 +1878,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) {

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(" ");
@@ -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;
@@ -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;
var optional = null;
while (true) {
if (is("operator", "?") && is_token(peek(), "punc", ".")) {
next();
next();
optional = expr;
}
if (is("punc", "[")) {
next();
var prop = expression();
expect("]");
return subscripts(new AST_Sub({
expr = new AST_Sub({
start: start,
optional: optional,
optional: optional === expr,
expression: expr,
property: prop,
end: prev(),
}), allow_calls);
}
if (allow_calls && is("punc", "(")) {
});
} else if (allow_calls && is("punc", "(")) {
next();
var call = new AST_Call({
expr = new AST_Call({
start: start,
optional: optional,
optional: optional === expr,
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({
} else if (optional === expr || is("punc", ".")) {
if (optional !== expr) next();
expr = new AST_Dot({
start: start,
optional: optional,
optional: optional === expr,
expression: expr,
property: as_name(),
end: prev(),
}), allow_calls);
});
} else if (is("punc", "`")) {
if (optional) croak("Invalid template on optional chain");
expr = template(expr);
} else {
break;
}
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);
}
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 = {
@@ -92,18 +92,35 @@ SymbolDef.prototype = {
if (def && def !== self) return def.redefined() || def;
},
unmangleable: function(options) {
return this.global && !options.toplevel
|| this.exported
|| this.undeclared
|| !options.eval && this.scope.pinned()
|| options.keep_fnames
&& (this.orig[0] instanceof AST_SymbolClass
|| this.orig[0] instanceof AST_SymbolDefClass
|| this.orig[0] instanceof AST_SymbolDefun
|| this.orig[0] instanceof AST_SymbolLambda);
if (this.exported) return true;
if (this.undeclared) return true;
if (!options.eval && this.scope.pinned()) return true;
if (options.keep_fargs && is_funarg(this)) return true;
if (options.keep_fnames) {
var sym = this.orig[0];
if (sym instanceof AST_SymbolClass) return true;
if (sym instanceof AST_SymbolDefClass) return true;
if (sym instanceof AST_SymbolDefun) return true;
if (sym instanceof AST_SymbolLambda) return true;
}
if (!options.toplevel && this.global) return true;
return false;
},
};
DEF_BITPROPS(SymbolDef, [
"const_redefs",
"cross_loop",
"direct_access",
"exported",
"global",
"undeclared",
]);
function is_funarg(def) {
return def.orig[0] instanceof AST_SymbolFunarg || def.orig[1] instanceof AST_SymbolFunarg;
}
var unary_side_effects = makePredicate("delete ++ --");
function is_lhs(node, parent) {
@@ -118,7 +135,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
@@ -205,20 +222,17 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
} else if (node instanceof AST_SymbolDefun) {
var def = defun.def_function(node, tw.parent());
if (exported) def.exported = true;
entangle(defun, scope);
} else if (node instanceof AST_SymbolFunarg) {
defun.def_variable(node);
entangle(defun, scope);
} else if (node instanceof AST_SymbolLambda) {
var def = defun.def_function(node, node.name == "arguments" ? undefined : defun);
if (options.ie8) def.defun = defun.parent_scope.resolve();
if (options.ie) def.defun = defun.parent_scope.resolve();
} else if (node instanceof AST_SymbolLet) {
var def = scope.def_variable(node);
if (exported) def.exported = true;
} else if (node instanceof AST_SymbolVar) {
var def = defun.def_variable(node, node instanceof AST_SymbolImport ? undefined : null);
if (exported) def.exported = true;
entangle(defun, scope);
}
function walk_scope(descend) {
@@ -231,16 +245,6 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
scope = save_scope;
defun = save_defun;
}
function entangle(defun, scope) {
if (defun === scope) return;
node.mark_enclosed(options);
var def = scope.find_variable(node.name);
if (node.thedef === def) return;
node.thedef = def;
def.orig.push(node);
node.mark_enclosed(options);
}
});
self.make_def = function(orig, init) {
return new SymbolDef(++next_def_id, this, orig, init);
@@ -261,6 +265,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
}
if (node instanceof AST_Lambda) {
in_arg.push(node);
if (node.name) node.name.walk(tw);
node.argnames.forEach(function(argname) {
argname.walk(tw);
});
@@ -287,6 +292,16 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
// ensure compression works if `const` reuses a scope variable
var redef = def.redefined();
if (redef) redef.const_redefs = true;
} else if (def.scope !== node.scope && (node instanceof AST_SymbolDefun
|| node instanceof AST_SymbolFunarg
|| node instanceof AST_SymbolVar)) {
node.mark_enclosed(options);
var redef = node.scope.find_variable(node.name);
if (node.thedef !== redef) {
node.thedef = redef;
redef.orig.push(node);
node.mark_enclosed(options);
}
}
if (node.name != "arguments") return true;
var parent = node instanceof AST_SymbolVar && tw.parent();
@@ -351,7 +366,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) {
@@ -363,7 +378,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) {
@@ -465,9 +480,12 @@ 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;
} else if (options.keep_fnames) {
s.functions.each(function(d) {
s._var_names = undefined;
} else {
if (options.keep_fargs && s instanceof AST_Lambda) s.each_argname(function(arg) {
push_uniq(def.scope.enclosed, arg.definition());
});
if (options.keep_fnames) s.functions.each(function(d) {
push_uniq(def.scope.enclosed, d);
});
}
@@ -510,12 +528,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);
}
});
}
@@ -526,34 +544,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;
}
if (member(scope, scopes)) break;
names_in_use(scope, options).each(function(marker, name) {
names.set(name, marker);
});
scopes.push(scope);
} else break;
} while (scope = scope.parent_scope);
});
var name;
for (var i = 0; i < holes.length; i++) {
name = base54(holes[i]);
if (names[name]) continue;
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;
}
@@ -572,7 +589,8 @@ AST_Symbol.DEFMETHOD("definition", function() {
function _default_mangler_options(options) {
options = defaults(options, {
eval : false,
ie8 : false,
ie : false,
keep_fargs : false,
keep_fnames : false,
reserved : [],
toplevel : false,
@@ -580,32 +598,30 @@ function _default_mangler_options(options) {
webkit : false,
});
if (!Array.isArray(options.reserved)) options.reserved = [];
// Never mangle arguments
// Never mangle `arguments`
push_uniq(options.reserved, "arguments");
options.reserved.has = makePredicate(options.reserved);
return options;
}
// We only need to mangle declaration nodes. Special logic wired into the code
// generator will display the mangled name if it is present (and for
// `AST_SymbolRef`s it will use the mangled name of the `AST_SymbolDeclaration`
// that it points to).
AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
options = _default_mangler_options(options);
// We only need to mangle declaration nodes. Special logic wired
// into the code generator will display the mangled name if it's
// present (and for AST_SymbolRef-s it'll use the mangled name of
// the AST_SymbolDeclaration that it points to).
var lname = -1;
if (options.cache && options.cache.props) {
var mangled_names = names_in_use(this, options);
options.cache.props.each(function(mangled_name) {
mangled_names[mangled_name] = true;
mangled_names.set(mangled_name, true);
});
}
var cutoff = 10;
var lname = -1;
var redefined = [];
var tw = new TreeWalker(function(node, descend) {
if (node instanceof AST_LabeledStatement) {
// lname is incremented when we get to the AST_Label
// `lname` is incremented when we get to the `AST_Label`
var save_nesting = lname;
descend();
if (!options.v8 || !in_label(tw)) lname = save_nesting;
@@ -627,9 +643,9 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
});
}, true);
}
node.to_mangle = [];
var to_mangle = node.to_mangle = [];
node.variables.each(function(def) {
if (!defer_redef(def)) node.to_mangle.push(def);
if (!defer_redef(def)) to_mangle.push(def);
});
descend();
if (options.cache && node instanceof AST_Toplevel) {
@@ -640,7 +656,23 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
sym.scope = node;
sym.reference(options);
}
node.to_mangle.forEach(mangle);
if (to_mangle.length > cutoff) {
var indices = to_mangle.map(function(def, index) {
return index;
}).sort(function(i, j) {
return to_mangle[j].references.length - to_mangle[i].references.length || i - j;
});
to_mangle = indices.slice(0, cutoff).sort(function(i, j) {
return i - j;
}).map(function(index) {
return to_mangle[index];
}).concat(indices.slice(cutoff).sort(function(i, j) {
return i - j;
}).map(function(index) {
return to_mangle[index];
}));
}
to_mangle.forEach(mangle);
return true;
}
if (node instanceof AST_Label) {

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.9",
"version": "3.15.0",
"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

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

@@ -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,
}
@@ -486,7 +508,7 @@ drop_value: {
((a, b) => a + b)(console.log(42));
}
expect: {
((a, b) => {})(console.log(42));
void console.log(42);
}
expect_stdout: "42"
node_version: ">=4"
@@ -556,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,
@@ -815,3 +906,24 @@ issue_4772: {
expect_stdout: "PASS"
node_version: ">=4"
}
issue_5251: {
options = {
inline: true,
toplevel: true,
}
input: {
(() => {
while (console.log(arguments))
var arguments = "FAIL";
})();
}
expect: {
(() => {
while (console.log(arguments))
var arguments = "FAIL";
})();
}
expect_stdout: true
node_version: ">=4"
}

View File

@@ -489,7 +489,7 @@ logical_assignments: {
node_version: ">=15"
}
logical_collapse_vars: {
logical_collapse_vars_1: {
options = {
collapse_vars: true,
}
@@ -509,6 +509,46 @@ logical_collapse_vars: {
node_version: ">=15"
}
logical_collapse_vars_2: {
options = {
collapse_vars: true,
}
input: {
var a = "PASS";
(function(b) {
b ||= (a = "FAIL", {});
return b;
})(console).log(a);
}
expect: {
var a = "PASS";
(function(b) {
return b ||= (a = "FAIL", {});
})(console).log(a);
}
expect_stdout: "PASS"
node_version: ">=15"
}
logical_collapse_vars_3: {
options = {
collapse_vars: true,
}
input: {
var a = 6;
a *= 7;
a ??= "FAIL";
console.log(a);
}
expect: {
var a = 6;
a = a * 7 ?? "FAIL";
console.log(a);
}
expect_stdout: "42"
node_version: ">=15"
}
logical_reduce_vars: {
options = {
evaluate: true,
@@ -550,6 +590,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,

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,7 @@ arithmetic: {
}
expect_exact: "console.log((1n+0x2n)*(0o3n- -4n)>>5n-6n);"
expect_stdout: "42n"
node_version: ">=10"
node_version: ">=10.4.0"
}
minus_dot: {
@@ -13,7 +13,7 @@ minus_dot: {
}
expect_exact: "console.log(typeof-42n.toString(),typeof(-42n).toString());"
expect_stdout: "number string"
node_version: ">=10"
node_version: ">=10.4.0"
}
evaluate: {
@@ -28,7 +28,7 @@ evaluate: {
console.log(0xdeadbeefn.toString(16));
}
expect_stdout: "deadbeef"
node_version: ">=10"
node_version: ">=10.4.0"
}
Number: {
@@ -42,7 +42,7 @@ Number: {
console.log(+("" + -0xfeed_dead_beef_badn));
}
expect_stdout: "-1148098955808013200"
node_version: ">=10"
node_version: ">=10.4.0"
}
issue_4590: {
@@ -58,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,148 @@ issue_4374: {
}
expect_stdout: "0"
}
issue_5028_1: {
options = {
booleans: true,
conditionals: true,
}
input: {
var a = 1;
console.log(function() {
return a-- ? a-- ? "FAIL 1" : "PASS" : "FAIL 2";
}());
}
expect: {
var a = 1;
console.log(function() {
return a-- ? a-- ? "FAIL 1" : "PASS" : "FAIL 2";
}());
}
expect_stdout: "PASS"
}
issue_5028_2: {
options = {
booleans: true,
conditionals: true,
dead_code: true,
if_return: true,
}
input: {
var a = 1;
(function() {
if (a--)
if (a--)
a = "FAIL";
else
return;
})();
console.log(a);
}
expect: {
var a = 1;
(function() {
a-- && a-- && (a = "FAIL");
})();
console.log(a);
}
expect_stdout: "-1"
}
issue_5028_3: {
options = {
booleans: true,
conditionals: true,
evaluate: true,
if_return: true,
}
input: {
var a = 1;
(function() {
if (a--)
if (a--)
a = "FAIL";
else
return;
})();
console.log(a);
}
expect: {
var a = 1;
(function() {
a-- && a-- && (a = "FAIL");
})();
console.log(a);
}
expect_stdout: "-1"
}
issue_5041_1: {
options = {
booleans: true,
conditionals: true,
}
input: {
var a = 42;
if (a)
if ([ a = null ])
if (a)
console.log("FAIL");
else
console.log("PASS");
}
expect: {
var a = 42;
a && [ a = null ] && (a ? console.log("FAIL") : console.log("PASS"));
}
expect_stdout: "PASS"
}
issue_5041_2: {
options = {
booleans: true,
conditionals: true,
}
input: {
var a;
if (!a)
if (a = 42)
if (a)
console.log("PASS");
else
console.log("FAIL");
}
expect: {
var a;
a || (a = 42) && (a ? console.log("PASS") : console.log("FAIL"));
}
expect_stdout: "PASS"
}
issue_5228: {
options = {
booleans: true,
evaluate: true,
inline: true,
passes: 2,
}
input: {
console.log(function() {
return !function() {
do {
return null;
} while (console);
}();
}());
}
expect: {
console.log(function() {
do {
return !0;
} while (console);
return !0;
}());
}
expect_stdout: "true"
}

View File

@@ -434,6 +434,33 @@ static_side_effects: {
console.log(a);
}
expect: {
var a = "FAIL 1";
(class {
static c = a = "PASS";
});
console.log(a);
}
expect_stdout: "PASS"
node_version: ">=12"
}
static_side_effects_strict: {
options = {
inline: true,
toplevel: true,
unused: true,
}
input: {
"use strict";
var a = "FAIL 1";
class A {
static p = a = "PASS";
q = a = "FAIL 2";
}
console.log(a);
}
expect: {
"use strict";
var a = "FAIL 1";
a = "PASS";
console.log(a);
@@ -807,6 +834,33 @@ unused_await: {
})();
}
expect: {
var await = "PASS";
(async function() {
(class {
static c = console.log(await);
});
})();
}
expect_stdout: true
node_version: ">=12 <16"
}
unused_await_strict: {
options = {
inline: true,
unused: true,
}
input: {
"use strict";
var await = "PASS";
(async function() {
class A {
static p = console.log(await);
}
})();
}
expect: {
"use strict";
var await = "PASS";
(async function() {
(() => console.log(await))();
@@ -890,7 +944,7 @@ keep_fnames: {
issue_805_1: {
options = {
inline: true,
passes: 2,
passes: 3,
pure_getters: "strict",
reduce_vars: true,
sequences: true,
@@ -926,7 +980,7 @@ issue_805_1: {
issue_805_2: {
options = {
inline: true,
passes: 2,
passes: 3,
pure_getters: "strict",
reduce_vars: true,
sequences: true,
@@ -1149,6 +1203,31 @@ issue_4705: {
}
}
expect: {
(class {
[console.log("PASS")]() {}
});
}
expect_stdout: "PASS"
node_version: ">=12"
}
issue_4705_strict: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
"use strict";
var a = "PASS";
class A {
p = a = "FAIL";
[console.log(a)];
}
}
expect: {
"use strict";
console.log("PASS");
}
expect_stdout: "PASS"
@@ -1157,7 +1236,7 @@ issue_4705: {
issue_4720: {
options = {
ie8: true,
ie: true,
reduce_vars: true,
toplevel: true,
unused: true,
@@ -1310,6 +1389,7 @@ issue_4725_1: {
issue_4725_2: {
options = {
if_return: true,
inline: true,
}
input: {
@@ -1370,9 +1450,40 @@ issue_4756: {
expect: {
try {
(class extends 42 {
[console.log("foo")]() {}
}),
(() => console.log("bar"))();
static [console.log("foo")] = console.log("bar");
});
} catch (e) {
console.log("baz");
}
}
expect_stdout: [
"foo",
"baz",
]
node_version: ">=12"
}
issue_4756_strict: {
options = {
toplevel: true,
unused: true,
}
input: {
"use strict";
try {
class A extends 42 {
static [console.log("foo")] = console.log("bar");
}
} catch (e) {
console.log("baz");
}
}
expect: {
"use strict";
try {
(class extends 42 {
static [console.log("foo")] = console.log("bar");
});
} catch (e) {
console.log("baz");
}
@@ -1629,7 +1740,7 @@ issue_4951_2: {
issue_4962_1: {
options = {
ie8: true,
ie: true,
inline: true,
reduce_vars: true,
unused: true,
@@ -1646,9 +1757,38 @@ issue_4962_1: {
}
expect: {
(function g() {}),
void function() {
void class {
static c = function() {
while (console.log(typeof g));
}();
};
}
expect_stdout: "undefined"
node_version: ">=12"
}
issue_4962_1_strict: {
options = {
ie: true,
inline: true,
reduce_vars: true,
unused: true,
}
input: {
"use strict";
(function() {
function f() {
while (console.log(typeof g));
}
class A {
static p = f();
}
})(function g() {});
}
expect: {
"use strict";
(function g() {});
while (console.log(typeof g));
}
expect_stdout: "undefined"
node_version: ">=12"
@@ -1656,7 +1796,7 @@ issue_4962_1: {
issue_4962_2: {
options = {
ie8: true,
ie: true,
inline: true,
reduce_vars: true,
unused: true,
@@ -1672,6 +1812,36 @@ issue_4962_2: {
}, typeof g));
}
expect: {
console.log(function f() {}(function g() {
(class {
static c = f;
});
}));
}
expect_stdout: "undefined"
node_version: ">=12"
}
issue_4962_2_strict: {
options = {
ie: true,
inline: true,
reduce_vars: true,
unused: true,
}
input: {
"use strict";
console.log(function f() {}(function g() {
function h() {
f;
}
class A {
static p = h();
}
}, typeof g));
}
expect: {
"use strict";
console.log(function f() {}(function g() {
f;
}));
@@ -1748,3 +1918,534 @@ issue_4992: {
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";
(class A {});
console.log("PASS");
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_5015_4: {
options = {
reduce_vars: true,
sequences: true,
side_effects: true,
toplevel: true,
unused: 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() {}
}
(class {
static c = new A();
});
})();
}
expect_stdout: "PASS"
node_version: ">=12"
}
issue_5082_1_strict: {
options = {
inline: true,
reduce_vars: true,
unused: true,
}
input: {
"use strict";
(function() {
class A {
p = console.log("PASS");
q() {}
}
class B {
static P = new A();
}
})();
}
expect: {
"use strict";
(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: {
(function() {
class A {
p = console.log("PASS");
q() {}
}
(class {
static c = new A();
});
})();
}
expect_stdout: "PASS"
node_version: ">=12"
}
issue_5082_2_static: {
options = {
inline: true,
passes: 2,
reduce_vars: true,
unused: true,
}
input: {
"use strict";
(function() {
class A {
p = console.log("PASS");
q() {}
}
class B {
static P = new A();
}
})();
}
expect: {
"use strict";
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"
}
issue_5294_1: {
options = {
reduce_vars: true,
side_effects: true,
toplevel: true,
}
input: {
(class A {
static p = console.log(typeof A);
});
}
expect: {
(class A {
static c = console.log(typeof A);
});
}
expect_stdout: "function"
node_version: ">=12"
}
issue_5294_2: {
options = {
reduce_vars: true,
side_effects: true,
toplevel: true,
}
input: {
class A {
static p = console.log(typeof A);
}
}
expect: {
class A {
static p = console.log(typeof A);
}
}
expect_stdout: "function"
node_version: ">=12"
}
issue_5294_3: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = this;
(class A {
static p = console.log(a === A ? "FAIL" : "PASS");
});
}
expect: {
var a = this;
(class A {
static p = console.log(a === A ? "FAIL" : "PASS");
});
}
expect_stdout: "PASS"
node_version: ">=12"
}
issue_5294_4: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
(class A {
static p = function() {
var a = this;
console.log(a === A ? "FAIL" : "PASS");
}();
});
}
expect: {
(class A {
static p = function() {
console.log(this === A ? "FAIL" : "PASS");
}();
});
}
expect_stdout: "PASS"
node_version: ">=12"
}

View File

@@ -346,9 +346,7 @@ collapse_vars_if: {
return "x" != "Bar" + x / 4 ? g9 : g5;
}
function f3(x) {
if (x)
return 1;
return 2;
return x ? 1 : 2;
}
}
}
@@ -1912,6 +1910,42 @@ collapse_vars_regexp: {
]
}
collapse_arg_sequence: {
options = {
collapse_vars: true,
unused: true,
}
input: {
(function(a) {
a("foo");
})((console.log("bar"), console.log));
}
expect: {
(function(a) {
(0, console.log)("foo");
})(console.log("bar"));
}
expect_stdout: [
"bar",
"foo",
]
}
collapse_for_init: {
options = {
collapse_vars: true,
toplevel: true,
}
input: {
for (var a = (Math, console), b = a.log("PASS"); b;);
}
expect: {
Math;
for (var a, b = console.log("PASS"); b;);
}
expect_stdout: "PASS"
}
issue_1537: {
options = {
collapse_vars: true,
@@ -2667,6 +2701,24 @@ chained_4: {
expect_stdout: "foo undefined"
}
chained_5: {
options = {
collapse_vars: true,
}
input: {
var a = "PASS";
var a = (console, console.log(a));
a && ++a;
}
expect: {
var a = "PASS";
console;
var a;
(a = console.log(a)) && ++a;
}
expect_stdout: "PASS"
}
boolean_binary_1: {
options = {
collapse_vars: true,
@@ -2906,6 +2958,128 @@ compound_assignment_2: {
expect_stdout: "4"
}
compound_assignment_3: {
options = {
collapse_vars: true,
}
input: {
var a = 1;
a += (console.log("PASS"), 2);
a.p;
}
expect: {
var a = 1;
(a += (console.log("PASS"), 2)).p;
}
expect_stdout: "PASS"
}
compound_assignment_4: {
options = {
collapse_vars: true,
evaluate: true,
}
input: {
A = "PASS";
var a = "";
a += (a = "FAIL", A);
a.p;
console.log(a);
}
expect: {
A = "PASS";
var a = "";
(a += (a = "FAIL", A)).p;
console.log(a);
}
expect_stdout: "PASS"
}
compound_assignment_5: {
options = {
collapse_vars: true,
}
input: {
var a = 0, b;
a += 42;
b && (a *= null);
console.log(a);
}
expect: {
var a = 0, b;
a += 42;
b && (a *= null);
console.log(a);
}
expect_stdout: "42"
}
compound_assignment_6: {
options = {
collapse_vars: true,
}
input: {
var a;
a ^= 6;
a *= a + 1;
console.log(a);
}
expect: {
var a;
a = (a ^= 6) * (a + 1);
console.log(a);
}
expect_stdout: "42"
}
compound_assignment_7: {
options = {
assignments: true,
collapse_vars: true,
reduce_vars: true,
toplevel: true,
}
input: {
var a = "FA";
a = a + "I";
a = a + "L";
if (console)
a = "PASS";
console.log(a);
}
expect: {
var a = "FA";
a = a + "I" + "L";
if (console)
a = "PASS";
console.log(a);
}
expect_stdout: "PASS"
}
compound_assignment_8: {
options = {
assignments: true,
collapse_vars: true,
reduce_vars: true,
toplevel: true,
}
input: {
var a = 2;
a = 3 * a;
a = 7 * a;
console || (a = "FAIL");
console.log(a);
}
expect: {
var a = 2;
a = a * 3 * 7;
console || (a = "FAIL");
console.log(a);
}
expect_stdout: "42"
}
issue_2187_1: {
options = {
collapse_vars: true,
@@ -3030,10 +3204,10 @@ issue_2203_2: {
a: "FAIL",
b: function() {
return function(c) {
return (String, (Object, function() {
return (Object, function() {
return this;
}())).a;
}();
}()).a;
}(String);
}
}.b());
}
@@ -3731,6 +3905,7 @@ issue_2437_1: {
options = {
collapse_vars: true,
conditionals: true,
if_return: true,
inline: true,
join_vars: true,
passes: 2,
@@ -3763,17 +3938,17 @@ issue_2437_1: {
console.log(foo());
}
expect: {
console.log(function() {
if (xhrDesc) {
var result = !!(req = new XMLHttpRequest()).onreadystatechange;
return Object.defineProperty(XMLHttpRequest.prototype, "onreadystatechange", xhrDesc || {}),
result;
}
var req = new XMLHttpRequest(), detectFunc = function(){};
return req.onreadystatechange = detectFunc,
var req, detectFunc, result;
console.log((
xhrDesc ? (result = !!(req = new XMLHttpRequest).onreadystatechange,
Object.defineProperty(XMLHttpRequest.prototype, "onreadystatechange", xhrDesc||{})
) : (
(req = new XMLHttpRequest).onreadystatechange = detectFunc = function(){},
result = req[SYMBOL_FAKE_ONREADYSTATECHANGE_1] === detectFunc,
req.onreadystatechange = null, result;
}());
req.onreadystatechange = null
),
result
));
}
}
@@ -3783,6 +3958,7 @@ issue_2437_2: {
conditionals: true,
inline: true,
join_vars: true,
negate_iife: true,
passes: 3,
reduce_funcs: true,
reduce_vars: true,
@@ -3813,15 +3989,15 @@ issue_2437_2: {
foo();
}
expect: {
!function() {
if (xhrDesc)
return (req = new XMLHttpRequest()).onreadystatechange,
Object.defineProperty(XMLHttpRequest.prototype, "onreadystatechange", xhrDesc || {});
var req = new XMLHttpRequest();
req.onreadystatechange = function(){},
var req;
xhrDesc ? (
(req = new XMLHttpRequest).onreadystatechange,
Object.defineProperty(XMLHttpRequest.prototype, "onreadystatechange", xhrDesc || {})
) : (
(req = new XMLHttpRequest).onreadystatechange = function(){},
req[SYMBOL_FAKE_ONREADYSTATECHANGE_1],
req.onreadystatechange = null;
}();
req.onreadystatechange = null
);
}
}
@@ -4728,7 +4904,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);
}
}
@@ -6008,7 +6184,7 @@ issue_3215_1: {
options = {
collapse_vars: true,
evaluate: true,
ie8: false,
ie: false,
inline: true,
passes: 2,
side_effects: true,
@@ -6030,7 +6206,7 @@ issue_3215_2: {
options = {
collapse_vars: true,
evaluate: true,
ie8: true,
ie: true,
inline: true,
passes: 2,
side_effects: true,
@@ -6055,7 +6231,7 @@ issue_3215_3: {
options = {
collapse_vars: true,
evaluate: true,
ie8: false,
ie: false,
inline: true,
passes: 2,
side_effects: true,
@@ -6078,7 +6254,7 @@ issue_3215_4: {
options = {
collapse_vars: true,
evaluate: true,
ie8: true,
ie: true,
inline: true,
passes: 2,
side_effects: true,
@@ -6443,7 +6619,8 @@ assign_undeclared: {
console.log(typeof B);
}
expect: {
B = new (console.log(42), function() {})();
console.log(42);
B = new function() {}();
console.log(typeof B);
}
expect_stdout: [
@@ -8156,9 +8333,9 @@ issue_3884_1: {
console.log(a, b);
}
expect: {
var a = 100, b = 1;
b <<= ++a;
console.log(a, b);
var a = 100;
++a;
console.log(a, 32);
}
expect_stdout: "101 32"
}
@@ -8863,7 +9040,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"
@@ -9139,9 +9316,7 @@ issue_4908: {
console.log(d[1]);
}
expect: {
var a = 0, b;
console || a++;
var c = a, d = [ (d = a) && d, d += 42 ];
var a = 0, b, c = (console || a++, a), d = [ (d = a) && d, d += 42 ];
console.log(d[1]);
}
expect_stdout: "42"
@@ -9253,13 +9428,13 @@ issue_4920_2: {
console.log(b);
}
expect: {
var o = {
var o;
var a = "PASS", b;
({
get PASS() {
a = "FAIL";
},
};
var a = "PASS", b;
o[b = a];
})[b = a];
console.log(b);
}
expect_stdout: "PASS"
@@ -9283,16 +9458,47 @@ issue_4920_3: {
}
expect: {
var log = console.log;
var o = {
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: {
@@ -9343,9 +9549,8 @@ inline_throw: {
expect: {
try {
(function(a) {
return function() {
throw a;
}();
return;
})("PASS");
} catch (e) {
console.log(e);
@@ -9412,3 +9617,231 @@ issue_4977_2: {
}
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"
}
issue_5273: {
options = {
collapse_vars: true,
evaluate: true,
inline: true,
reduce_vars: true,
sequences: true,
toplevel: true,
}
input: {
var a = "10", b = 1;
function f(c, d) {
return d;
}
f((b += a, b *= a), f);
console.log(b);
}
expect: {
var a = "10", b = 1;
function f(c, d) {
return d;
}
b = 1100,
f,
console.log(b);
}
expect_stdout: "1100"
}
issue_5276: {
options = {
collapse_vars: true,
pure_getters: "strict",
reduce_vars: true,
toplevel: true,
}
input: {
var a = A = "PASS";
a.p += null;
a.p -= 42;
console.log(a);
}
expect: {
var a = A = "PASS";
a.p = a.p + null - 42;
console.log(a);
}
expect_stdout: "PASS"
}
issue_5277: {
options = {
collapse_vars: true,
reduce_vars: true,
unused: true,
}
input: {
console.log(function() {
var a = function() {
a += null;
a -= 42;
};
}());
}
expect: {
console.log(function() {}());
}
expect_stdout: "undefined"
}
issue_5309_1: {
options = {
collapse_vars: true,
conditionals: true,
toplevel: true,
}
input: {
if (console)
var a = (console.log("PASS"), b), b = a;
else
console.log("FAIL");
}
expect: {
var a, b;
console ? (console.log("PASS"), b = b) : console.log("FAIL");
}
expect_stdout: "PASS"
}
issue_5309_2: {
options = {
collapse_vars: true,
toplevel: true,
}
input: {
var a, b;
console ? (a = (console.log("PASS"), b), b = a) : console.log("FAIL");
}
expect: {
var a, b;
console ? (console.log("PASS"), b = b) : console.log("FAIL");
}
expect_stdout: "PASS"
}

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,
@@ -1897,3 +1924,86 @@ object_super: {
expect_stdout: "PASS"
node_version: ">=4"
}
issue_5232_1: {
options = {
conditionals: true,
}
input: {
(function() {
if (Math) {
function f() {}
for (var a in [ 42 ])
console.log(typeof f);
} else {
var b = null;
return true;
}
})();
}
expect: {
(function() {
var b;
if (!Math)
return b = null, true;
function f() {}
for (var a in [ 42 ]) console.log(typeof f);
})();
}
expect_stdout: "function"
}
issue_5232_2: {
options = {
conditionals: true,
}
input: {
console.log(function() {
if (!Math);
else {
var b = null;
return "PASS";
}
}());
}
expect: {
console.log(function() {
var b;
if (Math)
return b = null, "PASS";
}());
}
expect_stdout: "PASS"
}
issue_5232_3: {
options = {
conditionals: true,
}
input: {
console.log(function() {
return function() {
if (console)
console.log("PASS");
else {
var a = null;
return "FAIL";
}
};
}()());
}
expect: {
console.log(function() {
return function() {
var a;
if (!console)
return a = null, "FAIL";
console.log("PASS");
};
}()());
}
expect_stdout: [
"PASS",
"undefined",
]
}

View File

@@ -220,6 +220,32 @@ merge_vars_3: {
expect_stdout: true
}
merge_vars_4: {
options = {
merge_vars: true,
toplevel: true,
}
input: {
var a = 1;
console.log(typeof a);
{
var b = console;
console.log(typeof b);
const a = 0;
}
}
expect: {
var a = 1;
console.log(typeof a);
{
var b = console;
console.log(typeof b);
const a = 0;
}
}
expect_stdout: true
}
use_before_init_1: {
options = {
reduce_vars: true,
@@ -486,7 +512,7 @@ do_continue: {
catch_ie8_1: {
options = {
ie8: true,
ie: true,
unused: true,
}
input: {
@@ -506,7 +532,7 @@ catch_ie8_1: {
catch_ie8_2: {
options = {
dead_code: true,
ie8: true,
ie: true,
passes: 2,
toplevel: true,
unused: true,
@@ -727,7 +753,7 @@ issue_4193: {
issue_4195: {
mangle = {
ie8: true,
ie: true,
}
input: {
console.log(function f(a) {
@@ -838,12 +864,10 @@ issue_4202: {
expect: {
{
const o = {};
(function() {
function f() {
o.p = 42;
}
f(f);
})();
console.log(o.p++);
}
}
@@ -1131,7 +1155,7 @@ issue_4225: {
issue_4229: {
options = {
ie8: true,
ie: true,
side_effects: true,
}
input: {
@@ -1151,7 +1175,7 @@ issue_4229: {
issue_4231: {
options = {
ie8: true,
ie: true,
side_effects: true,
}
input: {
@@ -1219,9 +1243,9 @@ issue_4248: {
expect_stdout: "PASS"
}
issue_4261: {
issue_4261_1: {
options = {
inline: true,
inline: 3,
reduce_funcs: true,
reduce_vars: true,
toplevel: true,
@@ -1259,6 +1283,43 @@ issue_4261: {
expect_stdout: "42"
}
issue_4261_2: {
options = {
if_return: true,
inline: true,
reduce_funcs: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
{
const a = 42;
(function() {
function f() {
console.log(a);
}
function g() {
while (f());
}
(function() {
while (g());
})();
})();
}
}
expect: {
{
const a = 42;
function g() {
while (void console.log(a));
}
while (g());
}
}
expect_stdout: "42"
}
issue_4274_1: {
options = {
loops: true,
@@ -1692,3 +1753,63 @@ issue_4965_2: {
expect_stdout: "undefined"
node_version: ">=4"
}
issue_5254: {
options = {
inline: true,
toplevel: true,
}
input: {
do {
(function() {
const a = console.log;
a && a("foo");
})();
} while (console.log("bar"));
}
expect: {
do {
const a = console.log;
a && a("foo");
} while (console.log("bar"));
}
expect_stdout: [
"foo",
"bar",
]
}
issue_5260: {
options = {
collapse_vars: true,
}
input: {
"use strict";
var a = "foo", o;
while (console.log("bar"));
o = {
baz: function(b) {
console.log(a, b);
},
};
for (const a in o)
o[a](a);
}
expect: {
"use strict";
var a = "foo", o;
while (console.log("bar"));
o = {
baz: function(b) {
console.log(a, b);
},
};
for (const a in o)
o[a](a);
}
expect_stdout: [
"bar",
"foo baz",
]
node_version: ">=4"
}

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;
}));
@@ -158,6 +158,28 @@ process_boolean_returns: {
node_version: ">=6"
}
collapse_arg_sequence: {
options = {
collapse_vars: true,
unused: true,
}
input: {
(function(a = (console.log("bar"), console.log)) {
a("foo");
})();
}
expect: {
(function(a = console.log("bar")) {
(0, console.log)("foo");
})();
}
expect_stdout: [
"bar",
"foo",
]
node_version: ">=6"
}
collapse_value_1: {
options = {
collapse_vars: true,
@@ -245,21 +267,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 +487,9 @@ inline_loop_1: {
inline_loop_2: {
options = {
inline: true,
sequences: true,
toplevel: true,
unused: true,
}
input: {
while (function(a = [ "PASS" ]) {
@@ -432,10 +499,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 +590,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,
@@ -673,7 +755,7 @@ unused_value_var_2: {
console.log(a);
}
expect: {
var [ a ] = [ "PASS" ];
var a = [ "PASS" ][0];
console.log(a);
}
expect_stdout: "PASS"
@@ -977,7 +1059,7 @@ mangle_arrow_1: {
});
}
expect_stdout: "PASS"
node_version: ">=6"
node_version: ">=6.9.3"
}
mangle_arrow_1_toplevel: {
@@ -1013,7 +1095,7 @@ mangle_arrow_1_toplevel: {
});
}
expect_stdout: "PASS"
node_version: ">=6"
node_version: ">=6.9.3"
}
mangle_arrow_2: {
@@ -1049,7 +1131,7 @@ mangle_arrow_2: {
});
}
expect_stdout: "PASS"
node_version: ">=6"
node_version: ">=6.9.3"
}
mangle_arrow_2_toplevel: {
@@ -1085,7 +1167,7 @@ mangle_arrow_2_toplevel: {
});
}
expect_stdout: "PASS"
node_version: ">=6"
node_version: ">=6.9.3"
}
issue_4444: {
@@ -1254,7 +1336,7 @@ issue_4468: {
expect: {
(function() {
var {
[console.log("PASS")]: b = 0,
[console.log("PASS")]: b,
} = 0;
})();
}
@@ -1413,6 +1495,7 @@ issue_4502_1: {
expect: {
(function() {
var a = "PASS";
void 0,
console.log(a),
a++,
void 0;
@@ -1436,6 +1519,7 @@ issue_4502_2: {
expect: {
(function() {
var a = "PASS";
void 0,
console.log(a),
a++,
void 0;
@@ -1525,7 +1609,7 @@ issue_4510_2: {
};
}
expect_stdout: "PASS"
node_version: ">=8"
node_version: ">=8.3.0"
}
issue_4523: {
@@ -1661,7 +1745,7 @@ issue_4588_2_evaluate: {
issue_4817: {
options = {
ie8: true,
ie: true,
inline: true,
unused: true,
}
@@ -1695,7 +1779,7 @@ issue_4854: {
}());
}
expect: {
console.log(void ([] = "foo"));
console.log(void 0);
}
expect_stdout: "undefined"
node_version: ">=6"
@@ -1726,3 +1810,274 @@ 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: 3,
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_5057_4: {
options = {
if_return: true,
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) {
var b = "FAIL 2";
(function(a = console.log("FAIL 1")) {})(b);
console.log(a);
})("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"
}
issue_5246_1: {
options = {
pure_getters: true,
unused: true,
}
input: {
console.log(function({} = 42) {
return "PASS";
}("foo"));
}
expect: {
console.log(function({} = 0) {
return "PASS";
}("foo"));
}
expect_stdout: "PASS"
expect_warnings: [
"INFO: Dropping unused default argument value {}=42 [test/compress/default-values.js:1,29]",
"INFO: Dropping unused default argument value {}=0 [test/compress/default-values.js:1,29]",
]
node_version: ">=6"
}
issue_5246_2: {
options = {
unused: true,
}
input: {
(function f(a = "FAIL", [] = 42) {
console.log(a);
})("PASS", []);
}
expect: {
(function(a = "FAIL", []) {
console.log(a);
})("PASS", []);
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5246_3: {
options = {
default_values: true,
unused: true,
}
input: {
console.log(function f([ , {} ] = null){}([ , {} ]));
}
expect: {
console.log(function([ {} ]){}([ {} ]));
}
expect_stdout: "undefined"
node_version: ">=6"
}
issue_5256: {
options = {
inline: true,
}
input: {
(function(arguments = console.log) {
console;
})();
console.log(typeof arguments);
}
expect: {
// Syntax error on Node.js v6
(function(arguments = console.log) {
console;
})();
console.log(typeof arguments);
}
expect_stdout: "undefined"
node_version: ">=8"
}

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: {
@@ -395,7 +395,8 @@ funarg_unused_6_keep_fargs: {
}
expect: {
(function() {
var {} = (console, 42);
console;
var {} = 42;
})();
console.log(typeof a);
}
@@ -1105,7 +1106,7 @@ drop_unused_1: {
try {
throw 42;
} catch (a) {
var [ a ] = [];
var a = [][0];
}
}
}
@@ -1138,6 +1139,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,
@@ -1412,6 +1582,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,
@@ -1606,13 +1845,13 @@ issue_4294: {
expect: {
A = "PASS";
(function() {
var b = function({
[b]: {},
var a = function({
[a]: {},
}) {}({
[b]: 0,
[a]: 0,
});
var b = A;
console.log(b);
var a = A;
console.log(a);
})();
}
expect_stdout: "PASS"
@@ -1831,7 +2070,7 @@ issue_4319: {
issue_4321: {
options = {
inline: true,
inline: 3,
keep_fargs: false,
}
input: {
@@ -1860,7 +2099,7 @@ issue_4321: {
issue_4323: {
options = {
ie8: true,
ie: true,
inline: true,
merge_vars: true,
reduce_vars: true,
@@ -1958,7 +2197,7 @@ issue_4372_2: {
}
expect: {
var a;
[ a ] = [ "PASS", "FAIL" ];
[ a ] = a = [ "PASS", "FAIL" ];
console.log(a);
}
expect_stdout: "PASS"
@@ -2592,3 +2831,598 @@ 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"
}
issue_5222: {
options = {
hoist_props: true,
inline: true,
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
function f() {
do {
(function() {
var a = {
p: [ a ] = [],
};
})();
} while (console.log("PASS"));
}
f();
}
expect: {
do {
a = void 0,
a = {
p: [ a ] = [],
};
} while (console.log("PASS"));
var a;
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5288: {
options = {
conditionals: true,
inline: true,
reduce_vars: true,
toplevel: true,
unused: true,
varify: true,
}
input: {
while (function([]) {}([ function f() {
if (console)
return console.log("PASS");
else {
let a = 0;
}
}() ]));
}
expect: {
while ([ [ console ? console.log("PASS") : 0 ] ], void 0);
}
expect_stdout: "PASS"
node_version: ">=6"
}

View File

@@ -1233,8 +1233,11 @@ issue_2105_2: {
issue_2105_3: {
options = {
inline: true,
passes: 2,
join_vars: true,
passes: 3,
reduce_vars: true,
side_effects: true,
sequences: true,
unused: true,
}
input: {
@@ -1258,12 +1261,12 @@ issue_2105_3: {
});
}
expect: {
!void void {
({
prop: function() {
console.log;
void console.log("PASS");
}
}.prop();
console.log,
console.log("PASS");
},
}).prop();
}
expect_stdout: "PASS"
}
@@ -1557,9 +1560,9 @@ issue_2665: {
}
expect: {
var a = 1;
!function g() {
(function g() {
a-- && g();
}();
})();
console.log(a);
}
expect_stdout: "-1"
@@ -1728,7 +1731,8 @@ issue_2768: {
}
expect: {
var a = "FAIL";
var c = (d = a, void (d && (a = "PASS")));
d = a;
var c = void (d && (a = "PASS"));
var d;
console.log(a, typeof c);
}
@@ -1765,7 +1769,7 @@ issue_2846: {
issue_805_1: {
options = {
inline: true,
passes: 2,
passes: 3,
pure_getters: "strict",
reduce_vars: true,
sequences: true,
@@ -1798,7 +1802,7 @@ issue_805_1: {
issue_805_2: {
options = {
inline: true,
passes: 2,
passes: 3,
pure_getters: "strict",
reduce_vars: true,
sequences: true,
@@ -2345,7 +2349,7 @@ function_argument_reference: {
function_parameter_ie8: {
options = {
ie8: true,
ie: true,
reduce_vars: true,
unused: true,
}
@@ -2382,7 +2386,8 @@ issue_3664: {
}
expect: {
console.log(function() {
var a, b = (a = (a = [ b && console.log("FAIL") ]).p = 0, 0);
a = (a = [ b && console.log("FAIL") ]).p = 0;
var a, b = 0;
return "PASS";
}());
}
@@ -2551,10 +2556,9 @@ issue_3899: {
console.log(typeof a);
}
expect: {
function a() {
console.log(typeof function() {
return 2;
}
console.log(typeof a);
});
}
expect_stdout: "function"
}
@@ -2916,7 +2920,7 @@ issue_4133: {
console.log(a);
}
expect: {
var b = 1;
var a = 1;
console.log(0);
}
expect_stdout: "0"
@@ -3062,7 +3066,7 @@ issue_4184: {
expect_stdout: "42"
}
issue_4235: {
issue_4235_1: {
options = {
inline: true,
reduce_vars: true,
@@ -3087,6 +3091,31 @@ issue_4235: {
expect_stdout: "undefined"
}
issue_4235_2: {
options = {
inline: true,
passes: 2,
reduce_vars: true,
side_effects: true,
unused: true,
varify: true,
}
input: {
(function() {
{
const f = 0;
}
(function f() {
var f = console.log(f);
})();
})();
}
expect: {
console.log(void 0);
}
expect_stdout: "undefined"
}
issue_4404: {
options = {
pure_getters: "strict",
@@ -3229,7 +3258,7 @@ issue_4558_1: {
issue_4558_2: {
options = {
evaluate: true,
ie8: true,
ie: true,
reduce_vars: true,
unused: true,
}
@@ -3378,7 +3407,7 @@ issue_4834: {
}
expect: {
try {
void b.p;
b.p;
} catch (e) {
console.log("PASS");
}
@@ -3468,3 +3497,96 @@ 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"
}
issue_5224: {
options = {
evaluate: true,
keep_fargs: false,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
function f() {
try {
var b = function() {
var a = "FAIL 1";
null && a;
a = console.log(a);
}(new function(c, d) {
console.log(d);
a;
}("FAIL 2", Infinity));
} finally {
return f;
}
}
f();
}
expect: {
(function f() {
try {
(function() {
var a = "FAIL 1";
null;
a = console.log(a);
})(function() {
console.log(1 / 0);
a;
}());
} finally {
return f;
}
})();
}
expect_stdout: "Infinity"
}
issue_5271: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
function f() {
do {
var a = b = 0 ^ f, b = b;
} while (console.log(42 - b));
}
f();
}
expect: {
(function f() {
do {
var b;
b = 0 ^ f;
} while (console.log(42 - b));
})();
}
expect_stdout: "42"
}

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";
}
expect_stdout: true
console.log(({ valueOf: v }) < 1);
console.log(({ valueOf: v }) + "");
console.log((( {valueOf: v }) + "")[2]);
console.log(({ valueOf: v }).valueOf());
function t() {
return this.toString === t ? "PASS" : "FAIL";
}
console.log(({ toString: t }) < 1);
console.log(({ toString: t }) + "");
console.log((( {toString: t }) + "")[2]);
console.log(({ toString: t }).toString());
}
expect_stdout: [
"false",
"PASS",
"S",
"PASS",
"false",
"PASS",
"S",
"PASS",
]
}
call_args: {
@@ -2731,8 +2752,7 @@ issue_3944: {
}
expect: {
void function f() {
while (a = 0 == (a = void 0), console.log(a), void 0);
var a;
while (0 == void 0, console.log(false), void 0);
f;
}();
}
@@ -3182,7 +3202,7 @@ issue_4552: {
expect_stdout: "NaN"
}
issue_4886: {
issue_4886_1: {
options = {
evaluate: true,
unsafe: true,
@@ -3201,3 +3221,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,7 +99,7 @@ issue_4664: {
expect: {
(function f() {
new function(a) {
console.log(typeof f, 1073741824, typeof this);
console.log(typeof f, 2 ** 30, typeof this);
}(A = 0);
})();
}

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

File diff suppressed because it is too large Load Diff

View File

@@ -217,7 +217,8 @@ name_collision_1: {
var obj_foo = 1;
var obj_bar = 2;
function f() {
var obj_foo$0 = 3,
var obj,
obj_foo$0 = 3,
obj_bar = 4,
obj_b_r = 5,
obj_b_r$0 = 6,
@@ -249,7 +250,8 @@ name_collision_2: {
console.log(o.p === o.p, o["+"](4), o["-"](5), o__$0, o__$1);
}
expect: {
var o_p = 1,
var o,
o_p = 1,
o__ = function(x) {
return x;
},
@@ -283,7 +285,8 @@ name_collision_3: {
console.log(o.p === o.p, o["+"](4), o["-"](5));
}
expect: {
var o_p = 1,
var o,
o_p = 1,
o__ = function(x) {
return x;
},
@@ -315,7 +318,7 @@ name_collision_4: {
}
expect: {
console.log(function() {
var o_p$0 = 0, o_q = "PASS";
var o, o_p$0 = 0, o_q = "PASS";
return function(o_p) {
if (!o_p$0) return o_p;
}(o_q);
@@ -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 = console;
log = o.log;
o = function(a) {
console.log(a ? "PASS" : "FAIL");
return a;
};
log(o(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,
@@ -233,7 +282,7 @@ issue_4736: {
(function() {
(function() {
0,
console.log(1073741824);
console.log(1 << 30);
})();
})();
}
@@ -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(2 + 1 / 0);
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

@@ -545,7 +545,36 @@ if_body_return_3: {
]
}
issue_3600: {
issue_3600_1: {
options = {
if_return: true,
inline: 3,
side_effects: true,
unused: true,
}
input: {
var c = 0;
(function() {
if ([ ][c++]); else return;
return void function() {
var b = --b, a = c = 42;
return c;
}();
})();
console.log(c);
}
expect: {
var c = 0;
(function() {
if ([][c++]) b = --b, c = 42;
var b;
})();
console.log(c);
}
expect_stdout: "1"
}
issue_3600_2: {
options = {
if_return: true,
inline: true,
@@ -566,7 +595,9 @@ issue_3600: {
expect: {
var c = 0;
(function() {
if ([][c++]) b = --b, c = 42;
if ([][c++])
b = --b,
c = 42;
var b;
})();
console.log(c);

View File

@@ -94,13 +94,31 @@ 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);
}
}
drop_side_effect_free: {
options = {
imports: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
import foo from "bar";
var a = foo;
}
expect: {
import "bar";
}
}

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: {
@@ -356,6 +356,7 @@ mangle_catch_redef_3: {
try {
throw 0;
} catch (o) {
// prints "FAIL" if inlined on Node.js v4-
(function() {
function f() {
o = "FAIL";
@@ -366,12 +367,13 @@ mangle_catch_redef_3: {
console.log(o);
}
expect_exact: 'var o="PASS";try{throw 0}catch(o){(function(){function c(){o="FAIL"}c(),c()})()}console.log(o);'
expect_stdout: true
expect_stdout: "PASS"
node_version: ">=6"
}
mangle_catch_redef_3_toplevel: {
mangle = {
ie8: false,
ie: false,
toplevel: true,
}
input: {
@@ -379,6 +381,7 @@ mangle_catch_redef_3_toplevel: {
try {
throw 0;
} catch (o) {
// prints "FAIL" if inlined on Node.js v4-
(function() {
function f() {
o = "FAIL";
@@ -389,12 +392,13 @@ mangle_catch_redef_3_toplevel: {
console.log(o);
}
expect_exact: 'var c="PASS";try{throw 0}catch(c){(function(){function o(){c="FAIL"}o(),o()})()}console.log(c);'
expect_stdout: true
expect_stdout: "PASS"
node_version: ">=6"
}
mangle_catch_redef_3_ie8: {
mangle = {
ie8: true,
ie: true,
toplevel: false,
}
input: {
@@ -402,6 +406,7 @@ mangle_catch_redef_3_ie8: {
try {
throw 0;
} catch (o) {
// prints "FAIL" if inlined on Node.js v4-
(function() {
function f() {
o = "FAIL";
@@ -412,12 +417,13 @@ mangle_catch_redef_3_ie8: {
console.log(o);
}
expect_exact: 'var o="PASS";try{throw 0}catch(o){(function(){function c(){o="FAIL"}c(),c()})()}console.log(o);'
expect_stdout: true
expect_stdout: "PASS"
node_version: ">=6"
}
mangle_catch_redef_3_ie8_toplevel: {
mangle = {
ie8: true,
ie: true,
toplevel: true,
}
input: {
@@ -425,6 +431,7 @@ mangle_catch_redef_3_ie8_toplevel: {
try {
throw 0;
} catch (o) {
// prints "FAIL" if inlined on Node.js v4-
(function() {
function f() {
o = "FAIL";
@@ -435,5 +442,6 @@ mangle_catch_redef_3_ie8_toplevel: {
console.log(o);
}
expect_exact: 'var c="PASS";try{throw 0}catch(c){(function(){function o(){c="FAIL"}o(),o()})()}console.log(c);'
expect_stdout: true
expect_stdout: "PASS"
node_version: ">=6"
}

View File

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

View File

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

View File

@@ -489,6 +489,160 @@ join_object_assignments_regex: {
expect_stdout: "1"
}
chained_assignments: {
options = {
join_vars: true,
}
input: {
var a, b = a = {};
b.p = "PASS";
console.log(a.p);
}
expect: {
var a, b = a = {
p: "PASS",
};
console.log(a.p);
}
expect_stdout: "PASS"
}
folded_assignments_1: {
options = {
evaluate: true,
join_vars: true,
}
input: {
var a = {};
a[a.PASS = 42] = "PASS";
console.log(a[42], a.PASS);
}
expect: {
var a = {
PASS: 42,
42: "PASS",
};
console.log(a[42], a.PASS);
}
expect_stdout: "PASS 42"
}
folded_assignments_2: {
options = {
evaluate: true,
join_vars: true,
}
input: {
"use strict";
var a = {};
a[42] = "FAIL";
a[a.PASS = 42] = "PASS";
console.log(a[42], a.PASS);
}
expect: {
"use strict";
var a = {
42: "FAIL",
PASS: 42,
};
a[42] = "PASS";
console.log(a[42], a.PASS);
}
expect_stdout: "PASS 42"
}
inlined_assignments: {
options = {
join_vars: true,
unused: true,
}
input: {
var a;
(a = {}).p = "PASS";
console.log(a.p);
}
expect: {
var a = {
p: "PASS",
};
console.log(a.p);
}
expect_stdout: "PASS"
}
inilne_for: {
options = {
inline: true,
join_vars: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = function() {
for (; console.log("PASS"););
};
a();
}
expect: {
for (; console.log("PASS"););
}
expect_stdout: "PASS"
}
inilne_var: {
options = {
inline: true,
join_vars: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
A = "PASS";
var a = function() {
var b = A;
for (b in console.log(b));
};
a();
}
expect: {
A = "PASS";
var b = A;
for (b in console.log(b));
}
expect_stdout: "PASS"
}
typescript_enum: {
rename = true
options = {
assignments: true,
collapse_vars: true,
evaluate: true,
hoist_props: true,
inline: true,
join_vars: true,
passes: 4,
reduce_vars: true,
sequences: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var Enum;
(function (Enum) {
Enum[Enum.PASS = 42] = "PASS";
})(Enum || (Enum = {}));
console.log(Enum[42], Enum.PASS);
}
expect: {
console.log("PASS", 42);
}
expect_stdout: "PASS 42"
}
issue_2816: {
options = {
join_vars: true,
@@ -1015,7 +1169,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;
})();
@@ -1172,10 +1326,7 @@ assign_sequence_var: {
console.log(a, b, c);
}
expect: {
var a = 0, b = 1;
console.log(a),
a++;
var b = 2, c = 3;
var a = 0, b = 1, c = (console.log(a), a++, b = 2, 3);
console.log(a, b, c);
}
expect_stdout: [
@@ -1183,3 +1334,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

@@ -181,10 +181,10 @@ issue_2203_2: {
a: "FAIL",
b: function() {
return function() {
return (String, (Object, function() {
return (Object, function() {
return this;
}())).a;
}();
}()).a;
}(String);
}
}.b());
}
@@ -925,6 +925,28 @@ duplicate_lambda_defun_name_2: {
expect_stdout: "0"
}
function_argument_mangle: {
mangle = {
keep_fargs: true,
toplevel: true,
}
input: {
A = "PASS";
var a = A;
(function(o) {
console.log(a);
})("FAIL");
}
expect: {
A = "PASS";
var n = A;
(function(o) {
console.log(n);
})("FAIL");
}
expect_stdout: "PASS"
}
function_name_mangle: {
options = {
keep_fargs: false,
@@ -951,7 +973,7 @@ function_name_mangle_ie8: {
unused: true,
}
mangle = {
ie8: true,
ie: true,
toplevel: true,
}
input: {
@@ -1217,6 +1239,7 @@ issues_3267_1: {
evaluate: true,
inline: true,
keep_fargs: false,
negate_iife: true,
reduce_vars: true,
sequences: true,
side_effects: true,
@@ -1235,7 +1258,8 @@ issues_3267_1: {
}
expect: {
!function() {
if (Object())
var i = Object();
if (i)
return console.log("PASS");
throw "FAIL";
}();

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

@@ -1,4 +1,4 @@
retain_block: {
retain_block_1: {
options = {}
input: {
"use strict";
@@ -20,6 +20,94 @@ retain_block: {
node_version: ">=4"
}
retain_block_2: {
options = {
toplevel: true,
unused: true,
}
input: {
"use strict";
{
var a;
let a;
}
}
expect: {
"use strict";
{
var a;
let a;
}
}
expect_stdout: true
node_version: ">=4"
}
retain_block_2_mangle: {
rename = true
mangle = {
toplevel: true,
}
input: {
"use strict";
{
var a;
let a;
}
}
expect: {
"use strict";
{
var t;
let t;
}
}
}
retain_block_3: {
options = {
toplevel: true,
unused: true,
}
input: {
"use strict";
{
let a;
var a;
}
}
expect: {
"use strict";
{
let a;
var a;
}
}
expect_stdout: true
node_version: ">=4"
}
retain_block_3_mangle: {
rename = true
mangle = {
toplevel: true,
}
input: {
"use strict";
{
let a;
var a;
}
}
expect: {
"use strict";
{
let t;
var t;
}
}
}
retain_assignment: {
options = {
dead_code: true,
@@ -182,8 +270,8 @@ merge_vars_3: {
var b = console;
console.log(typeof b);
}
var a = 1;
console.log(typeof a);
var b = 1;
console.log(typeof b);
}
expect_stdout: [
"object",
@@ -192,6 +280,38 @@ merge_vars_3: {
node_version: ">=4"
}
merge_vars_4: {
options = {
merge_vars: true,
toplevel: true,
}
input: {
"use strict";
var a = 1;
console.log(typeof a);
{
var b = console;
console.log(typeof b);
let a = 0;
}
}
expect: {
"use strict";
var a = 1;
console.log(typeof a);
{
var b = console;
console.log(typeof b);
let a = 0;
}
}
expect_stdout: [
"number",
"object",
]
node_version: ">=4"
}
use_before_init_1: {
options = {
evaluate: true,
@@ -494,6 +614,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,
@@ -931,12 +1086,10 @@ issue_4202: {
"use strict";
{
let o = {};
(function() {
function f() {
o.p = 42;
}
f(f);
})();
console.log(o.p++);
}
}
@@ -1129,7 +1282,7 @@ issue_4225: {
issue_4229: {
options = {
ie8: true,
ie: true,
side_effects: true,
}
input: {
@@ -1160,7 +1313,7 @@ issue_4229: {
issue_4231: {
options = {
ie8: true,
ie: true,
side_effects: true,
}
input: {
@@ -1518,7 +1671,7 @@ issue_4438: {
;
else {
let a = console.log;
a("PASS");
void a("PASS");
}
}
f();
@@ -1529,7 +1682,7 @@ issue_4438: {
issue_4531_1: {
mangle = {
ie8: true,
ie: true,
toplevel: true,
}
input: {
@@ -1555,11 +1708,11 @@ issue_4531_1: {
issue_4531_2: {
options = {
evaluate: true,
ie8: true,
ie: true,
toplevel: true,
}
mangle = {
ie8: true,
ie: true,
toplevel: true,
}
input: {
@@ -1712,3 +1865,111 @@ issue_4985: {
expect_stdout: "undefined"
node_version: ">=4"
}
issue_5240: {
options = {
inline: true,
}
input: {
"use strict";
function f() {
if (console) {
let g = function() {
e;
}, e;
(function() {
if (console) {
console.log(e);
var e = "FAIL";
}
})(console.log(e));
}
}
f();
}
expect: {
"use strict";
function f() {
if (console) {
let g = function() {
e;
}, e;
(function() {
if (console) {
console.log(e);
var e = "FAIL";
}
})(console.log(e));
}
}
f();
}
expect_stdout: [
"undefined",
"undefined",
]
node_version: ">=4"
}
issue_5254: {
options = {
inline: true,
toplevel: true,
}
input: {
"use strict";
do {
(function() {
let a = console.log;
a && a("foo");
})();
} while (console.log("bar"));
}
expect: {
"use strict";
do {
let a = console.log;
a && a("foo");
} while (console.log("bar"));
}
expect_stdout: [
"foo",
"bar",
]
node_version: ">=4"
}
issue_5260: {
options = {
collapse_vars: true,
}
input: {
"use strict";
var a = "foo", o;
while (console.log("bar"));
o = {
baz: function(b) {
console.log(a, b);
},
};
for (let a in o)
o[a](a);
}
expect: {
"use strict";
var a = "foo", o;
while (console.log("bar"));
o = {
baz: function(b) {
console.log(a, b);
},
};
for (let a in o)
o[a](a);
}
expect_stdout: [
"bar",
"foo baz",
]
node_version: ">=4"
}

View File

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

@@ -19,11 +19,11 @@ merge: {
expect: {
var a = "foo";
console.log(a);
function f(c) {
var c;
console.log(c);
c = "bar";
console.log(c);
function f(b) {
var b;
console.log(b);
b = "bar";
console.log(b);
}
f("baz");
var d = "moo";
@@ -56,17 +56,17 @@ merge_toplevel: {
console.log(d);
}
expect: {
var d = "foo";
console.log(d);
function f(c) {
var c;
console.log(c);
c = "bar";
console.log(c);
var a = "foo";
console.log(a);
function f(b) {
var b;
console.log(b);
b = "bar";
console.log(b);
}
f("baz");
var d = "moo";
console.log(d);
var a = "moo";
console.log(a);
}
expect_stdout: [
"foo",
@@ -94,16 +94,16 @@ segment: {
console.log(d);
}
expect: {
var d = "foo";
console.log(d);
for (var c, i = 0; i < 1; i++) {
var c = "bar";
console.log(c);
c = "baz";
console.log(c);
var a = "foo";
console.log(a);
for (var b, i = 0; i < 1; i++) {
var b = "bar";
console.log(b);
b = "baz";
console.log(b);
}
var d = "moo";
console.log(d);
var a = "moo";
console.log(a);
}
expect_stdout: [
"foo",
@@ -298,6 +298,89 @@ read_before_assign_2: {
expect_stdout: "PASS"
}
collapse_vars_1: {
options = {
collapse_vars: true,
merge_vars: true,
toplevel: true,
}
input: {
var a = a && a.p;
var b = "PASS";
var b = b && console.log(b);
}
expect: {
var a = a && a.p;
var a;
var a = (a = "PASS") && console.log(a);
}
expect_stdout: "PASS"
}
collapse_vars_2: {
options = {
collapse_vars: true,
merge_vars: true,
}
input: {
"use strict";
var log = console.log;
(function g(a) {
var b = a;
var c = Math.random();
var c = b;
log(c);
return c;
})("PASS");
}
expect: {
"use strict";
var log = console.log;
(function g(a) {
var a = a;
var c = Math.random();
var c;
log(c = a);
return c;
})("PASS");
}
expect_stdout: "PASS"
}
not_redefined: {
options = {
inline: true,
join_vars: true,
merge_vars: true,
reduce_vars: true,
unused: true,
varify: true,
}
input: {
var log = console.log;
(function() {
return f("PASS");
function f(a) {
const b = a;
const c = log(b);
const d = log;
c && log(d);
}
})();
}
expect: {
var log = console.log;
(function() {
return a = "PASS",
a = log(a),
d = log,
void (a && log(d));
var a, d;
})();
}
expect_stdout: "PASS"
}
issue_4103: {
options = {
merge_vars: true,
@@ -325,7 +408,7 @@ issue_4103: {
]
}
issue_4107: {
issue_4107_1: {
options = {
keep_fargs: false,
merge_vars: true,
@@ -342,6 +425,38 @@ issue_4107: {
})();
console.log(typeof a);
}
expect: {
(function() {
(function(c) {
c = console || c;
console.log(typeof c);
})();
})();
console.log(typeof a);
}
expect_stdout: [
"object",
"undefined",
]
}
issue_4107_2: {
options = {
keep_fargs: false,
merge_vars: true,
reduce_vars: true,
unused: true,
}
input: {
(function() {
function f(b, b, a) {
var d = 1 && c, c = console || a;
console.log(typeof c);
}
f();
})();
console.log(typeof a);
}
expect: {
(function() {
(function(a) {
@@ -359,7 +474,7 @@ issue_4107: {
issue_4109: {
options = {
ie8: true,
ie: true,
merge_vars: true,
toplevel: true,
}
@@ -476,9 +591,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;
}
@@ -538,12 +653,12 @@ cross_branch_1_1: {
expect: {
var a;
function f() {
var y, y;
var x, x;
if (a)
y = "foo";
console.log(y);
y = "bar";
console.log(y);
x = "foo";
console.log(x);
x = "bar";
console.log(x);
}
a = 0;
f();
@@ -581,13 +696,13 @@ cross_branch_1_2: {
expect: {
var a;
function f() {
var y, y;
var x, x;
if (a) {
y = "foo";
console.log(y);
x = "foo";
console.log(x);
}
y = "bar";
console.log(y);
x = "bar";
console.log(x);
}
a = 0;
f();
@@ -624,13 +739,13 @@ cross_branch_1_3: {
expect: {
var a;
function f() {
var y, y;
var x, x;
if (a) {
y = "foo";
console.log(y);
y = "bar";
x = "foo";
console.log(x);
x = "bar";
}
console.log(y);
console.log(x);
}
a = 0;
f();
@@ -666,12 +781,12 @@ cross_branch_1_4: {
expect: {
var a;
function f() {
var y, y;
y = "foo";
var x, x;
x = "foo";
if (a)
console.log(y);
y = "bar";
console.log(y);
console.log(x);
x = "bar";
console.log(x);
}
a = 0;
f();
@@ -751,12 +866,12 @@ cross_branch_1_6: {
expect: {
var a;
function f() {
var y, y;
y = "foo";
var x, x;
x = "foo";
if (a) {
console.log(y);
y = "bar";
console.log(y);
console.log(x);
x = "bar";
console.log(x);
}
}
a = 0;
@@ -835,12 +950,12 @@ cross_branch_1_8: {
expect: {
var a;
function f() {
var y, y;
y = "foo";
console.log(y);
var x, x;
x = "foo";
console.log(x);
if (a) {
y = "bar";
console.log(y);
x = "bar";
console.log(x);
}
}
a = 0;
@@ -877,12 +992,12 @@ cross_branch_1_9: {
expect: {
var a;
function f() {
var y, y;
y = "foo";
console.log(y);
y = "bar";
var x, x;
x = "foo";
console.log(x);
x = "bar";
if (a)
console.log(y);
console.log(x);
}
a = 0;
f();
@@ -924,14 +1039,14 @@ cross_branch_2a_1: {
expect: {
var a, b;
function f() {
var y, y;
var x, x;
if (a) {
if (b)
y = "foo";
console.log(y);
x = "foo";
console.log(x);
}
y = "bar";
console.log(y);
x = "bar";
console.log(x);
}
a = 0, b = 0;
f();
@@ -980,14 +1095,14 @@ cross_branch_2a_2: {
expect: {
var a, b;
function f() {
var y, y;
var x, x;
if (a) {
y = "foo";
x = "foo";
if (b)
console.log(y);
console.log(x);
}
y = "bar";
console.log(y);
x = "bar";
console.log(x);
}
a = 0, b = 0;
f();
@@ -1035,14 +1150,14 @@ cross_branch_2a_3: {
expect: {
var a, b;
function f() {
var y, y;
var x, x;
if (a) {
if (b)
y = "foo";
console.log(y);
y = "bar";
x = "foo";
console.log(x);
x = "bar";
}
console.log(y);
console.log(x);
}
a = 0, b = 0;
f();
@@ -1092,15 +1207,15 @@ cross_branch_2a_4: {
expect: {
var a, b;
function f() {
var y, y;
var x, x;
if (a) {
if (b) {
y = "foo";
console.log(y);
x = "foo";
console.log(x);
}
y = "bar";
x = "bar";
}
console.log(y);
console.log(x);
}
a = 0, b = 0;
f();
@@ -1148,14 +1263,14 @@ cross_branch_2a_5: {
expect: {
var a, b;
function f() {
var y, y;
var x, x;
if (a) {
y = "foo";
x = "foo";
if (b)
console.log(y);
y = "bar";
console.log(x);
x = "bar";
}
console.log(y);
console.log(x);
}
a = 0, b = 0;
f();
@@ -1427,13 +1542,13 @@ cross_branch_2a_10: {
expect: {
var a, b;
function f() {
var y, y;
y = "foo";
var x, x;
x = "foo";
if (a) {
if (b)
console.log(y);
y = "bar";
console.log(y);
console.log(x);
x = "bar";
console.log(x);
}
}
a = 0, b = 0;
@@ -1590,13 +1705,13 @@ cross_branch_2a_13: {
expect: {
var a, b;
function f() {
var y, y;
y = "foo";
var x, x;
x = "foo";
if (a) {
console.log(y);
console.log(x);
if (b) {
y = "bar";
console.log(y);
x = "bar";
console.log(x);
}
}
}
@@ -1644,13 +1759,13 @@ cross_branch_2a_14: {
expect: {
var a, b;
function f() {
var y, y;
y = "foo";
var x, x;
x = "foo";
if (a) {
console.log(y);
y = "bar";
console.log(x);
x = "bar";
if (b)
console.log(y);
console.log(x);
}
}
a = 0, b = 0;
@@ -1753,13 +1868,13 @@ cross_branch_2a_16: {
expect: {
var a, b;
function f() {
var y, y;
y = "foo";
console.log(y);
var x, x;
x = "foo";
console.log(x);
if (a) {
y = "bar";
x = "bar";
if (b)
console.log(y);
console.log(x);
}
}
a = 0, b = 0;
@@ -1807,13 +1922,13 @@ cross_branch_2b_1: {
expect: {
var a, b;
function f() {
var y, y;
var x, x;
if (a)
y = "foo";
x = "foo";
if (b)
console.log(y);
y = "bar";
console.log(y);
console.log(x);
x = "bar";
console.log(x);
}
a = 0, b = 0;
f();
@@ -1918,13 +2033,13 @@ cross_branch_2b_3: {
expect: {
var a, b;
function f() {
var y, y;
var x, x;
if (a)
y = "foo";
x = "foo";
if (b) {
console.log(y);
y = "bar";
console.log(y);
console.log(x);
x = "bar";
console.log(x);
}
}
a = 0, b = 0;
@@ -2028,13 +2143,13 @@ cross_branch_2b_5: {
expect: {
var a, b;
function f() {
var y, y;
var x, x;
if (a)
y = "foo";
console.log(y);
x = "foo";
console.log(x);
if (b) {
y = "bar";
console.log(y);
x = "bar";
console.log(x);
}
}
a = 0, b = 0;
@@ -2141,14 +2256,14 @@ cross_branch_2b_7: {
expect: {
var a, b;
function f() {
var y, y;
var x, x;
if (a) {
y = "foo";
console.log(y);
x = "foo";
console.log(x);
}
if (b) {
y = "bar";
console.log(y);
x = "bar";
console.log(x);
}
}
a = 0, b = 0;
@@ -2195,13 +2310,13 @@ cross_branch_2b_8: {
expect: {
var a, b;
function f() {
var y, y;
var x, x;
if (a)
y = "foo";
console.log(y);
y = "bar";
x = "foo";
console.log(x);
x = "bar";
if (b)
console.log(y);
console.log(x);
}
a = 0, b = 0;
f();
@@ -2250,14 +2365,14 @@ cross_branch_2b_9: {
expect: {
var a, b;
function f() {
var y, y;
var x, x;
if (a) {
y = "foo";
console.log(y);
x = "foo";
console.log(x);
}
y = "bar";
x = "bar";
if (b)
console.log(y);
console.log(x);
}
a = 0, b = 0;
f();
@@ -2304,14 +2419,14 @@ cross_branch_2b_10: {
expect: {
var a, b;
function f() {
var y, y;
var x, x;
if (a) {
y = "foo";
console.log(y);
y = "bar";
x = "foo";
console.log(x);
x = "bar";
}
if (b)
console.log(y);
console.log(x);
}
a = 0, b = 0;
f();
@@ -2412,13 +2527,13 @@ cross_branch_2b_12: {
expect: {
var a, b;
function f() {
var y, y;
y = "foo";
var x, x;
x = "foo";
if (a)
console.log(y);
console.log(x);
if (b) {
y = "bar";
console.log(y);
x = "bar";
console.log(x);
}
}
a = 0, b = 0;
@@ -2465,13 +2580,13 @@ cross_branch_2b_13: {
expect: {
var a, b;
function f() {
var y, y;
y = "foo";
var x, x;
x = "foo";
if (a)
console.log(y);
y = "bar";
console.log(x);
x = "bar";
if (b)
console.log(y);
console.log(x);
}
a = 0, b = 0;
f();
@@ -2620,11 +2735,11 @@ issue_4126_1: {
try {
console.log("PASS");
} catch (e) {
var c = a;
var b = a;
} finally {
var c = c;
var a = b;
}
console.log(c);
console.log(a);
}
f("FAIL");
}
@@ -2735,8 +2850,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"
@@ -2817,11 +2931,11 @@ conditional_write: {
console.log(b);
}
expect: {
var b = "FAIL", b;
var a = "FAIL", a;
if (console)
b = "PASS";
b = [b, 42].join();
console.log(b);
a = "PASS";
a = [a, 42].join();
console.log(a);
}
expect_stdout: "PASS,42"
}
@@ -2995,13 +3109,13 @@ issue_4168_use_strict: {
expect: {
"use strict";
var o = {
f: function(d, e, f) {
var d = d.d;
var e = e.e;
var f = f.f;
f: function(a, b, c) {
var a = a.d;
var b = b.e;
var c = c.f;
this.g(arguments);
if (d)
console.log(e, f);
if (a)
console.log(b, c);
},
g: function(args) {
console.log(args[0], args[1], args[2]);
@@ -3075,7 +3189,7 @@ issue_4237_2: {
console.log(function(a) {
do {
switch (0) {
case 0:
default:
var b = a++;
if (b)
return "FAIL";
@@ -3229,10 +3343,10 @@ issue_4653: {
f(a++ + (b = b), b |= console.log(a));
}
expect: {
var b = 1;
var b, a = 1;
(function(c, d) {
c || console.log(d);
})(+b + (b = void 0), b |= console.log(2));
})(+a + (b = b), b |= console.log(2));
}
expect_stdout: [
"2",
@@ -3378,3 +3492,60 @@ issue_4956_2: {
}
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

@@ -389,6 +389,7 @@ issue_1288_side_effects: {
options = {
conditionals: true,
negate_iife: true,
sequences: true,
side_effects: true,
}
input: {
@@ -409,10 +410,10 @@ issue_1288_side_effects: {
})(0);
}
expect: {
w;
w,
x || function() {
x = {};
}();
}(),
y;
}
}

View File

@@ -110,10 +110,186 @@ 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"
}
inline_binary_nullish: {
options = {
inline: true,
}
input: {
(function() {
while (console.log("foo"));
})() ?? (function() {
while (console.log("bar"));
})();
}
expect: {
if (null == function() {
while (console.log("foo"));
}())
while (console.log("bar"));
}
expect_stdout: [
"foo",
"bar",
]
node_version: ">=14"
}
issue_4679: {
options = {
comparisons: true,
ie8: true,
ie: true,
}
input: {
var a;
@@ -128,3 +304,42 @@ issue_4679: {
expect_stdout: "PASS"
node_version: ">=14"
}
issue_5266: {
options = {
inline: true,
}
input: {
[
42,
null,
false,
void 0,
"FAIL",
].forEach(function (a) {
a ?? function() {
while (console.log(a));
}();
});
}
expect: {
[
42,
null,
false,
void 0,
"FAIL",
].forEach(function (a) {
if (null == a) {
while (console.log(a));
return;
} else
return;
});
}
expect_stdout: [
"null",
"undefined",
]
node_version: ">=14"
}

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

@@ -58,7 +58,7 @@ assign_parentheses_dot: {
input: {
(console?.log).name.p = console.log("PASS");
}
expect_exact: '(console?.log.name).p=console.log("PASS");'
expect_exact: '(console?.log).name.p=console.log("PASS");'
expect_stdout: "PASS"
node_version: ">=14"
}
@@ -72,6 +72,26 @@ assign_no_parentheses: {
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 };
@@ -237,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,
@@ -248,7 +361,9 @@ issue_4906: {
} while (console.log("PASS"));
}
expect: {
do {} while (console.log("PASS"));
do {
var a = a?.[42];
} while (console.log("PASS"));
}
expect_stdout: "PASS"
node_version: ">=14"
@@ -256,7 +371,7 @@ issue_4906: {
issue_4928: {
options = {
ie8: true,
ie: true,
toplevel: true,
unused: true,
}
@@ -305,3 +420,200 @@ issue_4947_2: {
expect_stdout: "PASS"
node_version: ">=14"
}
issue_5039: {
options = {
ie: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var a = a?.[function f() {
f;
a;
}];
console.log("PASS");
}
expect: {
var a = a?.[function f() {}];
console.log("PASS");
}
expect_stdout: "PASS"
node_version: ">=14"
}
issue_5091: {
options = {
merge_vars: true,
}
input: {
function f(a) {
var b = a.p;
var c;
b?.[c = "FAIL 2"];
return b || c;
}
console.log(f("FAIL 1") || "PASS");
}
expect: {
function f(a) {
var a = a.p;
var c;
a?.[c = "FAIL 2"];
return a || c;
}
console.log(f("FAIL 1") || "PASS");
}
expect_stdout: "PASS"
node_version: ">=14"
}
issue_5292_dot: {
options = {
side_effects: true,
}
input: {
var o = {
get p() {
console.log("PASS");
}
};
o?.p;
}
expect: {
var o = {
get p() {
console.log("PASS");
}
};
o?.p;
}
expect_stdout: "PASS"
node_version: ">=14"
}
issue_5292_dot_pure_getters: {
options = {
pure_getters: true,
side_effects: true,
}
input: {
var o = {
get p() {
console.log("PASS");
}
};
o?.p;
}
expect: {
var o = {
get p() {
console.log("PASS");
}
};
}
}
issue_5292_dot_pure_getters_strict: {
options = {
pure_getters: "strict",
side_effects: true,
}
input: {
var o = {
get p() {
console.log("PASS");
}
};
o?.p;
}
expect: {
var o = {
get p() {
console.log("PASS");
}
};
o?.p;
}
expect_stdout: "PASS"
node_version: ">=14"
}
issue_5292_sub: {
options = {
side_effects: true,
}
input: {
var o = {
get p() {
console.log("foo");
}
};
o?.[console.log("bar"), "p"];
}
expect: {
var o = {
get p() {
console.log("foo");
}
};
o?.[console.log("bar"), "p"];
}
expect_stdout: [
"bar",
"foo",
]
node_version: ">=14"
}
issue_5292_sub_pure_getters: {
options = {
pure_getters: true,
side_effects: true,
}
input: {
var o = {
get p() {
console.log("foo");
}
};
o?.[console.log("bar"), "p"];
}
expect: {
var o = {
get p() {
console.log("foo");
}
};
console.log("bar");
}
}
issue_5292_sub_pure_getters_strict: {
options = {
pure_getters: "strict",
side_effects: true,
}
input: {
var o = {
get p() {
console.log("foo");
}
};
o?.[console.log("bar"), "p"];
}
expect: {
var o = {
get p() {
console.log("foo");
}
};
o?.[console.log("bar"), "p"];
}
expect_stdout: [
"bar",
"foo",
]
node_version: ">=14"
}

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",
@@ -1362,9 +1363,8 @@ issue_3490_1: {
}
expect: {
var b = 42, c = "FAIL";
if (function() {
var a;
}(), c = "PASS", b) while ("" == typeof d);
if (c = "PASS", b) while ("" == typeof d);
console.log(c, b);
}
expect_stdout: "PASS 42"
@@ -1639,6 +1639,26 @@ 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",

View File

@@ -41,10 +41,8 @@ reduce_vars: {
}
expect: {
var A = 1;
(function() {
console.log(-3);
console.log(A - 5);
})();
(function f1() {
var a = 2;
console.log(a - 5);
@@ -905,7 +903,7 @@ use_before_var: {
}
expect: {
function f(){
console.log(void 0);
console.log(t);
var t = 1;
}
}
@@ -981,7 +979,7 @@ inner_var_for_1: {
expect: {
function f() {
var a = 1;
x(1, void 0, d);
x(1, b, d);
for (var b = 2, c = 3; x(1, 2, 3, d); x(1, 2, 3, d)) {
var d = 4, e = 5;
x(1, 2, 3, d, e);
@@ -1292,6 +1290,7 @@ toplevel_on_loops_3: {
loops: true,
reduce_funcs: true,
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
@@ -2071,72 +2070,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 +2101,7 @@ issue_1670_5: {
expect_stdout: "1"
}
issue_1670_6: {
issue_1670_4: {
options = {
conditionals: true,
dead_code: true,
@@ -3158,7 +3091,7 @@ accessor_1: {
a = 2;
return a;
},
b: 1
b: 1,
}.b, a);
}
expect: {
@@ -3168,7 +3101,7 @@ accessor_1: {
a = 2;
return a;
},
b: 1
b: 1,
}.b, a);
}
expect_stdout: "1 1"
@@ -3188,7 +3121,7 @@ accessor_2: {
var B = {
get c() {
console.log(A);
}
},
};
B.c;
}
@@ -3196,7 +3129,7 @@ accessor_2: {
({
get c() {
console.log(1);
}
},
}).c;
}
expect_stdout: "1"
@@ -3242,7 +3175,7 @@ obj_var_1: {
var obj = {
bar: function() {
return C + C;
}
},
};
console.log(obj.bar());
}
@@ -3250,7 +3183,7 @@ obj_var_1: {
console.log({
bar: function() {
return 2;
}
},
}.bar());
}
expect_stdout: "2"
@@ -3274,7 +3207,7 @@ obj_var_2: {
var obj = {
bar: function() {
return C + C;
}
},
};
console.log(obj.bar());
}
@@ -4488,6 +4421,7 @@ perf_2: {
perf_3: {
options = {
passes: 2,
reduce_funcs: true,
reduce_vars: true,
toplevel: true,
@@ -4496,10 +4430,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 +4462,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 +4474,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 +4566,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 +4598,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 +4611,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);
@@ -6735,6 +6669,7 @@ issues_3267_1: {
dead_code: true,
evaluate: true,
inline: true,
negate_iife: true,
reduce_vars: true,
sequences: true,
side_effects: true,
@@ -6752,8 +6687,9 @@ issues_3267_1: {
});
}
expect: {
!function(i) {
if (Object())
!function(x) {
var i = Object();
if (i)
return console.log("PASS");
throw "FAIL";
}();
@@ -6769,6 +6705,7 @@ issues_3267_2: {
evaluate: true,
inline: true,
keep_fargs: false,
negate_iife: true,
passes: 2,
reduce_vars: true,
sequences: true,
@@ -7384,6 +7321,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 +7494,7 @@ issue_4030: {
collapse_vars: true,
evaluate: true,
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
@@ -7742,3 +7738,97 @@ issue_4949: {
}
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: {
@@ -359,10 +359,10 @@ retain_funarg_destructured_object_2: {
expect: {
console.log(function({ p: a, ... b }) {
return b;
}({ p: "FAIL" }).p || "PASS");
}({}).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,
@@ -418,9 +436,9 @@ merge_funarg: {
})();
}
expect: {
(function(...b) {
var b = b.length;
console.log(b);
(function(...a) {
var a = a.length;
console.log(a);
})();
}
expect_stdout: "0"
@@ -438,9 +456,9 @@ merge_funarg_destructured_array: {
})([]);
}
expect: {
(function([ ...b ]) {
var b = b.length;
console.log(b);
(function([ ...a ]) {
var a = a.length;
console.log(a);
})([]);
}
expect_stdout: "0"
@@ -458,13 +476,13 @@ merge_funarg_destructured_object: {
})([ "PASS" ]);
}
expect: {
(function({ ...b }) {
var b = b[0];
console.log(b);
(function({ ...a }) {
var a = a[0];
console.log(a);
})([ "PASS" ]);
}
expect_stdout: "PASS"
node_version: ">=8"
node_version: ">=8.3.0"
}
keep_arguments: {
@@ -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,
@@ -682,9 +866,9 @@ issue_4575: {
}
expect: {
(function(a) {
(function a(...d) {
(function(d) {
console.log(d.length);
})();
})([]);
})();
}
expect_stdout: "0"
@@ -784,3 +968,299 @@ issue_4666: {
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";
}([]));
}
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"
}
issue_5246_1: {
options = {
reduce_vars: true,
rests: true,
unused: true,
}
input: {
console.log(typeof function([ , ...a ]) {
return this && a;
}([ , function(){} ])[0]);
}
expect: {
console.log(typeof function([]) {
return this && [ function(){} ];
}([])[0]);
}
expect_stdout: "function"
node_version: ">=6"
}
issue_5246_2: {
options = {
reduce_vars: true,
rests: true,
toplevel: true,
unused: true,
}
input: {
A = [ , "PASS", "FAIL" ];
var [ , ...a ] = [ ... A ];
console.log(a[0]);
}
expect: {
A = [ , "PASS", "FAIL" ];
var [ , ...a ] = [ ... A ];
console.log(a[0]);
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5246_3: {
options = {
unused: true,
}
input: {
(function f(...[ [ a ] ]) {
console.log(a);
})([ "PASS" ]);
}
expect: {
(function(...[ a ]) {
console.log(a);
})([ "PASS" ][0]);
}
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

@@ -774,7 +774,7 @@ side_effects_cascade_3: {
}
expect: {
function f(a, b) {
(b += a) || (b = a) || (b -= a, b ^= a),
(b += a) || (b = a) || (b = b - a ^ a),
a--;
}
}
@@ -910,9 +910,7 @@ hoist_decl: {
var d;
}
expect: {
var a;
w();
var b = x(), c, d;
var a, b = (w(), x()), c, d;
for (y(); 0;) z();
}
}
@@ -1162,10 +1160,8 @@ issue_3490_1: {
}
expect: {
var b = 42, c = "FAIL";
if (function() {
var a;
a && a.p;
}(), c = "PASS", b) while ("" == typeof d);
if (a && a.p, c = "PASS", b) while ("" == typeof d);
console.log(c, b);
}
expect_stdout: "PASS 42"
@@ -1195,9 +1191,8 @@ issue_3490_2: {
}
expect: {
var b = 42, c = "FAIL";
for (function() {
var a;
}(), c = "PASS", b; "" == typeof d;);
for (c = "PASS", b; "" == typeof d;);
console.log(c, b);
}
expect_stdout: "PASS 42"

View File

@@ -147,7 +147,7 @@ dont_inline: {
node_version: ">=6"
}
do_inline: {
do_inline_1: {
options = {
inline: true,
spreads: true,
@@ -164,6 +164,46 @@ do_inline: {
node_version: ">=6"
}
do_inline_2: {
options = {
inline: true,
side_effects: true,
}
input: {
(function() {
(function() {
console.log("PASS");
})(..."");
})();
}
expect: {
[] = [ ..."" ],
console.log("PASS");
}
expect_stdout: "PASS"
node_version: ">=6"
}
do_inline_3: {
options = {
if_return: true,
inline: true,
}
input: {
(function() {
(function() {
while (console.log("PASS"));
})(..."");
})();
}
expect: {
var [] = [ ..."" ];
while (console.log("PASS"));
}
expect_stdout: "PASS"
node_version: ">=6"
}
drop_empty_call_1: {
options = {
side_effects: true,
@@ -201,7 +241,29 @@ drop_empty_call_2: {
node_version: ">=6"
}
convert_hole: {
convert_hole_array: {
options = {
spreads: true,
}
input: {
[ ...[ "PASS", , 42 ] ].forEach(function(a) {
console.log(a);
});
}
expect: {
[ "PASS", void 0, 42 ].forEach(function(a) {
console.log(a);
});
}
expect_stdout: [
"PASS",
"undefined",
"42",
]
node_version: ">=6"
}
convert_hole_call: {
options = {
spreads: true,
}
@@ -341,7 +403,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 +432,7 @@ keep_getter_1: {
});
}
expect_stdout: "PASS"
node_version: ">=8"
node_version: ">=8.3.0"
}
keep_getter_2: {
@@ -399,7 +461,7 @@ keep_getter_2: {
"foo",
"bar",
]
node_version: ">=8"
node_version: ">=8.3.0"
}
keep_getter_3: {
@@ -429,7 +491,7 @@ keep_getter_3: {
});
}
expect_stdout: "PASS"
node_version: ">=8"
node_version: ">=8.3.0"
}
keep_getter_4: {
@@ -460,7 +522,7 @@ keep_getter_4: {
});
}
expect_stdout: "PASS"
node_version: ">=8"
node_version: ">=8.3.0"
}
keep_accessor: {
@@ -508,7 +570,7 @@ keep_accessor: {
"q undefined",
"r null",
]
node_version: ">=8"
node_version: ">=8.3.0"
}
object_key_order_1: {
@@ -538,7 +600,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 +630,7 @@ object_key_order_2: {
"a 3",
"b 2",
]
node_version: ">=8"
node_version: ">=8.3.0"
}
object_key_order_3: {
@@ -598,7 +660,7 @@ object_key_order_3: {
"a 3",
"b 2",
]
node_version: ">=8"
node_version: ">=8.3.0"
}
object_key_order_4: {
@@ -628,7 +690,7 @@ object_key_order_4: {
"a 3",
"b 2",
]
node_version: ">=8"
node_version: ">=8.3.0"
}
object_spread_array: {
@@ -654,7 +716,7 @@ object_spread_array: {
"0 foo",
"1 bar",
]
node_version: ">=8"
node_version: ">=8.3.0"
}
object_spread_string: {
@@ -681,7 +743,7 @@ object_spread_string: {
"1 o",
"2 o",
]
node_version: ">=8"
node_version: ">=8.3.0"
}
unused_var_side_effects: {
@@ -711,7 +773,7 @@ unused_var_side_effects: {
});
}
expect_stdout: "PASS"
node_version: ">=8"
node_version: ">=8.3.0"
}
unsafe_join_1: {
@@ -793,7 +855,7 @@ issue_4329: {
}[0]);
}
expect_stdout: "PASS"
node_version: ">=8"
node_version: ">=8.3.0"
}
issue_4331: {
@@ -871,7 +933,7 @@ issue_4345: {
}[42]);
}
expect_stdout: "PASS"
node_version: ">=8"
node_version: ">=8.3.0"
}
issue_4361: {
@@ -901,7 +963,7 @@ issue_4361: {
"foo",
"undefined",
]
node_version: ">=8"
node_version: ">=8.3.0"
}
issue_4363: {
@@ -922,7 +984,7 @@ issue_4363: {
});
}
expect_stdout: "PASS"
node_version: ">=8"
node_version: ">=8.3.0"
}
issue_4556: {
@@ -945,78 +1007,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 +1056,7 @@ issue_4849: {
}()));
}
expect_stdout: "object"
node_version: ">=8"
node_version: ">=8.3.0"
}
issue_4882_1: {
@@ -1098,7 +1088,7 @@ issue_4882_1: {
"PASS",
"undefined",
]
node_version: ">=8"
node_version: ">=8.3.0"
}
issue_4882_2: {
@@ -1124,7 +1114,7 @@ issue_4882_2: {
"42",
"PASS",
]
node_version: ">=8"
node_version: ">=8.3.0"
}
issue_4882_3: {
@@ -1154,5 +1144,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: {
@@ -357,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"
@@ -434,3 +534,238 @@ issue_4931: {
]
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

@@ -436,6 +436,245 @@ emberjs_global: {
expect_stdout: Error("PASS")
}
reassign: {
options = {
comparisons: true,
conditionals: true,
passes: 2,
typeofs: true,
}
input: {
A = console;
if ("undefined" == typeof A)
console.log("FAIL 1");
else {
A = void 0;
while (console.log(void 0 === A ? "PASS" : "FAIL 2"));
}
}
expect: {
A = console;
if ("undefined" == typeof A)
console.log("FAIL 1");
else {
A = void 0;
while (console.log(void 0 === A ? "PASS" : "FAIL 2"));
}
}
expect_stdout: "PASS"
}
reassign_call: {
options = {
comparisons: true,
conditionals: true,
passes: 2,
typeofs: true,
}
input: {
A = console;
function f() {
A = void 0;
}
if ("undefined" == typeof A)
console.log("FAIL 1");
else {
f();
while (console.log(void 0 === A ? "PASS" : "FAIL 2"));
}
}
expect: {
A = console;
function f() {
A = void 0;
}
if ("undefined" == typeof A)
console.log("FAIL 1");
else {
f();
while (console.log(void 0 === A ? "PASS" : "FAIL 2"));
}
}
expect_stdout: "PASS"
}
reassign_conditional: {
options = {
comparisons: true,
conditionals: true,
passes: 2,
typeofs: true,
}
input: {
A = console;
if ("undefined" == typeof A)
console.log("FAIL 1");
else {
A &&= void 0;
while (console.log(void 0 === A ? "PASS" : "FAIL 2"));
}
}
expect: {
A = console;
if ("undefined" == typeof A)
console.log("FAIL 1");
else {
A &&= void 0;
while (console.log(void 0 === A ? "PASS" : "FAIL 2"));
}
}
expect_stdout: "PASS"
node_version: ">=15"
}
reassign_do: {
options = {
comparisons: true,
conditionals: true,
if_return: true,
passes: 2,
reduce_vars: true,
typeofs: true,
}
input: {
A = console;
(function() {
if ("undefined" == typeof A)
return;
var a = A, i = 2;
do {
console.log(void 0 === A, void 0 === a);
A = void 0;
} while (--i);
})();
}
expect: {
A = console;
(function() {
if ("undefined" != typeof A) {
var a = A, i = 2;
do {
console.log(void 0 === A, (a, false));
A = void 0;
} while (--i);
}
})();
}
expect_stdout: [
"false false",
"true false",
]
}
reassign_for: {
options = {
comparisons: true,
conditionals: true,
passes: 2,
reduce_vars: true,
toplevel: true,
typeofs: true,
}
input: {
if (A = console, "undefined" != typeof A)
for (var a = A, i = 0; i < 2; i++)
console.log(void 0 === A, void 0 === a),
A = void 0;
}
expect: {
if (A = console, "undefined" != typeof A)
for (var a = A, i = 0; i < 2; i++)
console.log(void 0 === A, (a, false)),
A = void 0;
}
expect_stdout: [
"false false",
"true false",
]
}
reassign_for_in: {
options = {
comparisons: true,
conditionals: true,
passes: 2,
reduce_vars: true,
typeofs: true,
}
input: {
(A = console) && "undefined" != typeof A && function(a) {
for (var k in [ a = A, 42 ]) {
console.log(void 0 === A, void 0 === a);
A = void 0;
}
}();
}
expect: {
(A = console) && "undefined" != typeof A && function(a) {
for (var k in [ a = A, 42 ]) {
console.log(void 0 === A, (a, false));
A = void 0;
}
}();
}
expect_stdout: [
"false false",
"true false",
]
}
reassign_iife: {
options = {
comparisons: true,
conditionals: true,
passes: 2,
typeofs: true,
}
input: {
A = console;
if ("undefined" == typeof A)
console.log("FAIL 1");
else (function() {
A = void 0;
})(console.log(void 0 === A ? "FAIL 2" : "PASS"));
}
expect: {
A = console;
"undefined" == typeof A ? console.log("FAIL 1") : function() {
A = void 0;
}(console.log((A, false) ? "FAIL 2" : "PASS"));
}
expect_stdout: "PASS"
}
reassign_property: {
options = {
comparisons: true,
conditionals: true,
passes: 2,
typeofs: true,
}
input: {
A = console;
if ("undefined" == typeof A)
console.log("FAIL 1");
else {
A.p = void 0;
console.log(void 0 === A ? "FAIL 2" : "PASS");
}
}
expect: {
A = console;
if ("undefined" == typeof A)
console.log("FAIL 1");
else {
A.p = void 0;
console.log((A, false) ? "FAIL 2" : "PASS");
}
}
expect_stdout: "PASS"
}
issue_3817: {
options = {
comparisons: true,

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

@@ -13,10 +13,10 @@ reduce_merge_const: {
console.log(b);
}
expect: {
var b = console;
console.log(typeof b);
b = typeof b;
console.log(b);
var a = console;
console.log(typeof a);
a = typeof a;
console.log(a);
}
expect_stdout: [
"object",
@@ -41,10 +41,10 @@ reduce_merge_let: {
}
expect: {
"use strict";
var b = console;
console.log(typeof b);
b = typeof b;
console.log(b);
var a = console;
console.log(typeof a);
a = typeof a;
console.log(a);
}
expect_stdout: [
"object",
@@ -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"

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() {
@@ -737,7 +749,7 @@ lift_sequence: {
node_version: ">=4"
}
inline_nested_yield: {
inline_nested: {
options = {
inline: true,
sequences: true,
@@ -772,6 +784,118 @@ inline_nested_yield: {
node_version: ">=4"
}
inline_nested_async: {
options = {
awaits: true,
inline: true,
sequences: true,
side_effects: true,
yields: true,
}
input: {
console.log("foo");
var a = async function*() {
console.log(await(yield* async function*() {
yield {
then: r => r("bar"),
};
return "baz";
}()));
}();
console.log("moo");
a.next().then(function f(b) {
console.log(b.value);
b.done || a.next().then(f);
});
console.log("moz");
}
expect: {
console.log("foo");
var a = async function*() {
console.log((yield {
then: r => r("bar"),
}, await "baz"));
}();
console.log("moo"),
a.next().then(function f(b) {
console.log(b.value),
b.done || a.next().then(f);
}),
console.log("moz");
}
expect_stdout: [
"foo",
"moo",
"moz",
"bar",
"baz",
"undefined",
]
node_version: ">=10"
}
inline_nested_block: {
options = {
if_return: true,
inline: true,
yields: true,
}
input: {
var a = function*() {
yield* function*() {
for (var a of [ "foo", "bar" ])
yield a;
return "FAIL";
}();
}(), b;
do {
b = a.next();
console.log(b.value);
} while (!b.done);
}
expect: {
var a = function*() {
for (var a of [ "foo", "bar" ])
yield a;
"FAIL";
}(), b;
do {
b = a.next();
console.log(b.value);
} while (!b.done);
}
expect_stdout: [
"foo",
"bar",
"undefined",
]
node_version: ">=4"
}
dont_inline_nested: {
options = {
inline: true,
}
input: {
var yield = "PASS";
(function*() {
(function() {
console.log(yield);
})();
})().next();
}
expect: {
var yield = "PASS";
(function*() {
(function() {
console.log(yield);
})();
})().next();
}
expect_stdout: "PASS"
node_version: ">=4"
}
drop_body: {
options = {
side_effects: true,
@@ -852,10 +976,10 @@ issue_4454_2: {
f("PASS");
}
expect: {
function f(b) {
(function*(c = console.log(b)) {})();
var b = 42..toString();
console.log(b);
function f(a) {
(function*(c = console.log(a)) {})();
var a = 42..toString();
console.log(a);
}
f("PASS");
}
@@ -958,7 +1082,7 @@ issue_4639_1: {
}().next().value());
}
expect_stdout: "PASS"
node_version: ">=4"
node_version: ">=4 <7 || >=8.7.0"
}
issue_4639_2: {
@@ -1083,3 +1207,245 @@ 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(a) {
var a = log(a), c = a;
log(a);
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_1: {
options = {
evaluate: true,
hoist_vars: true,
pure_getters: "strict",
sequences: true,
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_5076_2: {
options = {
evaluate: true,
hoist_vars: true,
passes: 2,
pure_getters: "strict",
sequences: true,
side_effects: true,
toplevel: true,
unused: true,
yields: true,
}
input: {
var a;
console.log("PASS");
var b = function*({
p: {},
}) {}({
p: { a } = 42,
});
}
expect: {
console.log("PASS");
}
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

@@ -68,6 +68,8 @@ if (typeof phantom == "undefined") {
(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",

View File

@@ -2,6 +2,7 @@ var assert = require("assert");
var exec = require("child_process").exec;
var fs = require("fs");
var run_code = require("../sandbox").run_code;
var semver = require("semver");
var to_ascii = require("../node").to_ascii;
function read(path) {
@@ -12,10 +13,13 @@ describe("bin/uglifyjs", function() {
var uglifyjscmd = '"' + process.argv[0] + '" bin/uglifyjs';
it("Should produce a functional build when using --self", function(done) {
this.timeout(30000);
var command = uglifyjscmd + ' --self -cm --wrap WrappedUglifyJS';
exec(command, {
maxBuffer: 1048576
}, function(err, stdout) {
var command = [
uglifyjscmd,
"--self",
semver.satisfies(process.version, "<=0.12") ? "-mc hoist_funs" : "-mc",
"--wrap WrappedUglifyJS",
].join(" ");
exec(command, { maxBuffer: 1048576 }, function(err, stdout) {
if (err) throw err;
eval(stdout);
assert.strictEqual(typeof WrappedUglifyJS, "object");
@@ -184,6 +188,30 @@ describe("bin/uglifyjs", function() {
child.stdin.end(read("test/input/issue-3040/input.js"));
}, 1000);
});
it("Should work with --keep-fargs (mangle only)", function(done) {
var command = uglifyjscmd + ' test/input/issue-1431/sample.js --keep-fargs -m';
exec(command, function(err, stdout) {
if (err) throw err;
assert.strictEqual(stdout, "function f(x){return function(){function n(a){return a*a}return x(n)}}function g(op){return op(1)+op(2)}console.log(f(g)()==5);\n");
done();
});
});
it("Should work with --keep-fargs (mangle & compress)", function(done) {
var command = uglifyjscmd + ' test/input/issue-1431/sample.js --keep-fargs -m -c';
exec(command, function(err, stdout) {
if (err) throw err;
assert.strictEqual(stdout, "function f(x){return function(){return x(function(a){return a*a})}}function g(op){return op(1)+op(2)}console.log(5==f(g)());\n");
done();
});
});
it("Should work with keep_fargs under mangler options", function(done) {
var command = uglifyjscmd + ' test/input/issue-1431/sample.js -m keep_fargs=true';
exec(command, function(err, stdout) {
if (err) throw err;
assert.strictEqual(stdout, "function f(x){return function(){function n(a){return a*a}return x(n)}}function g(op){return op(1)+op(2)}console.log(f(g)()==5);\n");
done();
});
});
it("Should work with --keep-fnames (mangle only)", function(done) {
var command = uglifyjscmd + ' test/input/issue-1431/sample.js --keep-fnames -m';
exec(command, function(err, stdout) {
@@ -193,10 +221,10 @@ describe("bin/uglifyjs", function() {
});
});
it("Should work with --keep-fnames (mangle & compress)", function(done) {
var command = uglifyjscmd + ' test/input/issue-1431/sample.js --keep-fnames -m -c unused=false';
var command = uglifyjscmd + ' test/input/issue-1431/sample.js --keep-fnames -m -c';
exec(command, function(err, stdout) {
if (err) throw err;
assert.strictEqual(stdout, "function f(r){return function(){function n(n){return n*n}return r(n)}}function g(n){return n(1)+n(2)}console.log(5==f(g)());\n");
assert.strictEqual(stdout, "function f(n){return function(){return n(function n(r){return r*r})}}function g(n){return n(1)+n(2)}console.log(5==f(g)());\n");
done();
});
});
@@ -721,6 +749,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);
@@ -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,7 +281,8 @@ 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") ? [
if (semver.satisfies(process.version, "<=0.10")) {
assert.strictEqual(result.code, [
"// Can't reproduce test failure",
"// minify options: {",
'// "compress": false,',
@@ -291,7 +291,10 @@ describe("test/reduce.js", function() {
'// "beautify": true',
"// }",
"// }",
] : [
].join("\n"));
} else {
var message = result.code.split(/\n/, 3)[1].slice("// output: ".length);
assert.strictEqual(result.code, [
[
"try{",
"null[function(){}]",
@@ -299,9 +302,9 @@ describe("test/reduce.js", function() {
"console.log(e)",
"}",
].join(""),
"// output: TypeError: Cannot read property 'function(){}' of null",
"// output: " + message,
"// ",
"// minify: TypeError: Cannot read property 'function() {}' of null",
"// minify: " + message.replace("(){}", "() {}"),
"// ",
"// options: {",
'// "compress": false,',
@@ -310,7 +313,8 @@ describe("test/reduce.js", function() {
'// "beautify": true',
"// }",
"// }",
]).join("\n"));
].join("\n"));
}
});
it("Should maintain block-scope for const/let", function() {
if (semver.satisfies(process.version, "<4")) return;
@@ -414,4 +418,20 @@ describe("test/reduce.js", function() {
if (result.error) throw result.error;
assert.deepEqual(result.warnings, []);
});
it("Should handle thrown falsy values gracefully", function() {
var code = [
"throw 0;",
"setTimeout(null, 42);",
].join("\n");
var result = reduce_test(code, {
mangle: false,
});
if (result.error) throw result.error;
assert.strictEqual(result.code, [
"// Can't reproduce test failure",
"// minify options: {",
'// "mangle": false',
"// }",
].join("\n"));
});
});

View File

@@ -205,8 +205,8 @@ describe("sourcemaps", function() {
});
if (result.error) throw result.error;
assert.strictEqual(result.code, [
"var Foo=function(){console.log(3)};new Foo;var bar=function(o){return o};",
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIiwiMSJdLCJuYW1lcyI6WyJGb28iLCJjb25zb2xlIiwibG9nIiwiYmFyIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFNQSxJQUFJLFdBQWdCQyxRQUFRQyxJQUFJLElBQVMsSUFBSUYsSUNBbkQsSUFBSUcsSUFDQSxTQUFjQSxHQUNWLE9BQU9BIn0=",
"var Foo=function(){console.log(3)},bar=(new Foo,function(o){return o});",
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIiwiMSJdLCJuYW1lcyI6WyJGb28iLCJjb25zb2xlIiwibG9nIiwiYmFyIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFNQSxJQUFJLFdBQWdCQyxRQUFRQyxJQUFJLElDQWxDQyxLREEyQyxJQUFJSCxJQ0MvQyxTQUFjRyxHQUNWLE9BQU9BIn0=",
].join("\n"));
assert.deepEqual(result.warnings, [ "WARN: inline source map not found: 1" ]);
});
@@ -362,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

@@ -1,37 +1,42 @@
var assert = require("assert");
var exec = require("child_process").exec;
var semver = require("semver");
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 options = semver.satisfies(process.version, "<=0.12") ? "-mc hoist_funs" : "-mc";
var command = [
[
uglifyjs,
"--self",
options,
"--wrap SpiderUglify",
"-o spidermonkey",
].join(" "),
[
uglifyjs,
"-p spidermonkey",
options,
].join(" "),
].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) {
@@ -215,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);
}
});
@@ -395,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))) {
@@ -548,7 +548,7 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
}));
var before_iterations = testcase;
for (var c = 0; c < max_iterations; ++c) {
if (verbose && pass == 1 && c % 25 == 0) {
if (verbose && c % (pass == 1 ? 25 : 100) == 0) {
log("// reduce test pass " + pass + ", iteration " + c + ": " + testcase.length + " bytes");
}
var CHANGED = false;
@@ -726,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

@@ -43,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');

View File

@@ -26,9 +26,11 @@ exports.run_code = semver.satisfies(process.version, "0.8") ? function(code, top
return stdout;
} : semver.satisfies(process.version, "<0.12") ? run_code_vm : function(code, toplevel, timeout) {
if ([
/\basync[ \t]*\([\s\S]*?\)[ \t]*=>/,
/\b(async[ \t]+function|Promise|setImmediate|setInterval|setTimeout)\b/,
/\basync([ \t]+|[ \t]*#|[ \t]*\*[ \t]*)[^\s()[\]{},.&|!~=*%/+-]+(\s*\(|[ \t]*=>)/,
/\basync([ \t]+|[ \t]*#)[^\s()[\]{}#:;,.&|!~=*%/+-]+(\s*\(|[ \t]*=>)/,
/\basync[ \t]*\*[ \t]*[^\s()[\]{}#:;,.&|!~=*%/+-]+\s*\(/,
/\basync([ \t]*\*)?[ \t]*\[[\s\S]*?\]\s*\(/,
/\basync[ \t]*\([\s\S]*?\)[ \t]*=>/,
].some(function(pattern) {
return pattern.test(code);
})) {
@@ -51,13 +53,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, ",");
@@ -146,7 +148,8 @@ function setup(global, builtins, setup_log, setup_tty) {
delete ex[name];
}
}
process.stderr.write(inspect(value) + "\n\n-----===== UNCAUGHT EXCEPTION =====-----\n\n");
var marker = "\n\n-----===== UNCAUGHT EXCEPTION =====-----\n\n";
process.stderr.write(marker + inspect(value) + marker);
throw ex;
}).on("unhandledRejection", function() {});
}
@@ -202,13 +205,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]";
},
});
}
function self() {
return this;
@@ -254,8 +255,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 +269,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,22 +282,26 @@ 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 match = /\n([^:\s]*Error)(?:: ([\s\S]+?))?\n( at [\s\S]+)\n$/.exec(msg);
var marker = "\n\n-----===== UNCAUGHT EXCEPTION =====-----\n\n";
var start = msg.indexOf(marker) + marker.length;
var end = msg.indexOf(marker, start);
var details;
if (end >= 0) {
details = msg.slice(0, end).replace(/<([1-9][0-9]*) empty items?>/g, function(match, count) {
details = msg.slice(start, end).replace(/<([1-9][0-9]*) empty items?>/g, function(match, count) {
return new Array(+count).join();
});
try {
details = vm.runInNewContext("(" + details + ")");
} catch (e) {}
} else if (!match) {
return new Error("Script execution aborted.");
}
var match = /\n([^:\s]*Error)(?:: ([\s\S]+?))?\n( at [\s\S]+)\n$/.exec(msg);
if (!match) return details;
var ex = new global[match[1]](match[2]);
ex.stack = ex.stack.slice(0, ex.stack.indexOf(" at ")) + match[3];

View File

@@ -334,6 +334,7 @@ var VAR_NAMES = [
"arguments",
"async",
"await",
"let",
"yield",
];
var INITIAL_NAMES_LEN = VAR_NAMES.length;
@@ -352,7 +353,7 @@ var TYPEOF_OUTCOMES = [
];
var avoid_vars = [];
var block_vars = [];
var block_vars = [ "let" ];
var lambda_vars = [];
var unique_vars = [];
var classes = [];
@@ -399,7 +400,7 @@ 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;
@@ -2027,6 +2028,7 @@ function removeAvoidVar(name) {
function isBannedKeyword(name) {
switch (name) {
case "arguments":
case "let":
return in_class;
case "await":
return async !== false;
@@ -2078,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) {
@@ -2256,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();
@@ -2288,12 +2290,26 @@ function fuzzy_match(original, uglified) {
return true;
function collect(input, nums) {
return input.replace(/-?([1-9][0-9]*(\.[0-9]+)?|0\.[0-9]+)(e-?[1-9][0-9]*)?/ig, function(num) {
return input.replace(/-?([1-9][0-9]*(\.[0-9]+)?|0\.[0-9]+)(e-?[1-9][0-9]*)?/gi, function(num) {
return "<|" + nums.push(+num) + "|>";
});
}
}
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);
}
@@ -2336,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;
@@ -2454,7 +2470,9 @@ for (var round = 1; round <= num_iterations; round++) {
println(result);
println();
// ignore v8 parser bug
return bug_async_arrow_rest(result);
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);
@@ -2469,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)) {
@@ -2481,7 +2501,7 @@ for (var round = 1; round <= num_iterations; round++) {
}
}
// ignore declaration order of global variables
if (!ok && !toplevel) {
if (!ok && !toplevel && uglify_result.name != "SyntaxError" && original_result.name != "SyntaxError") {
ok = sandbox.same_stdout(run_code(sort_globals(original_code)), run_code(sort_globals(uglify_code)));
}
// ignore numerical imprecision caused by `unsafe_math`
@@ -2500,18 +2520,23 @@ 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);
if (typeof original_strict != "string") {
ok = typeof uglify_strict != "string";
var original_strict = run_code('"use strict";\n' + original_code, toplevel);
if (/^(Syntax|Type)Error$/.test(uglify_result.name)) {
ok = typeof original_strict != "string";
} else {
ok = sandbox.same_stdout(original_strict, uglify_strict);
ok = sandbox.same_stdout(original_strict, uglify_result);
}
}
// ignore difference in error message caused by `import` symbol redeclaration
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
},
{
@@ -26,6 +26,7 @@
"passes": 1e6,
"unsafe": true
},
"keep_fargs": true,
"keep_fnames": true,
"toplevel": true
},